diff --git a/readme.html b/readme.html
index 5762b023..5f3af632 100644
--- a/readme.html
+++ b/readme.html
@@ -312,7 +312,7 @@ version of GLFW.
[Cocoa] Added support for joysticks
[Cocoa] Postponed menu creation to first window creation
[Cocoa] Replaced NSDate
time source with mach_absolute_time
- [Cocoa] Replaced deprecated CoreGraphics calls in video mode enumeration
+ [Cocoa] Replaced deprecated CoreGraphics calls in video mode enumeration and setting
[Cocoa] Bugfix: glfwOpenWindow
did not properly enforce the forward-compatible and context profile hints
[Cocoa] Bugfix: The loop condition for saving video modes used the wrong index variable
[Cocoa] Bugfix: The OpenGL framework was not retrieved, making glfwGetProcAddress crash
diff --git a/src/cocoa_fullscreen.m b/src/cocoa_fullscreen.m
index cc5df538..d3a715ba 100644
--- a/src/cocoa_fullscreen.m
+++ b/src/cocoa_fullscreen.m
@@ -29,6 +29,9 @@
#include "internal.h"
+#include
+#include
+
//========================================================================
// Check whether the display mode should be included in enumeration
@@ -91,6 +94,100 @@ static GLFWvidmode vidmodeFromCGDisplayMode(CGDisplayModeRef mode)
}
+//////////////////////////////////////////////////////////////////////////
+////// GLFW internal API //////
+//////////////////////////////////////////////////////////////////////////
+
+//========================================================================
+// Change the current video mode
+//========================================================================
+
+GLboolean _glfwSetVideoMode(int* width, int* height, int* bpp, int* refreshRate)
+{
+ CGDisplayModeRef bestMode = NULL;
+ CFArrayRef modes;
+ CFIndex count, i;
+ unsigned int leastSizeDiff = UINT_MAX;
+ double leastRateDiff = DBL_MAX;
+
+ modes = CGDisplayCopyAllDisplayModes(CGMainDisplayID(), NULL);
+ count = CFArrayGetCount(modes);
+
+ for (i = 0; i < count; i++)
+ {
+ CGDisplayModeRef mode = (CGDisplayModeRef) CFArrayGetValueAtIndex(modes, i);
+ if (!modeIsGood(mode))
+ continue;
+
+ int modeBPP;
+
+ // Identify display mode pixel encoding
+ {
+ CFStringRef format = CGDisplayModeCopyPixelEncoding(mode);
+
+ if (CFStringCompare(format, CFSTR(IO16BitDirectPixels), 0) == 0)
+ modeBPP = 16;
+ else
+ modeBPP = 32;
+
+ CFRelease(format);
+ }
+
+ int modeWidth = (int) CGDisplayModeGetWidth(mode);
+ int modeHeight = (int) CGDisplayModeGetHeight(mode);
+
+ unsigned int sizeDiff = (abs(modeBPP - *bpp) << 25) |
+ ((modeWidth - *width) * (modeWidth - *width) +
+ (modeHeight - *height) * (modeHeight - *height));
+
+ double rateDiff;
+
+ if (*refreshRate > 0)
+ rateDiff = fabs(CGDisplayModeGetRefreshRate(mode) - *refreshRate);
+ else
+ {
+ // If no refresh rate was specified, then they're all the same
+ rateDiff = 0;
+ }
+
+ if ((sizeDiff < leastSizeDiff) ||
+ (sizeDiff == leastSizeDiff && (rateDiff < leastRateDiff)))
+ {
+ bestMode = mode;
+
+ leastSizeDiff = sizeDiff;
+ leastRateDiff = rateDiff;
+ }
+ }
+
+ if (!bestMode)
+ {
+ CFRelease(modes);
+ return GL_FALSE;
+ }
+
+ CGDisplayCapture(CGMainDisplayID());
+ CGDisplaySetDisplayMode(CGMainDisplayID(), bestMode, NULL);
+
+ CFRelease(modes);
+ return GL_TRUE;
+}
+
+
+//========================================================================
+// Restore the previously saved (original) video mode
+//========================================================================
+
+void _glfwRestoreVideoMode(void)
+{
+ CGDisplaySetDisplayMode(CGMainDisplayID(),
+ _glfwLibrary.NS.desktopMode,
+ NULL);
+
+ CGDisplayRelease(CGMainDisplayID());
+}
+
+
//////////////////////////////////////////////////////////////////////////
////// GLFW platform API //////
//////////////////////////////////////////////////////////////////////////
diff --git a/src/cocoa_platform.h b/src/cocoa_platform.h
index 5a753707..a06c13a0 100644
--- a/src/cocoa_platform.h
+++ b/src/cocoa_platform.h
@@ -109,5 +109,8 @@ void _glfwInitTimer(void);
void _glfwInitJoysticks(void);
void _glfwTerminateJoysticks(void);
+// Fullscreen
+GLboolean _glfwSetVideoMode(int* width, int* height, int* bpp, int* refreshRate);
+void _glfwRestoreVideoMode(void);
#endif // _platform_h_
diff --git a/src/cocoa_window.m b/src/cocoa_window.m
index 94a11118..c1d710c0 100644
--- a/src/cocoa_window.m
+++ b/src/cocoa_window.m
@@ -850,28 +850,6 @@ int _glfwPlatformOpenWindow(_GLFWwindow* window,
// Don't use accumulation buffer support; it's not accelerated
// Aux buffers probably aren't accelerated either
- CFDictionaryRef fullscreenMode = NULL;
- if (wndconfig->mode == GLFW_FULLSCREEN)
- {
- // I think it's safe to pass 0 to the refresh rate for this function
- // rather than conditionalizing the code to call the version which
- // doesn't specify refresh...
- fullscreenMode =
- CGDisplayBestModeForParametersAndRefreshRateWithProperty(
- CGMainDisplayID(),
- colorBits + fbconfig->alphaBits,
- window->width, window->height,
- wndconfig->refreshRate,
- // Controversial, see macosx_fullscreen.m for discussion
- kCGDisplayModeIsSafeForHardware,
- NULL);
-
- window->width =
- [[(id)fullscreenMode objectForKey:(id)kCGDisplayWidth] intValue];
- window->height =
- [[(id)fullscreenMode objectForKey:(id)kCGDisplayHeight] intValue];
- }
-
if (!createWindow(window, wndconfig))
return GL_FALSE;
@@ -883,8 +861,15 @@ int _glfwPlatformOpenWindow(_GLFWwindow* window,
if (wndconfig->mode == GLFW_FULLSCREEN)
{
- CGCaptureAllDisplays();
- CGDisplaySwitchToMode(CGMainDisplayID(), fullscreenMode);
+ int bpp = colorBits + fbconfig->alphaBits;
+
+ if (!_glfwSetVideoMode(&window->width,
+ &window->height,
+ &bpp,
+ &window->refreshRate))
+ {
+ return GL_FALSE;
+ }
[[window->NS.window contentView] enterFullScreenMode:[NSScreen mainScreen]
withOptions:nil];
@@ -914,9 +899,7 @@ void _glfwPlatformCloseWindow(_GLFWwindow* window)
{
[[window->NS.window contentView] exitFullScreenModeWithOptions:nil];
- CGDisplaySwitchToMode(CGMainDisplayID(),
- (CFDictionaryRef) _glfwLibrary.NS.desktopMode);
- CGReleaseAllDisplays();
+ _glfwRestoreVideoMode();
}
[window->NSGL.pixelFormat release];