From cb511644db75fe5696e05dcb5a56f91ce8939fe0 Mon Sep 17 00:00:00 2001
From: ceylo <ceylo@4e206d99-4929-0410-ac5d-dfc041789085>
Date: Thu, 21 May 2009 15:07:33 +0000
Subject: [PATCH] Fixed problem with fullscreen/windowed display mode. Added
 check for Cocoa window import.

git-svn-id: https://sfml.svn.sourceforge.net/svnroot/sfml/trunk@1094 4e206d99-4929-0410-ac5d-dfc041789085
---
 src/SFML/Window/Cocoa/AppController.mm   | 39 ++++++++++++----
 src/SFML/Window/Cocoa/GLKit.mm           | 59 ++++++++++++------------
 src/SFML/Window/Cocoa/WindowImplCocoa.mm | 35 ++++++++------
 3 files changed, 82 insertions(+), 51 deletions(-)

diff --git a/src/SFML/Window/Cocoa/AppController.mm b/src/SFML/Window/Cocoa/AppController.mm
index 3ebba08a..8d07eaf8 100644
--- a/src/SFML/Window/Cocoa/AppController.mm
+++ b/src/SFML/Window/Cocoa/AppController.mm
@@ -44,6 +44,8 @@ static AppController *shared = nil;
 @end
 #endif
 
+#define ENABLE_FADE_OPERATIONS 1
+
 @implementation NSApplication (SFML)
 
 - (void)setRunning:(BOOL)flag
@@ -388,7 +390,7 @@ static AppController *shared = nil;
 - (void)setFullscreenWindow:(WindowWrapper *)aWrapper mode:(sf::VideoMode *)fullscreenMode
 {
 	// If we have a fullscreen window and want to remove it
-	if (myFullscreenWrapper && aWrapper == nil)
+	if (aWrapper == nil && myFullscreenWrapper)
 	{
 		// Get the CoreGraphics display mode according to the desktop mode
 		CFDictionaryRef displayMode = CGDisplayBestModeForParameters (kCGDirectMainDisplay,
@@ -397,8 +399,10 @@ static AppController *shared = nil;
 																	  myDesktopMode.Height,
 																	  NULL);
 		
+#if ENABLE_FADE_OPERATIONS
 		// Fade to black screen
 		[self doFadeOperation:FillScreen time:0.2f sync:true];
+#endif
 		
 		// Switch to the desktop display mode
 		CGDisplaySwitchToMode(kCGDirectMainDisplay, displayMode);
@@ -409,13 +413,15 @@ static AppController *shared = nil;
 		// Show the menu bar
 		[NSMenu setMenuBarVisible:YES];
 		
+#if ENABLE_FADE_OPERATIONS
 		// Fade to normal screen
 		[self doFadeOperation:CleanScreen time:0.5f sync:true];
+#endif
 		
 		// Release the saved window wrapper
-		[myFullscreenWrapper release], myFullscreenWrapper = nil;
+		myFullscreenWrapper = nil;
 	}
-	else if (myFullscreenWrapper == nil && aWrapper)
+	else if (aWrapper)
 	{
 		assert(fullscreenMode != NULL);
 		
@@ -426,24 +432,39 @@ static AppController *shared = nil;
 																	  fullscreenMode->Height,
 																	  NULL);
 		
+#if ENABLE_FADE_OPERATIONS
 		// Fade to a black screen
 		[self doFadeOperation:FillScreen time:0.5f sync:true];
+#endif
 		
-		// Hide to the main menu bar
-		[NSMenu setMenuBarVisible:NO];
+		if (!myFullscreenWrapper)
+		{
+			// Hide the main menu bar
+			[NSMenu setMenuBarVisible:NO];
+		}
 		
-		// Switch to the wished display mode
-		CGDisplaySwitchToMode(kCGDirectMainDisplay, displayMode);
+		if (myPrevMode != *fullscreenMode)
+		{
+			// Switch to the wished display mode
+			CGDisplaySwitchToMode(kCGDirectMainDisplay, displayMode);
+		}
+		
+		if (myFullscreenWrapper)
+		{
+			[[myFullscreenWrapper window] close];
+		}
 		
 		// Open and center the window
 		[[aWrapper window] makeKeyAndOrderFront:nil];
 		[[aWrapper window] center];
 		
+#if ENABLE_FADE_OPERATIONS
 		// Fade to normal screen
 		[self doFadeOperation:CleanScreen time:0.2f sync:false];
+#endif
 		
 		// Save the fullscreen wrapper
-		myFullscreenWrapper = [aWrapper retain];
+		myFullscreenWrapper = aWrapper;
 	}
 	else
 	{
@@ -453,7 +474,7 @@ static AppController *shared = nil;
 
 
 ////////////////////////////////////////////////////////////
-/// Perform fade operation where 'operation' is one of { FillScreen, CleanScreen}
+/// Perform fade operation where 'operation' is one of {FillScreen, CleanScreen}
 /// and 'time' is the time during which you wish the operation to be performed.
 /// Set 'sync' to true if you do not want the method to end before the end
 /// of the fade operation. Pass the last used token or a new one if you are
diff --git a/src/SFML/Window/Cocoa/GLKit.mm b/src/SFML/Window/Cocoa/GLKit.mm
index a8d3dbf6..e51edc80 100644
--- a/src/SFML/Window/Cocoa/GLKit.mm
+++ b/src/SFML/Window/Cocoa/GLKit.mm
@@ -502,37 +502,39 @@ static GLContext *sharedCtx = nil;
 			NSRect frame = NSMakeRect (0.0f, 0.0f, (float) mode.Width, (float) mode.Height);
 			unsigned int mask = 0;
 			
+			if (style & sf::Style::Fullscreen) {
+				myIsFullscreen = true;
+				
+				// Check display mode and put new values in 'mode' if needed
+				boolean_t exact = true;
+				
+				CFDictionaryRef properties = CGDisplayBestModeForParameters(kCGDirectMainDisplay, mode.BitsPerPixel,
+																			mode.Width, mode.Height, &exact);
+				
+				if (!properties) {
+					std::cerr << "Unable to get a display mode with the given parameters" << std::endl;
+					[self autorelease];
+					return nil;
+				}
+				
+				if (exact == false) {
+					CFNumberGetValue((CFNumberRef) CFDictionaryGetValue(properties, kCGDisplayWidth),
+									 kCFNumberIntType, &mode.Width);
+					
+					CFNumberGetValue((CFNumberRef) CFDictionaryGetValue(properties, kCGDisplayHeight),
+									 kCFNumberIntType, &mode.Height);
+					
+					CFNumberGetValue((CFNumberRef) CFDictionaryGetValue(properties, kCGDisplayBitsPerPixel),
+									 kCFNumberIntType, &mode.BitsPerPixel);
+					
+				}
+			}
+			
 			// We grab options from WindowStyle and add them to our window mask
 			if (style & sf::Style::None || style & sf::Style::Fullscreen) {
 				mask |= NSBorderlessWindowMask;
 				
-				if (style & sf::Style::Fullscreen) {
-					myIsFullscreen = true;
-					
-					// Check display mode and put new values in 'mode' if needed
-					boolean_t exact = true;
-					
-					CFDictionaryRef properties = CGDisplayBestModeForParameters(kCGDirectMainDisplay, mode.BitsPerPixel,
-																				mode.Width, mode.Height, &exact);
-					
-					if (!properties) {
-						std::cerr << "Unable to get a display mode with the given parameters" << std::endl;
-						[self autorelease];
-						return nil;
-					}
-					
-					if (exact == false) {
-						CFNumberGetValue((CFNumberRef) CFDictionaryGetValue(properties, kCGDisplayWidth),
-										 kCFNumberIntType, &mode.Width);
-						
-						CFNumberGetValue((CFNumberRef) CFDictionaryGetValue(properties, kCGDisplayHeight),
-										 kCFNumberIntType, &mode.Height);
-						
-						CFNumberGetValue((CFNumberRef) CFDictionaryGetValue(properties, kCGDisplayBitsPerPixel),
-										 kCFNumberIntType, &mode.BitsPerPixel);
-						
-					}
-				}
+				
 				
 			} else {
 				if (style & sf::Style::Titlebar) {
@@ -638,9 +640,8 @@ static GLContext *sharedCtx = nil;
 ////////////////////////////////////////////////////////////
 - (void)dealloc
 {
+	
 	// Remove the notification observer
-	if (myView)
-		[[NSNotificationCenter defaultCenter] removeObserver:myView];
 	[[NSNotificationCenter defaultCenter] removeObserver:self];
 	
 	// Close the window
diff --git a/src/SFML/Window/Cocoa/WindowImplCocoa.mm b/src/SFML/Window/Cocoa/WindowImplCocoa.mm
index be003049..3b66bbcc 100644
--- a/src/SFML/Window/Cocoa/WindowImplCocoa.mm
+++ b/src/SFML/Window/Cocoa/WindowImplCocoa.mm
@@ -93,21 +93,30 @@ myWheelStatus(0.0f)
 {
 	if (Handle)
 	{
-		// We create the window according to the given handle
-		myWrapper = [[WindowWrapper alloc] initWithWindow:(NSWindow *)Handle
-												  settings:params
-												  delegate:this];
-		
-		if (myWrapper)
+		if (![(NSWindow *)Handle isKindOfClass:[NSWindow class]])
+			std::cerr << "Cannot import this Window Handle because it is not a <NSWindow *> object"
+			<< "(or one of its subclasses). You gave a <" 
+			<< [[(NSWindow *)Handle className] UTF8String]
+			<< "> object." << std::endl;
+		else
 		{
-			// initial mouse state
-			myMouseIn = [myWrapper mouseInside];
 			
-			// We set the myWidth and myHeight members to the correct values
-			myWidth = (int) [[myWrapper glView] frame].size.width;
-			myHeight = (int) [[myWrapper glView] frame].size.height;
-		} else {
-			std::cerr << "Failed to make the public window" << std::endl;
+			// We create the window according to the given handle
+			myWrapper = [[WindowWrapper alloc] initWithWindow:(NSWindow *)Handle
+													 settings:params
+													 delegate:this];
+			
+			if (myWrapper)
+			{
+				// initial mouse state
+				myMouseIn = [myWrapper mouseInside];
+				
+				// We set the myWidth and myHeight members to the correct values
+				myWidth = (int) [[myWrapper glView] frame].size.width;
+				myHeight = (int) [[myWrapper glView] frame].size.height;
+			} else {
+				std::cerr << "Failed to make the public window" << std::endl;
+			}
 		}
 	}
 }