28#if OOLITE_MAC_OS_X && OOLITE_64_BIT
31#import <Carbon/Carbon.h>
38#define SUPPRESS_BLANKING_WINDOWS ( 1 && OO_DEBUG)
41@interface OOMacSnowLeopardFullScreenController ()
43@property (nonatomic, retain) NSWindow *fullScreenWindow;
44@property (nonatomic, retain) NSArray *blankingWindows;
45@property (nonatomic, retain) NSWindow *standardWindow;
47@property (nonatomic, retain) NSScreen *gameScreen;
49- (void) beginFullScreenMode;
50- (void) endFullScreenMode;
52- (void) screenParametersChanged:(NSNotification *)notification;
54- (void) setUpBlankingWindowsForScreensOtherThan:(NSScreen *)gameScreen;
55- (void) removeBlankingWindows;
60@implementation OOMacSnowLeopardFullScreenController
62@synthesize fullScreenMode = _fullScreenMode;
63@synthesize fullScreenWindow = _fullScreenWindow;
64@synthesize blankingWindows = _blankingWindows;
65@synthesize standardWindow = _standardWindow;
66@synthesize gameScreen = _gameScreen;
71 self.fullScreenMode = NO;
82- (void) setFullScreenMode:(BOOL)value
84 if (!value &&
self.fullScreenMode)
86 [
self endFullScreenMode];
88 else if (value && !
self.fullScreenMode)
90 [
self beginFullScreenMode];
95- (NSArray *) displayModes
97 NSSize
size =
self.fullScreenWindow.frame.size;
98 NSDictionary *fakeMode = [NSDictionary dictionaryWithObjectsAndKeys:
99 [NSNumber numberWithUnsignedInt:size.width], kOODisplayWidth,
100 [NSNumber numberWithUnsignedInt:size.height], kOODisplayHeight,
102 return [NSArray arrayWithObject:fakeMode];
106- (NSUInteger) indexOfCurrentDisplayMode
112- (BOOL) setDisplayWidth:(NSUInteger)width height:(NSUInteger)height refreshRate:(NSUInteger)refresh
118- (NSDictionary *) findDisplayModeForWidth:(NSUInteger)width height:(NSUInteger)height refreshRate:(NSUInteger)refresh
120 NSDictionary *fakeMode = [
self.displayModes objectAtIndex:0];
132 NSAssert(
self.fullScreenMode,
@"%s called in wrong state.", __FUNCTION__);
134 [
self.gameView noteMouseInteractionModeChangedFrom:oldMode to:newMode];
138#pragma mark - Actual full screen mode handling
140- (void) beginFullScreenMode
142 NSAssert(!
self.fullScreenMode,
@"%s called in wrong state.", __FUNCTION__);
145 self.standardWindow =
self.gameView.window;
151 self.gameScreen =
self.gameView.window.screen;
152 NSRect frame =
self.gameScreen.frame;
153 OOFullScreenWindow *window = [[OOFullScreenWindow alloc] initWithContentRect:frame
154 styleMask:NSBorderlessWindowMask
155 backing:NSBackingStoreBuffered
157 if (window ==
nil)
return;
159 self.fullScreenWindow = [window autorelease];
161 [window setOpaque:YES];
162 [window setMovable:YES];
163 window.canBecomeKeyWindow = YES;
164 window.canBecomeMainWindow = YES;
165 window.acceptsMouseMovedEvents = YES;
171 window.hidesOnDeactivate = YES;
176 [
self.standardWindow orderOut:nil];
177 window.contentView =
self.gameView;
179 SetSystemUIMode(kUIModeAllSuppressed, kUIOptionDisableMenuBarTransparency);
180 [
self setUpBlankingWindowsForScreensOtherThan:self.gameScreen];
182 [window makeKeyAndOrderFront:self];
184 _fullScreenMode = YES;
187 [[NSNotificationCenter defaultCenter] addObserver:self
188 selector:@selector(screenParametersChanged:)
189 name:NSApplicationDidChangeScreenParametersNotification
194- (void) endFullScreenMode
196 NSAssert(
self.fullScreenMode,
@"%s called in wrong state.", __FUNCTION__);
198 [
self.fullScreenWindow orderOut:nil];
200 [
self removeBlankingWindows];
201 SetSystemUIMode(kUIModeNormal, 0);
203 self.standardWindow.contentView =
self.gameView;
204 [
self.standardWindow makeKeyAndOrderFront:nil];
206 self.standardWindow =
nil;
207 self.fullScreenWindow =
nil;
208 self.gameScreen =
nil;
210 _fullScreenMode = NO;
213 [[NSNotificationCenter defaultCenter] removeObserver:self
214 name:NSApplicationDidChangeScreenParametersNotification
219- (void) screenParametersChanged:(NSNotification *)notification
221 NSAssert(
self.fullScreenMode,
@"%s called in wrong state.", __FUNCTION__);
223 [
self.fullScreenWindow setFrame:self.gameScreen.frame display:YES];
224 [
self setUpBlankingWindowsForScreensOtherThan:self.gameScreen];
228- (void) setUpBlankingWindowsForScreensOtherThan:(NSScreen *)gameScreen
230#if SUPPRESS_BLANKING_WINDOWS
243 [
self removeBlankingWindows];
245 NSArray *screens = [NSScreen screens];
246 if (screens.count <= 1)
252 NSMutableArray *windows = [NSMutableArray arrayWithCapacity:screens.count - 1];
253 for (NSScreen *screen in screens)
255 if ([screen isEqual:gameScreen])
continue;
257 NSRect frame = screen.frame;
258 OOFullScreenWindow *window = [[OOFullScreenWindow alloc] initWithContentRect:frame
259 styleMask:NSBorderlessWindowMask
260 backing:NSBackingStoreBuffered
263 [window setOpaque:YES];
264 [window setMovable:YES];
265 window.collectionBehavior = NSWindowCollectionBehaviorTransient | NSWindowCollectionBehaviorIgnoresCycle;
266 window.canBecomeKeyWindow = NO;
267 window.canBecomeMainWindow = NO;
268 window.hidesOnDeactivate = YES;
269 window.backgroundColor = [NSColor blackColor];
271 [windows addObject:window];
272 [window orderFront:nil];
276 self.blankingWindows = windows;
280- (void) removeBlankingWindows
282 for (NSWindow *window in
self.blankingWindows)
284 [window orderOut:nil];
286 self.blankingWindows =
nil;
290- (void) checkWindowVisible:(NSTimer *)timer
292 NSWindow *window = timer.userInfo;
293 OOLog(
@"temp.fullScreen",
@"Window %@ is %@ on screen %@", window, window.isVisible ?
@"visible" :
@"INVISIBLE", window.screen);
#define OOLog(class, format,...)