19682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* 29682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL - Simple DirectMedia Layer 39682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Copyright (C) 1997-2012 Sam Lantinga 49682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 59682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall This library is free software; you can redistribute it and/or 69682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall modify it under the terms of the GNU Library General Public 79682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall License as published by the Free Software Foundation; either 89682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall version 2 of the License, or (at your option) any later version. 99682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall This library is distributed in the hope that it will be useful, 119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall but WITHOUT ANY WARRANTY; without even the implied warranty of 129682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 139682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Library General Public License for more details. 149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall You should have received a copy of the GNU Library General Public 169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall License along with this library; if not, write to the Free 179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Sam Lantinga 209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall slouken@libsdl.org 219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall*/ 229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#include "SDL_config.h" 239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 249682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#include "SDL_QuartzVideo.h" 259682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#include "SDL_QuartzWindow.h" 26e4c5d95ed37611acc6a186522315195b4ebfb9efJesse Hall#include "SDL_QuartzWM.h" 279682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 289682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* These APIs aren't just deprecated; they're gone from the headers in the 299682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 10.7 SDK. If we're using a >= 10.7 SDK, but targeting < 10.7, then we 309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall force these function declarations. */ 319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#if ((MAC_OS_X_VERSION_MIN_REQUIRED < 1070) && (MAC_OS_X_VERSION_MAX_ALLOWED >= 1070)) 329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse HallCG_EXTERN void *CGDisplayBaseAddress(CGDirectDisplayID display) 339682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall CG_AVAILABLE_BUT_DEPRECATED(__MAC_10_0, __MAC_10_6, 349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall __IPHONE_NA, __IPHONE_NA); 359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse HallCG_EXTERN size_t CGDisplayBytesPerRow(CGDirectDisplayID display) 369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall CG_AVAILABLE_BUT_DEPRECATED(__MAC_10_0, __MAC_10_6, 379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall __IPHONE_NA, __IPHONE_NA); 389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif 399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 419682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic inline BOOL IS_LION_OR_LATER(_THIS) 429682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{ 439682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return (system_version >= 0x1070); 449682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 459682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 469682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic inline BOOL IS_SNOW_LEOPARD_OR_LATER(_THIS) 479682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{ 489682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return (system_version >= 0x1060); 499682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 509682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 519682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#if (MAC_OS_X_VERSION_MAX_ALLOWED < 1060) && !defined(__LP64__) /* Fixed in Snow Leopard */ 529682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* 539682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Add methods to get at private members of NSScreen. 549682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Since there is a bug in Apple's screen switching code 559682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall that does not update this variable when switching 569682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall to fullscreen, we'll set it manually (but only for the 579682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall main screen). 589682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall*/ 599682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall@interface NSScreen (NSScreenAccess) 609682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall- (void) setFrame:(NSRect)frame; 619682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall@end 629682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 639682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall@implementation NSScreen (NSScreenAccess) 649682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall- (void) setFrame:(NSRect)frame; 659682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{ 669682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall _frame = frame; 679682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 689682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall@end 699682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic inline void QZ_SetFrame(_THIS, NSScreen *nsscreen, NSRect frame) 709682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{ 719682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (!IS_SNOW_LEOPARD_OR_LATER(this)) { 729682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall [nsscreen setFrame:frame]; 739682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 749682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 759682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#else 769682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic inline void QZ_SetFrame(_THIS, NSScreen *nsscreen, NSRect frame) 779682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{ 789682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 799682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif 809682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 819682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall@interface SDLTranslatorResponder : NSTextView 829682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{ 839682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 849682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall- (void) doCommandBySelector:(SEL)myselector; 859682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall@end 869682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 879682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall@implementation SDLTranslatorResponder 889682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall- (void) doCommandBySelector:(SEL) myselector {} 899682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall@end 909682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 919682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* absent in 10.3.9. */ 929682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse HallCG_EXTERN CGImageRef CGBitmapContextCreateImage (CGContextRef); 939682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 949682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* Bootstrap functions */ 959682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic int QZ_Available (); 969682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic SDL_VideoDevice* QZ_CreateDevice (int device_index); 979682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic void QZ_DeleteDevice (SDL_VideoDevice *device); 989682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 999682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* Initialization, Query, Setup, and Redrawing functions */ 1009682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic int QZ_VideoInit (_THIS, SDL_PixelFormat *video_format); 1019682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1029682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic SDL_Rect** QZ_ListModes (_THIS, SDL_PixelFormat *format, 1039682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Uint32 flags); 1049682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic void QZ_UnsetVideoMode (_THIS, BOOL to_desktop, BOOL save_gl); 1059682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1069682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic SDL_Surface* QZ_SetVideoMode (_THIS, SDL_Surface *current, 1079682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall int width, int height, int bpp, 1089682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Uint32 flags); 1099682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic int QZ_ToggleFullScreen (_THIS, int on); 1109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic int QZ_SetColors (_THIS, int first_color, 1119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall int num_colors, SDL_Color *colors); 1129682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1139682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#if (MAC_OS_X_VERSION_MIN_REQUIRED < 1070) 1149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic int QZ_LockDoubleBuffer (_THIS, SDL_Surface *surface); 1159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic void QZ_UnlockDoubleBuffer (_THIS, SDL_Surface *surface); 1169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic int QZ_ThreadFlip (_THIS); 1179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic int QZ_FlipDoubleBuffer (_THIS, SDL_Surface *surface); 1189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic void QZ_DoubleBufferUpdate (_THIS, int num_rects, SDL_Rect *rects); 1199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic void QZ_DirectUpdate (_THIS, int num_rects, SDL_Rect *rects); 1209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif 1219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic void QZ_UpdateRects (_THIS, int num_rects, SDL_Rect *rects); 1239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic void QZ_VideoQuit (_THIS); 1249682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1259682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic int QZ_LockHWSurface(_THIS, SDL_Surface *surface); 1269682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic void QZ_UnlockHWSurface(_THIS, SDL_Surface *surface); 1279682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic int QZ_AllocHWSurface(_THIS, SDL_Surface *surface); 1289682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic void QZ_FreeHWSurface (_THIS, SDL_Surface *surface); 1299682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* Bootstrap binding, enables entry point into the driver */ 1319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse HallVideoBootStrap QZ_bootstrap = { 1329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall "Quartz", "Mac OS X CoreGraphics", QZ_Available, QZ_CreateDevice 1339682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall}; 1349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* Disable compiler warnings we can't avoid. */ 1369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#if (defined(__GNUC__) && (__GNUC__ >= 4)) 1379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall# if (MAC_OS_X_VERSION_MAX_ALLOWED <= 1070) 1389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall# pragma GCC diagnostic ignored "-Wdeprecated-declarations" 1399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall# endif 1409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif 1419682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1429682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic void QZ_ReleaseDisplayMode(_THIS, const void *moderef) 1439682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{ 1449682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* we only own these references in the 10.6+ API. */ 1459682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#if (MAC_OS_X_VERSION_MAX_ALLOWED >= 1060) 1469682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (use_new_mode_apis) { 1479682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall CGDisplayModeRelease((CGDisplayModeRef) moderef); 1489682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 1499682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif 1509682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 1519682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1529682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic void QZ_ReleaseDisplayModeList(_THIS, CFArrayRef mode_list) 1539682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{ 1549682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* we only own these references in the 10.6+ API. */ 1559682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#if (MAC_OS_X_VERSION_MAX_ALLOWED >= 1060) 1569682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (use_new_mode_apis) { 1579682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall CFRelease(mode_list); 1589682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 1599682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif 1609682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 1619682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1629682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1639682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* Bootstrap functions */ 1649682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic int QZ_Available () 1659682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{ 1669682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return 1; 1679682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 1689682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1699682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic SDL_VideoDevice* QZ_CreateDevice (int device_index) 1709682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{ 1719682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#pragma unused (device_index) 1729682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1739682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_VideoDevice *device; 1749682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_PrivateVideoData *hidden; 1759682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1769682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall device = (SDL_VideoDevice*) SDL_malloc (sizeof (*device) ); 1779682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall hidden = (SDL_PrivateVideoData*) SDL_malloc (sizeof (*hidden) ); 1789682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1799682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (device == NULL || hidden == NULL) 1809682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_OutOfMemory (); 1819682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1829682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_memset (device, 0, sizeof (*device) ); 1839682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_memset (hidden, 0, sizeof (*hidden) ); 1849682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1859682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall device->hidden = hidden; 1869682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1879682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall device->VideoInit = QZ_VideoInit; 1889682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall device->ListModes = QZ_ListModes; 1899682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall device->SetVideoMode = QZ_SetVideoMode; 1909682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall device->ToggleFullScreen = QZ_ToggleFullScreen; 1919682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall device->UpdateMouse = QZ_UpdateMouse; 1929682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall device->SetColors = QZ_SetColors; 1939682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* device->UpdateRects = QZ_UpdateRects; this is determined by SetVideoMode() */ 1949682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall device->VideoQuit = QZ_VideoQuit; 1959682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1969682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall device->LockHWSurface = QZ_LockHWSurface; 1979682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall device->UnlockHWSurface = QZ_UnlockHWSurface; 1989682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall device->AllocHWSurface = QZ_AllocHWSurface; 1999682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall device->FreeHWSurface = QZ_FreeHWSurface; 2009682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 2019682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall device->SetGamma = QZ_SetGamma; 2029682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall device->GetGamma = QZ_GetGamma; 2039682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall device->SetGammaRamp = QZ_SetGammaRamp; 2049682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall device->GetGammaRamp = QZ_GetGammaRamp; 2059682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 2069682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall device->GL_GetProcAddress = QZ_GL_GetProcAddress; 2079682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall device->GL_GetAttribute = QZ_GL_GetAttribute; 2089682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall device->GL_MakeCurrent = QZ_GL_MakeCurrent; 2099682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall device->GL_SwapBuffers = QZ_GL_SwapBuffers; 2109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall device->GL_LoadLibrary = QZ_GL_LoadLibrary; 2119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 2129682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall device->FreeWMCursor = QZ_FreeWMCursor; 2139682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall device->CreateWMCursor = QZ_CreateWMCursor; 2149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall device->ShowWMCursor = QZ_ShowWMCursor; 2159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall device->WarpWMCursor = QZ_WarpWMCursor; 2169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall device->MoveWMCursor = QZ_MoveWMCursor; 2179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall device->CheckMouseMode = QZ_CheckMouseMode; 2189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall device->InitOSKeymap = QZ_InitOSKeymap; 2199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall device->PumpEvents = QZ_PumpEvents; 2209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 2219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall device->SetCaption = QZ_SetCaption; 2229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall device->SetIcon = QZ_SetIcon; 2239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall device->IconifyWindow = QZ_IconifyWindow; 224e4c5d95ed37611acc6a186522315195b4ebfb9efJesse Hall device->SetWindowPos = QZ_SetWindowPos; 225e4c5d95ed37611acc6a186522315195b4ebfb9efJesse Hall device->GetWindowPos = QZ_GetWindowPos; 226e4c5d95ed37611acc6a186522315195b4ebfb9efJesse Hall device->IsWindowVisible = QZ_IsWindowVisible; 227e4c5d95ed37611acc6a186522315195b4ebfb9efJesse Hall device->GetMonitorDPI = QZ_GetMonitorDPI; 228e4c5d95ed37611acc6a186522315195b4ebfb9efJesse Hall device->GetMonitorRect = QZ_GetMonitorRect; 229e4c5d95ed37611acc6a186522315195b4ebfb9efJesse Hall device->GetWMInfo = QZ_GetWMInfo; 2309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall device->GrabInput = QZ_GrabInput; 2319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 2329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* 2339682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * This is a big hassle, needing QuickDraw and QuickTime on older 2349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * systems, and god knows what on 10.6, so we immediately fail here, 2359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * which causes SDL to make an RGB surface and manage the YUV overlay 2369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * in software. Sorry. Use SDL 1.3 if you want YUV rendering in a pixel 2379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * shader. :) 2389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall */ 2399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /*device->CreateYUVOverlay = QZ_CreateYUVOverlay;*/ 2409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 2419682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall device->free = QZ_DeleteDevice; 2429682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 2439682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return device; 2449682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 2459682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 2469682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic void QZ_DeleteDevice (SDL_VideoDevice *device) 2479682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{ 2489682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall _THIS = device; 2499682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall QZ_ReleaseDisplayMode(this, save_mode); 2509682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall QZ_ReleaseDisplayMode(this, mode); 2519682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_free (device->hidden); 2529682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_free (device); 2539682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 2549682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 2559682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic void QZ_GetModeInfo(_THIS, const void *_mode, Uint32 *w, Uint32 *h, Uint32 *bpp) 2569682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{ 2579682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall *w = *h = *bpp = 0; 2589682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (_mode == NULL) { 2599682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return; 2609682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 2619682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 2629682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#if (MAC_OS_X_VERSION_MAX_ALLOWED >= 1060) 2639682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (use_new_mode_apis) { 2649682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall CGDisplayModeRef vidmode = (CGDisplayModeRef) _mode; 2659682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall CFStringRef fmt = CGDisplayModeCopyPixelEncoding(vidmode); 2669682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 2679682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall *w = (Uint32) CGDisplayModeGetWidth(vidmode); 2689682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall *h = (Uint32) CGDisplayModeGetHeight(vidmode); 2699682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 2709682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* we only care about the 32-bit modes... */ 2719682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (CFStringCompare(fmt, CFSTR(IO32BitDirectPixels), 2729682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall kCFCompareCaseInsensitive) == kCFCompareEqualTo) { 2739682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall *bpp = 32; 2749682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 2759682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 2769682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall CFRelease(fmt); 2779682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 2789682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif 2799682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 2809682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#if (MAC_OS_X_VERSION_MIN_REQUIRED < 1060) 2819682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (!use_new_mode_apis) { 2829682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall CFDictionaryRef vidmode = (CFDictionaryRef) _mode; 2839682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall CFNumberGetValue ( 2849682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall CFDictionaryGetValue (vidmode, kCGDisplayBitsPerPixel), 2859682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall kCFNumberSInt32Type, bpp); 2869682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 2879682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall CFNumberGetValue ( 2889682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall CFDictionaryGetValue (vidmode, kCGDisplayWidth), 2899682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall kCFNumberSInt32Type, w); 2909682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 2919682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall CFNumberGetValue ( 2929682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall CFDictionaryGetValue (vidmode, kCGDisplayHeight), 2939682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall kCFNumberSInt32Type, h); 2949682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 2959682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif 2969682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 2979682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* we only care about the 32-bit modes... */ 2989682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (*bpp != 32) { 2999682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall *bpp = 0; 3009682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 3019682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 3029682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 3039682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic int QZ_VideoInit (_THIS, SDL_PixelFormat *video_format) 3049682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{ 3059682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall NSRect r = NSMakeRect(0.0, 0.0, 0.0, 0.0); 3069682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall const char *env = NULL; 3079682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 3089682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( Gestalt(gestaltSystemVersion, &system_version) != noErr ) 3099682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall system_version = 0; 3109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 3119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall use_new_mode_apis = NO; 3129682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 3139682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#if (MAC_OS_X_VERSION_MAX_ALLOWED >= 1060) 3149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall use_new_mode_apis = IS_SNOW_LEOPARD_OR_LATER(this); 3159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif 3169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 3179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Initialize the video settings; this data persists between mode switches */ 3189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall display_id = kCGDirectMainDisplay; 3199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 3209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#if 0 /* The mouse event code needs to take this into account... */ 3219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall env = getenv("SDL_VIDEO_FULLSCREEN_DISPLAY"); 3229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( env ) { 3239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall int monitor = SDL_atoi(env); 3249682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall CGDirectDisplayID activeDspys [3]; 3259682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall CGDisplayCount dspyCnt; 3269682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall CGGetActiveDisplayList (3, activeDspys, &dspyCnt); 3279682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( monitor >= 0 && monitor < dspyCnt ) { 3289682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall display_id = activeDspys[monitor]; 3299682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 3309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 3319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif 3329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 3339682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#if (MAC_OS_X_VERSION_MAX_ALLOWED >= 1060) 3349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (use_new_mode_apis) { 3359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall save_mode = CGDisplayCopyDisplayMode(display_id); 3369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 3379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif 3389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 3399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#if (MAC_OS_X_VERSION_MIN_REQUIRED < 1060) 3409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (!use_new_mode_apis) { 3419682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall save_mode = CGDisplayCurrentMode(display_id); 3429682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 3439682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif 3449682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 3459682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#if (MAC_OS_X_VERSION_MIN_REQUIRED < 1070) 3469682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (!IS_LION_OR_LATER(this)) { 3479682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall palette = CGPaletteCreateDefaultColorPalette(); 3489682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 3499682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif 3509682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 3519682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (save_mode == NULL) { 3529682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_SetError("Couldn't figure out current display mode."); 3539682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return -1; 3549682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 3559682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 3569682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Allow environment override of screensaver disable. */ 3579682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall env = SDL_getenv("SDL_VIDEO_ALLOW_SCREENSAVER"); 3589682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( env ) { 3599682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall allow_screensaver = SDL_atoi(env); 3609682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } else { 3619682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#ifdef SDL_VIDEO_DISABLE_SCREENSAVER 3629682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall allow_screensaver = 0; 3639682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#else 3649682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall allow_screensaver = 1; 3659682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif 3669682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 3679682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 3689682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Gather some information that is useful to know about the display */ 3699682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall QZ_GetModeInfo(this, save_mode, &device_width, &device_height, &device_bpp); 3709682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (device_bpp == 0) { 3719682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall QZ_ReleaseDisplayMode(this, save_mode); 3729682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall save_mode = NULL; 3739682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_SetError("Unsupported display mode"); 3749682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return -1; 3759682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 3769682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 3779682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Determine the current screen size */ 3789682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall this->info.current_w = device_width; 3799682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall this->info.current_h = device_height; 3809682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 3819682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Determine the default screen depth */ 3829682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall video_format->BitsPerPixel = device_bpp; 3839682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 3849682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Set misc globals */ 3859682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall current_grab_mode = SDL_GRAB_OFF; 3869682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall cursor_should_be_visible = YES; 3879682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall cursor_visible = YES; 3889682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall current_mods = 0; 3899682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall field_edit = [[SDLTranslatorResponder alloc] initWithFrame:r]; 3909682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 3919682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* register for sleep notifications so wake from sleep generates SDL_VIDEOEXPOSE */ 3929682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall QZ_RegisterForSleepNotifications (this); 3939682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 3949682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Fill in some window manager capabilities */ 3959682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall this->info.wm_available = 1; 3969682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 3979682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return 0; 3989682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 3999682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 4009682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic SDL_Rect** QZ_ListModes (_THIS, SDL_PixelFormat *format, Uint32 flags) 4019682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{ 4029682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall CFArrayRef mode_list = NULL; /* list of available fullscreen modes */ 4039682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall CFIndex num_modes; 4049682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall CFIndex i; 4059682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 4069682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall int list_size = 0; 4079682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 4089682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Any windowed mode is acceptable */ 4099682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( (flags & SDL_FULLSCREEN) == 0 ) 4109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return (SDL_Rect**)-1; 4119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 4129682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Free memory from previous call, if any */ 4139682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( client_mode_list != NULL ) { 4149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall int i; 4159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 4169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall for (i = 0; client_mode_list[i] != NULL; i++) 4179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_free (client_mode_list[i]); 4189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 4199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_free (client_mode_list); 4209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall client_mode_list = NULL; 4219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 4229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 4239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#if (MAC_OS_X_VERSION_MAX_ALLOWED >= 1060) 4249682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (use_new_mode_apis) { 4259682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mode_list = CGDisplayCopyAllDisplayModes(display_id, NULL); 4269682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 4279682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif 4289682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 4299682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#if (MAC_OS_X_VERSION_MIN_REQUIRED < 1060) 4309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (!use_new_mode_apis) { 4319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mode_list = CGDisplayAvailableModes(display_id); 4329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 4339682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif 4349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 4359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall num_modes = CFArrayGetCount (mode_list); 4369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 4379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Build list of modes with the requested bpp */ 4389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall for (i = 0; i < num_modes; i++) { 4399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Uint32 width, height, bpp; 4409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall const void *onemode = CFArrayGetValueAtIndex(mode_list, i); 4419682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 4429682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall QZ_GetModeInfo(this, onemode, &width, &height, &bpp); 4439682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 4449682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (bpp && (bpp == format->BitsPerPixel)) { 4459682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall int hasMode = SDL_FALSE; 4469682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall int i; 4479682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 4489682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Check if mode is already in the list */ 4499682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall for (i = 0; i < list_size; i++) { 4509682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (client_mode_list[i]->w == width && 4519682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall client_mode_list[i]->h == height) { 4529682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall hasMode = SDL_TRUE; 4539682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall break; 4549682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 4559682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 4569682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 4579682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Grow the list and add mode to the list */ 4589682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( ! hasMode ) { 4599682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_Rect *rect; 4609682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 4619682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall list_size++; 4629682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 4639682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (client_mode_list == NULL) 4649682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall client_mode_list = (SDL_Rect**) 4659682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_malloc (sizeof(*client_mode_list) * (list_size+1) ); 4669682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else { 4679682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* !!! FIXME: this leaks memory if SDL_realloc() fails! */ 4689682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall client_mode_list = (SDL_Rect**) 4699682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_realloc (client_mode_list, sizeof(*client_mode_list) * (list_size+1)); 4709682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 4719682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 4729682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall rect = (SDL_Rect*) SDL_malloc (sizeof(**client_mode_list)); 4739682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 4749682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (client_mode_list == NULL || rect == NULL) { 4759682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall QZ_ReleaseDisplayModeList(this, mode_list); 4769682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_OutOfMemory (); 4779682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return NULL; 4789682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 4799682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 4809682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall rect->x = rect->y = 0; 4819682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall rect->w = width; 4829682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall rect->h = height; 4839682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 4849682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall client_mode_list[list_size-1] = rect; 4859682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall client_mode_list[list_size] = NULL; 4869682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 4879682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 4889682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 4899682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 4909682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall QZ_ReleaseDisplayModeList(this, mode_list); 4919682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 4929682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Sort list largest to smallest (by area) */ 4939682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall { 4949682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall int i, j; 4959682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall for (i = 0; i < list_size; i++) { 4969682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall for (j = 0; j < list_size-1; j++) { 4979682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 4989682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall int area1, area2; 4999682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall area1 = client_mode_list[j]->w * client_mode_list[j]->h; 5009682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall area2 = client_mode_list[j+1]->w * client_mode_list[j+1]->h; 5019682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 5029682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (area1 < area2) { 5039682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_Rect *tmp = client_mode_list[j]; 5049682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall client_mode_list[j] = client_mode_list[j+1]; 5059682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall client_mode_list[j+1] = tmp; 5069682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 5079682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 5089682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 5099682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 5109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 5119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return client_mode_list; 5129682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 5139682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 5149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic SDL_bool QZ_WindowPosition(_THIS, int *x, int *y) 5159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{ 5169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall const char *window = getenv("SDL_VIDEO_WINDOW_POS"); 5179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( window ) { 5189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( sscanf(window, "%d,%d", x, y) == 2 ) { 5199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return SDL_TRUE; 5209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 5219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 5229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return SDL_FALSE; 5239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 5249682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 5259682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic CGError QZ_SetDisplayMode(_THIS, const void *vidmode) 5269682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{ 5279682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#if (MAC_OS_X_VERSION_MAX_ALLOWED >= 1060) 5289682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (use_new_mode_apis) { 5299682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return CGDisplaySetDisplayMode(display_id, (CGDisplayModeRef) vidmode, NULL); 5309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 5319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif 5329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 5339682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#if (MAC_OS_X_VERSION_MIN_REQUIRED < 1060) 5349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (!use_new_mode_apis) { 5359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return CGDisplaySwitchToMode(display_id, (CFDictionaryRef) vidmode); 5369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 5379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif 5389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 5399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return kCGErrorFailure; 5409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 5419682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 5429682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic inline CGError QZ_RestoreDisplayMode(_THIS) 5439682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{ 5449682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return QZ_SetDisplayMode(this, save_mode); 5459682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 5469682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 5479682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic void QZ_UnsetVideoMode (_THIS, BOOL to_desktop, BOOL save_gl) 5489682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{ 5499682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Reset values that may change between switches */ 5509682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall this->info.blit_fill = 0; 5519682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall this->FillHWRect = NULL; 5529682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall this->UpdateRects = NULL; 5539682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall this->LockHWSurface = NULL; 5549682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall this->UnlockHWSurface = NULL; 5559682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 5569682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (cg_context) { 5579682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall CGContextFlush (cg_context); 5589682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall CGContextRelease (cg_context); 5599682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall cg_context = nil; 5609682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 5619682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 5629682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Release fullscreen resources */ 5639682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( mode_flags & SDL_FULLSCREEN ) { 5649682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 5659682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall NSRect screen_rect; 5669682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 5679682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Release double buffer stuff */ 5689682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#if (MAC_OS_X_VERSION_MIN_REQUIRED < 1070) 5699682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( !IS_LION_OR_LATER(this) && (mode_flags & SDL_DOUBLEBUF) ) { 5709682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall quit_thread = YES; 5719682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_SemPost (sem1); 5729682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_WaitThread (thread, NULL); 5739682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_DestroySemaphore (sem1); 5749682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_DestroySemaphore (sem2); 5759682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_free (sw_buffers[0]); 5769682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 5779682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif 5789682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 5799682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* If we still have a valid window, close it. */ 5809682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( qz_window ) { 5819682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall NSCAssert([ qz_window delegate ] == nil, @"full screen window shouldn't have a delegate"); /* if that should ever change, we'd have to release it here */ 5829682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall [ qz_window close ]; /* includes release because [qz_window isReleasedWhenClosed] */ 5839682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall qz_window = nil; 5849682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall window_view = nil; 5859682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 5869682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* 5879682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Release the OpenGL context 5889682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Do this first to avoid trash on the display before fade 5899682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall */ 5909682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( mode_flags & SDL_OPENGL ) { 5919682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (!save_gl) { 5929682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall QZ_TearDownOpenGL (this); 5939682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 5949682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 5959682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall #ifdef __powerpc__ /* we only use this for pre-10.3 compatibility. */ 5969682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall CGLSetFullScreen (NULL); 5979682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall #endif 5989682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 5999682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (to_desktop) { 6009682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* !!! FIXME: keep an eye on this. 6019682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * This API is officially unavailable for 64-bit binaries. 6029682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * It happens to work, as of 10.7, but we're going to see if 6039682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * we can just simply do without it on newer OSes... 6049682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall */ 6059682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall #if (MAC_OS_X_VERSION_MIN_REQUIRED < 1070) && !defined(__LP64__) 6069682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( !IS_LION_OR_LATER(this) ) { 6079682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall ShowMenuBar (); 6089682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 6099682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall #endif 6109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 6119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Restore original screen resolution/bpp */ 6129682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall QZ_RestoreDisplayMode (this); 6139682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall CGReleaseAllDisplays (); 6149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* 6159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Reset the main screen's rectangle 6169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall See comment in QZ_SetVideoFullscreen for why we do this 6179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall */ 6189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall screen_rect = NSMakeRect(0,0,device_width,device_height); 6199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall QZ_SetFrame(this, [ NSScreen mainScreen ], screen_rect); 6209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 6219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 6229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Release window mode resources */ 6239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else { 6249682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall id delegate = [ qz_window delegate ]; 6259682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall [ qz_window close ]; /* includes release because [qz_window isReleasedWhenClosed] */ 6269682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (delegate != nil) [ delegate release ]; 6279682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall qz_window = nil; 6289682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall window_view = nil; 6299682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 6309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Release the OpenGL context */ 6319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( mode_flags & SDL_OPENGL ) { 6329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (!save_gl) { 6339682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall QZ_TearDownOpenGL (this); 6349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 6359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 6369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 6379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 6389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Signal successful teardown */ 6399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall video_set = SDL_FALSE; 6409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 6419682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 6429682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic const void *QZ_BestMode(_THIS, const int bpp, const int w, const int h) 6439682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{ 6449682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall const void *best = NULL; 6459682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 6469682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (bpp == 0) { 6479682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return NULL; 6489682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 6499682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 6509682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#if (MAC_OS_X_VERSION_MAX_ALLOWED >= 1060) 6519682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (use_new_mode_apis) { 6529682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* apparently, we have to roll our own now. :/ */ 6539682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall CFArrayRef mode_list = CGDisplayCopyAllDisplayModes(display_id, NULL); 6549682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (mode_list != NULL) { 6559682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall const CFIndex num_modes = CFArrayGetCount(mode_list); 6569682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall CFIndex i; 6579682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall for (i = 0; i < num_modes; i++) { 6589682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall const void *vidmode = CFArrayGetValueAtIndex(mode_list, i); 6599682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Uint32 thisw, thish, thisbpp; 6609682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall QZ_GetModeInfo(this, vidmode, &thisw, &thish, &thisbpp); 6619682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 6629682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* We only care about exact matches, apparently. */ 6639682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ((thisbpp == bpp) && (thisw == w) && (thish == h)) { 6649682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall best = vidmode; 6659682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall break; /* got it! */ 6669682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 6679682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 6689682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall CGDisplayModeRetain((CGDisplayModeRef) best); /* NULL is ok */ 6699682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall CFRelease(mode_list); 6709682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 6719682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 6729682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif 6739682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 6749682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#if (MAC_OS_X_VERSION_MIN_REQUIRED < 1060) 6759682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (!use_new_mode_apis) { 6769682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall boolean_t exact = 0; 6779682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall best = CGDisplayBestModeForParameters(display_id, bpp, w, h, &exact); 6789682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (!exact) { 6799682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall best = NULL; 6809682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 6819682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 6829682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif 6839682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 6849682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return best; 6859682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 6869682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 6879682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic SDL_Surface* QZ_SetVideoFullScreen (_THIS, SDL_Surface *current, int width, 6889682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall int height, int bpp, Uint32 flags, 6899682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall const BOOL save_gl) 6909682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{ 6919682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall const BOOL isLion = IS_LION_OR_LATER(this); 6929682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall NSRect screen_rect; 6939682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall CGError error; 6949682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall NSRect contentRect; 6959682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall CGDisplayFadeReservationToken fade_token = kCGDisplayFadeReservationInvalidToken; 6969682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 6979682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall current->flags = SDL_FULLSCREEN; 6989682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall current->w = width; 6999682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall current->h = height; 7009682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 7019682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall contentRect = NSMakeRect (0, 0, width, height); 7029682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 7039682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Fade to black to hide resolution-switching flicker (and garbage 7049682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall that is displayed by a destroyed OpenGL context, if applicable) */ 7059682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( CGAcquireDisplayFadeReservation (5, &fade_token) == kCGErrorSuccess ) { 7069682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall CGDisplayFade (fade_token, 0.3, kCGDisplayBlendNormal, kCGDisplayBlendSolidColor, 0.0, 0.0, 0.0, TRUE); 7079682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 7089682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 7099682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Destroy any previous mode */ 7109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (video_set == SDL_TRUE) 7119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall QZ_UnsetVideoMode (this, FALSE, save_gl); 7129682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 7139682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Sorry, QuickDraw was ripped out. */ 7149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (getenv("SDL_NSWindowPointer") || getenv("SDL_NSQuickDrawViewPointer")) { 7159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_SetError ("Embedded QuickDraw windows are no longer supported"); 7169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall goto ERR_NO_MATCH; 7179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 7189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 7199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall QZ_ReleaseDisplayMode(this, mode); /* NULL is okay. */ 7209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 7219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* See if requested mode exists */ 7229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mode = QZ_BestMode(this, bpp, width, height); 7239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 7249682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Require an exact match to the requested mode */ 7259682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( mode == NULL ) { 7269682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_SetError ("Failed to find display resolution: %dx%dx%d", width, height, bpp); 7279682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall goto ERR_NO_MATCH; 7289682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 7299682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 7309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Put up the blanking window (a window above all other windows) */ 7319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (getenv ("SDL_SINGLEDISPLAY")) 7329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall error = CGDisplayCapture (display_id); 7339682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else 7349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall error = CGCaptureAllDisplays (); 7359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 7369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( CGDisplayNoErr != error ) { 7379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_SetError ("Failed capturing display"); 7389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall goto ERR_NO_CAPTURE; 7399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 7409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 7419682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Do the physical switch */ 7429682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( CGDisplayNoErr != QZ_SetDisplayMode(this, mode) ) { 7439682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_SetError ("Failed switching display resolution"); 7449682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall goto ERR_NO_SWITCH; 7459682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 7469682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 7479682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#if (MAC_OS_X_VERSION_MIN_REQUIRED < 1070) 7489682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( !isLion ) { 7499682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall current->pixels = (Uint32*) CGDisplayBaseAddress (display_id); 7509682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall current->pitch = CGDisplayBytesPerRow (display_id); 7519682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 7529682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall current->flags |= SDL_HWSURFACE; 7539682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall current->flags |= SDL_PREALLOC; 7549682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* current->hwdata = (void *) CGDisplayGetDrawingContext (display_id); */ 7559682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 7569682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall this->UpdateRects = QZ_DirectUpdate; 7579682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall this->LockHWSurface = QZ_LockHWSurface; 7589682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall this->UnlockHWSurface = QZ_UnlockHWSurface; 7599682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 7609682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Setup double-buffer emulation */ 7619682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( flags & SDL_DOUBLEBUF ) { 7629682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 7639682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* 7649682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Setup a software backing store for reasonable results when 7659682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall double buffering is requested (since a single-buffered hardware 7669682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall surface looks hideous). 7679682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 7689682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall The actual screen blit occurs in a separate thread to allow 7699682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall other blitting while waiting on the VBL (and hence results in higher framerates). 7709682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall */ 7719682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall this->LockHWSurface = NULL; 7729682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall this->UnlockHWSurface = NULL; 7739682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall this->UpdateRects = NULL; 7749682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 7759682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall current->flags |= (SDL_HWSURFACE|SDL_DOUBLEBUF); 7769682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall this->UpdateRects = QZ_DoubleBufferUpdate; 7779682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall this->LockHWSurface = QZ_LockDoubleBuffer; 7789682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall this->UnlockHWSurface = QZ_UnlockDoubleBuffer; 7799682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall this->FlipHWSurface = QZ_FlipDoubleBuffer; 7809682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 7819682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall current->pixels = SDL_malloc (current->pitch * current->h * 2); 7829682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (current->pixels == NULL) { 7839682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_OutOfMemory (); 7849682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall goto ERR_DOUBLEBUF; 7859682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 7869682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 7879682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall sw_buffers[0] = current->pixels; 7889682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall sw_buffers[1] = (Uint8*)current->pixels + current->pitch * current->h; 7899682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 7909682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall quit_thread = NO; 7919682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall sem1 = SDL_CreateSemaphore (0); 7929682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall sem2 = SDL_CreateSemaphore (1); 7939682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall thread = SDL_CreateThread ((int (*)(void *))QZ_ThreadFlip, this); 7949682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 7959682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 7969682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( CGDisplayCanSetPalette (display_id) ) 7979682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall current->flags |= SDL_HWPALETTE; 7989682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 7999682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif 8009682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 8019682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Check if we should recreate the window */ 8029682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (qz_window == nil) { 8039682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Manually create a window, avoids having a nib file resource */ 8049682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall qz_window = [ [ SDL_QuartzWindow alloc ] 8059682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall initWithContentRect:contentRect 8069682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall styleMask:(isLion ? NSBorderlessWindowMask : 0) 8079682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall backing:NSBackingStoreBuffered 8089682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall defer:NO ]; 8099682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 8109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (qz_window != nil) { 8119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall [ qz_window setAcceptsMouseMovedEvents:YES ]; 8129682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall [ qz_window setViewsNeedDisplay:NO ]; 8139682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (isLion) { 8149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall [ qz_window setContentView: [ [ [ SDL_QuartzView alloc ] init ] autorelease ] ]; 8159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 8169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 8179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 8189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* We already have a window, just change its size */ 8199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else { 8209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall [ qz_window setContentSize:contentRect.size ]; 8219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall current->flags |= (SDL_NOFRAME|SDL_RESIZABLE) & mode_flags; 8229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall [ window_view setFrameSize:contentRect.size ]; 8239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 8249682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 8259682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Setup OpenGL for a fullscreen context */ 8269682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (flags & SDL_OPENGL) { 8279682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 8289682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( ! save_gl ) { 8299682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( ! QZ_SetupOpenGL (this, bpp, flags) ) { 8309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall goto ERR_NO_GL; 8319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 8329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 8339682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 8349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Initialize the NSView and add it to our window. The presence of a valid window and 8359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall view allow the cursor to be changed whilst in fullscreen.*/ 8369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall window_view = [ [ NSView alloc ] initWithFrame:contentRect ]; 8379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 8389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( isLion ) { 8399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall [ window_view setAutoresizingMask: NSViewWidthSizable | NSViewHeightSizable ]; 8409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 8419682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 8429682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall [ [ qz_window contentView ] addSubview:window_view ]; 8439682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 8449682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Apparently Lion checks some version flag set by the linker 8459682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall and changes API behavior. Annoying. */ 8469682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( isLion ) { 8479682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall [ qz_window setLevel:CGShieldingWindowLevel() ]; 8489682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall [ gl_context setView: window_view ]; 8499682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall //[ gl_context setFullScreen ]; 8509682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall [ gl_context update ]; 8519682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 8529682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 8539682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#if (MAC_OS_X_VERSION_MIN_REQUIRED < 1070) 8549682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( !isLion ) { 8559682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall CGLError err; 8569682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall CGLContextObj ctx; 8579682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 8589682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall [ qz_window setLevel:NSNormalWindowLevel ]; 8599682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall ctx = QZ_GetCGLContextObj (gl_context); 8609682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall err = CGLSetFullScreen (ctx); 8619682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 8629682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (err) { 8639682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_SetError ("Error setting OpenGL fullscreen: %s", CGLErrorString(err)); 8649682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall goto ERR_NO_GL; 8659682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 8669682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 8679682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif 8689682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 8699682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall [ window_view release ]; 8709682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall [ gl_context makeCurrentContext]; 8719682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 8729682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall glClear (GL_COLOR_BUFFER_BIT); 8739682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 8749682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall [ gl_context flushBuffer ]; 8759682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 8769682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall current->flags |= SDL_OPENGL; 8779682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } else if (isLion) { /* For 2D, we build a CGBitmapContext */ 8789682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall CGColorSpaceRef cgColorspace; 8799682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 8809682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Only recreate the view if it doesn't already exist */ 8819682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (window_view == nil) { 8829682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall window_view = [ [ NSView alloc ] initWithFrame:contentRect ]; 8839682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall [ window_view setAutoresizingMask: NSViewWidthSizable | NSViewHeightSizable ]; 8849682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall [ [ qz_window contentView ] addSubview:window_view ]; 8859682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall [ window_view release ]; 8869682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 8879682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 8889682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall cgColorspace = CGColorSpaceCreateDeviceRGB(); 8899682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall current->pitch = 4 * current->w; 8909682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall current->pixels = SDL_malloc (current->h * current->pitch); 8919682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 8929682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall cg_context = CGBitmapContextCreate (current->pixels, current->w, current->h, 8939682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 8, current->pitch, cgColorspace, 8949682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall kCGImageAlphaNoneSkipFirst); 8959682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall CGColorSpaceRelease (cgColorspace); 8969682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 8979682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall current->flags |= SDL_SWSURFACE; 8989682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall current->flags |= SDL_ASYNCBLIT; 8999682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall current->hwdata = (void *) cg_context; 9009682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 9019682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Force this window to draw above _everything_. */ 9029682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall [ qz_window setLevel:CGShieldingWindowLevel() ]; 9039682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 9049682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall this->UpdateRects = QZ_UpdateRects; 9059682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall this->LockHWSurface = QZ_LockHWSurface; 9069682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall this->UnlockHWSurface = QZ_UnlockHWSurface; 9079682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 9089682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 9099682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (isLion) { 9109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall [ qz_window setHasShadow:NO]; 9119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall [ qz_window setOpaque:YES]; 9129682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall [ qz_window makeKeyAndOrderFront:nil ]; 9139682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 9149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 9159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* !!! FIXME: keep an eye on this. 9169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * This API is officially unavailable for 64-bit binaries. 9179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * It happens to work, as of 10.7, but we're going to see if 9189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * we can just simply do without it on newer OSes... 9199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall */ 9209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall #if (MAC_OS_X_VERSION_MIN_REQUIRED < 1070) && !defined(__LP64__) 9219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( !isLion ) { 9229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* If we don't hide menu bar, it will get events and interrupt the program */ 9239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall HideMenuBar (); 9249682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 9259682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall #endif 9269682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 9279682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Fade in again (asynchronously) */ 9289682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( fade_token != kCGDisplayFadeReservationInvalidToken ) { 9299682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall CGDisplayFade (fade_token, 0.5, kCGDisplayBlendSolidColor, kCGDisplayBlendNormal, 0.0, 0.0, 0.0, FALSE); 9309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall CGReleaseDisplayFadeReservation(fade_token); 9319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 9329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 9339682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* 9349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall There is a bug in Cocoa where NSScreen doesn't synchronize 9359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall with CGDirectDisplay, so the main screen's frame is wrong. 9369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall As a result, coordinate translation produces incorrect results. 9379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall We can hack around this bug by setting the screen rect 9389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall ourselves. This hack should be removed if/when the bug is fixed. 9399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall */ 9409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall screen_rect = NSMakeRect(0,0,width,height); 9419682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall QZ_SetFrame(this, [ NSScreen mainScreen ], screen_rect); 9429682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 9439682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Save the flags to ensure correct tear-down */ 9449682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mode_flags = current->flags; 9459682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 9469682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Set app state, hide cursor if necessary, ... */ 9479682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall QZ_DoActivate(this); 9489682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 9499682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return current; 9509682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 9519682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Since the blanking window covers *all* windows (even force quit) correct recovery is crucial */ 9529682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse HallERR_NO_GL: goto ERR_DOUBLEBUF; /* this goto is to stop a compiler warning on newer SDKs. */ 9539682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse HallERR_DOUBLEBUF: QZ_RestoreDisplayMode(this); 9549682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse HallERR_NO_SWITCH: CGReleaseAllDisplays (); 9559682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse HallERR_NO_CAPTURE: 9569682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse HallERR_NO_MATCH: if ( fade_token != kCGDisplayFadeReservationInvalidToken ) { 9579682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall CGDisplayFade (fade_token, 0.5, kCGDisplayBlendSolidColor, kCGDisplayBlendNormal, 0.0, 0.0, 0.0, FALSE); 9589682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall CGReleaseDisplayFadeReservation (fade_token); 9599682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 9609682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return NULL; 9619682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 9629682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 9639682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic SDL_Surface* QZ_SetVideoWindowed (_THIS, SDL_Surface *current, int width, 9649682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall int height, int *bpp, Uint32 flags, 9659682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall const BOOL save_gl) 9669682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{ 9679682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall unsigned int style; 9689682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall NSRect contentRect; 9699682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall int center_window = 1; 9709682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall int origin_x, origin_y; 9719682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall CGDisplayFadeReservationToken fade_token = kCGDisplayFadeReservationInvalidToken; 9729682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 9739682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall current->flags = 0; 9749682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall current->w = width; 9759682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall current->h = height; 9769682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 9779682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall contentRect = NSMakeRect (0, 0, width, height); 9789682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 9799682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* 9809682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Check if we should completely destroy the previous mode 9819682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall - If it is fullscreen 9829682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall - If it has different noframe or resizable attribute 9839682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall - If it is OpenGL (since gl attributes could be different) 9849682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall - If new mode is OpenGL, but previous mode wasn't 9859682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall */ 9869682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (video_set == SDL_TRUE) { 9879682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (mode_flags & SDL_FULLSCREEN) { 9889682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Fade to black to hide resolution-switching flicker (and garbage 9899682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall that is displayed by a destroyed OpenGL context, if applicable) */ 9909682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (CGAcquireDisplayFadeReservation (5, &fade_token) == kCGErrorSuccess) { 9919682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall CGDisplayFade (fade_token, 0.3, kCGDisplayBlendNormal, kCGDisplayBlendSolidColor, 0.0, 0.0, 0.0, TRUE); 9929682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 9939682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall QZ_UnsetVideoMode (this, TRUE, save_gl); 9949682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 9959682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else if ( ((mode_flags ^ flags) & (SDL_NOFRAME|SDL_RESIZABLE)) || 9969682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall (mode_flags & SDL_OPENGL) || 9979682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall (flags & SDL_OPENGL) ) { 9989682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall QZ_UnsetVideoMode (this, TRUE, save_gl); 9999682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 10009682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 10019682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 10029682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Sorry, QuickDraw was ripped out. */ 10039682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (getenv("SDL_NSWindowPointer") || getenv("SDL_NSQuickDrawViewPointer")) { 10049682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_SetError ("Embedded QuickDraw windows are no longer supported"); 10059682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (fade_token != kCGDisplayFadeReservationInvalidToken) { 10069682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall CGDisplayFade (fade_token, 0.5, kCGDisplayBlendSolidColor, kCGDisplayBlendNormal, 0.0, 0.0, 0.0, FALSE); 10079682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall CGReleaseDisplayFadeReservation (fade_token); 10089682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 10099682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return NULL; 10109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 10119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 10129682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Check if we should recreate the window */ 10139682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (qz_window == nil) { 10149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 10159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Set the window style based on input flags */ 10169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( flags & SDL_NOFRAME ) { 10179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall style = NSBorderlessWindowMask; 10189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall current->flags |= SDL_NOFRAME; 10199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } else { 10209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall style = NSTitledWindowMask; 10219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall style |= (NSMiniaturizableWindowMask | NSClosableWindowMask); 10229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( flags & SDL_RESIZABLE ) { 10239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall style |= NSResizableWindowMask; 10249682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall current->flags |= SDL_RESIZABLE; 10259682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 10269682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 10279682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 10289682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Manually create a window, avoids having a nib file resource */ 10299682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall qz_window = [ [ SDL_QuartzWindow alloc ] 10309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall initWithContentRect:contentRect 10319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall styleMask:style 10329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall backing:NSBackingStoreBuffered 10336f5e132ea50c752390095001aa2d1d9a805fa92dJesse Hall defer:YES ]; 10349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 10359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (qz_window == nil) { 10369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_SetError ("Could not create the Cocoa window"); 10379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (fade_token != kCGDisplayFadeReservationInvalidToken) { 10389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall CGDisplayFade (fade_token, 0.5, kCGDisplayBlendSolidColor, kCGDisplayBlendNormal, 0.0, 0.0, 0.0, FALSE); 10399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall CGReleaseDisplayFadeReservation (fade_token); 10409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 10419682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return NULL; 10429682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 10439682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 10449682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /*[ qz_window setReleasedWhenClosed:YES ];*/ /* no need to set this as it's the default for NSWindows */ 10459682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall QZ_SetCaption(this, this->wm_title, this->wm_icon); 10469682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall [ qz_window setAcceptsMouseMovedEvents:YES ]; 10479682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall [ qz_window setViewsNeedDisplay:NO ]; 10489682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 10499682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( QZ_WindowPosition(this, &origin_x, &origin_y) ) { 10509682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* have to flip the Y value (NSPoint is lower left corner origin) */ 10519682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall [ qz_window setFrameTopLeftPoint:NSMakePoint((float) origin_x, (float) (this->info.current_h - origin_y))]; 10529682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall center_window = 0; 10539682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } else if ( center_window ) { 10549682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall [ qz_window center ]; 10559682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 10569682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 10579682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall [ qz_window setDelegate: 10589682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall [ [ SDL_QuartzWindowDelegate alloc ] init ] ]; 10599682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall [ qz_window setContentView: [ [ [ SDL_QuartzView alloc ] init ] autorelease ] ]; 10609682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 10619682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* We already have a window, just change its size */ 10629682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else { 10639682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall [ qz_window setContentSize:contentRect.size ]; 10649682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall current->flags |= (SDL_NOFRAME|SDL_RESIZABLE) & mode_flags; 10659682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall [ window_view setFrameSize:contentRect.size ]; 10669682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 10679682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 10689682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* For OpenGL, we bind the context to a subview */ 10699682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( flags & SDL_OPENGL ) { 10709682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 10719682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( ! save_gl ) { 10729682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( ! QZ_SetupOpenGL (this, *bpp, flags) ) { 10739682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (fade_token != kCGDisplayFadeReservationInvalidToken) { 10749682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall CGDisplayFade (fade_token, 0.5, kCGDisplayBlendSolidColor, kCGDisplayBlendNormal, 0.0, 0.0, 0.0, FALSE); 10759682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall CGReleaseDisplayFadeReservation (fade_token); 10769682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 10779682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return NULL; 10789682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 10799682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 10809682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 10819682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall window_view = [ [ NSView alloc ] initWithFrame:contentRect ]; 10829682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall [ window_view setAutoresizingMask: NSViewWidthSizable | NSViewHeightSizable ]; 10839682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall [ [ qz_window contentView ] addSubview:window_view ]; 10849682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall [ gl_context setView: window_view ]; 10859682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall [ window_view release ]; 10869682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall [ gl_context makeCurrentContext]; 10879682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall [ qz_window makeKeyAndOrderFront:nil ]; 10889682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall current->flags |= SDL_OPENGL; 10899682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 10909682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* For 2D, we build a CGBitmapContext */ 10919682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else { 10929682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall CGColorSpaceRef cgColorspace; 10939682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 10949682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Only recreate the view if it doesn't already exist */ 10959682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (window_view == nil) { 10969682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 10979682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall window_view = [ [ NSView alloc ] initWithFrame:contentRect ]; 10989682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall [ window_view setAutoresizingMask: NSViewWidthSizable | NSViewHeightSizable ]; 10999682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall [ [ qz_window contentView ] addSubview:window_view ]; 11009682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall [ window_view release ]; 11019682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall [ qz_window makeKeyAndOrderFront:nil ]; 11029682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 11039682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 11049682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall cgColorspace = CGColorSpaceCreateDeviceRGB(); 11059682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall current->pitch = 4 * current->w; 11069682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall current->pixels = SDL_malloc (current->h * current->pitch); 11079682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 11089682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall cg_context = CGBitmapContextCreate (current->pixels, current->w, current->h, 11099682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 8, current->pitch, cgColorspace, 11109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall kCGImageAlphaNoneSkipFirst); 11119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall CGColorSpaceRelease (cgColorspace); 11129682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 11139682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall current->flags |= SDL_SWSURFACE; 11149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall current->flags |= SDL_ASYNCBLIT; 11159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall current->hwdata = (void *) cg_context; 11169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 11179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall this->UpdateRects = QZ_UpdateRects; 11189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall this->LockHWSurface = QZ_LockHWSurface; 11199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall this->UnlockHWSurface = QZ_UnlockHWSurface; 11209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 11219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 11229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Save flags to ensure correct teardown */ 11239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mode_flags = current->flags; 11249682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 11259682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Fade in again (asynchronously) if we came from a fullscreen mode and faded to black */ 11269682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (fade_token != kCGDisplayFadeReservationInvalidToken) { 11279682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall CGDisplayFade (fade_token, 0.5, kCGDisplayBlendSolidColor, kCGDisplayBlendNormal, 0.0, 0.0, 0.0, FALSE); 11289682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall CGReleaseDisplayFadeReservation (fade_token); 11299682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 11309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 11319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return current; 11329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 11339682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 11349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 11359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic SDL_Surface* QZ_SetVideoModeInternal (_THIS, SDL_Surface *current, 11369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall int width, int height, int bpp, 11379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Uint32 flags, BOOL save_gl) 11389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{ 11399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall const BOOL isLion = IS_LION_OR_LATER(this); 11409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 11419682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall current->flags = 0; 11429682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall current->pixels = NULL; 11439682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 11449682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Setup full screen video */ 11459682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( flags & SDL_FULLSCREEN ) { 11469682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( isLion ) { 11479682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall bpp = 32; 11489682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 11499682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall current = QZ_SetVideoFullScreen (this, current, width, height, bpp, flags, save_gl ); 11509682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (current == NULL) 11519682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return NULL; 11529682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 11539682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Setup windowed video */ 11549682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else { 11559682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Force bpp to 32 */ 11569682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall bpp = 32; 11579682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall current = QZ_SetVideoWindowed (this, current, width, height, &bpp, flags, save_gl ); 11589682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (current == NULL) 11599682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return NULL; 11609682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 11619682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 11629682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (qz_window != nil) { 11639682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall nsgfx_context = [NSGraphicsContext graphicsContextWithWindow:qz_window]; 11649682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall [NSGraphicsContext setCurrentContext:nsgfx_context]; 11659682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 11669682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 11679682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Setup the new pixel format */ 11689682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall { 11699682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall int amask = 0, 11709682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall rmask = 0, 11719682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall gmask = 0, 11729682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall bmask = 0; 11739682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 11749682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall switch (bpp) { 11759682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall case 16: /* (1)-5-5-5 RGB */ 11769682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall amask = 0; 11779682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall rmask = 0x7C00; 11789682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall gmask = 0x03E0; 11799682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall bmask = 0x001F; 11809682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall break; 11819682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall case 24: 11829682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_SetError ("24bpp is not available"); 11839682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return NULL; 11849682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall case 32: /* (8)-8-8-8 ARGB */ 11859682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall amask = 0x00000000; 11869682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( (!isLion) && (flags & SDL_FULLSCREEN) ) { 11879682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall rmask = 0x00FF0000; 11889682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall gmask = 0x0000FF00; 11899682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall bmask = 0x000000FF; 11909682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } else { 11919682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#if SDL_BYTEORDER == SDL_LIL_ENDIAN 11929682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall rmask = 0x0000FF00; 11939682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall gmask = 0x00FF0000; 11949682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall bmask = 0xFF000000; 11959682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#else 11969682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall rmask = 0x00FF0000; 11979682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall gmask = 0x0000FF00; 11989682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall bmask = 0x000000FF; 11999682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif 12009682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall break; 12019682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 12029682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 12039682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 12049682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( ! SDL_ReallocFormat (current, bpp, 12059682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall rmask, gmask, bmask, amask ) ) { 12069682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_SetError ("Couldn't reallocate pixel format"); 12079682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return NULL; 12089682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 12099682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 12109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 12119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Signal successful completion (used internally) */ 12129682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall video_set = SDL_TRUE; 12139682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 12149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return current; 12159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 12169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 12179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic SDL_Surface* QZ_SetVideoMode(_THIS, SDL_Surface *current, 12189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall int width, int height, int bpp, 12199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Uint32 flags) 12209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{ 12219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Don't throw away the GL context if we can just resize the current one. */ 12229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#if 0 /* !!! FIXME: half-finished side project. Reenable this if you ever debug the corner cases. */ 12239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall const BOOL save_gl = ( (video_set == SDL_TRUE) && ((flags & SDL_OPENGL) == (current->flags & SDL_OPENGL)) && (bpp == current->format->BitsPerPixel) ); 12249682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#else 12259682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall const BOOL save_gl = NO; 12269682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif 12279682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 12289682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall NSOpenGLContext *glctx = gl_context; 12299682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_Surface* retval = NULL; 12309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 12319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (save_gl) { 12329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall [glctx retain]; /* just so we don't lose this when killing old views, etc */ 12339682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 12349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 12359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall retval = QZ_SetVideoModeInternal (this, current, width, height, bpp, flags, save_gl); 12369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 12379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (save_gl) { 12389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall [glctx release]; /* something else should own this now, or we legitimately release it. */ 12399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 12409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 12419682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return retval; 12429682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 12439682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 12449682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 12459682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic int QZ_ToggleFullScreen (_THIS, int on) 12469682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{ 12479682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return 0; 12489682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 12499682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 12509682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic int QZ_SetColors (_THIS, int first_color, int num_colors, 12519682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_Color *colors) 12529682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{ 12539682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#if (MAC_OS_X_VERSION_MIN_REQUIRED < 1070) 12549682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* we shouldn't have an 8-bit mode on Lion! */ 12559682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (!IS_LION_OR_LATER(this)) { 12569682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall CGTableCount index; 12579682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall CGDeviceColor color; 12589682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 12599682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall for (index = first_color; index < first_color+num_colors; index++) { 12609682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 12619682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Clamp colors between 0.0 and 1.0 */ 12629682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall color.red = colors->r / 255.0; 12639682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall color.blue = colors->b / 255.0; 12649682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall color.green = colors->g / 255.0; 12659682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 12669682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall colors++; 12679682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 12689682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall CGPaletteSetColorAtIndex (palette, color, index); 12699682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 12709682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 12719682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return ( CGDisplayNoErr == CGDisplaySetPalette (display_id, palette) ); 12729682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 12739682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif 12749682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 12759682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return 0; 12769682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 12779682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 12789682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#if (MAC_OS_X_VERSION_MIN_REQUIRED < 1070) 12799682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic int QZ_LockDoubleBuffer (_THIS, SDL_Surface *surface) 12809682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{ 12819682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return 1; 12829682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 12839682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 12849682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic void QZ_UnlockDoubleBuffer (_THIS, SDL_Surface *surface) 12859682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{ 12869682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 12879682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 12889682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* The VBL delay is based on code by Ian R Ollmann's RezLib <iano@cco.caltech.edu> */ 12899682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic AbsoluteTime QZ_SecondsToAbsolute ( double seconds ) 12909682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{ 12919682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall union 12929682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall { 12939682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall UInt64 i; 12949682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Nanoseconds ns; 12959682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } temp; 12969682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 12979682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall temp.i = seconds * 1000000000.0; 12989682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 12999682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return NanosecondsToAbsolute ( temp.ns ); 13009682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 13019682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 13029682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic int QZ_ThreadFlip (_THIS) 13039682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{ 13049682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Uint8 *src, *dst; 13059682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall int skip, len, h; 13069682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 13079682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* 13089682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Give this thread the highest scheduling priority possible, 13099682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall in the hopes that it will immediately run after the VBL delay 13109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall */ 13119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall { 13129682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall pthread_t current_thread; 13139682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall int policy; 13149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall struct sched_param param; 13159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 13169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall current_thread = pthread_self (); 13179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall pthread_getschedparam (current_thread, &policy, ¶m); 13189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall policy = SCHED_RR; 13199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall param.sched_priority = sched_get_priority_max (policy); 13209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall pthread_setschedparam (current_thread, policy, ¶m); 13219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 13229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 13239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall while (1) { 13249682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 13259682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_SemWait (sem1); 13269682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (quit_thread) 13279682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return 0; 13289682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 13299682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* 13309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * We have to add SDL_VideoSurface->offset here, since we might be a 13319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * smaller surface in the center of the framebuffer (you asked for 13329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * a fullscreen resolution smaller than the hardware could supply 13339682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * so SDL is centering it in a bigger resolution)... 13349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall */ 13359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall dst = ((Uint8 *)((size_t)CGDisplayBaseAddress (display_id))) + SDL_VideoSurface->offset; 13369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall src = current_buffer + SDL_VideoSurface->offset; 13379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall len = SDL_VideoSurface->w * SDL_VideoSurface->format->BytesPerPixel; 13389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall h = SDL_VideoSurface->h; 13399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall skip = SDL_VideoSurface->pitch; 13409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 13419682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Wait for the VBL to occur (estimated since we don't have a hardware interrupt) */ 13429682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall { 13439682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 13449682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* The VBL delay is based on Ian Ollmann's RezLib <iano@cco.caltech.edu> */ 13459682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall double refreshRate; 13469682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall double linesPerSecond; 13479682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall double target; 13489682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall double position; 13499682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall double adjustment; 13509682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall AbsoluteTime nextTime; 13519682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall CFNumberRef refreshRateCFNumber; 13529682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 13539682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall refreshRateCFNumber = CFDictionaryGetValue (mode, kCGDisplayRefreshRate); 13549682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( NULL == refreshRateCFNumber ) { 13559682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_SetError ("Mode has no refresh rate"); 13569682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall goto ERROR; 13579682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 13589682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 13599682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( 0 == CFNumberGetValue (refreshRateCFNumber, kCFNumberDoubleType, &refreshRate) ) { 13609682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_SetError ("Error getting refresh rate"); 13619682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall goto ERROR; 13629682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 13639682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 13649682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( 0 == refreshRate ) { 13659682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 13669682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_SetError ("Display has no refresh rate, using 60hz"); 13679682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 13689682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* ok, for LCD's we'll emulate a 60hz refresh, which may or may not look right */ 13699682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall refreshRate = 60.0; 13709682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 13719682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 13729682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall linesPerSecond = refreshRate * h; 13739682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall target = h; 13749682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 13759682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Figure out the first delay so we start off about right */ 13769682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall position = CGDisplayBeamPosition (display_id); 13779682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (position > target) 13789682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall position = 0; 13799682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 13809682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall adjustment = (target - position) / linesPerSecond; 13819682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 13829682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall nextTime = AddAbsoluteToAbsolute (UpTime (), QZ_SecondsToAbsolute (adjustment)); 13839682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 13849682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall MPDelayUntil (&nextTime); 13859682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 13869682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 13879682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 13889682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* On error, skip VBL delay */ 13899682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall ERROR: 13909682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 13919682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* TODO: use CGContextDrawImage here too! Create two CGContextRefs the same way we 13929682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall create two buffers, replace current_buffer with current_context and set it 13939682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall appropriately in QZ_FlipDoubleBuffer. */ 13949682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall while ( h-- ) { 13959682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 13969682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_memcpy (dst, src, len); 13979682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall src += skip; 13989682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall dst += skip; 13999682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 14009682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 14019682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* signal flip completion */ 14029682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_SemPost (sem2); 14039682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 14049682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 14059682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return 0; 14069682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 14079682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 14089682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic int QZ_FlipDoubleBuffer (_THIS, SDL_Surface *surface) 14099682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{ 14109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* wait for previous flip to complete */ 14119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_SemWait (sem2); 14129682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 14139682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall current_buffer = surface->pixels; 14149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 14159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (surface->pixels == sw_buffers[0]) 14169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall surface->pixels = sw_buffers[1]; 14179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else 14189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall surface->pixels = sw_buffers[0]; 14199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 14209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* signal worker thread to do the flip */ 14219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_SemPost (sem1); 14229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 14239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return 0; 14249682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 14259682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 14269682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic void QZ_DoubleBufferUpdate (_THIS, int num_rects, SDL_Rect *rects) 14279682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{ 14289682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* perform a flip if someone calls updaterects on a doublebuferred surface */ 14299682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall this->FlipHWSurface (this, SDL_VideoSurface); 14309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 14319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 14329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic void QZ_DirectUpdate (_THIS, int num_rects, SDL_Rect *rects) 14339682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{ 14349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#pragma unused(this,num_rects,rects) 14359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 14369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif 14379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 14389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* Resize icon, BMP format */ 14399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic const unsigned char QZ_ResizeIcon[] = { 14409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 0x42,0x4d,0x31,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x36,0x00,0x00,0x00,0x28,0x00, 14419682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 0x00,0x00,0x0d,0x00,0x00,0x00,0x0d,0x00,0x00,0x00,0x01,0x00,0x18,0x00,0x00,0x00, 14429682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 0x00,0x00,0xfb,0x01,0x00,0x00,0x13,0x0b,0x00,0x00,0x13,0x0b,0x00,0x00,0x00,0x00, 14439682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 14449682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 14459682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x0b,0xff,0xff, 14469682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 0xff,0xda,0xda,0xda,0x87,0x87,0x87,0xe8,0xe8,0xe8,0xff,0xff,0xff,0xda,0xda,0xda, 14479682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 0x87,0x87,0x87,0xe8,0xe8,0xe8,0xff,0xff,0xff,0xda,0xda,0xda,0x87,0x87,0x87,0xe8, 14489682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 0xe8,0xe8,0xff,0xff,0xff,0x0b,0xff,0xff,0xff,0xff,0xff,0xff,0xda,0xda,0xda,0x87, 14499682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 0x87,0x87,0xe8,0xe8,0xe8,0xff,0xff,0xff,0xda,0xda,0xda,0x87,0x87,0x87,0xe8,0xe8, 14509682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 0xe8,0xff,0xff,0xff,0xda,0xda,0xda,0x87,0x87,0x87,0xff,0xff,0xff,0x0b,0xff,0xff, 14519682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xd5,0xd5,0xd5,0x87,0x87,0x87,0xe8,0xe8,0xe8, 14529682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 0xff,0xff,0xff,0xda,0xda,0xda,0x87,0x87,0x87,0xe8,0xe8,0xe8,0xff,0xff,0xff,0xda, 14539682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 0xda,0xda,0xff,0xff,0xff,0x0b,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 14549682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 0xff,0xff,0xd7,0xd7,0xd7,0x87,0x87,0x87,0xe8,0xe8,0xe8,0xff,0xff,0xff,0xda,0xda, 14559682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 0xda,0x87,0x87,0x87,0xe8,0xe8,0xe8,0xff,0xff,0xff,0xff,0xff,0xff,0x0b,0xff,0xff, 14569682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xd7,0xd7,0xd7, 14579682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 0x87,0x87,0x87,0xe8,0xe8,0xe8,0xff,0xff,0xff,0xda,0xda,0xda,0x87,0x87,0x87,0xe8, 14589682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 0xe8,0xe8,0xff,0xff,0xff,0x0b,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 14599682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xd7,0xd7,0xd7,0x87,0x87,0x87,0xe8,0xe8, 14609682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 0xe8,0xff,0xff,0xff,0xdc,0xdc,0xdc,0x87,0x87,0x87,0xff,0xff,0xff,0x0b,0xff,0xff, 14619682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 14629682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 0xff,0xff,0xff,0xd9,0xd9,0xd9,0x87,0x87,0x87,0xe8,0xe8,0xe8,0xff,0xff,0xff,0xdc, 14639682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 0xdc,0xdc,0xff,0xff,0xff,0x0b,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 14649682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xdb,0xdb, 14659682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 0xdb,0x87,0x87,0x87,0xe8,0xe8,0xe8,0xff,0xff,0xff,0xff,0xff,0xff,0x0b,0xff,0xff, 14669682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 14679682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xdb,0xdb,0xdb,0x87,0x87,0x87,0xe8, 14689682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 0xe8,0xe8,0xff,0xff,0xff,0x0b,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 14699682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 14709682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 0xff,0xff,0xff,0xff,0xdc,0xdc,0xdc,0x87,0x87,0x87,0xff,0xff,0xff,0x0b,0xff,0xff, 14719682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 14729682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xdc, 14739682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 0xdc,0xdc,0xff,0xff,0xff,0x0b,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 14749682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 14759682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x0b 14769682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall}; 14779682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 14789682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic void QZ_DrawResizeIcon (_THIS) 14799682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{ 14809682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Check if we should draw the resize icon */ 14819682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (SDL_VideoSurface->flags & SDL_RESIZABLE) { 14829682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 14839682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_Rect icon_rect; 14849682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 14859682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Create the icon image */ 14869682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (resize_icon == NULL) { 14879682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 14889682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_RWops *rw; 14899682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_Surface *tmp; 14909682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 14919682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall rw = SDL_RWFromConstMem (QZ_ResizeIcon, sizeof(QZ_ResizeIcon)); 14929682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall tmp = SDL_LoadBMP_RW (rw, SDL_TRUE); 14939682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 14949682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall resize_icon = SDL_ConvertSurface (tmp, SDL_VideoSurface->format, SDL_SRCCOLORKEY); 14959682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_SetColorKey (resize_icon, SDL_SRCCOLORKEY, 0xFFFFFF); 14969682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 14979682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_FreeSurface (tmp); 14989682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 14999682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 15009682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall icon_rect.x = SDL_VideoSurface->w - 13; 15019682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall icon_rect.y = SDL_VideoSurface->h - 13; 15029682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall icon_rect.w = 13; 15039682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall icon_rect.h = 13; 15049682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 15059682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_BlitSurface (resize_icon, NULL, SDL_VideoSurface, &icon_rect); 15069682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 15079682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 15089682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 15099682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic void QZ_UpdateRects (_THIS, int numRects, SDL_Rect *rects) 15109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{ 15119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (SDL_VideoSurface->flags & SDL_OPENGLBLIT) { 15129682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall QZ_GL_SwapBuffers (this); 15139682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 15149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else if ( [ qz_window isMiniaturized ] ) { 15159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 15169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Do nothing if miniaturized */ 15179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 15189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 15199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else { 15209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall NSGraphicsContext *ctx = [NSGraphicsContext currentContext]; 15219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (ctx != nsgfx_context) { /* uhoh, you might be rendering from another thread... */ 15229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall [NSGraphicsContext setCurrentContext:nsgfx_context]; 15239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall ctx = nsgfx_context; 15249682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 15259682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall CGContextRef cgc = (CGContextRef) [ctx graphicsPort]; 15269682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall QZ_DrawResizeIcon (this); 15279682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall CGContextFlush (cg_context); 15289682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall CGImageRef image = CGBitmapContextCreateImage (cg_context); 15299682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall CGRect rectangle = CGRectMake (0,0,[window_view frame].size.width,[window_view frame].size.height); 15309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 15319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall CGContextDrawImage (cgc, rectangle, image); 15329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall CGImageRelease(image); 15339682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall CGContextFlush (cgc); 15349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 15359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 15369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 15379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic void QZ_VideoQuit (_THIS) 15389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{ 15399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall CGDisplayFadeReservationToken fade_token = kCGDisplayFadeReservationInvalidToken; 15409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 15419682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Restore gamma settings */ 15429682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall CGDisplayRestoreColorSyncSettings (); 15439682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 15449682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Ensure the cursor will be visible and working when we quit */ 15459682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall CGDisplayShowCursor (display_id); 15469682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall CGAssociateMouseAndMouseCursorPosition (1); 15479682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 15489682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (mode_flags & SDL_FULLSCREEN) { 15499682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Fade to black to hide resolution-switching flicker (and garbage 15509682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall that is displayed by a destroyed OpenGL context, if applicable) */ 15519682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (CGAcquireDisplayFadeReservation (5, &fade_token) == kCGErrorSuccess) { 15529682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall CGDisplayFade (fade_token, 0.3, kCGDisplayBlendNormal, kCGDisplayBlendSolidColor, 0.0, 0.0, 0.0, TRUE); 15539682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 15549682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall QZ_UnsetVideoMode (this, TRUE, FALSE); 15559682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (fade_token != kCGDisplayFadeReservationInvalidToken) { 15569682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall CGDisplayFade (fade_token, 0.5, kCGDisplayBlendSolidColor, kCGDisplayBlendNormal, 0.0, 0.0, 0.0, FALSE); 15579682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall CGReleaseDisplayFadeReservation (fade_token); 15589682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 15599682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 15609682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else 15619682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall QZ_UnsetVideoMode (this, TRUE, FALSE); 15629682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 15639682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#if (MAC_OS_X_VERSION_MIN_REQUIRED < 1070) 15649682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (!IS_LION_OR_LATER(this)) { 15659682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall CGPaletteRelease(palette); 15669682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 15679682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif 15689682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 15699682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (opengl_library) { 15709682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_UnloadObject(opengl_library); 15719682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall opengl_library = NULL; 15729682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 15739682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall this->gl_config.driver_loaded = 0; 15749682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 15759682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (field_edit) { 15769682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall [field_edit release]; 15779682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall field_edit = NULL; 15789682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 15799682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 15809682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 15819682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic int QZ_LockHWSurface(_THIS, SDL_Surface *surface) 15829682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{ 15839682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return 1; 15849682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 15859682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 15869682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic void QZ_UnlockHWSurface(_THIS, SDL_Surface *surface) 15879682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{ 15889682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 15899682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 15909682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic int QZ_AllocHWSurface(_THIS, SDL_Surface *surface) 15919682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{ 15929682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return(-1); /* unallowed (no HWSURFACE support here). */ 15939682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 15949682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 15959682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic void QZ_FreeHWSurface (_THIS, SDL_Surface *surface) 15969682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{ 15979682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 15989682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 15999682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* Gamma functions */ 16009682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallint QZ_SetGamma (_THIS, float red, float green, float blue) 16019682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{ 16029682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall const CGGammaValue min = 0.0, max = 1.0; 16039682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 16049682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (red == 0.0) 16059682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall red = FLT_MAX; 16069682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else 16079682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall red = 1.0 / red; 16089682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 16099682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (green == 0.0) 16109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall green = FLT_MAX; 16119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else 16129682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall green = 1.0 / green; 16139682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 16149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (blue == 0.0) 16159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall blue = FLT_MAX; 16169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else 16179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall blue = 1.0 / blue; 16189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 16199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( CGDisplayNoErr == CGSetDisplayTransferByFormula 16209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall (display_id, min, max, red, min, max, green, min, max, blue) ) { 16219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 16229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return 0; 16239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 16249682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else { 16259682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 16269682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return -1; 16279682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 16289682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 16299682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 16309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallint QZ_GetGamma (_THIS, float *red, float *green, float *blue) 16319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{ 16329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall CGGammaValue dummy; 16339682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( CGDisplayNoErr == CGGetDisplayTransferByFormula 16349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall (display_id, &dummy, &dummy, red, 16359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall &dummy, &dummy, green, &dummy, &dummy, blue) ) 16369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 16379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return 0; 16389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else 16399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return -1; 16409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 16419682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 16429682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallint QZ_SetGammaRamp (_THIS, Uint16 *ramp) 16439682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{ 16449682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall const uint32_t tableSize = 255; 16459682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall CGGammaValue redTable[tableSize]; 16469682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall CGGammaValue greenTable[tableSize]; 16479682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall CGGammaValue blueTable[tableSize]; 16489682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 16499682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall int i; 16509682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 16519682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Extract gamma values into separate tables, convert to floats between 0.0 and 1.0 */ 16529682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall for (i = 0; i < 256; i++) 16539682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall redTable[i % 256] = ramp[i] / 65535.0; 16549682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 16559682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall for (i=256; i < 512; i++) 16569682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall greenTable[i % 256] = ramp[i] / 65535.0; 16579682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 16589682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall for (i=512; i < 768; i++) 16599682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall blueTable[i % 256] = ramp[i] / 65535.0; 16609682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 16619682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( CGDisplayNoErr == CGSetDisplayTransferByTable 16629682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall (display_id, tableSize, redTable, greenTable, blueTable) ) 16639682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return 0; 16649682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else 16659682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return -1; 16669682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 16679682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 16689682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallint QZ_GetGammaRamp (_THIS, Uint16 *ramp) 16699682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{ 16709682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall const uint32_t tableSize = 255; 16719682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall CGGammaValue redTable[tableSize]; 16729682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall CGGammaValue greenTable[tableSize]; 16739682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall CGGammaValue blueTable[tableSize]; 16749682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall uint32_t actual; 16759682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall int i; 16769682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 16779682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( CGDisplayNoErr != CGGetDisplayTransferByTable 16789682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall (display_id, tableSize, redTable, greenTable, blueTable, &actual) || 16799682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall actual != tableSize) 16809682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 16819682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return -1; 16829682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 16839682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Pack tables into one array, with values from 0 to 65535 */ 16849682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall for (i = 0; i < 256; i++) 16859682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall ramp[i] = redTable[i % 256] * 65535.0; 16869682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 16879682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall for (i=256; i < 512; i++) 16889682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall ramp[i] = greenTable[i % 256] * 65535.0; 16899682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 16909682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall for (i=512; i < 768; i++) 16919682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall ramp[i] = blueTable[i % 256] * 65535.0; 16929682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 16939682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return 0; 16949682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 16959682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1696