GLFW-b 0.0.2.2 → 0.0.2.3
raw patch · 11 files changed
+1955/−19 lines, 11 filessetup-changedPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
Files
- GLFW-b.cabal +11/−2
- Makefile +15/−14
- Setup.hs +1/−3
- glfw/lib/cocoa/cocoa_enable.m +52/−0
- glfw/lib/cocoa/cocoa_fullscreen.m +103/−0
- glfw/lib/cocoa/cocoa_glext.m +64/−0
- glfw/lib/cocoa/cocoa_init.m +241/−0
- glfw/lib/cocoa/cocoa_joystick.m +66/−0
- glfw/lib/cocoa/cocoa_thread.c +416/−0
- glfw/lib/cocoa/cocoa_time.m +106/−0
- glfw/lib/cocoa/cocoa_window.m +880/−0
GLFW-b.cabal view
@@ -1,5 +1,5 @@ name: GLFW-b-version: 0.0.2.2+version: 0.0.2.3 category: Graphics @@ -41,7 +41,16 @@ glfw/lib/cocoa/platform.h glfw/lib/win32/platform.h glfw/lib/x11/platform.h-+ -- We can't explicitly list these as+ -- C sources so we list them here.+ glfw/lib/cocoa/cocoa_enable.m+ glfw/lib/cocoa/cocoa_joystick.m+ glfw/lib/cocoa/cocoa_fullscreen.m+ glfw/lib/cocoa/cocoa_time.m+ glfw/lib/cocoa/cocoa_glext.m+ glfw/lib/cocoa/cocoa_window.m+ glfw/lib/cocoa/cocoa_init.m+ glfw/lib/cocoa/cocoa_thread.c -- -- -- -- -- -- -- -- -- -- library
Makefile view
@@ -1,18 +1,19 @@-FRAMEWORK = -framework AGL -framework Cocoa -framework OpenGL-CFLAGS = -O2 -Iglfw/include -Iglfw/lib -Iglfw/lib/cocoa-SRC_DIR = glfw/lib/cocoa-BUILD_DIR = build+FRAMEWORK := -framework AGL -framework Cocoa -framework OpenGL+GLFW_FLAG := -m32 -O2 -Iglfw/include -Iglfw/lib -Iglfw/lib/cocoa $(CFLAGS)+SRC_DIR := glfw/lib/cocoa+GLFW_DIR := glfw/lib+BUILD_DIR := build -OBJ_C_SRC = $(shell find $(SRC_DIR) -name "*.m")-C_SRC = $(shell find $(SRC_DIR) -name "*.c")-GLFW_SRC = $(shell find glfw/lib -depth 1 -name "*.c")-SRC = $(OBJ_C_SRC) $(C_SRC)-OBJS = $(addprefix $(BUILD_DIR)/, $(OBJ_C_SRC:.m=.o) $(C_SRC:.c=.o))+OBJ_C_SRC := $(wildcard $(SRC_DIR)/*.m)+C_SRC := $(wildcard $(SRC_DIR)/*.c)+GLFW_SRC := $(wildcard $(GLFW_DIR)/*.c)+OBJS := $(addprefix $(BUILD_DIR)/, $(OBJ_C_SRC:.m=.o) $(C_SRC:.c=.o)) -all: $(BUILD_DIR)/libglfw.a $(BUILD_DIR)/libglfw.dylib+all: $(BUILD_DIR)/libglfw.a -$(BUILD_DIR)/libglfw.dylib: $(OBJS)- $(CC) -dynamiclib $(CFLAGS) -o $@ $(OBJS) $(GLFW_SRC) $(FRAMEWORK)+# The .dylib was creating more problems than it solved.+#$(BUILD_DIR)/libglfw.dylib: $(OBJS)+# $(CC) -dynamiclib $(GLFW_FLAG) -o $@ $(OBJS) $(GLFW_SRC) $(FRAMEWORK) $(BUILD_DIR)/libglfw.a: $(OBJS) ar -r -s $@ $(OBJS)@@ -24,9 +25,9 @@ $(OBJS): $(BUILD_DIR)/$(SRC_DIR)/.build-tag $(BUILD_DIR)/%.o : %.c- $(CC) -c $(CFLAGS) $< -o $@+ $(CC) -c $(GLFW_FLAG) $< -o $@ $(BUILD_DIR)/%.o : %.m- $(CC) -c $(CFLAGS) $< -o $@+ $(CC) -c $(GLFW_FLAG) $< -o $@ .PHONY: clean clean:
Setup.hs view
@@ -97,9 +97,7 @@ verbosity = fromFlag $ copyVerbosity flags copy dest f = installOrdinaryFile verbosity (extraLibDir</>f) (dest</>f) maybe (return ()) (copy libPref) (Just libName)- maybe (return ()) (copy libPref) (Just sharedName) _ -> return () -libName, sharedName :: FilePath+libName :: FilePath libName = "libglfw.a"-sharedName = "libglfw.dylib"
+ glfw/lib/cocoa/cocoa_enable.m view
@@ -0,0 +1,52 @@+//========================================================================+// GLFW - An OpenGL framework+// File: macosx_enable.m+// Platform: Mac OS X+// API Version: 2.7+// WWW: http://glfw.sourceforge.net+//------------------------------------------------------------------------+// Copyright (c) 2002-2006 Camilla Berglund+//+// This software is provided 'as-is', without any express or implied+// warranty. In no event will the authors be held liable for any damages+// arising from the use of this software.+//+// Permission is granted to anyone to use this software for any purpose,+// including commercial applications, and to alter it and redistribute it+// freely, subject to the following restrictions:+//+// 1. The origin of this software must not be misrepresented; you must not+// claim that you wrote the original software. If you use this software+// in a product, an acknowledgment in the product documentation would+// be appreciated but is not required.+//+// 2. Altered source versions must be plainly marked as such, and must not+// be misrepresented as being the original software.+//+// 3. This notice may not be removed or altered from any source+// distribution.+//+//========================================================================++#include "internal.h"++//************************************************************************+//**** Platform implementation functions ****+//************************************************************************++//========================================================================+// Enable and disable system keys+//========================================================================++void _glfwPlatformEnableSystemKeys( void )+{+ // This is checked in macosx_window.m; we take no action here+}++void _glfwPlatformDisableSystemKeys( void )+{+ // 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é+ // except in full-screen mode.+}+
+ glfw/lib/cocoa/cocoa_fullscreen.m view
@@ -0,0 +1,103 @@+//========================================================================+// GLFW - An OpenGL framework+// File: macosx_fullscreen.m+// Platform: Mac OS X+// API Version: 2.7+// WWW: http://glfw.sourceforge.net+//------------------------------------------------------------------------+// Copyright (c) 2002-2006 Camilla Berglund+//+// This software is provided 'as-is', without any express or implied+// warranty. In no event will the authors be held liable for any damages+// arising from the use of this software.+//+// Permission is granted to anyone to use this software for any purpose,+// including commercial applications, and to alter it and redistribute it+// freely, subject to the following restrictions:+//+// 1. The origin of this software must not be misrepresented; you must not+// claim that you wrote the original software. If you use this software+// in a product, an acknowledgment in the product documentation would+// be appreciated but is not required.+//+// 2. Altered source versions must be plainly marked as such, and must not+// be misrepresented as being the original software.+//+// 3. This notice may not be removed or altered from any source+// distribution.+//+//========================================================================++#include "internal.h"++//========================================================================+// Check whether the display mode should be included in enumeration+//========================================================================++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+ // checks. You might also want to reject modes which are interlaced,+ // or TV out. There is no one-size-fits-all policy that can work here.+ // This seems like a decent compromise, but certain applications may+ // wish to patch this...+ return [[mode objectForKey:(id)kCGDisplayBitsPerPixel] intValue] >= 15 &&+ [mode objectForKey:(id)kCGDisplayModeIsSafeForHardware] != nil &&+ [mode objectForKey:(id)kCGDisplayModeIsStretched] == nil;+}++//========================================================================+// Convert Core Graphics display mode to GLFW video mode+//========================================================================++static GLFWvidmode vidmodeFromCGDisplayMode( NSDictionary *mode )+{+ unsigned int width = [[mode objectForKey:(id)kCGDisplayWidth] unsignedIntValue];+ unsigned int height = [[mode objectForKey:(id)kCGDisplayHeight] unsignedIntValue];+ unsigned int bps = [[mode objectForKey:(id)kCGDisplayBitsPerSample] unsignedIntValue];++ GLFWvidmode result;+ result.Width = width;+ result.Height = height;+ result.RedBits = bps;+ result.GreenBits = bps;+ result.BlueBits = bps;+ return result;+}+++//************************************************************************+//**** Platform implementation functions ****+//************************************************************************++//========================================================================+// Get a list of available video modes+//========================================================================++int _glfwPlatformGetVideoModes( GLFWvidmode *list, int maxcount )+{+ NSArray *modes = (NSArray *)CGDisplayAvailableModes( CGMainDisplayID() );++ unsigned int i, j = 0, n = [modes count];+ for( i = 0; i < n && i < (unsigned)maxcount; i++ )+ {+ NSDictionary *mode = [modes objectAtIndex:i];+ if( modeIsGood( mode ) )+ {+ list[j++] = vidmodeFromCGDisplayMode( mode );+ }+ }++ return j;+}++//========================================================================+// Get the desktop video mode+//========================================================================++void _glfwPlatformGetDesktopMode( GLFWvidmode *mode )+{+ *mode = vidmodeFromCGDisplayMode( _glfwLibrary.DesktopMode );+}+
+ glfw/lib/cocoa/cocoa_glext.m view
@@ -0,0 +1,64 @@+//========================================================================+// GLFW - An OpenGL framework+// File: macosx_glext.m+// Platform: Mac OS X+// API Version: 2.7+// WWW: http://glfw.sourceforge.net+//------------------------------------------------------------------------+// Copyright (c) 2002-2006 Camilla Berglund+//+// This software is provided 'as-is', without any express or implied+// warranty. In no event will the authors be held liable for any damages+// arising from the use of this software.+//+// Permission is granted to anyone to use this software for any purpose,+// including commercial applications, and to alter it and redistribute it+// freely, subject to the following restrictions:+//+// 1. The origin of this software must not be misrepresented; you must not+// claim that you wrote the original software. If you use this software+// in a product, an acknowledgment in the product documentation would+// be appreciated but is not required.+//+// 2. Altered source versions must be plainly marked as such, and must not+// be misrepresented as being the original software.+//+// 3. This notice may not be removed or altered from any source+// distribution.+//+//========================================================================++#include "internal.h"++//************************************************************************+//**** Platform implementation functions ****+//************************************************************************++//========================================================================+// Check if an OpenGL extension is available at runtime+//========================================================================++int _glfwPlatformExtensionSupported( const char *extension )+{+ // There are no AGL, CGL or NSGL extensions.+ return GL_FALSE;+}++//========================================================================+// Get the function pointer to an OpenGL function+//========================================================================++void * _glfwPlatformGetProcAddress( const char *procname )+{+ CFStringRef symbolName = CFStringCreateWithCString( kCFAllocatorDefault,+ procname,+ kCFStringEncodingASCII );++ void *symbol = CFBundleGetFunctionPointerForName( _glfwLibrary.OpenGLFramework,+ symbolName );++ CFRelease( symbolName );++ return symbol;+}+
+ glfw/lib/cocoa/cocoa_init.m view
@@ -0,0 +1,241 @@+//========================================================================+// GLFW - An OpenGL framework+// File: macosx_init.m+// Platform: Mac OS X+// API Version: 2.7+// WWW: http://glfw.sourceforge.net+//------------------------------------------------------------------------+// Copyright (c) 2002-2006 Camilla Berglund+//+// This software is provided 'as-is', without any express or implied+// warranty. In no event will the authors be held liable for any damages+// arising from the use of this software.+//+// Permission is granted to anyone to use this software for any purpose,+// including commercial applications, and to alter it and redistribute it+// freely, subject to the following restrictions:+//+// 1. The origin of this software must not be misrepresented; you must not+// claim that you wrote the original software. If you use this software+// in a product, an acknowledgment in the product documentation would+// be appreciated but is not required.+//+// 2. Altered source versions must be plainly marked as such, and must not+// be misrepresented as being the original software.+//+// 3. This notice may not be removed or altered from any source+// distribution.+//+//========================================================================++// Needed for _NSGetProgname+#include <crt_externs.h>++#include "internal.h"++// Prior to Snow Leopard, we need to use this oddly-named semi-private API+// 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;+@end++// Keys to search for as potential application names+NSString *GLFWNameKeys[] =+{+ @"CFBundleDisplayName",+ @"CFBundleName",+ @"CFBundleExecutable",+};++//========================================================================+// Try to figure out what the calling application is called+//========================================================================+static NSString *findAppName( void )+{+ NSDictionary *infoDictionary = [[NSBundle mainBundle] infoDictionary];++ unsigned int i;+ for( i = 0; i < sizeof(GLFWNameKeys) / sizeof(GLFWNameKeys[0]); i++ )+ {+ id name = [infoDictionary objectForKey:GLFWNameKeys[i]];+ if (name &&+ [name isKindOfClass:[NSString class]] &&+ ![@"" isEqualToString:name])+ {+ return name;+ }+ }++ // If we get here, we're unbundled+ if( !_glfwLibrary.Unbundled )+ {+ // Could do this only if we discover we're unbundled, but it should+ // do no harm...+ ProcessSerialNumber psn = { 0, kCurrentProcess };+ 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 );++ _glfwLibrary.Unbundled = GL_TRUE;+ }++ char **progname = _NSGetProgname();+ if( progname && *progname )+ {+ // TODO: UTF8?+ return [NSString stringWithUTF8String:*progname];+ }++ // Really shouldn't get here+ return @"GLFW Application";+}++//========================================================================+// Set up the menu bar (manually)+// This is nasty, nasty stuff -- calls to undocumented semi-private APIs that+// could go away at any moment, lots of stuff that really should be+// localize(d|able), etc. Loading a nib would save us this horror, but that+// doesn't seem like a good thing to require of GLFW's clients.+//========================================================================+static void setUpMenuBar( void )+{+ NSString *appName = findAppName();++ NSMenu *bar = [[NSMenu alloc] init];+ [NSApp setMainMenu:bar];++ NSMenuItem *appMenuItem =+ [bar addItemWithTitle:@"" action:NULL keyEquivalent:@""];+ NSMenu *appMenu = [[NSMenu alloc] init];+ [appMenuItem setSubmenu:appMenu];++ [appMenu addItemWithTitle:[NSString stringWithFormat:@"About %@", appName]+ action:@selector(orderFrontStandardAboutPanel:)+ keyEquivalent:@""];+ [appMenu addItem:[NSMenuItem separatorItem]];+ NSMenu *servicesMenu = [[NSMenu alloc] init];+ [NSApp setServicesMenu:servicesMenu];+ [[appMenu addItemWithTitle:@"Services"+ action:NULL+ keyEquivalent:@""] setSubmenu:servicesMenu];+ [appMenu addItem:[NSMenuItem separatorItem]];+ [appMenu addItemWithTitle:[NSString stringWithFormat:@"Hide %@", appName]+ action:@selector(hide:)+ keyEquivalent:@"h"];+ [[appMenu addItemWithTitle:@"Hide Others"+ action:@selector(hideOtherApplications:)+ keyEquivalent:@"h"]+ setKeyEquivalentModifierMask:NSAlternateKeyMask | NSCommandKeyMask];+ [appMenu addItemWithTitle:@"Show All"+ action:@selector(unhideAllApplications:)+ keyEquivalent:@""];+ [appMenu addItem:[NSMenuItem separatorItem]];+ [appMenu addItemWithTitle:[NSString stringWithFormat:@"Quit %@", appName]+ action:@selector(terminate:)+ keyEquivalent:@"q"];++ NSMenuItem *windowMenuItem =+ [bar addItemWithTitle:@"" action:NULL keyEquivalent:@""];+ NSMenu *windowMenu = [[NSMenu alloc] initWithTitle:@"Window"];+ [NSApp setWindowsMenu:windowMenu];+ [windowMenuItem setSubmenu:windowMenu];++ [windowMenu addItemWithTitle:@"Miniaturize"+ action:@selector(performMiniaturize:)+ keyEquivalent:@"m"];+ [windowMenu addItemWithTitle:@"Zoom"+ action:@selector(performZoom:)+ keyEquivalent:@""];+ [windowMenu addItem:[NSMenuItem separatorItem]];+ [windowMenu addItemWithTitle:@"Bring All to Front"+ action:@selector(arrangeInFront:)+ keyEquivalent:@""];++ // 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:)] )+ {+ [NSApp setAppleMenu:appMenu];+ }+}++//========================================================================+// Initialize GLFW thread package+//========================================================================++static void initThreads( void )+{+ // Initialize critical section handle+ (void) pthread_mutex_init( &_glfwThrd.CriticalSection, NULL );++ // The first thread (the main thread) has ID 0+ _glfwThrd.NextID = 0;++ // Fill out information about the main thread (this thread)+ _glfwThrd.First.ID = _glfwThrd.NextID ++;+ _glfwThrd.First.Function = NULL;+ _glfwThrd.First.PosixID = pthread_self();+ _glfwThrd.First.Previous = NULL;+ _glfwThrd.First.Next = NULL;+}++//************************************************************************+//**** Platform implementation functions ****+//************************************************************************++//========================================================================+// Initialize the GLFW library+//========================================================================++int _glfwPlatformInit( void )+{+ _glfwLibrary.AutoreleasePool = [[NSAutoreleasePool alloc] init];++ // Implicitly create shared NSApplication instance+ [NSApplication sharedApplication];++ NSString* resourcePath = [[NSBundle mainBundle] resourcePath];++ if( access( [resourcePath cStringUsingEncoding:NSUTF8StringEncoding], R_OK ) == 0 )+ {+ chdir( [resourcePath cStringUsingEncoding:NSUTF8StringEncoding] );+ }++ // Setting up menu bar must go exactly here else weirdness ensues+ setUpMenuBar();++ [NSApp finishLaunching];++ initThreads();++ _glfwPlatformSetTime( 0.0 );++ _glfwLibrary.DesktopMode =+ (NSDictionary *)CGDisplayCurrentMode( CGMainDisplayID() );++ return GL_TRUE;+}++//========================================================================+// Close window, if open, and shut down GLFW+//========================================================================++int _glfwPlatformTerminate( void )+{+ // TODO: Fail unless this is the main thread++ glfwCloseWindow();++ // TODO: Kill all non-main threads?+ // TODO: Probably other cleanup++ [_glfwLibrary.AutoreleasePool release];+ _glfwLibrary.AutoreleasePool = nil;++ return GL_TRUE;+}+
+ glfw/lib/cocoa/cocoa_joystick.m view
@@ -0,0 +1,66 @@+//========================================================================+// GLFW - An OpenGL framework+// File: macosx_joystick.m+// Platform: Mac OS X+// API Version: 2.7+// WWW: http://glfw.sourceforge.net+//------------------------------------------------------------------------+// Copyright (c) 2002-2006 Camilla Berglund+//+// This software is provided 'as-is', without any express or implied+// warranty. In no event will the authors be held liable for any damages+// arising from the use of this software.+//+// Permission is granted to anyone to use this software for any purpose,+// including commercial applications, and to alter it and redistribute it+// freely, subject to the following restrictions:+//+// 1. The origin of this software must not be misrepresented; you must not+// claim that you wrote the original software. If you use this software+// in a product, an acknowledgment in the product documentation would+// be appreciated but is not required.+//+// 2. Altered source versions must be plainly marked as such, and must not+// be misrepresented as being the original software.+//+// 3. This notice may not be removed or altered from any source+// distribution.+//+//========================================================================++#include "internal.h"++//************************************************************************+//**** Platform implementation functions ****+//************************************************************************++//========================================================================+// Determine joystick capabilities+//========================================================================++int _glfwPlatformGetJoystickParam( int joy, int param )+{+ // TODO: Implement this.+ return 0;+}++//========================================================================+// Get joystick axis positions+//========================================================================++int _glfwPlatformGetJoystickPos( int joy, float *pos, int numaxes )+{+ // TODO: Implement this.+ return 0;+}++//========================================================================+// Get joystick button states+//========================================================================++int _glfwPlatformGetJoystickButtons( int joy, unsigned char *buttons, int numbuttons )+{+ // TODO: Implement this.+ return 0;+}+
+ glfw/lib/cocoa/cocoa_thread.c view
@@ -0,0 +1,416 @@+//========================================================================+// GLFW - An OpenGL framework+// File: macosx_thread.c+// Platform: Mac OS X+// API Version: 2.7+// WWW: http://glfw.sourceforge.net+//------------------------------------------------------------------------+// Copyright (c) 2002-2006 Camilla Berglund+//+// This software is provided 'as-is', without any express or implied+// warranty. In no event will the authors be held liable for any damages+// arising from the use of this software.+//+// Permission is granted to anyone to use this software for any purpose,+// including commercial applications, and to alter it and redistribute it+// freely, subject to the following restrictions:+//+// 1. The origin of this software must not be misrepresented; you must not+// claim that you wrote the original software. If you use this software+// in a product, an acknowledgment in the product documentation would+// be appreciated but is not required.+//+// 2. Altered source versions must be plainly marked as such, and must not+// be misrepresented as being the original software.+//+// 3. This notice may not be removed or altered from any source+// distribution.+//+//========================================================================++#include "internal.h"++#include <sys/time.h>+#include <sys/sysctl.h>+++//************************************************************************+//**** GLFW internal functions ****+//************************************************************************++//========================================================================+// _glfwNewThread() - This is simply a "wrapper" for calling the user+// thread function.+//========================================================================++void * _glfwNewThread( void * arg )+{+ GLFWthreadfun threadfun;+ _GLFWthread *t;++ // Get pointer to thread information for current thread+ t = _glfwGetThreadPointer( glfwGetThreadID() );+ if( t == NULL )+ {+ return 0;+ }++ // Get user thread function pointer+ threadfun = t->Function;++ // Call the user thread function+ threadfun( arg );++ // Remove thread from thread list+ ENTER_THREAD_CRITICAL_SECTION+ _glfwRemoveThread( t );+ LEAVE_THREAD_CRITICAL_SECTION++ // When the thread function returns, the thread will die...+ return NULL;+}++++//************************************************************************+//**** Platform implementation functions ****+//************************************************************************++//========================================================================+// _glfwPlatformCreateThread() - Create a new thread+//========================================================================++GLFWthread _glfwPlatformCreateThread( GLFWthreadfun fun, void *arg )+{+ GLFWthread ID;+ _GLFWthread *t;+ int result;++ // Enter critical section+ ENTER_THREAD_CRITICAL_SECTION++ // Create a new thread information memory area+ t = (_GLFWthread *) malloc( sizeof(_GLFWthread) );+ if( t == NULL )+ {+ // Leave critical section+ LEAVE_THREAD_CRITICAL_SECTION+ return -1;+ }++ // Get a new unique thread id+ ID = _glfwThrd.NextID ++;++ // Store thread information in the thread list+ t->Function = fun;+ t->ID = ID;++ // Create thread+ result = pthread_create(+ &t->PosixID, // Thread handle+ NULL, // Default thread attributes+ _glfwNewThread, // Thread function (a wrapper function)+ (void *)arg // Argument to thread is user argument+ );++ // Did the thread creation fail?+ if( result != 0 )+ {+ free( (void *) t );+ LEAVE_THREAD_CRITICAL_SECTION+ return -1;+ }++ // Append thread to thread list+ _glfwAppendThread( t );++ // Leave critical section+ LEAVE_THREAD_CRITICAL_SECTION++ // Return the GLFW thread ID+ return ID;+}+++//========================================================================+// _glfwPlatformDestroyThread() - Kill a thread. NOTE: THIS IS A VERY+// DANGEROUS OPERATION, AND SHOULD NOT BE USED EXCEPT IN EXTREME+// SITUATIONS!+//========================================================================++void _glfwPlatformDestroyThread( GLFWthread ID )+{+ _GLFWthread *t;++ // Enter critical section+ ENTER_THREAD_CRITICAL_SECTION++ // Get thread information pointer+ t = _glfwGetThreadPointer( ID );+ if( t == NULL )+ {+ LEAVE_THREAD_CRITICAL_SECTION+ return;+ }++ // Simply murder the process, no mercy!+ pthread_kill( t->PosixID, SIGKILL );++ // Remove thread from thread list+ _glfwRemoveThread( t );++ // Leave critical section+ LEAVE_THREAD_CRITICAL_SECTION+}+++//========================================================================+// _glfwPlatformWaitThread() - Wait for a thread to die+//========================================================================++int _glfwPlatformWaitThread( GLFWthread ID, int waitmode )+{+ pthread_t thread;+ _GLFWthread *t;++ // Enter critical section+ ENTER_THREAD_CRITICAL_SECTION++ // Get thread information pointer+ t = _glfwGetThreadPointer( ID );++ // Is the thread already dead?+ if( t == NULL )+ {+ LEAVE_THREAD_CRITICAL_SECTION+ return GL_TRUE;+ }++ // If got this far, the thread is alive => polling returns FALSE+ if( waitmode == GLFW_NOWAIT )+ {+ LEAVE_THREAD_CRITICAL_SECTION+ return GL_FALSE;+ }++ // Get thread handle+ thread = t->PosixID;++ // Leave critical section+ LEAVE_THREAD_CRITICAL_SECTION++ // Wait for thread to die+ (void) pthread_join( thread, NULL );++ return GL_TRUE;+}+++//========================================================================+// _glfwPlatformGetThreadID() - Return the thread ID for the current+// thread+//========================================================================++GLFWthread _glfwPlatformGetThreadID( void )+{+ _GLFWthread *t;+ GLFWthread ID = -1;+ pthread_t posixID;++ // Get current thread ID+ posixID = pthread_self();++ // Enter critical section+ ENTER_THREAD_CRITICAL_SECTION++ // Loop through entire list of threads to find the matching POSIX+ // thread ID+ for( t = &_glfwThrd.First; t != NULL; t = t->Next )+ {+ if( t->PosixID == posixID )+ {+ ID = t->ID;+ break;+ }+ }++ // Leave critical section+ LEAVE_THREAD_CRITICAL_SECTION++ // Return the found GLFW thread identifier+ return ID;+}+++//========================================================================+// _glfwPlatformCreateMutex() - Create a mutual exclusion object+//========================================================================++GLFWmutex _glfwPlatformCreateMutex( void )+{+ pthread_mutex_t *mutex;++ // Allocate memory for mutex+ mutex = (pthread_mutex_t *) malloc( sizeof( pthread_mutex_t ) );+ if( !mutex )+ {+ return NULL;+ }++ // Initialise a mutex object+ (void) pthread_mutex_init( mutex, NULL );++ // Cast to GLFWmutex and return+ return (GLFWmutex) mutex;+}+++//========================================================================+// _glfwPlatformDestroyMutex() - Destroy a mutual exclusion object+//========================================================================++void _glfwPlatformDestroyMutex( GLFWmutex mutex )+{+ // Destroy the mutex object+ pthread_mutex_destroy( (pthread_mutex_t *) mutex );++ // Free memory for mutex object+ free( (void *) mutex );+}+++//========================================================================+// _glfwPlatformLockMutex() - Request access to a mutex+//========================================================================++void _glfwPlatformLockMutex( GLFWmutex mutex )+{+ // Wait for mutex to be released+ (void) pthread_mutex_lock( (pthread_mutex_t *) mutex );+}+++//========================================================================+// _glfwPlatformUnlockMutex() - Release a mutex+//========================================================================++void _glfwPlatformUnlockMutex( GLFWmutex mutex )+{+ // Release mutex+ pthread_mutex_unlock( (pthread_mutex_t *) mutex );+}+++//========================================================================+// _glfwPlatformCreateCond() - Create a new condition variable object+//========================================================================++GLFWcond _glfwPlatformCreateCond( void )+{+ pthread_cond_t *cond;++ // Allocate memory for condition variable+ cond = (pthread_cond_t *) malloc( sizeof(pthread_cond_t) );+ if( !cond )+ {+ return NULL;+ }++ // Initialise condition variable+ (void) pthread_cond_init( cond, NULL );++ // Cast to GLFWcond and return+ return (GLFWcond) cond;+}+++//========================================================================+// _glfwPlatformDestroyCond() - Destroy a condition variable object+//========================================================================++void _glfwPlatformDestroyCond( GLFWcond cond )+{+ // Destroy the condition variable object+ (void) pthread_cond_destroy( (pthread_cond_t *) cond );++ // Free memory for condition variable object+ free( (void *) cond );+}+++//========================================================================+// _glfwPlatformWaitCond() - Wait for a condition to be raised+//========================================================================++void _glfwPlatformWaitCond( GLFWcond cond, GLFWmutex mutex,+ double timeout )+{+ struct timeval currenttime;+ struct timespec wait;+ long dt_sec, dt_usec;++ // Select infinite or timed wait+ if( timeout >= GLFW_INFINITY )+ {+ // Wait for condition (infinite wait)+ (void) pthread_cond_wait( (pthread_cond_t *) cond,+ (pthread_mutex_t *) mutex );+ }+ else+ {+ // Set timeout time, relatvie to current time+ gettimeofday( ¤ttime, NULL );+ dt_sec = (long) timeout;+ dt_usec = (long) ((timeout - (double)dt_sec) * 1000000.0);+ wait.tv_nsec = (currenttime.tv_usec + dt_usec) * 1000L;+ if( wait.tv_nsec > 1000000000L )+ {+ wait.tv_nsec -= 1000000000L;+ dt_sec ++;+ }+ wait.tv_sec = currenttime.tv_sec + dt_sec;++ // Wait for condition (timed wait)+ (void) pthread_cond_timedwait( (pthread_cond_t *) cond,+ (pthread_mutex_t *) mutex, &wait );+ }+}+++//========================================================================+// _glfwPlatformSignalCond() - Signal a condition to one waiting thread+//========================================================================++void _glfwPlatformSignalCond( GLFWcond cond )+{+ // Signal condition+ (void) pthread_cond_signal( (pthread_cond_t *) cond );+}+++//========================================================================+// _glfwPlatformBroadcastCond() - Broadcast a condition to all waiting+// threads+//========================================================================++void _glfwPlatformBroadcastCond( GLFWcond cond )+{+ // Broadcast condition+ (void) pthread_cond_broadcast( (pthread_cond_t *) cond );+}+++//========================================================================+// _glfwPlatformGetNumberOfProcessors() - Return the number of processors+// in the system.+//========================================================================++int _glfwPlatformGetNumberOfProcessors( void )+{+ int n;++ // Get number of processors online+ _glfw_numprocessors( n );+ return n;+}+
+ glfw/lib/cocoa/cocoa_time.m view
@@ -0,0 +1,106 @@+//========================================================================+// GLFW - An OpenGL framework+// File: macosx_time.m+// Platform: Mac OS X+// API Version: 2.7+// WWW: http://glfw.sourceforge.net+//------------------------------------------------------------------------+// Copyright (c) 2002-2006 Camilla Berglund+//+// This software is provided 'as-is', without any express or implied+// warranty. In no event will the authors be held liable for any damages+// arising from the use of this software.+//+// Permission is granted to anyone to use this software for any purpose,+// including commercial applications, and to alter it and redistribute it+// freely, subject to the following restrictions:+//+// 1. The origin of this software must not be misrepresented; you must not+// claim that you wrote the original software. If you use this software+// in a product, an acknowledgment in the product documentation would+// be appreciated but is not required.+//+// 2. Altered source versions must be plainly marked as such, and must not+// be misrepresented as being the original software.+//+// 3. This notice may not be removed or altered from any source+// distribution.+//+//========================================================================++#include "internal.h"++#include <sys/time.h>++//************************************************************************+//**** Platform implementation functions ****+//************************************************************************++//========================================================================+// Return timer value in seconds+//========================================================================++double _glfwPlatformGetTime( void )+{+ return [NSDate timeIntervalSinceReferenceDate] - _glfwLibrary.Timer.t0;+}++//========================================================================+// Set timer value in seconds+//========================================================================++void _glfwPlatformSetTime( double time )+{+ _glfwLibrary.Timer.t0 = [NSDate timeIntervalSinceReferenceDate] - time;+}++//========================================================================+// Put a thread to sleep for a specified amount of time+//========================================================================++void _glfwPlatformSleep( double time )+{+ if( time == 0.0 )+ {+ sched_yield();+ return;+ }++ struct timeval currenttime;+ struct timespec wait;+ pthread_mutex_t mutex;+ pthread_cond_t cond;+ long dt_sec, dt_usec;++ // Not all pthread implementations have a pthread_sleep() function. We+ // do it the portable way, using a timed wait for a condition that we+ // will never signal. NOTE: The unistd functions sleep/usleep suspends+ // the entire PROCESS, not a signle thread, which is why we can not+ // use them to implement glfwSleep.++ // Set timeout time, relatvie to current time+ gettimeofday( ¤ttime, NULL );+ dt_sec = (long) time;+ dt_usec = (long) ((time - (double)dt_sec) * 1000000.0);+ wait.tv_nsec = (currenttime.tv_usec + dt_usec) * 1000L;+ if( wait.tv_nsec > 1000000000L )+ {+ wait.tv_nsec -= 1000000000L;+ dt_sec ++;+ }+ wait.tv_sec = currenttime.tv_sec + dt_sec;++ // Initialize condition and mutex objects+ pthread_mutex_init( &mutex, NULL );+ pthread_cond_init( &cond, NULL );++ // Do a timed wait+ pthread_mutex_lock( &mutex );+ pthread_cond_timedwait( &cond, &mutex, &wait );+ pthread_mutex_unlock( &mutex );++ // Destroy condition and mutex objects+ pthread_mutex_destroy( &mutex );+ pthread_cond_destroy( &cond );+}+
+ glfw/lib/cocoa/cocoa_window.m view
@@ -0,0 +1,880 @@+//========================================================================+// GLFW - An OpenGL framework+// File: macosx_window.m+// Platform: Mac OS X+// API Version: 2.7+// WWW: http://glfw.sourceforge.net+//------------------------------------------------------------------------+// Copyright (c) 2002-2006 Camilla Berglund+//+// This software is provided 'as-is', without any express or implied+// warranty. In no event will the authors be held liable for any damages+// arising from the use of this software.+//+// Permission is granted to anyone to use this software for any purpose,+// including commercial applications, and to alter it and redistribute it+// freely, subject to the following restrictions:+//+// 1. The origin of this software must not be misrepresented; you must not+// claim that you wrote the original software. If you use this software+// in a product, an acknowledgment in the product documentation would+// be appreciated but is not required.+//+// 2. Altered source versions must be plainly marked as such, and must not+// be misrepresented as being the original software.+//+// 3. This notice may not be removed or altered from any source+// distribution.+//+//========================================================================++#include "internal.h"++//========================================================================+// Delegate for window related notifications+// (but also used as an application delegate)+//========================================================================++@interface GLFWWindowDelegate : NSObject+@end++@implementation GLFWWindowDelegate++- (BOOL)windowShouldClose:(id)window+{+ if( _glfwWin.windowCloseCallback )+ {+ if( !_glfwWin.windowCloseCallback() )+ {+ return NO;+ }+ }++ // This is horribly ugly, but it works+ glfwCloseWindow();+ return NO;+}++- (void)windowDidResize:(NSNotification *)notification+{+ [_glfwWin.context update];++ NSRect contentRect =+ [_glfwWin.window contentRectForFrameRect:[_glfwWin.window frame]];+ _glfwWin.width = contentRect.size.width;+ _glfwWin.height = contentRect.size.height;++ if( _glfwWin.windowSizeCallback )+ {+ _glfwWin.windowSizeCallback( _glfwWin.width, _glfwWin.height );+ }+}++- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender+{+ if( _glfwWin.windowCloseCallback )+ {+ if( !_glfwWin.windowCloseCallback() )+ {+ return NSTerminateCancel;+ }+ }++ // This is horribly ugly, but it works+ glfwCloseWindow();+ return NSTerminateCancel;+}++@end++// TODO: Need to find mappings for F13-F15, volume down/up/mute, and eject.+static const unsigned int MAC_TO_GLFW_KEYCODE_MAPPING[128] =+{+ /* 00 */ 'A',+ /* 01 */ 'S',+ /* 02 */ 'D',+ /* 03 */ 'F',+ /* 04 */ 'H',+ /* 05 */ 'G',+ /* 06 */ 'Z',+ /* 07 */ 'X',+ /* 08 */ 'C',+ /* 09 */ 'V',+ /* 0a */ -1,+ /* 0b */ 'B',+ /* 0c */ 'Q',+ /* 0d */ 'W',+ /* 0e */ 'E',+ /* 0f */ 'R',+ /* 10 */ 'Y',+ /* 11 */ 'T',+ /* 12 */ '1',+ /* 13 */ '2',+ /* 14 */ '3',+ /* 15 */ '4',+ /* 16 */ '6',+ /* 17 */ '5',+ /* 18 */ GLFW_KEY_KP_EQUAL,+ /* 19 */ '9',+ /* 1a */ '7',+ /* 1b */ '-',+ /* 1c */ '8',+ /* 1d */ '0',+ /* 1e */ ']',+ /* 1f */ 'O',+ /* 20 */ 'U',+ /* 21 */ '[',+ /* 22 */ 'I',+ /* 23 */ 'P',+ /* 24 */ GLFW_KEY_ENTER,+ /* 25 */ 'L',+ /* 26 */ 'J',+ /* 27 */ '\'',+ /* 28 */ 'K',+ /* 29 */ ';',+ /* 2a */ '\\',+ /* 2b */ ',',+ /* 2c */ '/',+ /* 2d */ 'N',+ /* 2e */ 'M',+ /* 2f */ '.',+ /* 30 */ GLFW_KEY_TAB,+ /* 31 */ GLFW_KEY_SPACE,+ /* 32 */ '`',+ /* 33 */ GLFW_KEY_BACKSPACE,+ /* 34 */ -1,+ /* 35 */ GLFW_KEY_ESC,+ /* 36 */ GLFW_KEY_RSUPER,+ /* 37 */ GLFW_KEY_LSUPER,+ /* 38 */ GLFW_KEY_LSHIFT,+ /* 39 */ GLFW_KEY_CAPS_LOCK,+ /* 3a */ GLFW_KEY_LALT,+ /* 3b */ GLFW_KEY_LCTRL,+ /* 3c */ GLFW_KEY_RSHIFT,+ /* 3d */ GLFW_KEY_RALT,+ /* 3e */ GLFW_KEY_RCTRL,+ /* 3f */ -1,+ /* 40 */ -1,+ /* 41 */ GLFW_KEY_KP_DECIMAL,+ /* 42 */ -1,+ /* 43 */ GLFW_KEY_KP_MULTIPLY,+ /* 44 */ -1,+ /* 45 */ GLFW_KEY_KP_ADD,+ /* 46 */ -1,+ /* 47 */ -1,+ /* 48 */ -1,+ /* 49 */ -1,+ /* 4a */ -1,+ /* 4b */ GLFW_KEY_KP_DIVIDE,+ /* 4c */ GLFW_KEY_KP_ENTER,+ /* 4d */ -1,+ /* 4e */ GLFW_KEY_KP_SUBTRACT,+ /* 4f */ -1,+ /* 50 */ -1,+ /* 51 */ -1,+ /* 52 */ GLFW_KEY_KP_0,+ /* 53 */ GLFW_KEY_KP_1,+ /* 54 */ GLFW_KEY_KP_2,+ /* 55 */ GLFW_KEY_KP_3,+ /* 56 */ GLFW_KEY_KP_4,+ /* 57 */ GLFW_KEY_KP_5,+ /* 58 */ GLFW_KEY_KP_6,+ /* 59 */ GLFW_KEY_KP_7,+ /* 5a */ -1,+ /* 5b */ GLFW_KEY_KP_8,+ /* 5c */ GLFW_KEY_KP_9,+ /* 5d */ -1,+ /* 5e */ -1,+ /* 5f */ -1,+ /* 60 */ GLFW_KEY_F5,+ /* 61 */ GLFW_KEY_F6,+ /* 62 */ GLFW_KEY_F7,+ /* 63 */ GLFW_KEY_F3,+ /* 64 */ GLFW_KEY_F8,+ /* 65 */ -1,+ /* 66 */ -1,+ /* 67 */ -1,+ /* 68 */ -1,+ /* 69 */ GLFW_KEY_F13,+ /* 6a */ GLFW_KEY_F16,+ /* 6b */ -1,+ /* 6c */ -1,+ /* 6d */ -1,+ /* 6e */ -1,+ /* 6f */ -1,+ /* 70 */ -1,+ /* 71 */ -1,+ /* 72 */ GLFW_KEY_INSERT,+ /* 73 */ GLFW_KEY_HOME,+ /* 74 */ GLFW_KEY_PAGEUP,+ /* 75 */ GLFW_KEY_DEL,+ /* 76 */ GLFW_KEY_F4,+ /* 77 */ GLFW_KEY_END,+ /* 78 */ GLFW_KEY_F2,+ /* 79 */ GLFW_KEY_PAGEDOWN,+ /* 7a */ GLFW_KEY_F1,+ /* 7b */ GLFW_KEY_LEFT,+ /* 7c */ GLFW_KEY_RIGHT,+ /* 7d */ GLFW_KEY_DOWN,+ /* 7e */ GLFW_KEY_UP,+ /* 7f */ -1,+};++//========================================================================+// Converts a Mac OS X keycode to a GLFW keycode+//========================================================================++static int convertMacKeyCode( unsigned int macKeyCode )+{+ 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+ // function should still get 'q' though.+ return MAC_TO_GLFW_KEYCODE_MAPPING[macKeyCode];+}++//========================================================================+// Content view class for the GLFW window+//========================================================================++@interface GLFWContentView : NSView+@end++@implementation GLFWContentView++- (BOOL)isOpaque+{+ return YES;+}++- (BOOL)canBecomeKeyView+{+ return YES;+}++- (BOOL)acceptsFirstResponder+{+ return YES;+}++- (void)mouseDown:(NSEvent *)event+{+ _glfwInputMouseClick( GLFW_MOUSE_BUTTON_LEFT, GLFW_PRESS );+}++- (void)mouseDragged:(NSEvent *)event+{+ [self mouseMoved:event];+}++- (void)mouseUp:(NSEvent *)event+{+ _glfwInputMouseClick( GLFW_MOUSE_BUTTON_LEFT, GLFW_RELEASE );+}++- (void)mouseMoved:(NSEvent *)event+{+ if( _glfwWin.mouseLock )+ {+ _glfwInput.MousePosX += [event deltaX];+ _glfwInput.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;+ }++ if( _glfwWin.mousePosCallback )+ {+ _glfwWin.mousePosCallback( _glfwInput.MousePosX, _glfwInput.MousePosY );+ }+}++- (void)rightMouseDown:(NSEvent *)event+{+ _glfwInputMouseClick( GLFW_MOUSE_BUTTON_RIGHT, GLFW_PRESS );+}++- (void)rightMouseDragged:(NSEvent *)event+{+ [self mouseMoved:event];+}++- (void)rightMouseUp:(NSEvent *)event+{+ _glfwInputMouseClick( GLFW_MOUSE_BUTTON_RIGHT, GLFW_RELEASE );+}++- (void)otherMouseDown:(NSEvent *)event+{+ _glfwInputMouseClick( [event buttonNumber], GLFW_PRESS );+}++- (void)otherMouseDragged:(NSEvent *)event+{+ [self mouseMoved:event];+}++- (void)otherMouseUp:(NSEvent *)event+{+ _glfwInputMouseClick( [event buttonNumber], GLFW_RELEASE );+}++- (void)keyDown:(NSEvent *)event+{+ NSUInteger length;+ NSString* characters;+ int i, code = convertMacKeyCode( [event keyCode] );++ if( code != -1 )+ {+ _glfwInputKey( code, GLFW_PRESS );++ if( [event modifierFlags] & NSCommandKeyMask )+ {+ if( !_glfwWin.sysKeysDisabled )+ {+ [super keyDown:event];+ }+ }+ else+ {+ characters = [event characters];+ length = [characters length];++ for( i = 0; i < length; i++ )+ {+ _glfwInputChar( [characters characterAtIndex:i], GLFW_PRESS );+ }+ }+ }+}++- (void)flagsChanged:(NSEvent *)event+{+ unsigned int newModifierFlags = [event modifierFlags];+ int mode;++ if( newModifierFlags > _glfwWin.modifierFlags )+ {+ mode = GLFW_PRESS;+ }+ else+ {+ mode = GLFW_RELEASE;+ }++ _glfwWin.modifierFlags = newModifierFlags;+ _glfwInputKey( 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 );+ }+ }+}++- (void)scrollWheel:(NSEvent *)event+{+ _glfwInput.WheelPosFloating += [event deltaY];+ _glfwInput.WheelPos = lrint(_glfwInput.WheelPosFloating);++ if( _glfwWin.mouseWheelCallback )+ {+ _glfwWin.mouseWheelCallback( _glfwInput.WheelPos );+ }+}++@end++//************************************************************************+//**** Platform implementation functions ****+//************************************************************************++//========================================================================+// Here is where the window is created, and the OpenGL rendering context is+// created+//========================================================================++int _glfwPlatformOpenWindow( int width, int height,+ const _GLFWwndconfig *wndconfig,+ const _GLFWfbconfig *fbconfig )+{+ int colorBits;++ _glfwWin.pixelFormat = nil;+ _glfwWin.window = nil;+ _glfwWin.context = nil;+ _glfwWin.delegate = nil;++ _glfwWin.delegate = [[GLFWWindowDelegate alloc] init];+ if( _glfwWin.delegate == nil )+ {+ _glfwPlatformCloseWindow();+ return GL_FALSE;+ }++ [NSApp setDelegate:_glfwWin.delegate];++ // Mac OS X needs non-zero color size, so set resonable values+ colorBits = fbconfig->redBits + fbconfig->greenBits + fbconfig->blueBits;+ if( colorBits == 0 )+ {+ colorBits = 24;+ }+ else if( colorBits < 15 )+ {+ colorBits = 15;+ }++ // Ignored hints:+ // OpenGLMajor, OpenGLMinor, OpenGLForward:+ // pending Mac OS X support for OpenGL 3.x+ // OpenGLDebug+ // pending it meaning anything on Mac OS X++ // 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 )+ {+ 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);++ width = [[(id)fullscreenMode objectForKey:(id)kCGDisplayWidth] intValue];+ height = [[(id)fullscreenMode objectForKey:(id)kCGDisplayHeight] intValue];+ }++ unsigned int styleMask = 0;+ if( wndconfig->mode == GLFW_WINDOW )+ {+ styleMask = NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask;++ if( !wndconfig->windowNoResize )+ {+ styleMask |= NSResizableWindowMask;+ }+ }+ else+ {+ styleMask = NSBorderlessWindowMask;+ }++ _glfwWin.window = [[NSWindow alloc]+ initWithContentRect:NSMakeRect(0, 0, width, 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 )+ {+ CGCaptureAllDisplays();+ CGDisplaySwitchToMode( CGMainDisplayID(), fullscreenMode );+ }++ unsigned int attribute_count = 0;+#define ADD_ATTR(x) attributes[attribute_count++] = x+#define ADD_ATTR2(x, y) (void)({ ADD_ATTR(x); ADD_ATTR(y); })+#define MAX_ATTRS 24 // urgh+ NSOpenGLPixelFormatAttribute attributes[MAX_ATTRS];++ ADD_ATTR( NSOpenGLPFADoubleBuffer );++ if( wndconfig->mode == GLFW_FULLSCREEN )+ {+ ADD_ATTR( NSOpenGLPFAFullScreen );+ ADD_ATTR( NSOpenGLPFANoRecovery );+ ADD_ATTR2( NSOpenGLPFAScreenMask,+ CGDisplayIDToOpenGLDisplayMask( CGMainDisplayID() ) );+ }++ ADD_ATTR2( NSOpenGLPFAColorSize, colorBits );++ if( fbconfig->alphaBits > 0)+ {+ ADD_ATTR2( NSOpenGLPFAAlphaSize, fbconfig->alphaBits );+ }++ if( fbconfig->depthBits > 0)+ {+ ADD_ATTR2( NSOpenGLPFADepthSize, fbconfig->depthBits );+ }++ 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( fbconfig->auxBuffers > 0)+ {+ ADD_ATTR2( NSOpenGLPFAAuxBuffers, fbconfig->auxBuffers );+ }++ if( fbconfig->stereo)+ {+ ADD_ATTR( NSOpenGLPFAStereo );+ }++ if( fbconfig->samples > 0)+ {+ ADD_ATTR2( NSOpenGLPFASampleBuffers, 1 );+ ADD_ATTR2( NSOpenGLPFASamples, fbconfig->samples );+ }++ ADD_ATTR(0);++ _glfwWin.pixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:attributes];+ if( _glfwWin.pixelFormat == nil )+ {+ _glfwPlatformCloseWindow();+ return GL_FALSE;+ }++ _glfwWin.context = [[NSOpenGLContext alloc] initWithFormat:_glfwWin.pixelFormat+ shareContext:nil];+ if( _glfwWin.context == nil )+ {+ _glfwPlatformCloseWindow();+ return GL_FALSE;+ }++ [_glfwWin.window makeKeyAndOrderFront:nil];+ [_glfwWin.context setView:[_glfwWin.window contentView]];++ if( wndconfig->mode == GLFW_FULLSCREEN )+ {+ // TODO: Make this work on pre-Leopard systems+ [[_glfwWin.window contentView] enterFullScreenMode:[NSScreen mainScreen]+ withOptions:nil];+ }++ [_glfwWin.context makeCurrentContext];++ NSPoint point = [[NSCursor currentCursor] hotSpot];+ _glfwInput.MousePosX = point.x;+ _glfwInput.MousePosY = point.y;++ return GL_TRUE;+}++//========================================================================+// Properly kill the window / video display+//========================================================================++void _glfwPlatformCloseWindow( void )+{+ [_glfwWin.window orderOut:nil];++ if( _glfwWin.fullscreen )+ {+ [[_glfwWin.window contentView] exitFullScreenModeWithOptions:nil];+ CGDisplaySwitchToMode( CGMainDisplayID(),+ (CFDictionaryRef)_glfwLibrary.DesktopMode );+ CGReleaseAllDisplays();+ }++ [_glfwWin.pixelFormat release];+ _glfwWin.pixelFormat = nil;++ [NSOpenGLContext clearCurrentContext];+ [_glfwWin.context release];+ _glfwWin.context = nil;++ [_glfwWin.window setDelegate:nil];+ [NSApp setDelegate:nil];+ [_glfwWin.delegate release];+ _glfwWin.delegate = nil;++ [_glfwWin.window close];+ _glfwWin.window = nil;++ // TODO: Probably more cleanup+}++//========================================================================+// Set the window title+//========================================================================++void _glfwPlatformSetWindowTitle( const char *title )+{+ [_glfwWin.window setTitle:[NSString stringWithCString:title+ encoding:NSISOLatin1StringEncoding]];+}++//========================================================================+// Set the window size+//========================================================================++void _glfwPlatformSetWindowSize( int width, int height )+{+ [_glfwWin.window setContentSize:NSMakeSize(width, height)];+}++//========================================================================+// Set the window position+//========================================================================++void _glfwPlatformSetWindowPos( int x, int y )+{+ NSRect contentRect = [_glfwWin.window contentRectForFrameRect:[_glfwWin.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];+ contentRect.origin = NSMakePoint(screenRect.origin.x + x,+ screenRect.origin.y + screenRect.size.height -+ y - contentRect.size.height);++ [_glfwWin.window setFrame:[_glfwWin.window frameRectForContentRect:contentRect]+ display:YES];+}++//========================================================================+// Iconify the window+//========================================================================++void _glfwPlatformIconifyWindow( void )+{+ [_glfwWin.window miniaturize:nil];+}++//========================================================================+// Restore (un-iconify) the window+//========================================================================++void _glfwPlatformRestoreWindow( void )+{+ [_glfwWin.window deminiaturize:nil];+}++//========================================================================+// Swap buffers+//========================================================================++void _glfwPlatformSwapBuffers( void )+{+ // ARP appears to be unnecessary, but this is future-proof+ [_glfwWin.context flushBuffer];+}++//========================================================================+// Set double buffering swap interval+//========================================================================++void _glfwPlatformSwapInterval( int interval )+{+ GLint sync = interval;+ [_glfwWin.context setValues:&sync forParameter:NSOpenGLCPSwapInterval];+}++//========================================================================+// Write back window parameters into GLFW window structure+//========================================================================++void _glfwPlatformRefreshWindowParams( void )+{+ GLint value;++ // Since GLFW 2.x doesn't understand screens, we use virtual screen zero++ [_glfwWin.pixelFormat getValues:&value+ forAttribute:NSOpenGLPFAAccelerated+ forVirtualScreen:0];+ _glfwWin.accelerated = value;++ [_glfwWin.pixelFormat getValues:&value+ forAttribute:NSOpenGLPFAAlphaSize+ forVirtualScreen:0];+ _glfwWin.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;++ [_glfwWin.pixelFormat getValues:&value+ forAttribute:NSOpenGLPFADepthSize+ forVirtualScreen:0];+ _glfwWin.depthBits = value;++ [_glfwWin.pixelFormat getValues:&value+ forAttribute:NSOpenGLPFAStencilSize+ forVirtualScreen:0];+ _glfwWin.stencilBits = value;++ [_glfwWin.pixelFormat getValues:&value+ forAttribute:NSOpenGLPFAAccumSize+ forVirtualScreen:0];+ _glfwWin.accumRedBits = value / 3;+ _glfwWin.accumGreenBits = value / 3;+ _glfwWin.accumBlueBits = value / 3;++ // TODO: Figure out what to set this value to+ _glfwWin.accumAlphaBits = 0;++ [_glfwWin.pixelFormat getValues:&value+ forAttribute:NSOpenGLPFAAuxBuffers+ forVirtualScreen:0];+ _glfwWin.auxBuffers = value;++ [_glfwWin.pixelFormat getValues:&value+ forAttribute:NSOpenGLPFAStereo+ forVirtualScreen:0];+ _glfwWin.stereo = value;++ [_glfwWin.pixelFormat getValues:&value+ forAttribute:NSOpenGLPFASamples+ forVirtualScreen:0];+ _glfwWin.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;+}++//========================================================================+// Poll for new window and input events+//========================================================================++void _glfwPlatformPollEvents( void )+{+ NSEvent *event;++ do+ {+ event = [NSApp nextEventMatchingMask:NSAnyEventMask+ untilDate:[NSDate distantPast]+ inMode:NSDefaultRunLoopMode+ dequeue:YES];++ if (event)+ {+ [NSApp sendEvent:event];+ }+ }+ while (event);++ [_glfwLibrary.AutoreleasePool drain];+ _glfwLibrary.AutoreleasePool = [[NSAutoreleasePool alloc] init];+}++//========================================================================+// Wait for new window and input events+//========================================================================++void _glfwPlatformWaitEvents( void )+{+ // I wanted to pass NO to dequeue:, and rely on PollEvents to+ // dequeue and send. For reasons not at all clear to me, passing+ // NO to dequeue: causes this method never to return.+ NSEvent *event = [NSApp nextEventMatchingMask:NSAnyEventMask+ untilDate:[NSDate distantFuture]+ inMode:NSDefaultRunLoopMode+ dequeue:YES];+ [NSApp sendEvent:event];++ _glfwPlatformPollEvents();+}++//========================================================================+// Hide mouse cursor (lock it)+//========================================================================++void _glfwPlatformHideMouseCursor( void )+{+ [NSCursor hide];+ CGAssociateMouseAndMouseCursorPosition( false );+}++//========================================================================+// Show mouse cursor (unlock it)+//========================================================================++void _glfwPlatformShowMouseCursor( void )+{+ [NSCursor unhide];+ CGAssociateMouseAndMouseCursorPosition( true );+}++//========================================================================+// Set physical mouse cursor position+//========================================================================++void _glfwPlatformSetMouseCursorPos( 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,+ // and other badness in pain. I think the API's just silly, but maybe I'm+ // misunderstanding it...++ // Also, (x, y) are window coords...++ // Also, it doesn't seem possible to write this robustly without+ // calculating the maximum y coordinate of all screens, since Cocoa's+ // "global coordinates" are upside down from CG's...++ // Without this (once per app run, but it's convenient to do it here)+ // events will be suppressed for a default of 0.25 seconds after we+ // move the cursor.+ CGSetLocalEventsSuppressionInterval( 0.0 );++ NSPoint localPoint = NSMakePoint( x, y );+ NSPoint globalPoint = [_glfwWin.window convertBaseToScreen:localPoint];+ CGPoint mainScreenOrigin = CGDisplayBounds( CGMainDisplayID() ).origin;+ double mainScreenHeight = CGDisplayBounds( CGMainDisplayID() ).size.height;+ CGPoint targetPoint = CGPointMake( globalPoint.x - mainScreenOrigin.x,+ mainScreenHeight - globalPoint.y - mainScreenOrigin.y );+ CGDisplayMoveCursorToPoint( CGMainDisplayID(), targetPoint );+}+