diff options
| author | Magnus Auvinen <magnus.auvinen@gmail.com> | 2007-08-22 07:52:33 +0000 |
|---|---|---|
| committer | Magnus Auvinen <magnus.auvinen@gmail.com> | 2007-08-22 07:52:33 +0000 |
| commit | 8b3c16e6152a527f9aec1a88a9eed74119de7000 (patch) | |
| tree | f0bde5cea15e696e42cade06a3b12ff6b13acc57 /src/engine/external/glfw/lib/macosx | |
| parent | 9899666a7ce6679a3b9667ab09f615f4d0769c16 (diff) | |
| download | zcatch-8b3c16e6152a527f9aec1a88a9eed74119de7000.tar.gz zcatch-8b3c16e6152a527f9aec1a88a9eed74119de7000.zip | |
major engine cleanup. dependency on baselib removed. engine is now C code (not ansi tho). some other cruft removed aswell
Diffstat (limited to 'src/engine/external/glfw/lib/macosx')
| -rw-r--r-- | src/engine/external/glfw/lib/macosx/macosx_enable.c | 42 | ||||
| -rw-r--r-- | src/engine/external/glfw/lib/macosx/macosx_fullscreen.c | 126 | ||||
| -rw-r--r-- | src/engine/external/glfw/lib/macosx/macosx_glext.c | 52 | ||||
| -rw-r--r-- | src/engine/external/glfw/lib/macosx/macosx_init.c | 194 | ||||
| -rw-r--r-- | src/engine/external/glfw/lib/macosx/macosx_joystick.c | 50 | ||||
| -rw-r--r-- | src/engine/external/glfw/lib/macosx/macosx_thread.c | 414 | ||||
| -rw-r--r-- | src/engine/external/glfw/lib/macosx/macosx_time.c | 112 | ||||
| -rw-r--r-- | src/engine/external/glfw/lib/macosx/macosx_window.c | 1279 | ||||
| -rw-r--r-- | src/engine/external/glfw/lib/macosx/platform.h | 349 |
9 files changed, 2618 insertions, 0 deletions
diff --git a/src/engine/external/glfw/lib/macosx/macosx_enable.c b/src/engine/external/glfw/lib/macosx/macosx_enable.c new file mode 100644 index 00000000..e4047366 --- /dev/null +++ b/src/engine/external/glfw/lib/macosx/macosx_enable.c @@ -0,0 +1,42 @@ +//======================================================================== +// GLFW - An OpenGL framework +// File: macosx_enable.c +// Platform: Mac OS X +// API Version: 2.6 +// 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. +// +//======================================================================== + +void _glfwPlatformEnableSystemKeys( void ) +{ + // Nothing to do; event handling code checks the status of + // _glfwWin.SysKeysDisabled to ensure this behavior. +} + +void _glfwPlatformDisableSystemKeys( void ) +{ + // Nothing to do; event handling code checks the status of + // _glfwWin.SysKeysDisabled to ensure this behavior. +} + diff --git a/src/engine/external/glfw/lib/macosx/macosx_fullscreen.c b/src/engine/external/glfw/lib/macosx/macosx_fullscreen.c new file mode 100644 index 00000000..b16495fb --- /dev/null +++ b/src/engine/external/glfw/lib/macosx/macosx_fullscreen.c @@ -0,0 +1,126 @@ +//======================================================================== +// GLFW - An OpenGL framework +// File: macosx_fullscreen.c +// Platform: Mac OS X +// API Version: 2.6 +// 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" + +//======================================================================== +// _glfwVideoModesEqual() - Compares two video modes +//======================================================================== + +static int _glfwVideoModesEqual( GLFWvidmode* first, + GLFWvidmode* second ) +{ + if( first->Width != second->Width ) + return 0; + + if( first->Height != second->Height ) + return 0; + + if( first->RedBits + first->GreenBits + first->BlueBits != + second->RedBits + second->GreenBits + second->BlueBits ) + return 0; + + return 1; +} + +//======================================================================== +// _glfwCGToGLFWVideoMode() - Converts a CG mode to a GLFW mode +//======================================================================== + +static void _glfwCGToGLFWVideoMode( CFDictionaryRef cgMode, + GLFWvidmode* glfwMode ) +{ + int bitsPerSample; + + CFNumberGetValue( CFDictionaryGetValue( cgMode, kCGDisplayWidth ), + kCFNumberIntType, + &(glfwMode->Width) ); + CFNumberGetValue( CFDictionaryGetValue( cgMode, kCGDisplayHeight ), + kCFNumberIntType, + &(glfwMode->Height) ); + + CFNumberGetValue( CFDictionaryGetValue( cgMode, kCGDisplayBitsPerSample ), + kCFNumberIntType, + &bitsPerSample ); + + glfwMode->RedBits = bitsPerSample; + glfwMode->GreenBits = bitsPerSample; + glfwMode->BlueBits = bitsPerSample; +} + +//======================================================================== +// _glfwPlatformGetVideoModes() - Get a list of available video modes +//======================================================================== + +int _glfwPlatformGetVideoModes( GLFWvidmode *list, int maxcount ) +{ + int i, j, maxModes, numModes; + GLFWvidmode mode; + CFArrayRef availableModes = CGDisplayAvailableModes( kCGDirectMainDisplay ); + CFIndex numberOfAvailableModes = CFArrayGetCount( availableModes ); + + numModes = 0; + maxModes = ( numberOfAvailableModes < maxcount ? + numberOfAvailableModes : + maxcount ); + + for( i = 0; i < maxModes; ++i ) + { + _glfwCGToGLFWVideoMode( CFArrayGetValueAtIndex( availableModes, i ), + &mode ); + + // Is it a valid mode? (only list depths >= 15 bpp) + if( mode.RedBits + mode.GreenBits + mode.BlueBits < 15 ) + continue; + + // Check for duplicate of current mode in target list + for( j = 0; j < numModes; ++j ) + { + if( _glfwVideoModesEqual( &mode, &(list[j]) ) ) + break; + } + + // If empty list or no match found + if( numModes == 0 || j == numModes ) + list[numModes++] = mode; + } + + return numModes; +} + +//======================================================================== +// glfwGetDesktopMode() - Get the desktop video mode +//======================================================================== + +void _glfwPlatformGetDesktopMode( GLFWvidmode *mode ) +{ + _glfwCGToGLFWVideoMode( _glfwDesktopVideoMode, mode ); +} + diff --git a/src/engine/external/glfw/lib/macosx/macosx_glext.c b/src/engine/external/glfw/lib/macosx/macosx_glext.c new file mode 100644 index 00000000..0b623a5c --- /dev/null +++ b/src/engine/external/glfw/lib/macosx/macosx_glext.c @@ -0,0 +1,52 @@ +//======================================================================== +// GLFW - An OpenGL framework +// File: macosx_glext.c +// Platform: Mac OS X +// API Version: 2.6 +// 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" + +int _glfwPlatformExtensionSupported( const char *extension ) +{ + // There are no AGL, CGL or NSGL extensions. + return GL_FALSE; +} + +void * _glfwPlatformGetProcAddress( const char *procname ) +{ + CFStringRef symbolName = CFStringCreateWithCString( kCFAllocatorDefault, + procname, + kCFStringEncodingASCII ); + + void *symbol = CFBundleGetFunctionPointerForName( _glfwLibrary.Libs.OpenGLFramework, + symbolName ); + + CFRelease( symbolName ); + + return symbol; +} + diff --git a/src/engine/external/glfw/lib/macosx/macosx_init.c b/src/engine/external/glfw/lib/macosx/macosx_init.c new file mode 100644 index 00000000..c123daf0 --- /dev/null +++ b/src/engine/external/glfw/lib/macosx/macosx_init.c @@ -0,0 +1,194 @@ +//======================================================================== +// GLFW - An OpenGL framework +// File: macosx_init.c +// Platform: Mac OS X +// API Version: 2.6 +// 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 <unistd.h> + +//======================================================================== +// Global variables +//======================================================================== + +// KCHR resource pointer for keycode translation +void *KCHRPtr; + + +//======================================================================== +// _glfwInitThreads() - Initialize GLFW thread package +//======================================================================== + +static void _glfwInitThreads( 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; +} + +#define NO_BUNDLE_MESSAGE \ + "Working in unbundled mode. " \ + "You should build a .app wrapper for your Mac OS X applications.\n" + +#define UNBUNDLED \ + fprintf(stderr, NO_BUNDLE_MESSAGE); \ + _glfwLibrary.Unbundled = 1; \ + return + +void _glfwChangeToResourcesDirectory( void ) +{ + CFBundleRef mainBundle = CFBundleGetMainBundle(); + CFURLRef resourcesURL = CFBundleCopyResourcesDirectoryURL( mainBundle ); + char resourcesPath[ _GLFW_MAX_PATH_LENGTH ]; + + CFStringRef lastComponent = CFURLCopyLastPathComponent( resourcesURL ); + if ( kCFCompareEqualTo != CFStringCompare( + CFSTR( "Resources" ), + lastComponent, + 0 ) ) + { + UNBUNDLED; + } + + CFRelease( lastComponent ); + + if( !CFURLGetFileSystemRepresentation( resourcesURL, + TRUE, + (UInt8*)resourcesPath, + _GLFW_MAX_PATH_LENGTH ) ) + { + CFRelease( resourcesURL ); + UNBUNDLED; + } + + CFRelease( resourcesURL ); + + if( chdir( resourcesPath ) != 0 ) + { + UNBUNDLED; + } +} + +int _glfwPlatformInit( void ) +{ + struct timeval tv; + UInt32 nullDummy = 0; + + _glfwWin.MacWindow = NULL; + _glfwWin.AGLContext = NULL; + _glfwWin.CGLContext = NULL; + _glfwWin.WindowFunctions = NULL; + _glfwWin.MouseUPP = NULL; + _glfwWin.CommandUPP = NULL; + _glfwWin.KeyboardUPP = NULL; + _glfwWin.WindowUPP = NULL; + + _glfwInput.Modifiers = 0; + + _glfwLibrary.Unbundled = 0; + + _glfwLibrary.Libs.OpenGLFramework + = CFBundleGetBundleWithIdentifier( CFSTR( "com.apple.opengl" ) ); + if( _glfwLibrary.Libs.OpenGLFramework == NULL ) + { + fprintf( + stderr, + "glfwInit failing because you aren't linked to OpenGL\n" ); + return GL_FALSE; + } + + _glfwDesktopVideoMode = CGDisplayCurrentMode( kCGDirectMainDisplay ); + if( _glfwDesktopVideoMode == NULL ) + { + fprintf( + stderr, + "glfwInit failing because it kind find the desktop display mode\n" ); + return GL_FALSE; + } + + _glfwInitThreads(); + + _glfwChangeToResourcesDirectory(); + + if( !_glfwInstallEventHandlers() ) + { + fprintf( + stderr, + "glfwInit failing because it can't install event handlers\n" ); + _glfwPlatformTerminate(); + return GL_FALSE; + } + + // Ugly hack to reduce the nasty jump that occurs at the first non- + // sys keypress, caused by OS X loading certain meta scripts used + // for lexical- and raw keycode translation - instead of letting + // this happen while our application is running, we do some blunt + // function calls in advance just to get the script caching out of + // the way BEFORE our window/screen is opened. These calls might + // generate err return codes, but we don't care in this case. + // NOTE: KCHRPtr is declared globally, because we need it later on. + KCHRPtr = (void *)GetScriptVariable( smCurrentScript, smKCHRCache ); + KeyTranslate( KCHRPtr, 0, &nullDummy ); + UppercaseText( (char *)&nullDummy, 0, smSystemScript ); + + gettimeofday( &tv, NULL ); + _glfwLibrary.Timer.t0 = tv.tv_sec + (double) tv.tv_usec / 1000000.0; + + return GL_TRUE; +} + +int _glfwPlatformTerminate( void ) +{ + if( _glfwWin.MouseUPP != NULL ) + { + DisposeEventHandlerUPP( _glfwWin.MouseUPP ); + _glfwWin.MouseUPP = NULL; + } + if( _glfwWin.CommandUPP != NULL ) + { + DisposeEventHandlerUPP( _glfwWin.CommandUPP ); + _glfwWin.CommandUPP = NULL; + } + if( _glfwWin.KeyboardUPP != NULL ) + { + DisposeEventHandlerUPP( _glfwWin.KeyboardUPP ); + _glfwWin.KeyboardUPP = NULL; + } + + return GL_TRUE; +} + diff --git a/src/engine/external/glfw/lib/macosx/macosx_joystick.c b/src/engine/external/glfw/lib/macosx/macosx_joystick.c new file mode 100644 index 00000000..527de017 --- /dev/null +++ b/src/engine/external/glfw/lib/macosx/macosx_joystick.c @@ -0,0 +1,50 @@ +//======================================================================== +// GLFW - An OpenGL framework +// File: macosx_joystick.c +// Platform: Mac OS X +// API Version: 2.6 +// 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" + +// TO DO: use HID manager to implement joystick support. + +int _glfwPlatformGetJoystickParam( int joy, int param ) +{ + // GL_FALSE == 0 + return 0; +} + +int _glfwPlatformGetJoystickPos( int joy, float *pos, int numaxes ) +{ + return 0; +} + +int _glfwPlatformGetJoystickButtons( int joy, unsigned char *buttons, int numbuttons ) +{ + return 0; +} + diff --git a/src/engine/external/glfw/lib/macosx/macosx_thread.c b/src/engine/external/glfw/lib/macosx/macosx_thread.c new file mode 100644 index 00000000..c1213957 --- /dev/null +++ b/src/engine/external/glfw/lib/macosx/macosx_thread.c @@ -0,0 +1,414 @@ +//======================================================================== +// GLFW - An OpenGL framework +// File: macosx_thread.c +// Platform: Mac OS X +// API Version: 2.6 +// 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" + + + +//************************************************************************ +//**** 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; +} + diff --git a/src/engine/external/glfw/lib/macosx/macosx_time.c b/src/engine/external/glfw/lib/macosx/macosx_time.c new file mode 100644 index 00000000..cde52b4b --- /dev/null +++ b/src/engine/external/glfw/lib/macosx/macosx_time.c @@ -0,0 +1,112 @@ +//======================================================================== +// GLFW - An OpenGL framework +// File: macosx_time.c +// Platform: Mac OS X +// API Version: 2.6 +// 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 **** +//************************************************************************ + +//======================================================================== +// Return timer value in seconds +//======================================================================== + +double _glfwPlatformGetTime( void ) +{ + struct timeval tv; + + gettimeofday( &tv, NULL ); + return tv.tv_sec + (double) tv.tv_usec / 1000000.0 - _glfwLibrary.Timer.t0; +} + + +//======================================================================== +// Set timer value in seconds +//======================================================================== + +void _glfwPlatformSetTime( double time ) +{ + struct timeval tv; + + gettimeofday( &tv, NULL ); + _glfwLibrary.Timer.t0 = tv.tv_sec + (double) tv.tv_usec / 1000000.0 - 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 ); +} + diff --git a/src/engine/external/glfw/lib/macosx/macosx_window.c b/src/engine/external/glfw/lib/macosx/macosx_window.c new file mode 100644 index 00000000..b8af0c4e --- /dev/null +++ b/src/engine/external/glfw/lib/macosx/macosx_window.c @@ -0,0 +1,1279 @@ +//======================================================================== +// GLFW - An OpenGL framework +// File: macosx_window.c +// Platform: Mac OS X +// API Version: 2.6 +// 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" + +static _GLFWmacwindowfunctions _glfwMacFSWindowFunctions = +{ + _glfwMacFSOpenWindow, + _glfwMacFSCloseWindow, + _glfwMacFSSetWindowTitle, + _glfwMacFSSetWindowSize, + _glfwMacFSSetWindowPos, + _glfwMacFSIconifyWindow, + _glfwMacFSRestoreWindow, + _glfwMacFSRefreshWindowParams, + _glfwMacFSSetMouseCursorPos +}; + +static _GLFWmacwindowfunctions _glfwMacDWWindowFunctions = +{ + _glfwMacDWOpenWindow, + _glfwMacDWCloseWindow, + _glfwMacDWSetWindowTitle, + _glfwMacDWSetWindowSize, + _glfwMacDWSetWindowPos, + _glfwMacDWIconifyWindow, + _glfwMacDWRestoreWindow, + _glfwMacDWRefreshWindowParams, + _glfwMacDWSetMouseCursorPos +}; + +#define _glfwTestModifier( modifierMask, glfwKey ) \ +if ( changed & modifierMask ) \ +{ \ + _glfwInputKey( glfwKey, (modifiers & modifierMask ? GLFW_PRESS : GLFW_RELEASE) ); \ +} + +void _glfwHandleMacModifierChange( UInt32 modifiers ) +{ + UInt32 changed = modifiers ^ _glfwInput.Modifiers; + + _glfwTestModifier( shiftKey, GLFW_KEY_LSHIFT ); + _glfwTestModifier( rightShiftKey, GLFW_KEY_RSHIFT ); + _glfwTestModifier( controlKey, GLFW_KEY_LCTRL ); + _glfwTestModifier( rightControlKey, GLFW_KEY_RCTRL ); + _glfwTestModifier( optionKey, GLFW_KEY_LALT ); + _glfwTestModifier( rightOptionKey, GLFW_KEY_RALT ); + + _glfwInput.Modifiers = modifiers; +} + +void _glfwHandleMacKeyChange( UInt32 keyCode, int action ) +{ + switch ( keyCode ) + { + case MAC_KEY_ENTER: _glfwInputKey( GLFW_KEY_ENTER, action); break; + case MAC_KEY_RETURN: _glfwInputKey( GLFW_KEY_KP_ENTER, action); break; + case MAC_KEY_ESC: _glfwInputKey( GLFW_KEY_ESC, action); break; + case MAC_KEY_F1: _glfwInputKey( GLFW_KEY_F1, action); break; + case MAC_KEY_F2: _glfwInputKey( GLFW_KEY_F2, action); break; + case MAC_KEY_F3: _glfwInputKey( GLFW_KEY_F3, action); break; + case MAC_KEY_F4: _glfwInputKey( GLFW_KEY_F4, action); break; + case MAC_KEY_F5: _glfwInputKey( GLFW_KEY_F5, action); break; + case MAC_KEY_F6: _glfwInputKey( GLFW_KEY_F6, action); break; + case MAC_KEY_F7: _glfwInputKey( GLFW_KEY_F7, action); break; + case MAC_KEY_F8: _glfwInputKey( GLFW_KEY_F8, action); break; + case MAC_KEY_F9: _glfwInputKey( GLFW_KEY_F9, action); break; + case MAC_KEY_F10: _glfwInputKey( GLFW_KEY_F10, action); break; + case MAC_KEY_F11: _glfwInputKey( GLFW_KEY_F11, action); break; + case MAC_KEY_F12: _glfwInputKey( GLFW_KEY_F12, action); break; + case MAC_KEY_F13: _glfwInputKey( GLFW_KEY_F13, action); break; + case MAC_KEY_F14: _glfwInputKey( GLFW_KEY_F14, action); break; + case MAC_KEY_F15: _glfwInputKey( GLFW_KEY_F15, action); break; + case MAC_KEY_UP: _glfwInputKey( GLFW_KEY_UP, action); break; + case MAC_KEY_DOWN: _glfwInputKey( GLFW_KEY_DOWN, action); break; + case MAC_KEY_LEFT: _glfwInputKey( GLFW_KEY_LEFT, action); break; + case MAC_KEY_RIGHT: _glfwInputKey( GLFW_KEY_RIGHT, action); break; + case MAC_KEY_TAB: _glfwInputKey( GLFW_KEY_TAB, action); break; + case MAC_KEY_BACKSPACE: _glfwInputKey( GLFW_KEY_BACKSPACE, action); break; + case MAC_KEY_HELP: _glfwInputKey( GLFW_KEY_INSERT, action); break; + case MAC_KEY_DEL: _glfwInputKey( GLFW_KEY_DEL, action); break; + case MAC_KEY_PAGEUP: _glfwInputKey( GLFW_KEY_PAGEUP, action); break; + case MAC_KEY_PAGEDOWN: _glfwInputKey( GLFW_KEY_PAGEDOWN, action); break; + case MAC_KEY_HOME: _glfwInputKey( GLFW_KEY_HOME, action); break; + case MAC_KEY_END: _glfwInputKey( GLFW_KEY_END, action); break; + case MAC_KEY_KP_0: _glfwInputKey( GLFW_KEY_KP_0, action); break; + case MAC_KEY_KP_1: _glfwInputKey( GLFW_KEY_KP_1, action); break; + case MAC_KEY_KP_2: _glfwInputKey( GLFW_KEY_KP_2, action); break; + case MAC_KEY_KP_3: _glfwInputKey( GLFW_KEY_KP_3, action); break; + case MAC_KEY_KP_4: _glfwInputKey( GLFW_KEY_KP_4, action); break; + case MAC_KEY_KP_5: _glfwInputKey( GLFW_KEY_KP_5, action); break; + case MAC_KEY_KP_6: _glfwInputKey( GLFW_KEY_KP_6, action); break; + case MAC_KEY_KP_7: _glfwInputKey( GLFW_KEY_KP_7, action); break; + case MAC_KEY_KP_8: _glfwInputKey( GLFW_KEY_KP_8, action); break; + case MAC_KEY_KP_9: _glfwInputKey( GLFW_KEY_KP_9, action); break; + case MAC_KEY_KP_DIVIDE: _glfwInputKey( GLFW_KEY_KP_DIVIDE, action); break; + case MAC_KEY_KP_MULTIPLY: _glfwInputKey( GLFW_KEY_KP_MULTIPLY, action); break; + case MAC_KEY_KP_SUBTRACT: _glfwInputKey( GLFW_KEY_KP_SUBTRACT, action); break; + case MAC_KEY_KP_ADD: _glfwInputKey( GLFW_KEY_KP_ADD, action); break; + case MAC_KEY_KP_DECIMAL: _glfwInputKey( GLFW_KEY_KP_DECIMAL, action); break; + case MAC_KEY_KP_EQUAL: _glfwInputKey( GLFW_KEY_KP_EQUAL, action); break; + case MAC_KEY_KP_ENTER: _glfwInputKey( GLFW_KEY_KP_ENTER, action); break; + default: + { + extern void *KCHRPtr; + UInt32 state = 0; + char charCode = (char)KeyTranslate( KCHRPtr, keyCode, &state ); + UppercaseText( &charCode, 1, smSystemScript ); + _glfwInputKey( (unsigned char)charCode, action ); + } + break; + } +} + +EventTypeSpec GLFW_KEY_EVENT_TYPES[] = +{ + { kEventClassKeyboard, kEventRawKeyDown }, + { kEventClassKeyboard, kEventRawKeyUp }, + { kEventClassKeyboard, kEventRawKeyModifiersChanged } +}; + +OSStatus _glfwKeyEventHandler( EventHandlerCallRef handlerCallRef, + EventRef event, + void *userData ) +{ + UInt32 keyCode; + short int keyChar; + UInt32 modifiers; + + switch( GetEventKind( event ) ) + { + case kEventRawKeyDown: + { + if( GetEventParameter( event, + kEventParamKeyCode, + typeUInt32, + NULL, + sizeof( UInt32 ), + NULL, + &keyCode ) == noErr ) + { + _glfwHandleMacKeyChange( keyCode, GLFW_PRESS ); + } + if( GetEventParameter( event, + kEventParamKeyUnicodes, + typeUnicodeText, + NULL, + sizeof(keyChar), + NULL, + &keyChar) == noErr ) + { + _glfwInputChar( keyChar, GLFW_PRESS ); + } + return noErr; + } + + case kEventRawKeyUp: + { + if( GetEventParameter( event, + kEventParamKeyCode, + typeUInt32, + NULL, + sizeof( UInt32 ), + NULL, + &keyCode ) == noErr ) + { + _glfwHandleMacKeyChange( keyCode, GLFW_RELEASE ); + } + if( GetEventParameter( event, + kEventParamKeyUnicodes, + typeUnicodeText, + NULL, + sizeof(keyChar), + NULL, + &keyChar) == noErr ) + { + _glfwInputChar( keyChar, GLFW_RELEASE ); + } + return noErr; + } + + case kEventRawKeyModifiersChanged: + { + if( GetEventParameter( event, + kEventParamKeyModifiers, + typeUInt32, + NULL, + sizeof( UInt32 ), + NULL, + &modifiers ) == noErr ) + { + _glfwHandleMacModifierChange( modifiers ); + return noErr; + } + } + break; + } + + return eventNotHandledErr; +} + +EventTypeSpec GLFW_MOUSE_EVENT_TYPES[] = +{ + { kEventClassMouse, kEventMouseDown }, + { kEventClassMouse, kEventMouseUp }, + { kEventClassMouse, kEventMouseMoved }, + { kEventClassMouse, kEventMouseDragged }, + { kEventClassMouse, kEventMouseWheelMoved }, +}; + +OSStatus _glfwMouseEventHandler( EventHandlerCallRef handlerCallRef, + EventRef event, + void *userData ) +{ + switch( GetEventKind( event ) ) + { + case kEventMouseDown: + { + WindowRef window; + EventRecord oldStyleMacEvent; + ConvertEventRefToEventRecord( event, &oldStyleMacEvent ); + if( FindWindow ( oldStyleMacEvent.where, &window ) == inMenuBar ) + { + MenuSelect( oldStyleMacEvent.where ); + HiliteMenu(0); + return noErr; + } + else + { + EventMouseButton button; + if( GetEventParameter( event, + kEventParamMouseButton, + typeMouseButton, + NULL, + sizeof( EventMouseButton ), + NULL, + &button ) == noErr ) + { + button -= kEventMouseButtonPrimary; + if( button <= GLFW_MOUSE_BUTTON_LAST ) + { + _glfwInputMouseClick( button + + GLFW_MOUSE_BUTTON_LEFT, + GLFW_PRESS ); + } + return noErr; + } + } + break; + } + + case kEventMouseUp: + { + EventMouseButton button; + if( GetEventParameter( event, + kEventParamMouseButton, + typeMouseButton, + NULL, + sizeof( EventMouseButton ), + NULL, + &button ) == noErr ) + { + button -= kEventMouseButtonPrimary; + if( button <= GLFW_MOUSE_BUTTON_LAST ) + { + _glfwInputMouseClick( button + + GLFW_MOUSE_BUTTON_LEFT, + GLFW_RELEASE ); + } + return noErr; + } + break; + } + + case kEventMouseMoved: + case kEventMouseDragged: + { + HIPoint mouseLocation; + if( _glfwWin.MouseLock ) + { + if( GetEventParameter( event, + kEventParamMouseDelta, + typeHIPoint, + NULL, + sizeof( HIPoint ), + NULL, + &mouseLocation ) != noErr ) + { + break; + } + + _glfwInput.MousePosX += mouseLocation.x; + _glfwInput.MousePosY += mouseLocation.y; + } + else + { + if( GetEventParameter( event, + kEventParamMouseLocation, + typeHIPoint, + NULL, + sizeof( HIPoint ), + NULL, + &mouseLocation ) != noErr ) + { + break; + } + + _glfwInput.MousePosX = mouseLocation.x; + _glfwInput.MousePosY = mouseLocation.y; + + if( !_glfwWin.Fullscreen ) + { + Rect content; + GetWindowBounds( _glfwWin.MacWindow, + kWindowContentRgn, + &content ); + + _glfwInput.MousePosX -= content.left; + _glfwInput.MousePosY -= content.top; + } + } + + if( _glfwWin.MousePosCallback ) + { + _glfwWin.MousePosCallback( _glfwInput.MousePosX, + _glfwInput.MousePosY ); + } + + break; + } + + case kEventMouseWheelMoved: + { + EventMouseWheelAxis axis; + if( GetEventParameter( event, + kEventParamMouseWheelAxis, + typeMouseWheelAxis, + NULL, + sizeof( EventMouseWheelAxis ), + NULL, + &axis) == noErr ) + { + long wheelDelta; + if( axis == kEventMouseWheelAxisY && + GetEventParameter( event, + kEventParamMouseWheelDelta, + typeLongInteger, + NULL, + sizeof( long ), + NULL, + &wheelDelta ) == noErr ) + { + _glfwInput.WheelPos += wheelDelta; + if( _glfwWin.MouseWheelCallback ) + { + _glfwWin.MouseWheelCallback( _glfwInput.WheelPos ); + } + return noErr; + } + } + break; + } + } + + return eventNotHandledErr; +} + +EventTypeSpec GLFW_COMMAND_EVENT_TYPES[] = +{ + { kEventClassCommand, kEventCommandProcess } +}; + +OSStatus _glfwCommandHandler( EventHandlerCallRef handlerCallRef, + EventRef event, + void *userData ) +{ + if( _glfwWin.SysKeysDisabled ) + { + // TO DO: give adequate UI feedback that this is the case + return eventNotHandledErr; + } + + HICommand command; + if( GetEventParameter( event, + kEventParamDirectObject, + typeHICommand, + NULL, + sizeof( HICommand ), + NULL, + &command ) == noErr ) + { + switch( command.commandID ) + { + case kHICommandClose: + case kHICommandQuit: + { + // Check if the program wants us to close the window + if( _glfwWin.WindowCloseCallback ) + { + if( _glfwWin.WindowCloseCallback() ) + { + glfwCloseWindow(); + } + } + else + { + glfwCloseWindow(); + } + return noErr; + } + } + } + + return eventNotHandledErr; +} + +EventTypeSpec GLFW_WINDOW_EVENT_TYPES[] = +{ + { kEventClassWindow, kEventWindowBoundsChanged }, + { kEventClassWindow, kEventWindowClose }, + { kEventClassWindow, kEventWindowDrawContent }, + { kEventClassWindow, kEventWindowActivated }, + { kEventClassWindow, kEventWindowDeactivated }, +}; + +OSStatus _glfwWindowEventHandler( EventHandlerCallRef handlerCallRef, + EventRef event, + void *userData ) +{ + switch( GetEventKind(event) ) + { + case kEventWindowBoundsChanged: + { + WindowRef window; + GetEventParameter( event, kEventParamDirectObject, typeWindowRef, NULL, + sizeof(WindowRef), NULL, &window ); + + Rect rect; + GetWindowPortBounds( window, &rect ); + + if( _glfwWin.Width != rect.right || + _glfwWin.Height != rect.bottom ) + { + aglUpdateContext(_glfwWin.AGLContext); + + _glfwWin.Width = rect.right; + _glfwWin.Height = rect.bottom; + if( _glfwWin.WindowSizeCallback ) + { + _glfwWin.WindowSizeCallback( _glfwWin.Width, + _glfwWin.Height ); + } + // Emulate (force) content invalidation + if( _glfwWin.WindowRefreshCallback ) + { + _glfwWin.WindowRefreshCallback(); + } + } + break; + } + + case kEventWindowClose: + { + // Check if the program wants us to close the window + if( _glfwWin.WindowCloseCallback ) + { + if( _glfwWin.WindowCloseCallback() ) + { + glfwCloseWindow(); + } + } + else + { + glfwCloseWindow(); + } + return noErr; + } + + case kEventWindowDrawContent: + { + // Call user callback function + if( _glfwWin.WindowRefreshCallback ) + { + _glfwWin.WindowRefreshCallback(); + } + break; + } + + case kEventWindowActivated: + { + _glfwWin.Active = GL_TRUE; + break; + } + + case kEventWindowDeactivated: + { + _glfwWin.Active = GL_FALSE; + _glfwInputDeactivation(); + break; + } + } + + return eventNotHandledErr; +} + +int _glfwInstallEventHandlers( void ) +{ + OSStatus error; + + _glfwWin.MouseUPP = NewEventHandlerUPP( _glfwMouseEventHandler ); + + error = InstallEventHandler( GetApplicationEventTarget(), + _glfwWin.MouseUPP, + GetEventTypeCount( GLFW_MOUSE_EVENT_TYPES ), + GLFW_MOUSE_EVENT_TYPES, + NULL, + NULL ); + if( error != noErr ) + { + fprintf( stderr, "glfwOpenWindow failing because it can't install mouse event handler\n" ); + return GL_FALSE; + } + + _glfwWin.CommandUPP = NewEventHandlerUPP( _glfwCommandHandler ); + + error = InstallEventHandler( GetApplicationEventTarget(), + _glfwWin.CommandUPP, + GetEventTypeCount( GLFW_COMMAND_EVENT_TYPES ), + GLFW_COMMAND_EVENT_TYPES, + NULL, + NULL ); + if( error != noErr ) + { + fprintf( stderr, "glfwOpenWindow failing because it can't install command event handler\n" ); + return GL_FALSE; + } + + _glfwWin.KeyboardUPP = NewEventHandlerUPP( _glfwKeyEventHandler ); + + error = InstallEventHandler( GetApplicationEventTarget(), + _glfwWin.KeyboardUPP, + GetEventTypeCount( GLFW_KEY_EVENT_TYPES ), + GLFW_KEY_EVENT_TYPES, + NULL, + NULL ); + if( error != noErr ) + { + fprintf( stderr, "glfwOpenWindow failing because it can't install key event handler\n" ); + return GL_FALSE; + } + + return GL_TRUE; +} + +#define _setAGLAttribute( aglAttributeName, AGLparameter ) \ +if ( AGLparameter != 0 ) \ +{ \ + AGLpixelFormatAttributes[numAGLAttrs++] = aglAttributeName; \ + AGLpixelFormatAttributes[numAGLAttrs++] = AGLparameter; \ +} + +#define _getAGLAttribute( aglAttributeName, variableName ) \ +{ \ + GLint aglValue; \ + (void)aglDescribePixelFormat( pixelFormat, aglAttributeName, &aglValue ); \ + variableName = aglValue; \ +} + +#define _setCGLAttribute( cglAttributeName, CGLparameter ) \ +if ( CGLparameter != 0 ) \ +{ \ + CGLpixelFormatAttributes[ numCGLAttrs++ ] = cglAttributeName; \ + CGLpixelFormatAttributes[ numCGLAttrs++ ] = CGLparameter; \ +} + +#define _getCGLAttribute( cglAttributeName, variableName ) \ +{ \ + long cglValue; \ + (void)CGLDescribePixelFormat( CGLpfObj, 0, cglAttributeName, &cglValue ); \ + variableName = cglValue; \ +} + +int _glfwPlatformOpenWindow( int width, + int height, + int redbits, + int greenbits, + int bluebits, + int alphabits, + int depthbits, + int stencilbits, + int mode, + _GLFWhints* hints ) +{ + OSStatus error; + ProcessSerialNumber psn; + + unsigned int windowAttributes; + + // TO DO: Refactor this function! + _glfwWin.WindowFunctions = ( _glfwWin.Fullscreen ? + &_glfwMacFSWindowFunctions : + &_glfwMacDWWindowFunctions ); + + // Windowed or fullscreen; AGL or CGL? Quite the mess... + // AGL appears to be the only choice for attaching OpenGL contexts to + // Carbon windows, but it leaves the user no control over fullscreen + // mode stretching. Solution: AGL for windowed, CGL for fullscreen. + if( !_glfwWin.Fullscreen ) + { + // create AGL pixel format attribute list + GLint AGLpixelFormatAttributes[256]; + int numAGLAttrs = 0; + + AGLpixelFormatAttributes[numAGLAttrs++] = AGL_RGBA; + AGLpixelFormatAttributes[numAGLAttrs++] = AGL_DOUBLEBUFFER; + + if( hints->Stereo ) + { + AGLpixelFormatAttributes[numAGLAttrs++] = AGL_STEREO; + } + + _setAGLAttribute( AGL_AUX_BUFFERS, hints->AuxBuffers); + _setAGLAttribute( AGL_RED_SIZE, redbits ); + _setAGLAttribute( AGL_GREEN_SIZE, greenbits ); + _setAGLAttribute( AGL_BLUE_SIZE, bluebits ); + _setAGLAttribute( AGL_ALPHA_SIZE, alphabits ); + _setAGLAttribute( AGL_DEPTH_SIZE, depthbits ); + _setAGLAttribute( AGL_STENCIL_SIZE, stencilbits ); + _setAGLAttribute( AGL_ACCUM_RED_SIZE, hints->AccumRedBits ); + _setAGLAttribute( AGL_ACCUM_GREEN_SIZE, hints->AccumGreenBits ); + _setAGLAttribute( AGL_ACCUM_BLUE_SIZE, hints->AccumBlueBits ); + _setAGLAttribute( AGL_ACCUM_ALPHA_SIZE, hints->AccumAlphaBits ); + + if( hints->Samples > 1 ) + { + _setAGLAttribute( AGL_SAMPLE_BUFFERS_ARB, 1 ); + _setAGLAttribute( AGL_SAMPLES_ARB, hints->Samples ); + AGLpixelFormatAttributes[numAGLAttrs++] = AGL_NO_RECOVERY; + } + + AGLpixelFormatAttributes[numAGLAttrs++] = AGL_NONE; + + // create pixel format descriptor + AGLDevice mainMonitor = GetMainDevice(); + AGLPixelFormat pixelFormat = aglChoosePixelFormat( &mainMonitor, + 1, + AGLpixelFormatAttributes ); + if( pixelFormat == NULL ) + { + fprintf( stderr, "glfwOpenWindow failing because it can't create a pixel format\n" ); + return GL_FALSE; + } + + // store pixel format's values for _glfwPlatformGetWindowParam's use + _getAGLAttribute( AGL_ACCELERATED, _glfwWin.Accelerated ); + _getAGLAttribute( AGL_RED_SIZE, _glfwWin.RedBits ); + _getAGLAttribute( AGL_GREEN_SIZE, _glfwWin.GreenBits ); + _getAGLAttribute( AGL_BLUE_SIZE, _glfwWin.BlueBits ); + _getAGLAttribute( AGL_ALPHA_SIZE, _glfwWin.AlphaBits ); + _getAGLAttribute( AGL_DEPTH_SIZE, _glfwWin.DepthBits ); + _getAGLAttribute( AGL_STENCIL_SIZE, _glfwWin.StencilBits ); + _getAGLAttribute( AGL_ACCUM_RED_SIZE, _glfwWin.AccumRedBits ); + _getAGLAttribute( AGL_ACCUM_GREEN_SIZE, _glfwWin.AccumGreenBits ); + _getAGLAttribute( AGL_ACCUM_BLUE_SIZE, _glfwWin.AccumBlueBits ); + _getAGLAttribute( AGL_ACCUM_ALPHA_SIZE, _glfwWin.AccumAlphaBits ); + _getAGLAttribute( AGL_AUX_BUFFERS, _glfwWin.AuxBuffers ); + _getAGLAttribute( AGL_STEREO, _glfwWin.Stereo ); + _getAGLAttribute( AGL_SAMPLES_ARB, _glfwWin.Samples ); + _glfwWin.RefreshRate = hints->RefreshRate; + + // create AGL context + _glfwWin.AGLContext = aglCreateContext( pixelFormat, NULL ); + + aglDestroyPixelFormat( pixelFormat ); + + if( _glfwWin.AGLContext == NULL ) + { + fprintf( stderr, "glfwOpenWindow failing because it can't create an OpenGL context\n" ); + _glfwPlatformCloseWindow(); + return GL_FALSE; + } + + if (_glfwLibrary.Unbundled) + { + if( GetCurrentProcess( &psn ) != noErr ) + { + fprintf( stderr, "glfwOpenWindow failing because it can't get its PSN\n" ); + _glfwPlatformCloseWindow(); + return GL_FALSE; + } + + if( TransformProcessType( &psn, kProcessTransformToForegroundApplication ) != noErr ) + { + fprintf( stderr, "glfwOpenWindow failing because it can't become a foreground application\n" ); + _glfwPlatformCloseWindow(); + return GL_FALSE; + } + + /* Keith Bauer 2007-07-12 - I don't believe this is desirable + if( SetFrontProcess( &psn ) != noErr ) + { + fprintf( stderr, "glfwOpenWindow failing because it can't become the front process\n" ); + _glfwPlatformCloseWindow(); + return GL_FALSE; + } + */ + } + + // create window + Rect windowContentBounds; + windowContentBounds.left = 0; + windowContentBounds.top = 0; + windowContentBounds.right = width; + windowContentBounds.bottom = height; + + windowAttributes = ( kWindowCloseBoxAttribute \ + | kWindowCollapseBoxAttribute \ + | kWindowStandardHandlerAttribute ); + + if( hints->WindowNoResize ) + { + windowAttributes |= kWindowLiveResizeAttribute; + } + else + { + windowAttributes |= ( kWindowFullZoomAttribute | kWindowResizableAttribute ); + } + + error = CreateNewWindow( kDocumentWindowClass, + windowAttributes, + &windowContentBounds, + &( _glfwWin.MacWindow ) ); + if( ( error != noErr ) || ( _glfwWin.MacWindow == NULL ) ) + { + fprintf( stderr, "glfwOpenWindow failing because it can't create a window\n" ); + _glfwPlatformCloseWindow(); + return GL_FALSE; + } + + _glfwWin.WindowUPP = NewEventHandlerUPP( _glfwWindowEventHandler ); + + error = InstallWindowEventHandler( _glfwWin.MacWindow, + _glfwWin.WindowUPP, + GetEventTypeCount( GLFW_WINDOW_EVENT_TYPES ), + GLFW_WINDOW_EVENT_TYPES, + NULL, + NULL ); + if( error != noErr ) + { + fprintf( stderr, "glfwOpenWindow failing because it can't install window event handlers\n" ); + _glfwPlatformCloseWindow(); + return GL_FALSE; + } + + // Don't care if we fail here + (void)SetWindowTitleWithCFString( _glfwWin.MacWindow, CFSTR( "GLFW Window" ) ); + (void)RepositionWindow( _glfwWin.MacWindow, + NULL, + kWindowCenterOnMainScreen ); + + if( !aglSetDrawable( _glfwWin.AGLContext, + GetWindowPort( _glfwWin.MacWindow ) ) ) + { + fprintf( stderr, "glfwOpenWindow failing because it can't draw to the window\n" ); + _glfwPlatformCloseWindow(); + return GL_FALSE; + } + + // Make OpenGL context current + if( !aglSetCurrentContext( _glfwWin.AGLContext ) ) + { + fprintf( stderr, "glfwOpenWindow failing because it can't make the OpenGL context current\n" ); + _glfwPlatformCloseWindow(); + return GL_FALSE; + } + + // show window + ShowWindow( _glfwWin.MacWindow ); + + return GL_TRUE; + } + else + { + CGDisplayErr cgErr; + CGLError cglErr; + + CFDictionaryRef optimalMode; + + CGLPixelFormatObj CGLpfObj; + long numCGLvs = 0; + + CGLPixelFormatAttribute CGLpixelFormatAttributes[64]; + int numCGLAttrs = 0; + + // variables for enumerating color depths + long rgbColorDepth; + long rgbaAccumDepth = 0; + int rgbChannelDepth = 0; + + // CGL pixel format attributes + _setCGLAttribute( kCGLPFADisplayMask, + CGDisplayIDToOpenGLDisplayMask( kCGDirectMainDisplay ) ); + + if( hints->Stereo ) + { + CGLpixelFormatAttributes[ numCGLAttrs++ ] = kCGLPFAStereo; + } + + if( hints->Samples > 1 ) + { + _setCGLAttribute( kCGLPFASamples, (CGLPixelFormatAttribute)hints->Samples ); + _setCGLAttribute( kCGLPFASampleBuffers, (CGLPixelFormatAttribute)1 ); + CGLpixelFormatAttributes[ numCGLAttrs++ ] = kCGLPFANoRecovery; + } + + CGLpixelFormatAttributes[ numCGLAttrs++ ] = kCGLPFAFullScreen; + CGLpixelFormatAttributes[ numCGLAttrs++ ] = kCGLPFADoubleBuffer; + CGLpixelFormatAttributes[ numCGLAttrs++ ] = kCGLPFAAccelerated; + CGLpixelFormatAttributes[ numCGLAttrs++ ] = kCGLPFANoRecovery; + CGLpixelFormatAttributes[ numCGLAttrs++ ] = kCGLPFAMinimumPolicy; + + _setCGLAttribute( kCGLPFAAccumSize, + (CGLPixelFormatAttribute)( hints->AccumRedBits \ + + hints->AccumGreenBits \ + + hints->AccumBlueBits \ + + hints->AccumAlphaBits ) ); + + _setCGLAttribute( kCGLPFAAlphaSize, (CGLPixelFormatAttribute)alphabits ); + _setCGLAttribute( kCGLPFADepthSize, (CGLPixelFormatAttribute)depthbits ); + _setCGLAttribute( kCGLPFAStencilSize, (CGLPixelFormatAttribute)stencilbits ); + _setCGLAttribute( kCGLPFAAuxBuffers, (CGLPixelFormatAttribute)hints->AuxBuffers ); + + CGLpixelFormatAttributes[ numCGLAttrs++ ] = (CGLPixelFormatAttribute)NULL; + + // create a suitable pixel format with above attributes.. + cglErr = CGLChoosePixelFormat( CGLpixelFormatAttributes, + &CGLpfObj, + &numCGLvs ); + if( cglErr != kCGLNoError ) + { + return GL_FALSE; + } + + // ..and create a rendering context using that pixel format + cglErr = CGLCreateContext( CGLpfObj, NULL, &_glfwWin.CGLContext ); + if( cglErr != kCGLNoError ) + { + return GL_FALSE; + } + + // enumerate depth of RGB channels - unlike AGL, CGL works with + // a single parameter reflecting the full depth of the frame buffer + (void)CGLDescribePixelFormat( CGLpfObj, 0, kCGLPFAColorSize, &rgbColorDepth ); + if( rgbColorDepth == 24 || rgbColorDepth == 32 ) + { + rgbChannelDepth = 8; + } + if( rgbColorDepth == 16 ) + { + rgbChannelDepth = 5; + } + + // get pixel depth of accumulator - I haven't got the slightest idea + // how this number conforms to any other channel depth than 8 bits, + // so this might end up giving completely knackered results... + (void)CGLDescribePixelFormat( CGLpfObj, 0, kCGLPFAAccumSize, &rgbaAccumDepth ); + if( rgbaAccumDepth == 32 ) + { + rgbaAccumDepth = 8; + } + + // store values of pixel format for _glfwPlatformGetWindowParam's use + _getCGLAttribute( kCGLPFAAccelerated, _glfwWin.Accelerated ); + _getCGLAttribute( rgbChannelDepth, _glfwWin.RedBits ); + _getCGLAttribute( rgbChannelDepth, _glfwWin.GreenBits ); + _getCGLAttribute( rgbChannelDepth, _glfwWin.BlueBits ); + _getCGLAttribute( kCGLPFAAlphaSize, _glfwWin.AlphaBits ); + _getCGLAttribute( kCGLPFADepthSize, _glfwWin.DepthBits ); + _getCGLAttribute( kCGLPFAStencilSize, _glfwWin.StencilBits ); + _getCGLAttribute( rgbaAccumDepth, _glfwWin.AccumRedBits ); + _getCGLAttribute( rgbaAccumDepth, _glfwWin.AccumGreenBits ); + _getCGLAttribute( rgbaAccumDepth, _glfwWin.AccumBlueBits ); + _getCGLAttribute( rgbaAccumDepth, _glfwWin.AccumAlphaBits ); + _getCGLAttribute( kCGLPFAAuxBuffers, _glfwWin.AuxBuffers ); + _getCGLAttribute( kCGLPFAStereo, _glfwWin.Stereo ); + _glfwWin.RefreshRate = hints->RefreshRate; + + // destroy our pixel format + (void)CGLDestroyPixelFormat( CGLpfObj ); + + // capture the display for our application + cgErr = CGCaptureAllDisplays(); + if( cgErr != kCGErrorSuccess ) + { + return GL_FALSE; + } + + // find closest matching NON-STRETCHED display mode.. + optimalMode = CGDisplayBestModeForParametersAndRefreshRateWithProperty( kCGDirectMainDisplay, + rgbColorDepth, + width, + /* Check further to the right -> */ height, + hints->RefreshRate, + NULL, + NULL ); + if( optimalMode == NULL ) + { + return GL_FALSE; + } + + // ..and switch to that mode + cgErr = CGDisplaySwitchToMode( kCGDirectMainDisplay, optimalMode ); + if( cgErr != kCGErrorSuccess ) + { + return GL_FALSE; + } + + // switch to our OpenGL context, and bring it up fullscreen + cglErr = CGLSetCurrentContext( _glfwWin.CGLContext ); + if( cglErr != kCGLNoError ) + { + return GL_FALSE; + } + + cglErr = CGLSetFullScreen( _glfwWin.CGLContext ); + if( cglErr != kCGLNoError ) + { + return GL_FALSE; + } + + return GL_TRUE; + } +} + +void _glfwPlatformCloseWindow( void ) +{ + if( _glfwWin.WindowFunctions != NULL ) + { + if( _glfwWin.WindowUPP != NULL ) + { + DisposeEventHandlerUPP( _glfwWin.WindowUPP ); + _glfwWin.WindowUPP = NULL; + } + + _glfwWin.WindowFunctions->CloseWindow(); + + if( !_glfwWin.Fullscreen && _glfwWin.AGLContext != NULL ) + { + aglSetCurrentContext( NULL ); + aglSetDrawable( _glfwWin.AGLContext, NULL ); + aglDestroyContext( _glfwWin.AGLContext ); + _glfwWin.AGLContext = NULL; + } + + if( _glfwWin.Fullscreen && _glfwWin.CGLContext != NULL ) + { + CGLSetCurrentContext( NULL ); + CGLClearDrawable( _glfwWin.CGLContext ); + CGLDestroyContext( _glfwWin.CGLContext ); + CGReleaseAllDisplays(); + _glfwWin.CGLContext = NULL; + } + + if( _glfwWin.MacWindow != NULL ) + { + ReleaseWindow( _glfwWin.MacWindow ); + _glfwWin.MacWindow = NULL; + } + + _glfwWin.WindowFunctions = NULL; + } +} + +void _glfwPlatformSetWindowTitle( const char *title ) +{ + _glfwWin.WindowFunctions->SetWindowTitle( title ); +} + +void _glfwPlatformSetWindowSize( int width, int height ) +{ + _glfwWin.WindowFunctions->SetWindowSize( width, height ); +} + +void _glfwPlatformSetWindowPos( int x, int y ) +{ + _glfwWin.WindowFunctions->SetWindowPos( x, y ); +} + +void _glfwPlatformIconifyWindow( void ) +{ + _glfwWin.WindowFunctions->IconifyWindow(); +} + +void _glfwPlatformRestoreWindow( void ) +{ + _glfwWin.WindowFunctions->RestoreWindow(); +} + +void _glfwPlatformSwapBuffers( void ) +{ + if( !_glfwWin.Fullscreen ) + { + aglSwapBuffers( _glfwWin.AGLContext ); + } + else + { + CGLFlushDrawable( _glfwWin.CGLContext ); + } +} + +void _glfwPlatformSwapInterval( int interval ) +{ + GLint AGLparameter = interval; + + // CGL doesn't seem to like intervals other than 0 (vsync off) or 1 (vsync on) + long CGLparameter = ( interval == 0 ? 0 : 1 ); + + if( !_glfwWin.Fullscreen ) + { + // Don't care if we fail here.. + (void)aglSetInteger( _glfwWin.AGLContext, + AGL_SWAP_INTERVAL, + &AGLparameter ); + } + else + { + // ..or here + (void)CGLSetParameter( _glfwWin.CGLContext, + kCGLCPSwapInterval, + &CGLparameter ); + } +} + +void _glfwPlatformRefreshWindowParams( void ) +{ + _glfwWin.WindowFunctions->RefreshWindowParams(); +} + +int _glfwPlatformGetWindowParam( int param ) +{ + switch ( param ) + { + case GLFW_ACCELERATED: return _glfwWin.Accelerated; break; + case GLFW_RED_BITS: return _glfwWin.RedBits; break; + case GLFW_GREEN_BITS: return _glfwWin.GreenBits; break; + case GLFW_BLUE_BITS: return _glfwWin.BlueBits; break; + case GLFW_ALPHA_BITS: return _glfwWin.AlphaBits; break; + case GLFW_DEPTH_BITS: return _glfwWin.DepthBits; break; + case GLFW_STENCIL_BITS: return _glfwWin.StencilBits; break; + case GLFW_ACCUM_RED_BITS: return _glfwWin.AccumRedBits; break; + case GLFW_ACCUM_GREEN_BITS: return _glfwWin.AccumGreenBits; break; + case GLFW_ACCUM_BLUE_BITS: return _glfwWin.AccumBlueBits; break; + case GLFW_ACCUM_ALPHA_BITS: return _glfwWin.AccumAlphaBits; break; + case GLFW_AUX_BUFFERS: return _glfwWin.AuxBuffers; break; + case GLFW_STEREO: return _glfwWin.Stereo; break; + case GLFW_REFRESH_RATE: return _glfwWin.RefreshRate; break; + default: return GL_FALSE; + } +} + +void _glfwPlatformPollEvents( void ) +{ + EventRef event; + EventTargetRef eventDispatcher = GetEventDispatcherTarget(); + + while ( ReceiveNextEvent( 0, NULL, 0.0, TRUE, &event ) == noErr ) + { + SendEventToEventTarget( event, eventDispatcher ); + ReleaseEvent( event ); + } +} + +void _glfwPlatformWaitEvents( void ) +{ + EventRef event; + + // Wait for new events + ReceiveNextEvent( 0, NULL, kEventDurationForever, FALSE, &event ); + + // Poll new events + _glfwPlatformPollEvents(); +} + +void _glfwPlatformHideMouseCursor( void ) +{ + // TO DO: What if we fail here? + CGDisplayHideCursor( kCGDirectMainDisplay ); + CGAssociateMouseAndMouseCursorPosition( false ); +} + +void _glfwPlatformShowMouseCursor( void ) +{ + // TO DO: What if we fail here? + CGDisplayShowCursor( kCGDirectMainDisplay ); + CGAssociateMouseAndMouseCursorPosition( true ); +} + +void _glfwPlatformSetMouseCursorPos( int x, int y ) +{ + _glfwWin.WindowFunctions->SetMouseCursorPos( x, y ); +} + +int _glfwMacFSOpenWindow( int width, + int height, + 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 refreshrate ) +{ + return GL_FALSE; +} + +void _glfwMacFSCloseWindow( void ) +{ + // TO DO: un-capture displays, &c. +} + +void _glfwMacFSSetWindowTitle( const char *title ) +{ + // no-op really, change "fake" mini-window title + _glfwMacDWSetWindowTitle( title ); +} + +void _glfwMacFSSetWindowSize( int width, int height ) +{ + // TO DO: something funky for full-screen + _glfwMacDWSetWindowSize( width, height ); +} + +void _glfwMacFSSetWindowPos( int x, int y ) +{ + // no-op really, change "fake" mini-window position + _glfwMacDWSetWindowPos( x, y ); +} + +void _glfwMacFSIconifyWindow( void ) +{ + // TO DO: Something funky for full-screen + _glfwMacDWIconifyWindow(); +} + +void _glfwMacFSRestoreWindow( void ) +{ + _glfwMacDWRestoreWindow(); + // TO DO: Something funky for full-screen +} + +void _glfwMacFSRefreshWindowParams( void ) +{ + // TO DO: implement this! +} + +void _glfwMacFSSetMouseCursorPos( int x, int y ) +{ + // TO DO: what if we fail here? + CGDisplayMoveCursorToPoint( kCGDirectMainDisplay, + CGPointMake( x, y ) ); +} + +int _glfwMacDWOpenWindow( int width, + int height, + 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 refreshrate ) +{ + return GL_FALSE; +} + +void _glfwMacDWCloseWindow( void ) +{ +} + +void _glfwMacDWSetWindowTitle( const char *title ) +{ + CFStringRef windowTitle = CFStringCreateWithCString( kCFAllocatorDefault, + title, + kCFStringEncodingISOLatin1 ); + + // Don't care if we fail + (void)SetWindowTitleWithCFString( _glfwWin.MacWindow, windowTitle ); + + CFRelease( windowTitle ); +} + +void _glfwMacDWSetWindowSize( int width, int height ) +{ + SizeWindow( _glfwWin.MacWindow, + width, + height, + TRUE ); +} + +void _glfwMacDWSetWindowPos( int x, int y ) +{ + // TO DO: take main monitor bounds into account + MoveWindow( _glfwWin.MacWindow, + x, + y, + FALSE ); +} + +void _glfwMacDWIconifyWindow( void ) +{ + // TO DO: What if we fail here? + (void)CollapseWindow( _glfwWin.MacWindow, + TRUE ); +} + +void _glfwMacDWRestoreWindow( void ) +{ + // TO DO: What if we fail here? + (void)CollapseWindow( _glfwWin.MacWindow, + FALSE ); +} + +void _glfwMacDWRefreshWindowParams( void ) +{ + // TO DO: implement this! +} + +void _glfwMacDWSetMouseCursorPos( int x, int y ) +{ + Rect content; + GetWindowBounds(_glfwWin.MacWindow, kWindowContentRgn, &content); + + _glfwInput.MousePosX = x + content.left; + _glfwInput.MousePosY = y + content.top; + + CGDisplayMoveCursorToPoint( kCGDirectMainDisplay, + CGPointMake( _glfwInput.MousePosX, + _glfwInput.MousePosY ) ); +} + diff --git a/src/engine/external/glfw/lib/macosx/platform.h b/src/engine/external/glfw/lib/macosx/platform.h new file mode 100644 index 00000000..6f90df88 --- /dev/null +++ b/src/engine/external/glfw/lib/macosx/platform.h @@ -0,0 +1,349 @@ +//======================================================================== +// GLFW - An OpenGL framework +// File: platform.h +// Platform: Mac OS X +// API Version: 2.6 +// 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. +// +//======================================================================== + +#ifndef _platform_h_ +#define _platform_h_ + + +// This is the Mac OS X version of GLFW +#define _GLFW_MAC_OS_X + + +// Include files +#include <Carbon/Carbon.h> +#include <OpenGL/OpenGL.h> +#include <AGL/agl.h> +#include <sched.h> +#include <pthread.h> +#include <sys/sysctl.h> +#include "../../include/GL/glfw.h" + + +//======================================================================== +// Defines +//======================================================================== + +#define _GLFW_MAX_PATH_LENGTH (8192) + +#define MAC_KEY_ENTER 0x24 +#define MAC_KEY_RETURN 0x34 +#define MAC_KEY_ESC 0x35 +#define MAC_KEY_F1 0x7A +#define MAC_KEY_F2 0x78 +#define MAC_KEY_F3 0x63 +#define MAC_KEY_F4 0x76 +#define MAC_KEY_F5 0x60 +#define MAC_KEY_F6 0x61 +#define MAC_KEY_F7 0x62 +#define MAC_KEY_F8 0x64 +#define MAC_KEY_F9 0x65 +#define MAC_KEY_F10 0x6D +#define MAC_KEY_F11 0x67 +#define MAC_KEY_F12 0x6F +#define MAC_KEY_F13 0x69 +#define MAC_KEY_F14 0x6B +#define MAC_KEY_F15 0x71 +#define MAC_KEY_UP 0x7E +#define MAC_KEY_DOWN 0x7D +#define MAC_KEY_LEFT 0x7B +#define MAC_KEY_RIGHT 0x7C +#define MAC_KEY_TAB 0x30 +#define MAC_KEY_BACKSPACE 0x33 +#define MAC_KEY_HELP 0x72 +#define MAC_KEY_DEL 0x75 +#define MAC_KEY_PAGEUP 0x74 +#define MAC_KEY_PAGEDOWN 0x79 +#define MAC_KEY_HOME 0x73 +#define MAC_KEY_END 0x77 +#define MAC_KEY_KP_0 0x52 +#define MAC_KEY_KP_1 0x53 +#define MAC_KEY_KP_2 0x54 +#define MAC_KEY_KP_3 0x55 +#define MAC_KEY_KP_4 0x56 +#define MAC_KEY_KP_5 0x57 +#define MAC_KEY_KP_6 0x58 +#define MAC_KEY_KP_7 0x59 +#define MAC_KEY_KP_8 0x5B +#define MAC_KEY_KP_9 0x5C +#define MAC_KEY_KP_DIVIDE 0x4B +#define MAC_KEY_KP_MULTIPLY 0x43 +#define MAC_KEY_KP_SUBTRACT 0x4E +#define MAC_KEY_KP_ADD 0x45 +#define MAC_KEY_KP_DECIMAL 0x41 +#define MAC_KEY_KP_EQUAL 0x51 +#define MAC_KEY_KP_ENTER 0x4C + +//======================================================================== +// full-screen/desktop-window "virtual" function table +//======================================================================== + +typedef int ( * GLFWmacopenwindowfun )( int, int, int, int, int, int, int, int, int, int, int, int, int, int, int ); +typedef void ( * GLFWmacclosewindowfun )( void ); +typedef void ( * GLFWmacsetwindowtitlefun )( const char * ); +typedef void ( * GLFWmacsetwindowsizefun )( int, int ); +typedef void ( * GLFWmacsetwindowposfun )( int, int ); +typedef void ( * GLFWmaciconifywindowfun )( void ); +typedef void ( * GLFWmacrestorewindowfun )( void ); +typedef void ( * GLFWmacrefreshwindowparamsfun )( void ); +typedef void ( * GLFWmacsetmousecursorposfun )( int, int ); + +typedef struct +{ + GLFWmacopenwindowfun OpenWindow; + GLFWmacclosewindowfun CloseWindow; + GLFWmacsetwindowtitlefun SetWindowTitle; + GLFWmacsetwindowsizefun SetWindowSize; + GLFWmacsetwindowposfun SetWindowPos; + GLFWmaciconifywindowfun IconifyWindow; + GLFWmacrestorewindowfun RestoreWindow; + GLFWmacrefreshwindowparamsfun RefreshWindowParams; + GLFWmacsetmousecursorposfun SetMouseCursorPos; +} +_GLFWmacwindowfunctions; + + +//======================================================================== +// Global variables (GLFW internals) +//======================================================================== + +GLFWGLOBAL CFDictionaryRef _glfwDesktopVideoMode; + +//------------------------------------------------------------------------ +// Window structure +//------------------------------------------------------------------------ +typedef struct _GLFWwin_struct _GLFWwin; + +struct _GLFWwin_struct { + + // ========= PLATFORM INDEPENDENT MANDATORY PART ========================= + + // Window states + int Opened; // Flag telling if window is opened or not + int Active; // Application active flag + int Iconified; // Window iconified flag + + // 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 AutoPollEvents; // Auto polling flag + int SysKeysDisabled; // System keys disabled flag + int RefreshRate; // Refresh rate (for fullscreen mode) + int WindowNoResize; // Resize- and maximize gadgets disabled flag + int Samples; + + // Window status + int Width, Height; // Window width and heigth + + // Extensions & OpenGL version + int Has_GL_SGIS_generate_mipmap; + int Has_GL_ARB_texture_non_power_of_two; + int GLVerMajor,GLVerMinor; + + + // ========= PLATFORM SPECIFIC PART ====================================== + + WindowRef MacWindow; + AGLContext AGLContext; + CGLContextObj CGLContext; + + EventHandlerUPP MouseUPP; + EventHandlerUPP CommandUPP; + EventHandlerUPP KeyboardUPP; + EventHandlerUPP WindowUPP; + + _GLFWmacwindowfunctions* WindowFunctions; + + // for easy access by _glfwPlatformGetWindowParam + int Accelerated; + int RedBits, GreenBits, BlueBits, AlphaBits; + int DepthBits; + int StencilBits; + int AccumRedBits, AccumGreenBits, AccumBlueBits, AccumAlphaBits; + int AuxBuffers; + int Stereo; +}; + +GLFWGLOBAL _GLFWwin _glfwWin; + + +//------------------------------------------------------------------------ +// 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 ====================================== + + UInt32 Modifiers; + +} _glfwInput; + + + + +//------------------------------------------------------------------------ +// Thread information +//------------------------------------------------------------------------ +typedef struct _GLFWthread_struct _GLFWthread; + +// Thread record (one for each thread) +struct _GLFWthread_struct { + // Pointer to previous and next threads in linked list + _GLFWthread *Previous, *Next; + + // GLFW user side thread information + GLFWthread ID; + GLFWthreadfun Function; + + // System side thread information + pthread_t PosixID; +}; + +// General thread information +GLFWGLOBAL struct { + // Critical section lock + pthread_mutex_t CriticalSection; + + // Next thread ID to use (increments for every created thread) + GLFWthread NextID; + + // First thread in linked list (always the main thread) + _GLFWthread First; +} _glfwThrd; + + +//------------------------------------------------------------------------ +// Library global data +//------------------------------------------------------------------------ +GLFWGLOBAL struct { + + // Timer data + struct { + double t0; + } Timer; + + struct { + // Bundle for dynamically-loading extension function pointers + CFBundleRef OpenGLFramework; + } Libs; + + int Unbundled; + +} _glfwLibrary; + + + +//======================================================================== +// Macros for encapsulating critical code sections (i.e. making parts +// of GLFW thread safe) +//======================================================================== + +// Define so we can use the same thread code as X11 +#define _glfw_numprocessors(n) { \ + int mib[2], ncpu; \ + size_t len = 1; \ + mib[0] = CTL_HW; \ + mib[1] = HW_NCPU; \ + n = 1; \ + if( sysctl( mib, 2, &ncpu, &len, NULL, 0 ) != -1 ) \ + { \ + if( len > 0 ) \ + { \ + n = ncpu; \ + } \ + } \ +} + +// Thread list management +#define ENTER_THREAD_CRITICAL_SECTION \ +pthread_mutex_lock( &_glfwThrd.CriticalSection ); +#define LEAVE_THREAD_CRITICAL_SECTION \ +pthread_mutex_unlock( &_glfwThrd.CriticalSection ); + + +//======================================================================== +// Prototypes for platform specific internal functions +//======================================================================== + +void _glfwChangeToResourcesDirectory( void ); + +int _glfwInstallEventHandlers( void ); + +//======================================================================== +// Prototypes for full-screen/desktop-window "virtual" functions +//======================================================================== + +int _glfwMacFSOpenWindow( int width, int height, 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 refreshrate ); +void _glfwMacFSCloseWindow( void ); +void _glfwMacFSSetWindowTitle( const char *title ); +void _glfwMacFSSetWindowSize( int width, int height ); +void _glfwMacFSSetWindowPos( int x, int y ); +void _glfwMacFSIconifyWindow( void ); +void _glfwMacFSRestoreWindow( void ); +void _glfwMacFSRefreshWindowParams( void ); +void _glfwMacFSSetMouseCursorPos( int x, int y ); + +int _glfwMacDWOpenWindow( int width, int height, 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 refreshrate ); +void _glfwMacDWCloseWindow( void ); +void _glfwMacDWSetWindowTitle( const char *title ); +void _glfwMacDWSetWindowSize( int width, int height ); +void _glfwMacDWSetWindowPos( int x, int y ); +void _glfwMacDWIconifyWindow( void ); +void _glfwMacDWRestoreWindow( void ); +void _glfwMacDWRefreshWindowParams( void ); +void _glfwMacDWSetMouseCursorPos( int x, int y ); + +#endif // _platform_h_ |