From 26eb8e74c86b1856d6742037918f8479fe86ff0c Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Wed, 15 Sep 2010 18:57:25 +0200 Subject: [PATCH] Converted Cocoa port to new API. --- src/cocoa/CMakeLists.txt | 7 +- src/cocoa/cocoa_enable.m | 4 +- src/cocoa/cocoa_fullscreen.m | 22 +- src/cocoa/cocoa_glext.m | 16 +- src/cocoa/cocoa_init.m | 73 ++--- src/cocoa/cocoa_time.m | 6 +- src/cocoa/cocoa_window.m | 539 +++++++++++++++++------------------ src/cocoa/platform.h | 142 +++------ 8 files changed, 367 insertions(+), 442 deletions(-) diff --git a/src/cocoa/CMakeLists.txt b/src/cocoa/CMakeLists.txt index 115e9bf2..5c867591 100644 --- a/src/cocoa/CMakeLists.txt +++ b/src/cocoa/CMakeLists.txt @@ -3,10 +3,9 @@ configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/libglfw.pc.cmake ${CMAKE_CURRENT_BINARY_DIR}/libglfw.pc @ONLY) -include_directories( - ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_SOURCE_DIR}/lib - ${GLFW_INCLUDE_DIR}) +include_directories(${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_SOURCE_DIR}/src + ${GLFW_INCLUDE_DIR}) set(cocoa_SOURCES cocoa_enable.m diff --git a/src/cocoa/cocoa_enable.m b/src/cocoa/cocoa_enable.m index 4f7ddad6..1dfd7e5e 100644 --- a/src/cocoa/cocoa_enable.m +++ b/src/cocoa/cocoa_enable.m @@ -37,12 +37,12 @@ // Enable and disable system keys //======================================================================== -void _glfwPlatformEnableSystemKeys( void ) +void _glfwPlatformEnableSystemKeys(_GLFWwindow* window) { // This is checked in macosx_window.m; we take no action here } -void _glfwPlatformDisableSystemKeys( void ) +void _glfwPlatformDisableSystemKeys(_GLFWwindow* window) { // This is checked in macosx_window.m; we take no action here // I don't think it's really possible to disable stuff like Exposé diff --git a/src/cocoa/cocoa_fullscreen.m b/src/cocoa/cocoa_fullscreen.m index af97b484..3ef8071a 100644 --- a/src/cocoa/cocoa_fullscreen.m +++ b/src/cocoa/cocoa_fullscreen.m @@ -33,7 +33,7 @@ // Check whether the display mode should be included in enumeration //======================================================================== -static BOOL modeIsGood( NSDictionary *mode ) +static BOOL modeIsGood(NSDictionary* mode) { // This is a bit controversial, if you've got something other than an // LCD computer monitor as an output device you might not want these @@ -50,7 +50,7 @@ static BOOL modeIsGood( NSDictionary *mode ) // Convert Core Graphics display mode to GLFW video mode //======================================================================== -static GLFWvidmode vidmodeFromCGDisplayMode( NSDictionary *mode ) +static GLFWvidmode vidmodeFromCGDisplayMode(NSDictionary* mode) { unsigned int width = [[mode objectForKey:(id)kCGDisplayWidth] unsignedIntValue]; unsigned int height = [[mode objectForKey:(id)kCGDisplayHeight] unsignedIntValue]; @@ -74,18 +74,16 @@ static GLFWvidmode vidmodeFromCGDisplayMode( NSDictionary *mode ) // Get a list of available video modes //======================================================================== -int _glfwPlatformGetVideoModes( GLFWvidmode *list, int maxcount ) +int _glfwPlatformGetVideoModes(GLFWvidmode* list, int maxcount) { - NSArray *modes = (NSArray *)CGDisplayAvailableModes( CGMainDisplayID() ); - + NSArray* modes = (NSArray*) CGDisplayAvailableModes(CGMainDisplayID()); unsigned int i, j = 0, n = [modes count]; - for( i = 0; i < n && i < (unsigned)maxcount; i++ ) + + for (i = 0; i < n && i < (unsigned)maxcount; i++) { NSDictionary *mode = [modes objectAtIndex:i]; - if( modeIsGood( mode ) ) - { - list[j++] = vidmodeFromCGDisplayMode( mode ); - } + if (modeIsGood(mode)) + list[j++] = vidmodeFromCGDisplayMode(mode); } return j; @@ -95,8 +93,8 @@ int _glfwPlatformGetVideoModes( GLFWvidmode *list, int maxcount ) // Get the desktop video mode //======================================================================== -void _glfwPlatformGetDesktopMode( GLFWvidmode *mode ) +void _glfwPlatformGetDesktopMode(GLFWvidmode *mode) { - *mode = vidmodeFromCGDisplayMode( _glfwLibrary.DesktopMode ); + *mode = vidmodeFromCGDisplayMode(_glfwLibrary.NS.desktopMode); } diff --git a/src/cocoa/cocoa_glext.m b/src/cocoa/cocoa_glext.m index a30988e9..ca11272d 100644 --- a/src/cocoa/cocoa_glext.m +++ b/src/cocoa/cocoa_glext.m @@ -37,7 +37,7 @@ // Check if an OpenGL extension is available at runtime //======================================================================== -int _glfwPlatformExtensionSupported( const char *extension ) +int _glfwPlatformExtensionSupported(const char* extension) { // There are no AGL, CGL or NSGL extensions. return GL_FALSE; @@ -47,16 +47,16 @@ int _glfwPlatformExtensionSupported( const char *extension ) // Get the function pointer to an OpenGL function //======================================================================== -void * _glfwPlatformGetProcAddress( const char *procname ) +void* _glfwPlatformGetProcAddress(const char* procname) { - CFStringRef symbolName = CFStringCreateWithCString( kCFAllocatorDefault, - procname, - kCFStringEncodingASCII ); + CFStringRef symbolName = CFStringCreateWithCString(kCFAllocatorDefault, + procname, + kCFStringEncodingASCII); - void *symbol = CFBundleGetFunctionPointerForName( _glfwLibrary.OpenGLFramework, - symbolName ); + void* symbol = CFBundleGetFunctionPointerForName(_glfwLibrary.NS.OpenGLFramework, + symbolName); - CFRelease( symbolName ); + CFRelease(symbolName); return symbol; } diff --git a/src/cocoa/cocoa_init.m b/src/cocoa/cocoa_init.m index 2f71a54f..910fe063 100644 --- a/src/cocoa/cocoa_init.m +++ b/src/cocoa/cocoa_init.m @@ -42,14 +42,10 @@ // down the command key don't get sent to the key window. - (void)sendEvent:(NSEvent *)event { - if( [event type] == NSKeyUp && ( [event modifierFlags] & NSCommandKeyMask ) ) - { + if ([event type] == NSKeyUp && ([event modifierFlags] & NSCommandKeyMask)) [[self keyWindow] sendEvent:event]; - } else - { [super sendEvent:event]; - } } @end @@ -58,11 +54,11 @@ // to get the application menu working properly. Need to be careful in // case it goes away in a future OS update. @interface NSApplication (NSAppleMenu) -- (void)setAppleMenu:(NSMenu *)m; +- (void)setAppleMenu:(NSMenu*)m; @end // Keys to search for as potential application names -NSString *GLFWNameKeys[] = +NSString* GLFWNameKeys[] = { @"CFBundleDisplayName", @"CFBundleName", @@ -72,12 +68,12 @@ NSString *GLFWNameKeys[] = //======================================================================== // Try to figure out what the calling application is called //======================================================================== -static NSString *findAppName( void ) +static NSString* findAppName(void) { - NSDictionary *infoDictionary = [[NSBundle mainBundle] infoDictionary]; - unsigned int i; - for( i = 0; i < sizeof(GLFWNameKeys) / sizeof(GLFWNameKeys[0]); i++ ) + NSDictionary* infoDictionary = [[NSBundle mainBundle] infoDictionary]; + + for (i = 0; i < sizeof(GLFWNameKeys) / sizeof(GLFWNameKeys[0]); i++) { id name = [infoDictionary objectForKey:GLFWNameKeys[i]]; if (name && @@ -89,22 +85,22 @@ static NSString *findAppName( void ) } // If we get here, we're unbundled - if( !_glfwLibrary.Unbundled ) + if (!_glfwLibrary.NS.unbundled) { // Could do this only if we discover we're unbundled, but it should // do no harm... ProcessSerialNumber psn = { 0, kCurrentProcess }; - TransformProcessType( &psn, kProcessTransformToForegroundApplication ); + TransformProcessType(&psn, kProcessTransformToForegroundApplication); // Having the app in front of the terminal window is also generally // handy. There is an NSApplication API to do this, but... - SetFrontProcess( &psn ); + SetFrontProcess(&psn); - _glfwLibrary.Unbundled = GL_TRUE; + _glfwLibrary.NS.unbundled = GL_TRUE; } - char **progname = _NSGetProgname(); - if( progname && *progname ) + char** progname = _NSGetProgname(); + if (progname && *progname) { // TODO: UTF8? return [NSString stringWithUTF8String:*progname]; @@ -178,17 +174,15 @@ static void setUpMenuBar( void ) // At least guard the call to private API to avoid an exception if it // goes away. Hopefully that means the worst we'll break in future is to // look ugly... - if( [NSApp respondsToSelector:@selector(setAppleMenu:)] ) - { + if ([NSApp respondsToSelector:@selector(setAppleMenu:)]) [NSApp setAppleMenu:appMenu]; - } } //======================================================================== // Terminate GLFW when exiting application //======================================================================== -static void glfw_atexit( void ) +static void glfw_atexit(void) { glfwTerminate(); } @@ -202,19 +196,17 @@ static void glfw_atexit( void ) // Initialize the GLFW library //======================================================================== -int _glfwPlatformInit( void ) +int _glfwPlatformInit(void) { - _glfwLibrary.AutoreleasePool = [[NSAutoreleasePool alloc] init]; + _glfwLibrary.NS.autoreleasePool = [[NSAutoreleasePool alloc] init]; // Implicitly create shared NSApplication instance [GLFWApplication sharedApplication]; NSString* resourcePath = [[NSBundle mainBundle] resourcePath]; - if( access( [resourcePath cStringUsingEncoding:NSUTF8StringEncoding], R_OK ) == 0 ) - { - chdir( [resourcePath cStringUsingEncoding:NSUTF8StringEncoding] ); - } + if (access([resourcePath cStringUsingEncoding:NSUTF8StringEncoding], R_OK) == 0) + chdir([resourcePath cStringUsingEncoding:NSUTF8StringEncoding]); // Setting up menu bar must go exactly here else weirdness ensues setUpMenuBar(); @@ -222,12 +214,12 @@ int _glfwPlatformInit( void ) [NSApp finishLaunching]; // Install atexit routine - atexit( glfw_atexit ); + atexit(glfw_atexit); - _glfwPlatformSetTime( 0.0 ); + _glfwPlatformSetTime(0.0); - _glfwLibrary.DesktopMode = - (NSDictionary *)CGDisplayCurrentMode( CGMainDisplayID() ); + _glfwLibrary.NS.desktopMode = + (NSDictionary*) CGDisplayCurrentMode(CGMainDisplayID()); return GL_TRUE; } @@ -238,13 +230,24 @@ int _glfwPlatformInit( void ) int _glfwPlatformTerminate( void ) { - glfwCloseWindow(); - // TODO: Probably other cleanup - [_glfwLibrary.AutoreleasePool release]; - _glfwLibrary.AutoreleasePool = nil; + [_glfwLibrary.NS.autoreleasePool release]; + _glfwLibrary.NS.autoreleasePool = nil; return GL_TRUE; } + +//======================================================================== +// Get the GLFW version string +//======================================================================== + +const char* _glfwPlatformGetVersionString(void) +{ + // TODO: Bring in CMake version + const char* version = "GLFW" " Cocoa"; + + return version; +} + diff --git a/src/cocoa/cocoa_time.m b/src/cocoa/cocoa_time.m index a3671d29..fd613224 100644 --- a/src/cocoa/cocoa_time.m +++ b/src/cocoa/cocoa_time.m @@ -39,7 +39,8 @@ double _glfwPlatformGetTime( void ) { - return [NSDate timeIntervalSinceReferenceDate] - _glfwLibrary.Timer.t0; + return [NSDate timeIntervalSinceReferenceDate] - + _glfwLibrary.NS.timer.t0; } //======================================================================== @@ -48,6 +49,7 @@ double _glfwPlatformGetTime( void ) void _glfwPlatformSetTime( double time ) { - _glfwLibrary.Timer.t0 = [NSDate timeIntervalSinceReferenceDate] - time; + _glfwLibrary.NS.timer.t0 = + [NSDate timeIntervalSinceReferenceDate] - time; } diff --git a/src/cocoa/cocoa_window.m b/src/cocoa/cocoa_window.m index 7c69edb4..52633e52 100644 --- a/src/cocoa/cocoa_window.m +++ b/src/cocoa/cocoa_window.m @@ -35,52 +35,59 @@ //======================================================================== @interface GLFWWindowDelegate : NSObject +{ + _GLFWwindow* window; +} + +- (id)initWithRats:(_GLFWwindow*)initWndow; + @end @implementation GLFWWindowDelegate -- (BOOL)windowShouldClose:(id)window +- (id)initWithRats:(_GLFWwindow*)initWindow { - if( _glfwWin.windowCloseCallback ) + self = [super init]; + if (self != nil) + window = initWindow; + + return self; +} + +- (BOOL)windowShouldClose:(id)sender +{ + if (window->windowCloseCallback) { - if( !_glfwWin.windowCloseCallback() ) - { + if (!window->windowCloseCallback(window)) return NO; - } } - // This is horribly ugly, but it works - glfwCloseWindow(); + window->closed = GL_TRUE; return NO; } - (void)windowDidResize:(NSNotification *)notification { - [_glfwWin.context update]; + [window->NSGL.context update]; NSRect contentRect = - [_glfwWin.window contentRectForFrameRect:[_glfwWin.window frame]]; - _glfwWin.width = contentRect.size.width; - _glfwWin.height = contentRect.size.height; + [window->NS.window contentRectForFrameRect:[window->NS.window frame]]; + window->width = contentRect.size.width; + window->height = contentRect.size.height; - if( _glfwWin.windowSizeCallback ) - { - _glfwWin.windowSizeCallback( _glfwWin.width, _glfwWin.height ); - } + if (window->windowSizeCallback) + window->windowSizeCallback(window, window->width, window->height); } - (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender { - if( _glfwWin.windowCloseCallback ) + if (window->windowCloseCallback) { - if( !_glfwWin.windowCloseCallback() ) - { + if (!window->windowCloseCallback(window)) return NSTerminateCancel; - } } - // This is horribly ugly, but it works - glfwCloseWindow(); + window->closed = GL_TRUE; return NSTerminateCancel; } @@ -223,12 +230,10 @@ static const unsigned int MAC_TO_GLFW_KEYCODE_MAPPING[128] = // Converts a Mac OS X keycode to a GLFW keycode //======================================================================== -static int convertMacKeyCode( unsigned int macKeyCode ) +static int convertMacKeyCode(unsigned int macKeyCode) { - if( macKeyCode >= 128 ) - { + if (macKeyCode >= 128) return -1; - } // This treats keycodes as *positional*; that is, we'll return 'a' // for the key left of 's', even on an AZERTY keyboard. The charInput @@ -241,10 +246,25 @@ static int convertMacKeyCode( unsigned int macKeyCode ) //======================================================================== @interface GLFWContentView : NSView +{ + _GLFWwindow* window; +} + +- (id)initWithRats:(_GLFWwindow*)initWindow; + @end @implementation GLFWContentView +- (id)initWithRats:(_GLFWwindow*)initWindow +{ + self = [super init]; + if (self != nil) + window = initWindow; + + return self; +} + - (BOOL)isOpaque { return YES; @@ -262,7 +282,7 @@ static int convertMacKeyCode( unsigned int macKeyCode ) - (void)mouseDown:(NSEvent *)event { - _glfwInputMouseClick( GLFW_MOUSE_BUTTON_LEFT, GLFW_PRESS ); + _glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_LEFT, GLFW_PRESS); } - (void)mouseDragged:(NSEvent *)event @@ -272,34 +292,32 @@ static int convertMacKeyCode( unsigned int macKeyCode ) - (void)mouseUp:(NSEvent *)event { - _glfwInputMouseClick( GLFW_MOUSE_BUTTON_LEFT, GLFW_RELEASE ); + _glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_LEFT, GLFW_RELEASE); } - (void)mouseMoved:(NSEvent *)event { - if( _glfwWin.mouseLock ) + if (window == _glfwLibrary.cursorLockWindow) { - _glfwInput.MousePosX += [event deltaX]; - _glfwInput.MousePosY += [event deltaY]; + window->mousePosX += [event deltaX]; + window->mousePosY += [event deltaY]; } else { NSPoint p = [event locationInWindow]; // Cocoa coordinate system has origin at lower left - _glfwInput.MousePosX = p.x; - _glfwInput.MousePosY = [[_glfwWin.window contentView] bounds].size.height - p.y; + window->mousePosX = p.x; + window->mousePosY = [[window->NS.window contentView] bounds].size.height - p.y; } - if( _glfwWin.mousePosCallback ) - { - _glfwWin.mousePosCallback( _glfwInput.MousePosX, _glfwInput.MousePosY ); - } + if (window->mousePosCallback) + window->mousePosCallback(window, window->mousePosX, window->mousePosY); } - (void)rightMouseDown:(NSEvent *)event { - _glfwInputMouseClick( GLFW_MOUSE_BUTTON_RIGHT, GLFW_PRESS ); + _glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_RIGHT, GLFW_PRESS); } - (void)rightMouseDragged:(NSEvent *)event @@ -309,12 +327,12 @@ static int convertMacKeyCode( unsigned int macKeyCode ) - (void)rightMouseUp:(NSEvent *)event { - _glfwInputMouseClick( GLFW_MOUSE_BUTTON_RIGHT, GLFW_RELEASE ); + _glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_RIGHT, GLFW_RELEASE); } - (void)otherMouseDown:(NSEvent *)event { - _glfwInputMouseClick( [event buttonNumber], GLFW_PRESS ); + _glfwInputMouseClick(window, [event buttonNumber], GLFW_PRESS); } - (void)otherMouseDragged:(NSEvent *)event @@ -324,86 +342,64 @@ static int convertMacKeyCode( unsigned int macKeyCode ) - (void)otherMouseUp:(NSEvent *)event { - _glfwInputMouseClick( [event buttonNumber], GLFW_RELEASE ); + _glfwInputMouseClick(window, [event buttonNumber], GLFW_RELEASE); } - (void)keyDown:(NSEvent *)event { - NSUInteger length; + NSUInteger i, length; NSString* characters; - int i, code = convertMacKeyCode( [event keyCode] ); + int code = convertMacKeyCode([event keyCode]); - if( code != -1 ) + if (code != -1) { - _glfwInputKey( code, GLFW_PRESS ); + _glfwInputKey(window, code, GLFW_PRESS); - if( [event modifierFlags] & NSCommandKeyMask ) + if ([event modifierFlags] & NSCommandKeyMask) { - if( !_glfwWin.sysKeysDisabled ) - { + if (!window->sysKeysDisabled) [super keyDown:event]; - } } else { characters = [event characters]; length = [characters length]; - for( i = 0; i < length; i++ ) - { - _glfwInputChar( [characters characterAtIndex:i], GLFW_PRESS ); - } + for (i = 0; i < length; i++) + _glfwInputChar(window, [characters characterAtIndex:i]); } } } - (void)flagsChanged:(NSEvent *)event { - unsigned int newModifierFlags = [event modifierFlags] | NSDeviceIndependentModifierFlagsMask; int mode; + unsigned int newModifierFlags = + [event modifierFlags] | NSDeviceIndependentModifierFlagsMask; - if( newModifierFlags > _glfwWin.modifierFlags ) - { + if (newModifierFlags > window->NS.modifierFlags) mode = GLFW_PRESS; - } else - { mode = GLFW_RELEASE; - } - _glfwWin.modifierFlags = newModifierFlags; - _glfwInputKey( MAC_TO_GLFW_KEYCODE_MAPPING[[event keyCode]], mode ); + window->NS.modifierFlags = newModifierFlags; + _glfwInputKey(window, MAC_TO_GLFW_KEYCODE_MAPPING[[event keyCode]], mode); } - (void)keyUp:(NSEvent *)event { - NSUInteger length; - NSString* characters; - int i, code = convertMacKeyCode( [event keyCode] ); - - if( code != -1 ) - { - _glfwInputKey( code, GLFW_RELEASE ); - - characters = [event characters]; - length = [characters length]; - - for( i = 0; i < length; i++ ) - { - _glfwInputChar( [characters characterAtIndex:i], GLFW_RELEASE ); - } - } + int code = convertMacKeyCode([event keyCode]); + if (code != -1) + _glfwInputKey(window, code, GLFW_RELEASE); } - (void)scrollWheel:(NSEvent *)event { - _glfwInput.WheelPosFloating += [event deltaY]; - _glfwInput.WheelPos = lrint(_glfwInput.WheelPosFloating); + window->NS.wheelPosFloating += [event deltaY]; + window->wheelPos = lrint(window->NS.wheelPosFloating); - if( _glfwWin.mouseWheelCallback ) - { - _glfwWin.mouseWheelCallback( _glfwInput.WheelPos ); - } + if (window->mouseWheelCallback) + window->mouseWheelCallback(window, window->wheelPos); } @end @@ -417,43 +413,37 @@ static int convertMacKeyCode( unsigned int macKeyCode ) // created //======================================================================== -int _glfwPlatformOpenWindow( int width, int height, - const _GLFWwndconfig *wndconfig, - const _GLFWfbconfig *fbconfig ) +int _glfwPlatformOpenWindow(_GLFWwindow* window, + const _GLFWwndconfig *wndconfig, + const _GLFWfbconfig *fbconfig) { - int colorBits; - - _glfwWin.pixelFormat = nil; - _glfwWin.window = nil; - _glfwWin.context = nil; - _glfwWin.delegate = nil; + window->NS.window = nil; + window->NS.delegate = nil; + window->NSGL.pixelFormat = nil; + window->NSGL.context = nil; // Fail if OpenGL 3.0 or above was requested - if( wndconfig->glMajor > 2 ) + if (wndconfig->glMajor > 2) { - _glfwPlatformCloseWindow(); + _glfwSetError(GLFW_UNAVAILABLE_VERSION); return GL_FALSE; } - _glfwWin.delegate = [[GLFWWindowDelegate alloc] init]; - if( _glfwWin.delegate == nil ) + window->NS.delegate = [[GLFWWindowDelegate alloc] initWithRats:window]; + if (window->NS.delegate == nil) { - _glfwPlatformCloseWindow(); + _glfwSetError(GLFW_INTERNAL_ERROR); return GL_FALSE; } - [NSApp setDelegate:_glfwWin.delegate]; + [NSApp setDelegate:window->NS.delegate]; // Mac OS X needs non-zero color size, so set resonable values - colorBits = fbconfig->redBits + fbconfig->greenBits + fbconfig->blueBits; - if( colorBits == 0 ) - { + int colorBits = fbconfig->redBits + fbconfig->greenBits + fbconfig->blueBits; + if (colorBits == 0) colorBits = 24; - } - else if( colorBits < 15 ) - { + else if (colorBits < 15) colorBits = 15; - } // Ignored hints: // OpenGLMajor, OpenGLMinor, OpenGLForward: @@ -465,55 +455,55 @@ int _glfwPlatformOpenWindow( int width, int height, // Aux buffers probably aren't accelerated either CFDictionaryRef fullscreenMode = NULL; - if( wndconfig->mode == GLFW_FULLSCREEN ) + 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 = - // 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... CGDisplayBestModeForParametersAndRefreshRateWithProperty( - CGMainDisplayID(), - colorBits + fbconfig->alphaBits, - width, - height, - wndconfig->refreshRate, - // Controversial, see macosx_fullscreen.m for discussion - kCGDisplayModeIsSafeForHardware, - NULL); + CGMainDisplayID(), + colorBits + fbconfig->alphaBits, + window->width, window->height, + wndconfig->refreshRate, + // Controversial, see macosx_fullscreen.m for discussion + kCGDisplayModeIsSafeForHardware, + NULL); - width = [[(id)fullscreenMode objectForKey:(id)kCGDisplayWidth] intValue]; - height = [[(id)fullscreenMode objectForKey:(id)kCGDisplayHeight] intValue]; + window->width = [[(id)fullscreenMode objectForKey:(id)kCGDisplayWidth] intValue]; + window->height = [[(id)fullscreenMode objectForKey:(id)kCGDisplayHeight] intValue]; } unsigned int styleMask = 0; - if( wndconfig->mode == GLFW_WINDOW ) + + if (wndconfig->mode == GLFW_WINDOWED) { styleMask = NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask; - if( !wndconfig->windowNoResize ) - { + if (!wndconfig->windowNoResize) styleMask |= NSResizableWindowMask; - } } else - { styleMask = NSBorderlessWindowMask; - } - _glfwWin.window = [[NSWindow alloc] - initWithContentRect:NSMakeRect(0, 0, width, height) + window->NS.window = [[NSWindow alloc] + initWithContentRect:NSMakeRect(0, 0, window->width, window->height) styleMask:styleMask backing:NSBackingStoreBuffered defer:NO]; - [_glfwWin.window setContentView:[[GLFWContentView alloc] init]]; - [_glfwWin.window setDelegate:_glfwWin.delegate]; - [_glfwWin.window setAcceptsMouseMovedEvents:YES]; - [_glfwWin.window center]; - if( wndconfig->mode == GLFW_FULLSCREEN ) + [window->NS.window setTitle:[NSString stringWithCString:wndconfig->title + encoding:NSISOLatin1StringEncoding]]; + + [window->NS.window setContentView:[[GLFWContentView alloc] initWithRats:window]]; + [window->NS.window setDelegate:window->NS.delegate]; + [window->NS.window setAcceptsMouseMovedEvents:YES]; + [window->NS.window center]; + + if (wndconfig->mode == GLFW_FULLSCREEN) { CGCaptureAllDisplays(); - CGDisplaySwitchToMode( CGMainDisplayID(), fullscreenMode ); + CGDisplaySwitchToMode(CGMainDisplayID(), fullscreenMode); } unsigned int attribute_count = 0; @@ -522,123 +512,125 @@ int _glfwPlatformOpenWindow( int width, int height, #define MAX_ATTRS 24 // urgh NSOpenGLPixelFormatAttribute attributes[MAX_ATTRS]; - ADD_ATTR( NSOpenGLPFADoubleBuffer ); + ADD_ATTR(NSOpenGLPFADoubleBuffer); - if( wndconfig->mode == GLFW_FULLSCREEN ) + if (wndconfig->mode == GLFW_FULLSCREEN) { - ADD_ATTR( NSOpenGLPFAFullScreen ); - ADD_ATTR( NSOpenGLPFANoRecovery ); - ADD_ATTR2( NSOpenGLPFAScreenMask, - CGDisplayIDToOpenGLDisplayMask( CGMainDisplayID() ) ); + ADD_ATTR(NSOpenGLPFAFullScreen); + ADD_ATTR(NSOpenGLPFANoRecovery); + ADD_ATTR2(NSOpenGLPFAScreenMask, + CGDisplayIDToOpenGLDisplayMask(CGMainDisplayID())); } - ADD_ATTR2( NSOpenGLPFAColorSize, colorBits ); + ADD_ATTR2(NSOpenGLPFAColorSize, colorBits); - if( fbconfig->alphaBits > 0) - { - ADD_ATTR2( NSOpenGLPFAAlphaSize, fbconfig->alphaBits ); - } + if (fbconfig->alphaBits > 0) + ADD_ATTR2(NSOpenGLPFAAlphaSize, fbconfig->alphaBits); - if( fbconfig->depthBits > 0) - { - ADD_ATTR2( NSOpenGLPFADepthSize, fbconfig->depthBits ); - } + if (fbconfig->depthBits > 0) + ADD_ATTR2(NSOpenGLPFADepthSize, fbconfig->depthBits); - if( fbconfig->stencilBits > 0) - { - ADD_ATTR2( NSOpenGLPFAStencilSize, fbconfig->stencilBits ); - } + if (fbconfig->stencilBits > 0) + ADD_ATTR2(NSOpenGLPFAStencilSize, fbconfig->stencilBits); int accumBits = fbconfig->accumRedBits + fbconfig->accumGreenBits + fbconfig->accumBlueBits + fbconfig->accumAlphaBits; - if( accumBits > 0) - { - ADD_ATTR2( NSOpenGLPFAAccumSize, accumBits ); - } + if (accumBits > 0) + ADD_ATTR2(NSOpenGLPFAAccumSize, accumBits); - if( fbconfig->auxBuffers > 0) - { - ADD_ATTR2( NSOpenGLPFAAuxBuffers, fbconfig->auxBuffers ); - } + if (fbconfig->auxBuffers > 0) + ADD_ATTR2(NSOpenGLPFAAuxBuffers, fbconfig->auxBuffers); - if( fbconfig->stereo) - { - ADD_ATTR( NSOpenGLPFAStereo ); - } + if (fbconfig->stereo) + ADD_ATTR(NSOpenGLPFAStereo ); - if( fbconfig->samples > 0) + if (fbconfig->samples > 0) { - ADD_ATTR2( NSOpenGLPFASampleBuffers, 1 ); - ADD_ATTR2( NSOpenGLPFASamples, fbconfig->samples ); + ADD_ATTR2(NSOpenGLPFASampleBuffers, 1); + ADD_ATTR2(NSOpenGLPFASamples, fbconfig->samples); } ADD_ATTR(0); - _glfwWin.pixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:attributes]; - if( _glfwWin.pixelFormat == nil ) + window->NSGL.pixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:attributes]; + if (window->NSGL.pixelFormat == nil) { - _glfwPlatformCloseWindow(); + _glfwSetError(GLFW_NO_PIXEL_FORMAT); return GL_FALSE; } - _glfwWin.context = [[NSOpenGLContext alloc] initWithFormat:_glfwWin.pixelFormat - shareContext:nil]; - if( _glfwWin.context == nil ) + window->NSGL.context = [[NSOpenGLContext alloc] initWithFormat:window->NSGL.pixelFormat + shareContext:nil]; + if (window->NSGL.context == nil) { - _glfwPlatformCloseWindow(); + _glfwSetError(GLFW_INTERNAL_ERROR); return GL_FALSE; } - [_glfwWin.window makeKeyAndOrderFront:nil]; - [_glfwWin.context setView:[_glfwWin.window contentView]]; + [window->NS.window makeKeyAndOrderFront:nil]; + [window->NSGL.context setView:[window->NS.window contentView]]; - if( wndconfig->mode == GLFW_FULLSCREEN ) + if (wndconfig->mode == GLFW_FULLSCREEN) { // TODO: Make this work on pre-Leopard systems - [[_glfwWin.window contentView] enterFullScreenMode:[NSScreen mainScreen] - withOptions:nil]; + [[window->NS.window contentView] enterFullScreenMode:[NSScreen mainScreen] + withOptions:nil]; } - [_glfwWin.context makeCurrentContext]; + glfwMakeWindowCurrent(window); NSPoint point = [[NSCursor currentCursor] hotSpot]; - _glfwInput.MousePosX = point.x; - _glfwInput.MousePosY = point.y; + window->mousePosX = point.x; + window->mousePosY = point.y; return GL_TRUE; } +//======================================================================== +// Make the OpenGL context associated with the specified window current +//======================================================================== + +void _glfwPlatformMakeWindowCurrent(_GLFWwindow* window) +{ + if (window) + [window->NSGL.context makeCurrentContext]; + else + [NSOpenGLContext clearCurrentContext]; +} + + //======================================================================== // Properly kill the window / video display //======================================================================== -void _glfwPlatformCloseWindow( void ) +void _glfwPlatformCloseWindow(_GLFWwindow* window) { - [_glfwWin.window orderOut:nil]; + [window->NS.window orderOut:nil]; - if( _glfwWin.fullscreen ) + if (window->mode == GLFW_FULLSCREEN) { - [[_glfwWin.window contentView] exitFullScreenModeWithOptions:nil]; - CGDisplaySwitchToMode( CGMainDisplayID(), - (CFDictionaryRef)_glfwLibrary.DesktopMode ); + [[window->NS.window contentView] exitFullScreenModeWithOptions:nil]; + + CGDisplaySwitchToMode(CGMainDisplayID(), + (CFDictionaryRef) _glfwLibrary.NS.desktopMode); CGReleaseAllDisplays(); } - [_glfwWin.pixelFormat release]; - _glfwWin.pixelFormat = nil; + [window->NSGL.pixelFormat release]; + window->NSGL.pixelFormat = nil; [NSOpenGLContext clearCurrentContext]; - [_glfwWin.context release]; - _glfwWin.context = nil; + [window->NSGL.context release]; + window->NSGL.context = nil; - [_glfwWin.window setDelegate:nil]; + [window->NS.window setDelegate:nil]; [NSApp setDelegate:nil]; - [_glfwWin.delegate release]; - _glfwWin.delegate = nil; + [window->NS.delegate release]; + window->NS.delegate = nil; - [_glfwWin.window close]; - _glfwWin.window = nil; + [window->NS.window close]; + window->NS.window = nil; // TODO: Probably more cleanup } @@ -647,37 +639,37 @@ void _glfwPlatformCloseWindow( void ) // Set the window title //======================================================================== -void _glfwPlatformSetWindowTitle( const char *title ) +void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char *title) { - [_glfwWin.window setTitle:[NSString stringWithCString:title - encoding:NSISOLatin1StringEncoding]]; + [window->NS.window setTitle:[NSString stringWithCString:title + encoding:NSISOLatin1StringEncoding]]; } //======================================================================== // Set the window size //======================================================================== -void _glfwPlatformSetWindowSize( int width, int height ) +void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height) { - [_glfwWin.window setContentSize:NSMakeSize(width, height)]; + [window->NS.window setContentSize:NSMakeSize(width, height)]; } //======================================================================== // Set the window position //======================================================================== -void _glfwPlatformSetWindowPos( int x, int y ) +void _glfwPlatformSetWindowPos(_GLFWwindow* window, int x, int y) { - NSRect contentRect = [_glfwWin.window contentRectForFrameRect:[_glfwWin.window frame]]; + NSRect contentRect = [window->NS.window contentRectForFrameRect:[window->NS.window frame]]; // We assume here that the client code wants to position the window within the // screen the window currently occupies - NSRect screenRect = [[_glfwWin.window screen] visibleFrame]; + NSRect screenRect = [[window->NS.window screen] visibleFrame]; contentRect.origin = NSMakePoint(screenRect.origin.x + x, screenRect.origin.y + screenRect.size.height - y - contentRect.size.height); - [_glfwWin.window setFrame:[_glfwWin.window frameRectForContentRect:contentRect] + [window->NS.window setFrame:[window->NS.window frameRectForContentRect:contentRect] display:YES]; } @@ -685,117 +677,122 @@ void _glfwPlatformSetWindowPos( int x, int y ) // Iconify the window //======================================================================== -void _glfwPlatformIconifyWindow( void ) +void _glfwPlatformIconifyWindow(_GLFWwindow* window) { - [_glfwWin.window miniaturize:nil]; + [window->NS.window miniaturize:nil]; } //======================================================================== // Restore (un-iconify) the window //======================================================================== -void _glfwPlatformRestoreWindow( void ) +void _glfwPlatformRestoreWindow(_GLFWwindow* window) { - [_glfwWin.window deminiaturize:nil]; + [window->NS.window deminiaturize:nil]; } //======================================================================== // Swap buffers //======================================================================== -void _glfwPlatformSwapBuffers( void ) +void _glfwPlatformSwapBuffers(void) { + _GLFWwindow* window = _glfwLibrary.currentWindow; + // ARP appears to be unnecessary, but this is future-proof - [_glfwWin.context flushBuffer]; + [window->NSGL.context flushBuffer]; } //======================================================================== // Set double buffering swap interval //======================================================================== -void _glfwPlatformSwapInterval( int interval ) +void _glfwPlatformSwapInterval(int interval) { + _GLFWwindow* window = _glfwLibrary.currentWindow; + GLint sync = interval; - [_glfwWin.context setValues:&sync forParameter:NSOpenGLCPSwapInterval]; + [window->NSGL.context setValues:&sync forParameter:NSOpenGLCPSwapInterval]; } //======================================================================== // Write back window parameters into GLFW window structure //======================================================================== -void _glfwPlatformRefreshWindowParams( void ) +void _glfwPlatformRefreshWindowParams(void) { GLint value; + _GLFWwindow* window = _glfwLibrary.currentWindow; - // Since GLFW 2.x doesn't understand screens, we use virtual screen zero + // Since GLFW doesn't understand screens, we use virtual screen zero - [_glfwWin.pixelFormat getValues:&value - forAttribute:NSOpenGLPFAAccelerated - forVirtualScreen:0]; - _glfwWin.accelerated = value; + [window->NSGL.pixelFormat getValues:&value + forAttribute:NSOpenGLPFAAccelerated + forVirtualScreen:0]; + window->accelerated = value; - [_glfwWin.pixelFormat getValues:&value - forAttribute:NSOpenGLPFAAlphaSize - forVirtualScreen:0]; - _glfwWin.alphaBits = value; + [window->NSGL.pixelFormat getValues:&value + forAttribute:NSOpenGLPFAAlphaSize + forVirtualScreen:0]; + window->alphaBits = value; // It seems that the color size includes the size of the alpha channel - [_glfwWin.pixelFormat getValues:&value - forAttribute:NSOpenGLPFAColorSize - forVirtualScreen:0]; - value -= _glfwWin.alphaBits; - _glfwWin.redBits = value / 3; - _glfwWin.greenBits = value / 3; - _glfwWin.blueBits = value / 3; + [window->NSGL.pixelFormat getValues:&value + forAttribute:NSOpenGLPFAColorSize + forVirtualScreen:0]; + value -= window->alphaBits; + window->redBits = value / 3; + window->greenBits = value / 3; + window->blueBits = value / 3; - [_glfwWin.pixelFormat getValues:&value - forAttribute:NSOpenGLPFADepthSize - forVirtualScreen:0]; - _glfwWin.depthBits = value; + [window->NSGL.pixelFormat getValues:&value + forAttribute:NSOpenGLPFADepthSize + forVirtualScreen:0]; + window->depthBits = value; - [_glfwWin.pixelFormat getValues:&value - forAttribute:NSOpenGLPFAStencilSize - forVirtualScreen:0]; - _glfwWin.stencilBits = value; + [window->NSGL.pixelFormat getValues:&value + forAttribute:NSOpenGLPFAStencilSize + forVirtualScreen:0]; + window->stencilBits = value; - [_glfwWin.pixelFormat getValues:&value - forAttribute:NSOpenGLPFAAccumSize - forVirtualScreen:0]; - _glfwWin.accumRedBits = value / 3; - _glfwWin.accumGreenBits = value / 3; - _glfwWin.accumBlueBits = value / 3; + [window->NSGL.pixelFormat getValues:&value + forAttribute:NSOpenGLPFAAccumSize + forVirtualScreen:0]; + window->accumRedBits = value / 3; + window->accumGreenBits = value / 3; + window->accumBlueBits = value / 3; // TODO: Figure out what to set this value to - _glfwWin.accumAlphaBits = 0; + window->accumAlphaBits = 0; - [_glfwWin.pixelFormat getValues:&value - forAttribute:NSOpenGLPFAAuxBuffers - forVirtualScreen:0]; - _glfwWin.auxBuffers = value; + [window->NSGL.pixelFormat getValues:&value + forAttribute:NSOpenGLPFAAuxBuffers + forVirtualScreen:0]; + window->auxBuffers = value; - [_glfwWin.pixelFormat getValues:&value - forAttribute:NSOpenGLPFAStereo - forVirtualScreen:0]; - _glfwWin.stereo = value; + [window->NSGL.pixelFormat getValues:&value + forAttribute:NSOpenGLPFAStereo + forVirtualScreen:0]; + window->stereo = value; - [_glfwWin.pixelFormat getValues:&value - forAttribute:NSOpenGLPFASamples - forVirtualScreen:0]; - _glfwWin.samples = value; + [window->NSGL.pixelFormat getValues:&value + forAttribute:NSOpenGLPFASamples + forVirtualScreen:0]; + window->samples = value; // These are forced to false as long as Mac OS X lacks support for OpenGL 3.0+ - _glfwWin.glForward = GL_FALSE; - _glfwWin.glDebug = GL_FALSE; - _glfwWin.glProfile = 0; + window->glForward = GL_FALSE; + window->glDebug = GL_FALSE; + window->glProfile = 0; } //======================================================================== // Poll for new window and input events //======================================================================== -void _glfwPlatformPollEvents( void ) +void _glfwPlatformPollEvents(void) { - NSEvent *event; + NSEvent* event; do { @@ -805,14 +802,12 @@ void _glfwPlatformPollEvents( void ) dequeue:YES]; if (event) - { [NSApp sendEvent:event]; - } } while (event); - [_glfwLibrary.AutoreleasePool drain]; - _glfwLibrary.AutoreleasePool = [[NSAutoreleasePool alloc] init]; + [_glfwLibrary.NS.autoreleasePool drain]; + _glfwLibrary.NS.autoreleasePool = [[NSAutoreleasePool alloc] init]; } //======================================================================== @@ -837,27 +832,27 @@ void _glfwPlatformWaitEvents( void ) // Hide mouse cursor (lock it) //======================================================================== -void _glfwPlatformHideMouseCursor( void ) +void _glfwPlatformHideMouseCursor(_GLFWwindow* window) { [NSCursor hide]; - CGAssociateMouseAndMouseCursorPosition( false ); + CGAssociateMouseAndMouseCursorPosition(false); } //======================================================================== // Show mouse cursor (unlock it) //======================================================================== -void _glfwPlatformShowMouseCursor( void ) +void _glfwPlatformShowMouseCursor(_GLFWwindow* window) { [NSCursor unhide]; - CGAssociateMouseAndMouseCursorPosition( true ); + CGAssociateMouseAndMouseCursorPosition(true); } //======================================================================== // Set physical mouse cursor position //======================================================================== -void _glfwPlatformSetMouseCursorPos( int x, int y ) +void _glfwPlatformSetMouseCursorPos(_GLFWwindow* window, int x, int y) { // The library seems to assume that after calling this the mouse won't move, // but obviously it will, and escape the app's window, and activate other apps, @@ -876,7 +871,7 @@ void _glfwPlatformSetMouseCursorPos( int x, int y ) CGSetLocalEventsSuppressionInterval( 0.0 ); NSPoint localPoint = NSMakePoint( x, y ); - NSPoint globalPoint = [_glfwWin.window convertBaseToScreen:localPoint]; + NSPoint globalPoint = [window->NS.window convertBaseToScreen:localPoint]; CGPoint mainScreenOrigin = CGDisplayBounds( CGMainDisplayID() ).origin; double mainScreenHeight = CGDisplayBounds( CGMainDisplayID() ).size.height; CGPoint targetPoint = CGPointMake( globalPoint.x - mainScreenOrigin.x, diff --git a/src/cocoa/platform.h b/src/cocoa/platform.h index 9b445aa4..a031f5b2 100644 --- a/src/cocoa/platform.h +++ b/src/cocoa/platform.h @@ -31,25 +31,33 @@ #define _platform_h_ +#include + + // This is the Mac OS X version of GLFW #define _GLFW_MAC_OS_X #if defined(__OBJC__) #import #else -typedef void *id; +typedef void* id; #endif -#include "../../include/GL/glfw.h" +#include "../../include/GL/glfw3.h" #ifndef GL_VERSION_3_0 -typedef const GLubyte * (APIENTRY *PFNGLGETSTRINGIPROC) (GLenum, GLuint); +typedef const GLubyte* (APIENTRY *PFNGLGETSTRINGIPROC)(GLenum, GLuint); #endif /*GL_VERSION_3_0*/ +#define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowNS NS +#define _GLFW_PLATFORM_LIBRARY_STATE _GLFWlibraryNS NS +#define _GLFW_PLATFORM_CONTEXT_STATE _GLFWcontextNSGL NSGL + + //======================================================================== // GLFW platform specific types //======================================================================== @@ -60,127 +68,47 @@ typedef const GLubyte * (APIENTRY *PFNGLGETSTRINGIPROC) (GLenum, GLuint); typedef intptr_t GLFWintptr; //------------------------------------------------------------------------ -// Window structure +// Platform-specific OpenGL context structure //------------------------------------------------------------------------ -typedef struct _GLFWwin_struct _GLFWwin; +typedef struct _GLFWcontextNSGL +{ + id pixelFormat; + id context; +} _GLFWcontextNSGL; -struct _GLFWwin_struct { -// ========= PLATFORM INDEPENDENT MANDATORY PART ========================= - - // User callback functions - GLFWwindowsizefun windowSizeCallback; - GLFWwindowclosefun windowCloseCallback; - GLFWwindowrefreshfun windowRefreshCallback; - GLFWmousebuttonfun mouseButtonCallback; - GLFWmouseposfun mousePosCallback; - GLFWmousewheelfun mouseWheelCallback; - GLFWkeyfun keyCallback; - GLFWcharfun charCallback; - - // User selected window settings - int fullscreen; // Fullscreen flag - int mouseLock; // Mouse-lock flag - int sysKeysDisabled; // System keys disabled flag - int windowNoResize; // Resize- and maximize gadgets disabled flag - int refreshRate; // Vertical monitor refresh rate - - // Window status & parameters - int opened; // Flag telling if window is opened or not - int active; // Application active flag - int iconified; // Window iconified flag - int width, height; // Window width and heigth - int accelerated; // GL_TRUE if window is HW accelerated - - // Framebuffer attributes - int redBits; - int greenBits; - int blueBits; - int alphaBits; - int depthBits; - int stencilBits; - int accumRedBits; - int accumGreenBits; - int accumBlueBits; - int accumAlphaBits; - int auxBuffers; - int stereo; - int samples; - - // OpenGL extensions and context attributes - int glMajor, glMinor, glRevision; - int glForward, glDebug, glProfile; - - PFNGLGETSTRINGIPROC GetStringi; - -// ========= PLATFORM SPECIFIC PART ====================================== - - id window; - id pixelFormat; - id context; - id delegate; +//------------------------------------------------------------------------ +// Platform-specific window structure +//------------------------------------------------------------------------ +typedef struct _GLFWwindowNS +{ + id window; + id delegate; unsigned int modifierFlags; -}; - -GLFWGLOBAL _GLFWwin _glfwWin; + double wheelPosFloating; +} _GLFWwindowNS; //------------------------------------------------------------------------ -// Library global data +// Platform-specific library global data //------------------------------------------------------------------------ -GLFWGLOBAL struct { - -// ========= PLATFORM INDEPENDENT MANDATORY PART ========================= - - // Window opening hints - _GLFWhints hints; - -// ========= PLATFORM SPECIFIC PART ====================================== - +typedef struct _GLFWlibraryNS +{ // Timer data struct { double t0; - } Timer; + } timer; // dlopen handle for dynamically-loading extension function pointers - void *OpenGLFramework; + void* OpenGLFramework; - int Unbundled; + int unbundled; - id DesktopMode; + id desktopMode; - id AutoreleasePool; + id autoreleasePool; -} _glfwLibrary; - - -//------------------------------------------------------------------------ -// User input status (some of this should go in _GLFWwin) -//------------------------------------------------------------------------ -GLFWGLOBAL struct { - -// ========= PLATFORM INDEPENDENT MANDATORY PART ========================= - - // Mouse status - int MousePosX, MousePosY; - int WheelPos; - char MouseButton[ GLFW_MOUSE_BUTTON_LAST+1 ]; - - // Keyboard status - char Key[ GLFW_KEY_LAST+1 ]; - int LastChar; - - // User selected settings - int StickyKeys; - int StickyMouseButtons; - int KeyRepeat; - - -// ========= PLATFORM SPECIFIC PART ====================================== - - double WheelPosFloating; - -} _glfwInput; +} _GLFWlibraryNS; #endif // _platform_h_