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 | |
| 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')
46 files changed, 15611 insertions, 0 deletions
diff --git a/src/engine/external/glfw/lib/enable.c b/src/engine/external/glfw/lib/enable.c new file mode 100644 index 00000000..6231a1f9 --- /dev/null +++ b/src/engine/external/glfw/lib/enable.c @@ -0,0 +1,295 @@ +//======================================================================== +// GLFW - An OpenGL framework +// File: enable.c +// Platform: Any +// 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 **** +//************************************************************************ + +//======================================================================== +// Enable (show) mouse cursor +//======================================================================== + +static void _glfwEnableMouseCursor( void ) +{ + int CenterPosX, CenterPosY; + + if( !_glfwWin.Opened || !_glfwWin.MouseLock ) + { + return; + } + + // Show mouse cursor + _glfwPlatformShowMouseCursor(); + + CenterPosX = _glfwWin.Width / 2; + CenterPosY = _glfwWin.Height / 2; + + if( CenterPosX != _glfwInput.MousePosX || CenterPosY != _glfwInput.MousePosY ) + { + _glfwPlatformSetMouseCursorPos( CenterPosX, CenterPosY ); + + _glfwInput.MousePosX = CenterPosX; + _glfwInput.MousePosY = CenterPosY; + + if( _glfwWin.MousePosCallback ) + { + _glfwWin.MousePosCallback( _glfwInput.MousePosX, + _glfwInput.MousePosY ); + } + } + + // From now on the mouse is unlocked + _glfwWin.MouseLock = GL_FALSE; +} + +//======================================================================== +// Disable (hide) mouse cursor +//======================================================================== + +static void _glfwDisableMouseCursor( void ) +{ + if( !_glfwWin.Opened || _glfwWin.MouseLock ) + { + return; + } + + // Hide mouse cursor + _glfwPlatformHideMouseCursor(); + + // Move cursor to the middle of the window + _glfwPlatformSetMouseCursorPos( _glfwWin.Width>>1, + _glfwWin.Height>>1 ); + + // From now on the mouse is locked + _glfwWin.MouseLock = GL_TRUE; +} + + +//======================================================================== +// _glfwEnableStickyKeys() - Enable sticky keys +// _glfwDisableStickyKeys() - Disable sticky keys +//======================================================================== + +static void _glfwEnableStickyKeys( void ) +{ + _glfwInput.StickyKeys = 1; +} + +static void _glfwDisableStickyKeys( void ) +{ + int i; + + _glfwInput.StickyKeys = 0; + + // Release all sticky keys + for( i = 0; i <= GLFW_KEY_LAST; i ++ ) + { + if( _glfwInput.Key[ i ] == 2 ) + { + _glfwInput.Key[ i ] = 0; + } + } +} + + +//======================================================================== +// _glfwEnableStickyMouseButtons() - Enable sticky mouse buttons +// _glfwDisableStickyMouseButtons() - Disable sticky mouse buttons +//======================================================================== + +static void _glfwEnableStickyMouseButtons( void ) +{ + _glfwInput.StickyMouseButtons = 1; +} + +static void _glfwDisableStickyMouseButtons( void ) +{ + int i; + + _glfwInput.StickyMouseButtons = 0; + + // Release all sticky mouse buttons + for( i = 0; i <= GLFW_MOUSE_BUTTON_LAST; i ++ ) + { + if( _glfwInput.MouseButton[ i ] == 2 ) + { + _glfwInput.MouseButton[ i ] = 0; + } + } +} + + +//======================================================================== +// _glfwEnableSystemKeys() - Enable system keys +// _glfwDisableSystemKeys() - Disable system keys +//======================================================================== + +static void _glfwEnableSystemKeys( void ) +{ + if( !_glfwWin.SysKeysDisabled ) + { + return; + } + + _glfwPlatformEnableSystemKeys(); + + // Indicate that system keys are no longer disabled + _glfwWin.SysKeysDisabled = GL_FALSE; +} + +static void _glfwDisableSystemKeys( void ) +{ + if( _glfwWin.SysKeysDisabled ) + { + return; + } + + _glfwPlatformDisableSystemKeys(); + + // Indicate that system keys are now disabled + _glfwWin.SysKeysDisabled = GL_TRUE; +} + + +//======================================================================== +// _glfwEnableKeyRepeat() - Enable key repeat +// _glfwDisableKeyRepeat() - Disable key repeat +//======================================================================== + +static void _glfwEnableKeyRepeat( void ) +{ + _glfwInput.KeyRepeat = 1; +} + +static void _glfwDisableKeyRepeat( void ) +{ + _glfwInput.KeyRepeat = 0; +} + + +//======================================================================== +// _glfwEnableAutoPollEvents() - Enable automatic event polling +// _glfwDisableAutoPollEvents() - Disable automatic event polling +//======================================================================== + +static void _glfwEnableAutoPollEvents( void ) +{ + _glfwWin.AutoPollEvents = 1; +} + +static void _glfwDisableAutoPollEvents( void ) +{ + _glfwWin.AutoPollEvents = 0; +} + + + +//************************************************************************ +//**** GLFW user functions **** +//************************************************************************ + +//======================================================================== +// glfwEnable() - Enable certain GLFW/window/system functions. +//======================================================================== + +GLFWAPI void GLFWAPIENTRY glfwEnable( int token ) +{ + // Is GLFW initialized? + if( !_glfwInitialized ) + { + return; + } + + switch( token ) + { + case GLFW_MOUSE_CURSOR: + _glfwEnableMouseCursor(); + break; + case GLFW_STICKY_KEYS: + _glfwEnableStickyKeys(); + break; + case GLFW_STICKY_MOUSE_BUTTONS: + _glfwEnableStickyMouseButtons(); + break; + case GLFW_SYSTEM_KEYS: + _glfwEnableSystemKeys(); + break; + case GLFW_KEY_REPEAT: + _glfwEnableKeyRepeat(); + break; + case GLFW_AUTO_POLL_EVENTS: + _glfwEnableAutoPollEvents(); + break; + default: + break; + } +} + + +//======================================================================== +// glfwDisable() - Disable certain GLFW/window/system functions. +//======================================================================== + +GLFWAPI void GLFWAPIENTRY glfwDisable( int token ) +{ + // Is GLFW initialized? + if( !_glfwInitialized ) + { + return; + } + + switch( token ) + { + case GLFW_MOUSE_CURSOR: + _glfwDisableMouseCursor(); + break; + case GLFW_STICKY_KEYS: + _glfwDisableStickyKeys(); + break; + case GLFW_STICKY_MOUSE_BUTTONS: + _glfwDisableStickyMouseButtons(); + break; + case GLFW_SYSTEM_KEYS: + _glfwDisableSystemKeys(); + break; + case GLFW_KEY_REPEAT: + _glfwDisableKeyRepeat(); + break; + case GLFW_AUTO_POLL_EVENTS: + _glfwDisableAutoPollEvents(); + break; + default: + break; + } +} + diff --git a/src/engine/external/glfw/lib/fullscreen.c b/src/engine/external/glfw/lib/fullscreen.c new file mode 100644 index 00000000..e9f09cc6 --- /dev/null +++ b/src/engine/external/glfw/lib/fullscreen.c @@ -0,0 +1,95 @@ +//======================================================================== +// GLFW - An OpenGL framework +// File: fullscreen.c +// Platform: Any +// 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 user functions **** +//************************************************************************ + +//======================================================================== +// glfwGetVideoModes() - Get a list of available video modes +//======================================================================== + +GLFWAPI int GLFWAPIENTRY glfwGetVideoModes( GLFWvidmode *list, + int maxcount ) +{ + int count, i, swap, res1, res2, depth1, depth2; + GLFWvidmode vm; + + if( !_glfwInitialized || maxcount <= 0 || list == (GLFWvidmode*) 0 ) + { + return 0; + } + + // Get list of video modes + count = _glfwPlatformGetVideoModes( list, maxcount ); + + // Sort list (bubble sort) + do + { + swap = 0; + for( i = 0; i < count-1; ++ i ) + { + res1 = list[i].Width*list[i].Height; + depth1 = list[i].RedBits+list[i].GreenBits+list[i].BlueBits; + res2 = list[i+1].Width*list[i+1].Height; + depth2 = list[i+1].RedBits+list[i+1].GreenBits+ + list[i+1].BlueBits; + if( (depth2<depth1) || ((depth2==depth1) && (res2<res1)) ) + { + vm = list[i]; + list[i] = list[i+1]; + list[i+1] = vm; + swap = 1; + } + } + } + while( swap ); + + return count; +} + + +//======================================================================== +// glfwGetDesktopMode() - Get the desktop video mode +//======================================================================== + +GLFWAPI void GLFWAPIENTRY glfwGetDesktopMode( GLFWvidmode *mode ) +{ + if( !_glfwInitialized || mode == (GLFWvidmode*) 0 ) + { + return; + } + + _glfwPlatformGetDesktopMode( mode ); +} + diff --git a/src/engine/external/glfw/lib/glext.c b/src/engine/external/glfw/lib/glext.c new file mode 100644 index 00000000..fda56fa2 --- /dev/null +++ b/src/engine/external/glfw/lib/glext.c @@ -0,0 +1,201 @@ +//======================================================================== +// GLFW - An OpenGL framework +// File: glext.c +// Platform: Any +// 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 **** +//************************************************************************ + +//======================================================================== +// _glfwStringInExtensionString() - Check if a string can be found in an +// OpenGL extension string +//======================================================================== + +int _glfwStringInExtensionString( const char *string, + const GLubyte *extensions ) +{ + const GLubyte *start; + GLubyte *where, *terminator; + + // It takes a bit of care to be fool-proof about parsing the + // OpenGL extensions string. Don't be fooled by sub-strings, + // etc. + start = extensions; + while( 1 ) + { + where = (GLubyte *) strstr( (const char *) start, string ); + if( !where ) + { + return GL_FALSE; + } + terminator = where + strlen( string ); + if( where == start || *(where - 1) == ' ' ) + { + if( *terminator == ' ' || *terminator == '\0' ) + { + break; + } + } + start = terminator; + } + + return GL_TRUE; +} + + + +//************************************************************************ +//**** GLFW user functions **** +//************************************************************************ + +//======================================================================== +// glfwExtensionSupported() - Check if an OpenGL extension is available +// at runtime +//======================================================================== + +GLFWAPI int GLFWAPIENTRY glfwExtensionSupported( const char *extension ) +{ + const GLubyte *extensions; + GLubyte *where; + + // Is GLFW initialized? + if( !_glfwInitialized || !_glfwWin.Opened ) + { + return GL_FALSE; + } + + // Extension names should not have spaces + where = (GLubyte *) strchr( extension, ' ' ); + if( where || *extension == '\0' ) + { + return GL_FALSE; + } + + // Check if extension is in the standard OpenGL extensions string + extensions = (GLubyte *) glGetString( GL_EXTENSIONS ); + if( extensions != NULL ) + { + if( _glfwStringInExtensionString( extension, extensions ) ) + { + return GL_TRUE; + } + } + + // Additional platform specific extension checking (e.g. WGL) + if( _glfwPlatformExtensionSupported( extension ) ) + { + return GL_TRUE; + } + + return GL_FALSE; +} + + +//======================================================================== +// glfwGetProcAddress() - Get the function pointer to an OpenGL function. +// This function can be used to get access to extended OpenGL functions. +//======================================================================== + +GLFWAPI void * GLFWAPIENTRY glfwGetProcAddress( const char *procname ) +{ + // Is GLFW initialized? + if( !_glfwInitialized || !_glfwWin.Opened ) + { + return NULL; + } + + return _glfwPlatformGetProcAddress( procname ); +} + + +//======================================================================== +// glfwGetGLVersion() - Get OpenGL version +//======================================================================== + +GLFWAPI void GLFWAPIENTRY glfwGetGLVersion( int *major, int *minor, + int *rev ) +{ + GLuint _major, _minor = 0, _rev = 0; + const GLubyte *version; + GLubyte *ptr; + + // Is GLFW initialized? + if( !_glfwInitialized || !_glfwWin.Opened ) + { + return; + } + + // Get OpenGL version string + version = glGetString( GL_VERSION ); + if( !version ) + { + return; + } + + // Parse string + ptr = (GLubyte*) version; + for( _major = 0; *ptr >= '0' && *ptr <= '9'; ptr ++ ) + { + _major = 10*_major + (*ptr - '0'); + } + if( *ptr == '.' ) + { + ptr ++; + for( _minor = 0; *ptr >= '0' && *ptr <= '9'; ptr ++ ) + { + _minor = 10*_minor + (*ptr - '0'); + } + if( *ptr == '.' ) + { + ptr ++; + for( _rev = 0; *ptr >= '0' && *ptr <= '9'; ptr ++ ) + { + _rev = 10*_rev + (*ptr - '0'); + } + } + } + + // Return parsed values + if( major != NULL ) + { + *major = _major; + } + if( minor != NULL ) + { + *minor = _minor; + } + if( rev != NULL ) + { + *rev = _rev; + } +} + diff --git a/src/engine/external/glfw/lib/image.c b/src/engine/external/glfw/lib/image.c new file mode 100644 index 00000000..3caa1518 --- /dev/null +++ b/src/engine/external/glfw/lib/image.c @@ -0,0 +1,629 @@ +//======================================================================== +// GLFW - An OpenGL framework +// File: image.c +// Platform: Any +// 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. +// +//======================================================================== + +//======================================================================== +// Description: +// +// This module acts as an interface for different image file formats (the +// image file format is detected automatically). +// +// By default the loaded image is rescaled (using bilinear interpolation) +// to the next higher 2^N x 2^M resolution, unless it has a valid +// 2^N x 2^M resolution. The interpolation is quite slow, even if the +// routine has been optimized for speed (a 200x200 RGB image is scaled to +// 256x256 in ~30 ms on a P3-500). +// +// Paletted images are converted to RGB/RGBA images. +// +// A convenience function is also included (glfwLoadTexture2D), which +// loads a texture image from a file directly to OpenGL texture memory, +// with an option to generate all mipmap levels. GL_SGIS_generate_mipmap +// is used whenever available, which should give an optimal mipmap +// generation speed (possibly performed in hardware). A software fallback +// method is included when GL_SGIS_generate_mipmap is not supported (it +// generates all mipmaps of a 256x256 RGB texture in ~3 ms on a P3-500). +// +//======================================================================== + + +#include "internal.h" + + +// We want to support automatic mipmap generation +#ifndef GL_SGIS_generate_mipmap + #define GL_GENERATE_MIPMAP_SGIS 0x8191 + #define GL_GENERATE_MIPMAP_HINT_SGIS 0x8192 + #define GL_SGIS_generate_mipmap 1 +#endif // GL_SGIS_generate_mipmap + + +//************************************************************************ +//**** GLFW internal functions **** +//************************************************************************ + +//======================================================================== +// _glfwUpsampleImage() - Upsample image, from size w1 x h1 to w2 x h2 +//======================================================================== + +static void _glfwUpsampleImage( unsigned char *src, unsigned char *dst, + int w1, int h1, int w2, int h2, int bpp ) +{ + int m, n, k, x, y, col8; + float dx, dy, xstep, ystep, col, col1, col2; + unsigned char *src1, *src2, *src3, *src4; + + // Calculate scaling factor + xstep = (float)(w1-1) / (float)(w2-1); + ystep = (float)(h1-1) / (float)(h2-1); + + // Copy source data to destination data with bilinear interpolation + // Note: The rather strange look of this routine is a direct result of + // my attempts at optimizing it. Improvements are welcome! + dy = 0.0f; + y = 0; + for( n = 0; n < h2; n ++ ) + { + dx = 0.0f; + src1 = &src[ y*w1*bpp ]; + src3 = y < (h1-1) ? src1 + w1*bpp : src1; + src2 = src1 + bpp; + src4 = src3 + bpp; + x = 0; + for( m = 0; m < w2; m ++ ) + { + for( k = 0; k < bpp; k ++ ) + { + col1 = *src1 ++; + col2 = *src2 ++; + col = col1 + (col2 - col1) * dx; + col1 = *src3 ++; + col2 = *src4 ++; + col2 = col1 + (col2 - col1) * dx; + col += (col2 - col) * dy; + col8 = (int) (col + 0.5); + if( col8 >= 256 ) col8 = 255; + *dst++ = (unsigned char) col8; + } + dx += xstep; + if( dx >= 1.0f ) + { + x ++; + dx -= 1.0f; + if( x >= (w1-1) ) + { + src2 = src1; + src4 = src3; + } + } + else + { + src1 -= bpp; + src2 -= bpp; + src3 -= bpp; + src4 -= bpp; + } + } + dy += ystep; + if( dy >= 1.0f ) + { + y ++; + dy -= 1.0f; + } + } +} + + +//======================================================================== +// _glfwHalveImage() - Build the next mip-map level +//======================================================================== + +static int _glfwHalveImage( GLubyte *src, int *width, int *height, + int components ) +{ + int halfwidth, halfheight, m, n, k, idx1, idx2; + GLubyte *dst; + + // Last level? + if( *width <= 1 && *height <= 1 ) + { + return GL_FALSE; + } + + // Calculate new width and height (handle 1D case) + halfwidth = *width > 1 ? *width / 2 : 1; + halfheight = *height > 1 ? *height / 2 : 1; + + // Downsample image with a simple box-filter + dst = src; + if( *width == 1 || *height == 1 ) + { + // 1D case + for( m = 0; m < halfwidth+halfheight-1; m ++ ) + { + for( k = 0; k < components; k ++ ) + { + *dst ++ = (GLubyte) (((int)*src + + (int)src[components] + 1) >> 1); + src ++; + } + src += components; + } + } + else + { + // 2D case + idx1 = *width*components; + idx2 = (*width+1)*components; + for( m = 0; m < halfheight; m ++ ) + { + for( n = 0; n < halfwidth; n ++ ) + { + for( k = 0; k < components; k ++ ) + { + *dst ++ = (GLubyte) (((int)*src + + (int)src[components] + + (int)src[idx1] + + (int)src[idx2] + 2) >> 2); + src ++; + } + src += components; + } + src += components * (*width); + } + } + + // Return new width and height + *width = halfwidth; + *height = halfheight; + + return GL_TRUE; +} + + +//======================================================================== +// _glfwRescaleImage() - Rescales an image into power-of-two dimensions +//======================================================================== + +static int _glfwRescaleImage( GLFWimage* image ) +{ + int width, height, log2, newsize; + unsigned char *data; + + // Calculate next larger 2^N width + for( log2 = 0, width = image->Width; width > 1; width >>= 1, log2 ++ ) + ; + width = (int) 1 << log2; + if( width < image->Width ) + { + width <<= 1; + } + + // Calculate next larger 2^M height + for( log2 = 0, height = image->Height; height > 1; height >>= 1, log2 ++ ) + ; + height = (int) 1 << log2; + if( height < image->Height ) + { + height <<= 1; + } + + // Do we really need to rescale? + if( width != image->Width || height != image->Height ) + { + // Allocate memory for new (upsampled) image data + newsize = width * height * image->BytesPerPixel; + data = (unsigned char *) malloc( newsize ); + if( data == NULL ) + { + free( image->Data ); + return GL_FALSE; + } + + // Copy old image data to new image data with interpolation + _glfwUpsampleImage( image->Data, data, image->Width, image->Height, + width, height, image->BytesPerPixel ); + + // Free memory for old image data (not needed anymore) + free( image->Data ); + + // Set pointer to new image data, and set new image dimensions + image->Data = data; + image->Width = width; + image->Height = height; + } + + return GL_TRUE; +} + + +//************************************************************************ +//**** GLFW user functions **** +//************************************************************************ + +//======================================================================== +// glfwReadImage() - Read an image from a named file +//======================================================================== + +GLFWAPI int GLFWAPIENTRY glfwReadImage( const char *name, GLFWimage *img, + int flags ) +{ + _GLFWstream stream; + + // Is GLFW initialized? + if( !_glfwInitialized ) + { + return GL_FALSE; + } + + // Start with an empty image descriptor + img->Width = 0; + img->Height = 0; + img->BytesPerPixel = 0; + img->Data = NULL; + + // Open file + if( !_glfwOpenFileStream( &stream, name, "rb" ) ) + { + return GL_FALSE; + } + + // We only support TGA files at the moment + if( !_glfwReadTGA( &stream, img, flags ) ) + { + _glfwCloseStream( &stream ); + return GL_FALSE; + } + + // Close stream + _glfwCloseStream( &stream ); + + // Should we rescale the image to closest 2^N x 2^M resolution? + if( !(flags & GLFW_NO_RESCALE_BIT) ) + { + if( !_glfwRescaleImage( img ) ) + { + return GL_FALSE; + } + } + + // Interpret BytesPerPixel as an OpenGL format + switch( img->BytesPerPixel ) + { + default: + case 1: + if( flags & GLFW_ALPHA_MAP_BIT ) + { + img->Format = GL_ALPHA; + } + else + { + img->Format = GL_LUMINANCE; + } + break; + case 3: + img->Format = GL_RGB; + break; + case 4: + img->Format = GL_RGBA; + break; + } + + return GL_TRUE; +} + + +//======================================================================== +// glfwReadMemoryImage() - Read an image file from a memory buffer +//======================================================================== + +GLFWAPI int GLFWAPIENTRY glfwReadMemoryImage( const void *data, long size, GLFWimage *img, int flags ) +{ + _GLFWstream stream; + + // Is GLFW initialized? + if( !_glfwInitialized ) + { + return GL_FALSE; + } + + // Start with an empty image descriptor + img->Width = 0; + img->Height = 0; + img->BytesPerPixel = 0; + img->Data = NULL; + + // Open buffer + if( !_glfwOpenBufferStream( &stream, (void*) data, size ) ) + { + return GL_FALSE; + } + + // We only support TGA files at the moment + if( !_glfwReadTGA( &stream, img, flags ) ) + { + _glfwCloseStream( &stream ); + return GL_FALSE; + } + + // Close stream + _glfwCloseStream( &stream ); + + // Should we rescale the image to closest 2^N x 2^M resolution? + if( !(flags & GLFW_NO_RESCALE_BIT) ) + { + if( !_glfwRescaleImage( img ) ) + { + return GL_FALSE; + } + } + + // Interpret BytesPerPixel as an OpenGL format + switch( img->BytesPerPixel ) + { + default: + case 1: + if( flags & GLFW_ALPHA_MAP_BIT ) + { + img->Format = GL_ALPHA; + } + else + { + img->Format = GL_LUMINANCE; + } + break; + case 3: + img->Format = GL_RGB; + break; + case 4: + img->Format = GL_RGBA; + break; + } + + return GL_TRUE; +} + + +//======================================================================== +// glfwFreeImage() - Free allocated memory for an image +//======================================================================== + +GLFWAPI void GLFWAPIENTRY glfwFreeImage( GLFWimage *img ) +{ + // Is GLFW initialized? + if( !_glfwInitialized ) + { + return; + } + + // Free memory + if( img->Data != NULL ) + { + free( img->Data ); + img->Data = NULL; + } + + // Clear all fields + img->Width = 0; + img->Height = 0; + img->Format = 0; + img->BytesPerPixel = 0; +} + + +//======================================================================== +// glfwLoadTexture2D() - Read an image from a file, and upload it to +// texture memory +//======================================================================== + +GLFWAPI int GLFWAPIENTRY glfwLoadTexture2D( const char *name, int flags ) +{ + GLFWimage img; + + // Is GLFW initialized? + if( !_glfwInitialized || !_glfwWin.Opened ) + { + return GL_FALSE; + } + + // Force rescaling if necessary + if( !_glfwWin.Has_GL_ARB_texture_non_power_of_two ) + { + flags &= (~GLFW_NO_RESCALE_BIT); + } + + // Read image from file + if( !glfwReadImage( name, &img, flags ) ) + { + return GL_FALSE; + } + + if( !glfwLoadTextureImage2D( &img, flags ) ) + { + return GL_FALSE; + } + + // Data buffer is not needed anymore + glfwFreeImage( &img ); + + return GL_TRUE; +} + + +//======================================================================== +// glfwLoadMemoryTexture2D() - Read an image from a buffer, and upload it to +// texture memory +//======================================================================== + +GLFWAPI int GLFWAPIENTRY glfwLoadMemoryTexture2D( const void *data, long size, int flags ) +{ + GLFWimage img; + + // Is GLFW initialized? + if( !_glfwInitialized || !_glfwWin.Opened ) + { + return GL_FALSE; + } + + // Force rescaling if necessary + if( !_glfwWin.Has_GL_ARB_texture_non_power_of_two ) + { + flags &= (~GLFW_NO_RESCALE_BIT); + } + + // Read image from file + if( !glfwReadMemoryImage( data, size, &img, flags ) ) + { + return GL_FALSE; + } + + if( !glfwLoadTextureImage2D( &img, flags ) ) + { + return GL_FALSE; + } + + // Data buffer is not needed anymore + glfwFreeImage( &img ); + + return GL_TRUE; +} + + +//======================================================================== +// glfwLoadTextureImage2D() - Upload an image object to texture memory +//======================================================================== + +GLFWAPI int GLFWAPIENTRY glfwLoadTextureImage2D( GLFWimage *img, int flags ) +{ + GLint UnpackAlignment, GenMipMap; + int level, format, AutoGen, newsize, n; + unsigned char *data, *dataptr; + + // Is GLFW initialized? + if( !_glfwInitialized || !_glfwWin.Opened ) + { + return GL_FALSE; + } + + // TODO: Use GL_MAX_TEXTURE_SIZE or GL_PROXY_TEXTURE_2D to determine + // whether the image size is valid. + // NOTE: May require box filter downsampling routine. + + // Do we need to convert the alpha map to RGBA format (OpenGL 1.0)? + if( (_glfwWin.GLVerMajor == 1) && (_glfwWin.GLVerMinor == 0) && + (img->Format == GL_ALPHA) ) + { + // We go to RGBA representation instead + img->BytesPerPixel = 4; + + // Allocate memory for new RGBA image data + newsize = img->Width * img->Height * img->BytesPerPixel; + data = (unsigned char *) malloc( newsize ); + if( data == NULL ) + { + free( img->Data ); + return GL_FALSE; + } + + // Convert Alpha map to RGBA + dataptr = data; + for( n = 0; n < (img->Width*img->Height); ++ n ) + { + *dataptr ++ = 255; + *dataptr ++ = 255; + *dataptr ++ = 255; + *dataptr ++ = img->Data[n]; + } + + // Free memory for old image data (not needed anymore) + free( img->Data ); + + // Set pointer to new image data + img->Data = data; + } + + // Set unpack alignment to one byte + glGetIntegerv( GL_UNPACK_ALIGNMENT, &UnpackAlignment ); + glPixelStorei( GL_UNPACK_ALIGNMENT, 1 ); + + // Should we use automatic mipmap generation? + AutoGen = ( flags & GLFW_BUILD_MIPMAPS_BIT ) && + _glfwWin.Has_GL_SGIS_generate_mipmap; + + // Enable automatic mipmap generation + if( AutoGen ) + { + glGetTexParameteriv( GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS, + &GenMipMap ); + glTexParameteri( GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS, + GL_TRUE ); + } + + // Format specification is different for OpenGL 1.0 + if( _glfwWin.GLVerMajor == 1 && _glfwWin.GLVerMinor == 0 ) + { + format = img->BytesPerPixel; + } + else + { + format = img->Format; + } + + // Upload to texture memeory + level = 0; + do + { + // Upload this mipmap level + glTexImage2D( GL_TEXTURE_2D, level, format, + img->Width, img->Height, 0, format, + GL_UNSIGNED_BYTE, (void*) img->Data ); + + // Build next mipmap level manually, if required + if( ( flags & GLFW_BUILD_MIPMAPS_BIT ) && !AutoGen ) + { + level = _glfwHalveImage( img->Data, &img->Width, + &img->Height, img->BytesPerPixel ) ? + level + 1 : 0; + } + } + while( level != 0 ); + + // Restore old automatic mipmap generation state + if( AutoGen ) + { + glTexParameteri( GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS, + GenMipMap ); + } + + // Restore old unpack alignment + glPixelStorei( GL_UNPACK_ALIGNMENT, UnpackAlignment ); + + return GL_TRUE; +} + diff --git a/src/engine/external/glfw/lib/init.c b/src/engine/external/glfw/lib/init.c new file mode 100644 index 00000000..6d149d84 --- /dev/null +++ b/src/engine/external/glfw/lib/init.c @@ -0,0 +1,108 @@ +//======================================================================== +// GLFW - An OpenGL framework +// File: init.c +// Platform: Any +// 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. +// +//======================================================================== + +#define _init_c_ +#include "internal.h" + + +//************************************************************************ +//**** GLFW user functions **** +//************************************************************************ + +//======================================================================== +// glfwInit() - Initialize various GLFW state +//======================================================================== + +GLFWAPI int GLFWAPIENTRY glfwInit( void ) +{ + // Is GLFW already initialized? + if( _glfwInitialized ) + { + return GL_TRUE; + } + + // Window is not yet opened + _glfwWin.Opened = GL_FALSE; + + // Default enable/disable settings + _glfwWin.SysKeysDisabled = GL_FALSE; + + // Clear window hints + _glfwClearWindowHints(); + + // Platform specific initialization + if( !_glfwPlatformInit() ) + { + return GL_FALSE; + } + + // Form now on, GLFW state is valid + _glfwInitialized = GL_TRUE; + + return GL_TRUE; +} + + + +//======================================================================== +// glfwTerminate() - Close window and kill all threads. +//======================================================================== + +GLFWAPI void GLFWAPIENTRY glfwTerminate( void ) +{ + // Is GLFW initialized? + if( !_glfwInitialized ) + { + return; + } + + // Platform specific termination + if( !_glfwPlatformTerminate() ) + { + return; + } + + // GLFW is no longer initialized + _glfwInitialized = GL_FALSE; +} + + +//======================================================================== +// glfwGetVersion() - Get GLFW version +//======================================================================== + +GLFWAPI void GLFWAPIENTRY glfwGetVersion( int *major, int *minor, + int *rev ) +{ + if( major != NULL ) *major = GLFW_VERSION_MAJOR; + if( minor != NULL ) *minor = GLFW_VERSION_MINOR; + if( rev != NULL ) *rev = GLFW_VERSION_REVISION; +} + diff --git a/src/engine/external/glfw/lib/input.c b/src/engine/external/glfw/lib/input.c new file mode 100644 index 00000000..e944706b --- /dev/null +++ b/src/engine/external/glfw/lib/input.c @@ -0,0 +1,280 @@ +//======================================================================== +// GLFW - An OpenGL framework +// File: input.c +// Platform: Any +// 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" + + +//======================================================================== +// glfwGetKey() +//======================================================================== + +GLFWAPI int GLFWAPIENTRY glfwGetKey( int key ) +{ + // Is GLFW initialized? + if( !_glfwInitialized || !_glfwWin.Opened ) + { + return GLFW_RELEASE; + } + + // Is it a valid key? + if( key < 0 || key > GLFW_KEY_LAST ) + { + return GLFW_RELEASE; + } + + if( _glfwInput.Key[ key ] == GLFW_STICK ) + { + // Sticky mode: release key now + _glfwInput.Key[ key ] = GLFW_RELEASE; + return GLFW_PRESS; + } + + return (int) _glfwInput.Key[ key ]; +} + + +//======================================================================== +// glfwGetMouseButton() +//======================================================================== + +GLFWAPI int GLFWAPIENTRY glfwGetMouseButton( int button ) +{ + // Is GLFW initialized? + if( !_glfwInitialized || !_glfwWin.Opened ) + { + return GLFW_RELEASE; + } + + // Is it a valid mouse button? + if( button < 0 || button > GLFW_MOUSE_BUTTON_LAST ) + { + return GLFW_RELEASE; + } + + if( _glfwInput.MouseButton[ button ] == GLFW_STICK ) + { + // Sticky mode: release mouse button now + _glfwInput.MouseButton[ button ] = GLFW_RELEASE; + return GLFW_PRESS; + } + + return (int) _glfwInput.MouseButton[ button ]; +} + + +//======================================================================== +// glfwGetMousePos() +//======================================================================== + +GLFWAPI void GLFWAPIENTRY glfwGetMousePos( int *xpos, int *ypos ) +{ + // Is GLFW initialized? + if( !_glfwInitialized || !_glfwWin.Opened ) + { + return; + } + + // Return mouse position + if( xpos != NULL ) + { + *xpos = _glfwInput.MousePosX; + } + if( ypos != NULL ) + { + *ypos = _glfwInput.MousePosY; + } +} + + +//======================================================================== +// glfwSetMousePos() +//======================================================================== + +GLFWAPI void GLFWAPIENTRY glfwSetMousePos( int xpos, int ypos ) +{ + // Is GLFW initialized? + if( !_glfwInitialized || !_glfwWin.Opened ) + { + return; + } + + // Don't do anything if the mouse position did not change + if( xpos == _glfwInput.MousePosX && ypos == _glfwInput.MousePosY ) + { + return; + } + + // Set GLFW mouse position + _glfwInput.MousePosX = xpos; + _glfwInput.MousePosY = ypos; + + // If we have a locked mouse, do not change cursor position + if( _glfwWin.MouseLock ) + { + return; + } + + // Update physical cursor position + _glfwPlatformSetMouseCursorPos( xpos, ypos ); +} + + +//======================================================================== +// glfwGetMouseWheel() +//======================================================================== + +GLFWAPI int GLFWAPIENTRY glfwGetMouseWheel( void ) +{ + // Is GLFW initialized? + if( !_glfwInitialized || !_glfwWin.Opened ) + { + return 0; + } + + // Return mouse wheel position + return _glfwInput.WheelPos; +} + + +//======================================================================== +// glfwSetMouseWheel() +//======================================================================== + +GLFWAPI void GLFWAPIENTRY glfwSetMouseWheel( int pos ) +{ + // Is GLFW initialized? + if( !_glfwInitialized || !_glfwWin.Opened ) + { + return; + } + + // Set mouse wheel position + _glfwInput.WheelPos = pos; +} + + +//======================================================================== +// glfwSetKeyCallback() - Set callback function for keyboard input +//======================================================================== + +GLFWAPI void GLFWAPIENTRY glfwSetKeyCallback( GLFWkeyfun cbfun ) +{ + // Is GLFW initialized? + if( !_glfwInitialized || !_glfwWin.Opened ) + { + return; + } + + // Set callback function + _glfwWin.KeyCallback = cbfun; +} + + +//======================================================================== +// glfwSetCharCallback() - Set callback function for character input +//======================================================================== + +GLFWAPI void GLFWAPIENTRY glfwSetCharCallback( GLFWcharfun cbfun ) +{ + // Is GLFW initialized? + if( !_glfwInitialized || !_glfwWin.Opened ) + { + return; + } + + // Set callback function + _glfwWin.CharCallback = cbfun; +} + + +//======================================================================== +// glfwSetMouseButtonCallback() - Set callback function for mouse clicks +//======================================================================== + +GLFWAPI void GLFWAPIENTRY glfwSetMouseButtonCallback( GLFWmousebuttonfun cbfun ) +{ + // Is GLFW initialized? + if( !_glfwInitialized || !_glfwWin.Opened ) + { + return; + } + + // Set callback function + _glfwWin.MouseButtonCallback = cbfun; +} + + +//======================================================================== +// glfwSetMousePosCallback() - Set callback function for mouse moves +//======================================================================== + +GLFWAPI void GLFWAPIENTRY glfwSetMousePosCallback( GLFWmouseposfun cbfun ) +{ + // Is GLFW initialized? + if( !_glfwInitialized || !_glfwWin.Opened ) + { + return; + } + + // Set callback function + _glfwWin.MousePosCallback = cbfun; + + // Call the callback function to let the application know the current + // mouse position + if( cbfun ) + { + cbfun( _glfwInput.MousePosX, _glfwInput.MousePosY ); + } +} + + +//======================================================================== +// glfwSetMouseWheelCallback() - Set callback function for mouse wheel +//======================================================================== + +GLFWAPI void GLFWAPIENTRY glfwSetMouseWheelCallback( GLFWmousewheelfun cbfun ) +{ + // Is GLFW initialized? + if( !_glfwInitialized || !_glfwWin.Opened ) + { + return; + } + + // Set callback function + _glfwWin.MouseWheelCallback = cbfun; + + // Call the callback function to let the application know the current + // mouse wheel position + if( cbfun ) + { + cbfun( _glfwInput.WheelPos ); + } +} + diff --git a/src/engine/external/glfw/lib/internal.h b/src/engine/external/glfw/lib/internal.h new file mode 100644 index 00000000..1785d1e9 --- /dev/null +++ b/src/engine/external/glfw/lib/internal.h @@ -0,0 +1,210 @@ +//======================================================================== +// GLFW - An OpenGL framework +// File: internal.h +// Platform: Any +// 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 _internal_h_ +#define _internal_h_ + +//======================================================================== +// GLFWGLOBAL is a macro that places all global variables in the init.c +// module (all other modules reference global variables as 'extern') +//======================================================================== + +#if defined( _init_c_ ) +#define GLFWGLOBAL +#else +#define GLFWGLOBAL extern +#endif + + +//======================================================================== +// Input handling definitions +//======================================================================== + +// Internal key and button state/action definitions +#define GLFW_STICK 2 + + +//======================================================================== +// System independent include files +//======================================================================== + +#include <stdlib.h> +#include <string.h> +#include <stdio.h> + + +//------------------------------------------------------------------------ +// Platform specific definitions goes in platform.h (which also includes +// glfw.h) +//------------------------------------------------------------------------ + +#include "platform.h" + + +//======================================================================== +// System independent global variables (GLFW internals) +//======================================================================== + +// Flag indicating if GLFW has been initialized +#if defined( _init_c_ ) +int _glfwInitialized = 0; +#else +GLFWGLOBAL int _glfwInitialized; +#endif + + +//------------------------------------------------------------------------ +// Window hints (set by glfwOpenWindowHint - will go into _GLFWthread) +//------------------------------------------------------------------------ +typedef struct { + int RefreshRate; + int AccumRedBits; + int AccumGreenBits; + int AccumBlueBits; + int AccumAlphaBits; + int AuxBuffers; + int Stereo; + int WindowNoResize; + int Samples; +} _GLFWhints; + +GLFWGLOBAL _GLFWhints _glfwWinHints; + + +//------------------------------------------------------------------------ +// Abstracted data stream (for image I/O) +//------------------------------------------------------------------------ +typedef struct { + FILE* File; + void* Data; + long Position; + long Size; +} _GLFWstream; + + +//======================================================================== +// Prototypes for platform specific implementation functions +//======================================================================== + +// Init/terminate +int _glfwPlatformInit( void ); +int _glfwPlatformTerminate( void ); + +// Enable/Disable +void _glfwPlatformEnableSystemKeys( void ); +void _glfwPlatformDisableSystemKeys( void ); + +// Fullscreen +int _glfwPlatformGetVideoModes( GLFWvidmode *list, int maxcount ); +void _glfwPlatformGetDesktopMode( GLFWvidmode *mode ); + +// OpenGL extensions +int _glfwPlatformExtensionSupported( const char *extension ); +void * _glfwPlatformGetProcAddress( const char *procname ); + +// Joystick +int _glfwPlatformGetJoystickParam( int joy, int param ); +int _glfwPlatformGetJoystickPos( int joy, float *pos, int numaxes ); +int _glfwPlatformGetJoystickButtons( int joy, unsigned char *buttons, int numbuttons ); + +// Threads +GLFWthread _glfwPlatformCreateThread( GLFWthreadfun fun, void *arg ); +void _glfwPlatformDestroyThread( GLFWthread ID ); +int _glfwPlatformWaitThread( GLFWthread ID, int waitmode ); +GLFWthread _glfwPlatformGetThreadID( void ); +GLFWmutex _glfwPlatformCreateMutex( void ); +void _glfwPlatformDestroyMutex( GLFWmutex mutex ); +void _glfwPlatformLockMutex( GLFWmutex mutex ); +void _glfwPlatformUnlockMutex( GLFWmutex mutex ); +GLFWcond _glfwPlatformCreateCond( void ); +void _glfwPlatformDestroyCond( GLFWcond cond ); +void _glfwPlatformWaitCond( GLFWcond cond, GLFWmutex mutex, double timeout ); +void _glfwPlatformSignalCond( GLFWcond cond ); +void _glfwPlatformBroadcastCond( GLFWcond cond ); +int _glfwPlatformGetNumberOfProcessors( void ); + +// Time +double _glfwPlatformGetTime( void ); +void _glfwPlatformSetTime( double time ); +void _glfwPlatformSleep( double time ); + +// Window management +int _glfwPlatformOpenWindow( int width, int height, int redbits, int greenbits, int bluebits, int alphabits, int depthbits, int stencilbits, int mode, _GLFWhints* hints ); +void _glfwPlatformCloseWindow( void ); +void _glfwPlatformSetWindowTitle( const char *title ); +void _glfwPlatformSetWindowSize( int width, int height ); +void _glfwPlatformSetWindowPos( int x, int y ); +void _glfwPlatformIconifyWindow( void ); +void _glfwPlatformRestoreWindow( void ); +void _glfwPlatformSwapBuffers( void ); +void _glfwPlatformSwapInterval( int interval ); +void _glfwPlatformRefreshWindowParams( void ); +void _glfwPlatformPollEvents( void ); +void _glfwPlatformWaitEvents( void ); +void _glfwPlatformHideMouseCursor( void ); +void _glfwPlatformShowMouseCursor( void ); +void _glfwPlatformSetMouseCursorPos( int x, int y ); + + +//======================================================================== +// Prototypes for platform independent internal functions +//======================================================================== + +// Window management (window.c) +void _glfwClearWindowHints( void ); + +// Input handling (window.c) +void _glfwClearInput( void ); +void _glfwInputDeactivation( void ); +void _glfwInputKey( int key, int action ); +void _glfwInputChar( int character, int action ); +void _glfwInputMouseClick( int button, int action ); + +// Threads (thread.c) +_GLFWthread * _glfwGetThreadPointer( int ID ); +void _glfwAppendThread( _GLFWthread * t ); +void _glfwRemoveThread( _GLFWthread * t ); + +// OpenGL extensions (glext.c) +int _glfwStringInExtensionString( const char *string, const GLubyte *extensions ); + +// Abstracted data streams (stream.c) +int _glfwOpenFileStream( _GLFWstream *stream, const char *name, const char *mode ); +int _glfwOpenBufferStream( _GLFWstream *stream, void *data, long size ); +long _glfwReadStream( _GLFWstream *stream, void *data, long size ); +long _glfwTellStream( _GLFWstream *stream ); +int _glfwSeekStream( _GLFWstream *stream, long offset, int whence ); +void _glfwCloseStream( _GLFWstream *stream ); + +// Targa image I/O (tga.c) +int _glfwReadTGA( _GLFWstream *s, GLFWimage *img, int flags ); + + +#endif // _internal_h_ diff --git a/src/engine/external/glfw/lib/joystick.c b/src/engine/external/glfw/lib/joystick.c new file mode 100644 index 00000000..9ce139f5 --- /dev/null +++ b/src/engine/external/glfw/lib/joystick.c @@ -0,0 +1,101 @@ +//======================================================================== +// GLFW - An OpenGL framework +// File: joystick.c +// Platform: Any +// 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 user functions **** +//************************************************************************ + +//======================================================================== +// glfwGetJoystickParam() - Determine joystick capabilities +//======================================================================== + +GLFWAPI int GLFWAPIENTRY glfwGetJoystickParam( int joy, int param ) +{ + // Is GLFW initialized? + if( !_glfwInitialized ) + { + return 0; + } + + return _glfwPlatformGetJoystickParam( joy, param ); +} + + +//======================================================================== +// glfwGetJoystickPos() - Get joystick axis positions +//======================================================================== + +GLFWAPI int GLFWAPIENTRY glfwGetJoystickPos( int joy, float *pos, + int numaxes ) +{ + int i; + + // Is GLFW initialized? + if( !_glfwInitialized ) + { + return 0; + } + + // Clear positions + for( i = 0; i < numaxes; i++ ) + { + pos[ i ] = 0.0f; + } + + return _glfwPlatformGetJoystickPos( joy, pos, numaxes ); +} + + +//======================================================================== +// glfwGetJoystickButtons() - Get joystick button states +//======================================================================== + +GLFWAPI int GLFWAPIENTRY glfwGetJoystickButtons( int joy, + unsigned char *buttons, int numbuttons ) +{ + int i; + + // Is GLFW initialized? + if( !_glfwInitialized ) + { + return 0; + } + + // Clear button states + for( i = 0; i < numbuttons; i++ ) + { + buttons[ i ] = GLFW_RELEASE; + } + + return _glfwPlatformGetJoystickButtons( joy, buttons, numbuttons ); +} 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_ diff --git a/src/engine/external/glfw/lib/stream.c b/src/engine/external/glfw/lib/stream.c new file mode 100644 index 00000000..34f75c85 --- /dev/null +++ b/src/engine/external/glfw/lib/stream.c @@ -0,0 +1,194 @@ +//======================================================================== +// GLFW - An OpenGL framework +// File: stream.c +// Platform: Any +// 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" + + +//======================================================================== +// Opens a GLFW stream with a file +//======================================================================== + +int _glfwOpenFileStream( _GLFWstream *stream, const char* name, const char* mode ) +{ + memset( stream, 0, sizeof(_GLFWstream) ); + + stream->File = fopen( name, mode ); + if( stream->File == NULL ) + { + return GL_FALSE; + } + + return GL_TRUE; +} + + +//======================================================================== +// Opens a GLFW stream with a memory block +//======================================================================== + +int _glfwOpenBufferStream( _GLFWstream *stream, void *data, long size ) +{ + memset( stream, 0, sizeof(_GLFWstream) ); + + stream->Data = data; + stream->Size = size; + return GL_TRUE; +} + + +//======================================================================== +// Reads data from a GLFW stream +//======================================================================== + +long _glfwReadStream( _GLFWstream *stream, void *data, long size ) +{ + if( stream->File != NULL ) + { + return fread( data, 1, size, stream->File ); + } + + if( stream->Data != NULL ) + { + // Check for EOF + if( stream->Position == stream->Size ) + { + return 0; + } + + // Clamp read size to available data + if( stream->Position + size > stream->Size ) + { + size = stream->Size - stream->Position; + } + + // Perform data read + memcpy( data, (unsigned char*) stream->Data + stream->Position, size ); + stream->Position += size; + return size; + } + + return 0; +} + + +//======================================================================== +// Returns the current position of a GLFW stream +//======================================================================== + +long _glfwTellStream( _GLFWstream *stream ) +{ + if( stream->File != NULL ) + { + return ftell( stream->File ); + } + + if( stream->Data != NULL ) + { + return stream->Position; + } + + return 0; +} + + +//======================================================================== +// Sets the current position of a GLFW stream +//======================================================================== + +int _glfwSeekStream( _GLFWstream *stream, long offset, int whence ) +{ + long position; + + if( stream->File != NULL ) + { + if( fseek( stream->File, offset, whence ) != 0 ) + { + return GL_FALSE; + } + + return GL_TRUE; + } + + if( stream->Data != NULL ) + { + position = offset; + + // Handle whence parameter + if( whence == SEEK_CUR ) + { + position += stream->Position; + } + else if( whence == SEEK_END ) + { + position += stream->Size; + } + else if( whence != SEEK_SET ) + { + return GL_FALSE; + } + + // Clamp offset to buffer bounds and apply it + if( position > stream->Size ) + { + stream->Position = stream->Size; + } + else if( position < 0 ) + { + stream->Position = 0; + } + else + { + stream->Position = position; + } + + return GL_TRUE; + } + + return GL_FALSE; +} + + +//======================================================================== +// Closes a GLFW stream +//======================================================================== + +void _glfwCloseStream( _GLFWstream *stream ) +{ + if( stream->File != NULL ) + { + fclose( stream->File ); + } + + // Nothing to be done about (user allocated) memory blocks + + memset( stream, 0, sizeof(_GLFWstream) ); +} + diff --git a/src/engine/external/glfw/lib/tga.c b/src/engine/external/glfw/lib/tga.c new file mode 100644 index 00000000..51e73844 --- /dev/null +++ b/src/engine/external/glfw/lib/tga.c @@ -0,0 +1,405 @@ +//======================================================================== +// GLFW - An OpenGL framework +// File: tga.c +// Platform: Any +// 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. +// +//======================================================================== + +//======================================================================== +// Description: +// +// TGA format image file loader. This module supports version 1 Targa +// images, with these restrictions: +// - Pixel format may only be 8, 24 or 32 bits +// - Colormaps must be no longer than 256 entries +// +//======================================================================== + + +#include "internal.h" + + +//************************************************************************ +//**** GLFW internal functions & declarations **** +//************************************************************************ + +//======================================================================== +// TGA file header information +//======================================================================== + +typedef struct { + int idlen; // 1 byte + int cmaptype; // 1 byte + int imagetype; // 1 byte + int cmapfirstidx; // 2 bytes + int cmaplen; // 2 bytes + int cmapentrysize; // 1 byte + int xorigin; // 2 bytes + int yorigin; // 2 bytes + int width; // 2 bytes + int height; // 2 bytes + int bitsperpixel; // 1 byte + int imageinfo; // 1 byte + int _alphabits; // (derived from imageinfo) + int _origin; // (derived from imageinfo) +} _tga_header_t; + +#define _TGA_CMAPTYPE_NONE 0 +#define _TGA_CMAPTYPE_PRESENT 1 + +#define _TGA_IMAGETYPE_NONE 0 +#define _TGA_IMAGETYPE_CMAP 1 +#define _TGA_IMAGETYPE_TC 2 +#define _TGA_IMAGETYPE_GRAY 3 +#define _TGA_IMAGETYPE_CMAP_RLE 9 +#define _TGA_IMAGETYPE_TC_RLE 10 +#define _TGA_IMAGETYPE_GRAY_RLE 11 + +#define _TGA_IMAGEINFO_ALPHA_MASK 0x0f +#define _TGA_IMAGEINFO_ALPHA_SHIFT 0 +#define _TGA_IMAGEINFO_ORIGIN_MASK 0x30 +#define _TGA_IMAGEINFO_ORIGIN_SHIFT 4 + +#define _TGA_ORIGIN_BL 0 +#define _TGA_ORIGIN_BR 1 +#define _TGA_ORIGIN_UL 2 +#define _TGA_ORIGIN_UR 3 + + +//======================================================================== +// _glfwReadTGAHeader() - Read TGA file header (and check that it is +// valid) +//======================================================================== + +static int _glfwReadTGAHeader( _GLFWstream *s, _tga_header_t *h ) +{ + unsigned char buf[ 18 ]; + int pos; + + // Read TGA file header from file + pos = _glfwTellStream( s ); + _glfwReadStream( s, buf, 18 ); + + // Interpret header (endian independent parsing) + h->idlen = (int) buf[0]; + h->cmaptype = (int) buf[1]; + h->imagetype = (int) buf[2]; + h->cmapfirstidx = (int) buf[3] | (((int) buf[4]) << 8); + h->cmaplen = (int) buf[5] | (((int) buf[6]) << 8); + h->cmapentrysize = (int) buf[7]; + h->xorigin = (int) buf[8] | (((int) buf[9]) << 8); + h->yorigin = (int) buf[10] | (((int) buf[11]) << 8); + h->width = (int) buf[12] | (((int) buf[13]) << 8); + h->height = (int) buf[14] | (((int) buf[15]) << 8); + h->bitsperpixel = (int) buf[16]; + h->imageinfo = (int) buf[17]; + + // Extract alphabits and origin information + h->_alphabits = (int) (h->imageinfo & _TGA_IMAGEINFO_ALPHA_MASK) >> + _TGA_IMAGEINFO_ALPHA_SHIFT; + h->_origin = (int) (h->imageinfo & _TGA_IMAGEINFO_ORIGIN_MASK) >> + _TGA_IMAGEINFO_ORIGIN_SHIFT; + + // Validate TGA header (is this a TGA file?) + if( (h->cmaptype == 0 || h->cmaptype == 1) && + ((h->imagetype >= 1 && h->imagetype <= 3) || + (h->imagetype >= 9 && h->imagetype <= 11)) && + (h->bitsperpixel == 8 || h->bitsperpixel == 24 || + h->bitsperpixel == 32) ) + { + // Skip the ID field + _glfwSeekStream( s, h->idlen, SEEK_CUR ); + + // Indicate that the TGA header was valid + return GL_TRUE; + } + else + { + // Restore file position + _glfwSeekStream( s, pos, SEEK_SET ); + + // Indicate that the TGA header was invalid + return GL_FALSE; + } +} + +//======================================================================== +// _glfwReadTGA_RLE() - Read Run-Length Encoded data +//======================================================================== + +static void _glfwReadTGA_RLE( unsigned char *buf, int size, int bpp, + _GLFWstream *s ) +{ + int repcount, bytes, k, n; + unsigned char pixel[ 4 ]; + char c; + + // Dummy check + if( bpp > 4 ) + { + return; + } + + while( size > 0 ) + { + // Get repetition count + _glfwReadStream( s, &c, 1 ); + repcount = (unsigned int) c; + bytes = ((repcount & 127) + 1) * bpp; + if( size < bytes ) + { + bytes = size; + } + + // Run-Length packet? + if( repcount & 128 ) + { + _glfwReadStream( s, pixel, bpp ); + for( n = 0; n < (repcount & 127) + 1; n ++ ) + { + for( k = 0; k < bpp; k ++ ) + { + *buf ++ = pixel[ k ]; + } + } + } + else + { + // It's a Raw packet + _glfwReadStream( s, buf, bytes ); + buf += bytes; + } + + size -= bytes; + } +} + + +//======================================================================== +// _glfwReadTGA() - Read a TGA image from a file +//======================================================================== + +int _glfwReadTGA( _GLFWstream *s, GLFWimage *img, int flags ) +{ + _tga_header_t h; + unsigned char *cmap, *pix, tmp, *src, *dst; + int cmapsize, pixsize, pixsize2; + int bpp, bpp2, k, m, n, swapx, swapy; + + // Read TGA header + if( !_glfwReadTGAHeader( s, &h ) ) + { + return 0; + } + + // Is there a colormap? + cmapsize = (h.cmaptype == _TGA_CMAPTYPE_PRESENT ? 1 : 0) * h.cmaplen * + ((h.cmapentrysize+7) / 8); + if( cmapsize > 0 ) + { + // Is it a colormap that we can handle? + if( (h.cmapentrysize != 24 && h.cmapentrysize != 32) || + h.cmaplen == 0 || h.cmaplen > 256 ) + { + return 0; + } + + // Allocate memory for colormap + cmap = (unsigned char *) malloc( cmapsize ); + if( cmap == NULL ) + { + return 0; + } + + // Read colormap from file + _glfwReadStream( s, cmap, cmapsize ); + } + else + { + cmap = NULL; + } + + // Size of pixel data + pixsize = h.width * h.height * ((h.bitsperpixel + 7) / 8); + + // Bytes per pixel (pixel data - unexpanded) + bpp = (h.bitsperpixel + 7) / 8; + + // Bytes per pixel (expanded pixels - not colormap indeces) + if( cmap ) + { + bpp2 = (h.cmapentrysize + 7) / 8; + } + else + { + bpp2 = bpp; + } + + // For colormaped images, the RGB/RGBA image data may use more memory + // than the stored pixel data + pixsize2 = h.width * h.height * bpp2; + + // Allocate memory for pixel data + pix = (unsigned char *) malloc( pixsize2 ); + if( pix == NULL ) + { + if( cmap ) + { + free( cmap ); + } + return 0; + } + + // Read pixel data from file + if( h.imagetype >= _TGA_IMAGETYPE_CMAP_RLE ) + { + _glfwReadTGA_RLE( pix, pixsize, bpp, s ); + } + else + { + _glfwReadStream( s, pix, pixsize ); + } + + // If the image origin is not what we want, re-arrange the pixels + switch( h._origin ) + { + default: + case _TGA_ORIGIN_UL: + swapx = 0; + swapy = 1; + break; + + case _TGA_ORIGIN_BL: + swapx = 0; + swapy = 0; + break; + + case _TGA_ORIGIN_UR: + swapx = 1; + swapy = 1; + break; + + case _TGA_ORIGIN_BR: + swapx = 1; + swapy = 0; + break; + } + if( (swapy && !(flags & GLFW_ORIGIN_UL_BIT)) || + (!swapy && (flags & GLFW_ORIGIN_UL_BIT)) ) + { + src = pix; + dst = &pix[ (h.height-1)*h.width*bpp ]; + for( n = 0; n < h.height/2; n ++ ) + { + for( m = 0; m < h.width ; m ++ ) + { + for( k = 0; k < bpp; k ++ ) + { + tmp = *src; + *src ++ = *dst; + *dst ++ = tmp; + } + } + dst -= 2*h.width*bpp; + } + } + if( swapx ) + { + src = pix; + dst = &pix[ (h.width-1)*bpp ]; + for( n = 0; n < h.height; n ++ ) + { + for( m = 0; m < h.width/2 ; m ++ ) + { + for( k = 0; k < bpp; k ++ ) + { + tmp = *src; + *src ++ = *dst; + *dst ++ = tmp; + } + dst -= 2*bpp; + } + src += ((h.width+1)/2)*bpp; + dst += ((3*h.width+1)/2)*bpp; + } + } + + // Convert BGR/BGRA to RGB/RGBA, and optionally colormap indeces to + // RGB/RGBA values + if( cmap ) + { + // Convert colormap pixel format (BGR -> RGB or BGRA -> RGBA) + if( bpp2 == 3 || bpp2 == 4 ) + { + for( n = 0; n < h.cmaplen; n ++ ) + { + tmp = cmap[ n*bpp2 ]; + cmap[ n*bpp2 ] = cmap[ n*bpp2 + 2 ]; + cmap[ n*bpp2 + 2 ] = tmp; + } + } + + // Convert pixel data to RGB/RGBA data + for( m = h.width * h.height - 1; m >= 0; m -- ) + { + n = pix[ m ]; + for( k = 0; k < bpp2; k ++ ) + { + pix[ m*bpp2 + k ] = cmap[ n*bpp2 + k ]; + } + } + + // Free memory for colormap (it's not needed anymore) + free( cmap ); + } + else + { + // Convert image pixel format (BGR -> RGB or BGRA -> RGBA) + if( bpp2 == 3 || bpp2 == 4 ) + { + src = pix; + dst = &pix[ 2 ]; + for( n = 0; n < h.height * h.width; n ++ ) + { + tmp = *src; + *src = *dst; + *dst = tmp; + src += bpp2; + dst += bpp2; + } + } + } + + // Fill out GLFWimage struct (the Format field will be set by + // glfwReadImage) + img->Width = h.width; + img->Height = h.height; + img->BytesPerPixel = bpp2; + img->Data = pix; + + return 1; +} + diff --git a/src/engine/external/glfw/lib/thread.c b/src/engine/external/glfw/lib/thread.c new file mode 100644 index 00000000..8094332c --- /dev/null +++ b/src/engine/external/glfw/lib/thread.c @@ -0,0 +1,340 @@ +//======================================================================== +// GLFW - An OpenGL framework +// File: thread.c +// Platform: Any +// 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 **** +//************************************************************************ + +//======================================================================== +// _glfwGetThreadPointer() - Find pointer to thread with a matching ID +//======================================================================== + +_GLFWthread * _glfwGetThreadPointer( int ID ) +{ + _GLFWthread *t; + + for( t = &_glfwThrd.First; t != NULL; t = t->Next ) + { + if( t->ID == ID ) + { + break; + } + } + + return t; +} + + +//======================================================================== +// _glfwAppendThread() - Append thread to thread list +//======================================================================== + +void _glfwAppendThread( _GLFWthread * t ) +{ + _GLFWthread *t_tmp; + + t_tmp = &_glfwThrd.First; + while( t_tmp->Next != NULL ) + { + t_tmp = t_tmp->Next; + } + t_tmp->Next = t; + t->Previous = t_tmp; + t->Next = NULL; +} + + +//======================================================================== +// _glfwRemoveThread() - Remove thread from thread list +//======================================================================== + +void _glfwRemoveThread( _GLFWthread * t ) +{ + if( t->Previous != NULL ) + { + t->Previous->Next = t->Next; + } + if( t->Next != NULL ) + { + t->Next->Previous = t->Previous; + } + free( (void *) t ); +} + + + +//************************************************************************ +//**** GLFW user functions **** +//************************************************************************ + +//======================================================================== +// glfwCreateThread() - Create a new thread +//======================================================================== + +GLFWAPI GLFWthread GLFWAPIENTRY glfwCreateThread( GLFWthreadfun fun, + void *arg ) +{ + // Is GLFW initialized? + if( !_glfwInitialized ) + { + return -1; + } + + // Return the GLFW thread ID + return _glfwPlatformCreateThread( fun, arg ); +} + + +//======================================================================== +// glfwDestroyThread() - Kill a thread. NOTE: THIS IS A VERY DANGEROUS +// OPERATION, AND SHOULD NOT BE USED EXCEPT IN EXTREME SITUATIONS! +//======================================================================== + +GLFWAPI void GLFWAPIENTRY glfwDestroyThread( GLFWthread ID ) +{ + // Is GLFW initialized? + if( !_glfwInitialized ) + { + return; + } + + // Is it a valid thread? (killing the main thread is not allowed) + if( ID < 1 ) + { + return; + } + + _glfwPlatformDestroyThread( ID ); +} + + +//======================================================================== +// glfwWaitThread() - Wait for a thread to die +//======================================================================== + +GLFWAPI int GLFWAPIENTRY glfwWaitThread( GLFWthread ID, int waitmode ) +{ + // Is GLFW initialized? + if( !_glfwInitialized ) + { + return GL_TRUE; + } + + // Is it a valid thread? (waiting for the main thread is not allowed) + if( ID < 1 ) + { + return GL_TRUE; + } + + return _glfwPlatformWaitThread( ID, waitmode ); +} + + +//======================================================================== +// glfwGetThreadID() - Return the thread ID for the current thread +//======================================================================== + +GLFWAPI GLFWthread GLFWAPIENTRY glfwGetThreadID( void ) +{ + // Is GLFW initialized? + if( !_glfwInitialized ) + { + return 0; + } + + return _glfwPlatformGetThreadID(); +} + + +//======================================================================== +// glfwCreateMutex() - Create a mutual exclusion object +//======================================================================== + +GLFWAPI GLFWmutex GLFWAPIENTRY glfwCreateMutex( void ) +{ + // Is GLFW initialized? + if( !_glfwInitialized ) + { + return (GLFWmutex) 0; + } + + return _glfwPlatformCreateMutex(); +} + + +//======================================================================== +// glfwDestroyMutex() - Destroy a mutual exclusion object +//======================================================================== + +GLFWAPI void GLFWAPIENTRY glfwDestroyMutex( GLFWmutex mutex ) +{ + // Initialized & valid mutex (no real way of assuring this)? + if( !_glfwInitialized || !mutex ) + { + return; + } + + _glfwPlatformDestroyMutex( mutex ); +} + + +//======================================================================== +// glfwLockMutex() - Request access to a mutex +//======================================================================== + +GLFWAPI void GLFWAPIENTRY glfwLockMutex( GLFWmutex mutex ) +{ + // Initialized & valid mutex (no real way of assuring this)? + if( !_glfwInitialized && !mutex ) + { + return; + } + + _glfwPlatformLockMutex( mutex ); +} + + +//======================================================================== +// glfwUnlockMutex() - Release a mutex +//======================================================================== + +GLFWAPI void GLFWAPIENTRY glfwUnlockMutex( GLFWmutex mutex ) +{ + // Initialized & valid mutex (no real way of assuring this)? + if( !_glfwInitialized && !mutex ) + { + return; + } + + _glfwPlatformUnlockMutex( mutex ); +} + + +//======================================================================== +// glfwCreateCond() - Create a new condition variable object +//======================================================================== + +GLFWAPI GLFWcond GLFWAPIENTRY glfwCreateCond( void ) +{ + // Is GLFW initialized? + if( !_glfwInitialized ) + { + return (GLFWcond) 0; + } + + return _glfwPlatformCreateCond(); +} + + +//======================================================================== +// glfwDestroyCond() - Destroy a condition variable object +//======================================================================== + +GLFWAPI void GLFWAPIENTRY glfwDestroyCond( GLFWcond cond ) +{ + // Initialized & valid condition variable? + if( !_glfwInitialized || !cond ) + { + return; + } + + _glfwPlatformDestroyCond( cond ); +} + + +//======================================================================== +// glfwWaitCond() - Wait for a condition to be raised +//======================================================================== + +GLFWAPI void GLFWAPIENTRY glfwWaitCond( GLFWcond cond, GLFWmutex mutex, + double timeout ) +{ + // Initialized & valid condition variable and mutex? + if( !_glfwInitialized || !cond || !mutex ) + { + return; + } + + _glfwPlatformWaitCond( cond, mutex, timeout ); +} + + +//======================================================================== +// glfwSignalCond() - Signal a condition to one waiting thread +//======================================================================== + +GLFWAPI void GLFWAPIENTRY glfwSignalCond( GLFWcond cond ) +{ + // Initialized & valid condition variable? + if( !_glfwInitialized || !cond ) + { + return; + } + + _glfwPlatformSignalCond( cond ); +} + + +//======================================================================== +// glfwBroadcastCond() - Broadcast a condition to all waiting threads +//======================================================================== + +GLFWAPI void GLFWAPIENTRY glfwBroadcastCond( GLFWcond cond ) +{ + // Initialized & valid condition variable? + if( !_glfwInitialized || !cond ) + { + return; + } + + _glfwPlatformBroadcastCond( cond ); +} + + +//======================================================================== +// glfwGetNumberOfProcessors() - Return the number of processors in the +// system. This information can be useful for determining the optimal +// number of threads to use for performing a certain task. +//======================================================================== + +GLFWAPI int GLFWAPIENTRY glfwGetNumberOfProcessors( void ) +{ + // Is GLFW initialized? + if( !_glfwInitialized ) + { + return 0; + } + + return _glfwPlatformGetNumberOfProcessors(); +} diff --git a/src/engine/external/glfw/lib/time.c b/src/engine/external/glfw/lib/time.c new file mode 100644 index 00000000..7f9f106d --- /dev/null +++ b/src/engine/external/glfw/lib/time.c @@ -0,0 +1,83 @@ +//======================================================================== +// GLFW - An OpenGL framework +// File: time.c +// Platform: Any +// 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 user functions **** +//************************************************************************ + +//======================================================================== +// glfwGetTime() - Return timer value in seconds +//======================================================================== + +GLFWAPI double GLFWAPIENTRY glfwGetTime( void ) +{ + // Is GLFW initialized? + if( !_glfwInitialized ) + { + return 0.0; + } + + return _glfwPlatformGetTime(); +} + + +//======================================================================== +// glfwSetTime() - Set timer value in seconds +//======================================================================== + +GLFWAPI void GLFWAPIENTRY glfwSetTime( double time ) +{ + // Is GLFW initialized? + if( !_glfwInitialized ) + { + return; + } + + _glfwPlatformSetTime( time ); +} + + +//======================================================================== +// glfwSleep() - Put a thread to sleep for a specified amount of time +//======================================================================== + +GLFWAPI void GLFWAPIENTRY glfwSleep( double time ) +{ + // Is GLFW initialized? + if( !_glfwInitialized ) + { + return; + } + + _glfwPlatformSleep( time ); +} diff --git a/src/engine/external/glfw/lib/win32/glfwdll.def b/src/engine/external/glfw/lib/win32/glfwdll.def new file mode 100644 index 00000000..1b40765a --- /dev/null +++ b/src/engine/external/glfw/lib/win32/glfwdll.def @@ -0,0 +1,67 @@ +LIBRARY GLFW.DLL + +EXPORTS +glfwBroadcastCond +glfwCloseWindow +glfwCreateCond +glfwCreateMutex +glfwCreateThread +glfwDestroyCond +glfwDestroyMutex +glfwDestroyThread +glfwDisable +glfwEnable +glfwExtensionSupported +glfwFreeImage +glfwGetDesktopMode +glfwGetGLVersion +glfwGetJoystickButtons +glfwGetJoystickParam +glfwGetJoystickPos +glfwGetKey +glfwGetMouseButton +glfwGetMousePos +glfwGetMouseWheel +glfwGetNumberOfProcessors +glfwGetProcAddress +glfwGetThreadID +glfwGetTime +glfwGetVersion +glfwGetVideoModes +glfwGetWindowParam +glfwGetWindowSize +glfwIconifyWindow +glfwInit +glfwLoadMemoryTexture2D +glfwLoadTexture2D +glfwLoadTextureImage2D +glfwLockMutex +glfwOpenWindow +glfwOpenWindowHint +glfwPollEvents +glfwReadImage +glfwReadMemoryImage +glfwRestoreWindow +glfwSetCharCallback +glfwSetKeyCallback +glfwSetMouseButtonCallback +glfwSetMousePos +glfwSetMousePosCallback +glfwSetMouseWheel +glfwSetMouseWheelCallback +glfwSetTime +glfwSetWindowCloseCallback +glfwSetWindowRefreshCallback +glfwSetWindowPos +glfwSetWindowSize +glfwSetWindowSizeCallback +glfwSetWindowTitle +glfwSignalCond +glfwSleep +glfwSwapBuffers +glfwSwapInterval +glfwTerminate +glfwUnlockMutex +glfwWaitCond +glfwWaitEvents +glfwWaitThread diff --git a/src/engine/external/glfw/lib/win32/glfwdll_mgw1.def b/src/engine/external/glfw/lib/win32/glfwdll_mgw1.def new file mode 100644 index 00000000..b193aa95 --- /dev/null +++ b/src/engine/external/glfw/lib/win32/glfwdll_mgw1.def @@ -0,0 +1,67 @@ +LIBRARY GLFW.DLL + +EXPORTS +glfwBroadcastCond = glfwBroadcastCond@4 +glfwCloseWindow = glfwCloseWindow@0 +glfwCreateCond = glfwCreateCond@0 +glfwCreateMutex = glfwCreateMutex@0 +glfwCreateThread = glfwCreateThread@8 +glfwDestroyCond = glfwDestroyCond@4 +glfwDestroyMutex = glfwDestroyMutex@4 +glfwDestroyThread = glfwDestroyThread@4 +glfwDisable = glfwDisable@4 +glfwEnable = glfwEnable@4 +glfwExtensionSupported = glfwExtensionSupported@4 +glfwFreeImage = glfwFreeImage@4 +glfwGetDesktopMode = glfwGetDesktopMode@4 +glfwGetGLVersion = glfwGetGLVersion@12 +glfwGetJoystickButtons = glfwGetJoystickButtons@12 +glfwGetJoystickParam = glfwGetJoystickParam@8 +glfwGetJoystickPos = glfwGetJoystickPos@12 +glfwGetKey = glfwGetKey@4 +glfwGetMouseButton = glfwGetMouseButton@4 +glfwGetMousePos = glfwGetMousePos@8 +glfwGetMouseWheel = glfwGetMouseWheel@0 +glfwGetNumberOfProcessors = glfwGetNumberOfProcessors@0 +glfwGetProcAddress = glfwGetProcAddress@4 +glfwGetThreadID = glfwGetThreadID@0 +glfwGetTime = glfwGetTime@0 +glfwGetVersion = glfwGetVersion@12 +glfwGetVideoModes = glfwGetVideoModes@8 +glfwGetWindowParam = glfwGetWindowParam@4 +glfwGetWindowSize = glfwGetWindowSize@8 +glfwIconifyWindow = glfwIconifyWindow@0 +glfwInit = glfwInit@0 +glfwLoadMemoryTexture2D = glfwLoadMemoryTexture2D@12 +glfwLoadTexture2D = glfwLoadTexture2D@8 +glfwLoadTextureImage2D = glfwLoadTextureImage2D@8 +glfwLockMutex = glfwLockMutex@4 +glfwOpenWindow = glfwOpenWindow@36 +glfwOpenWindowHint = glfwOpenWindowHint@8 +glfwPollEvents = glfwPollEvents@0 +glfwReadImage = glfwReadImage@12 +glfwReadMemoryImage = glfwReadMemoryImage@16 +glfwRestoreWindow = glfwRestoreWindow@0 +glfwSetCharCallback = glfwSetCharCallback@4 +glfwSetKeyCallback = glfwSetKeyCallback@4 +glfwSetMouseButtonCallback = glfwSetMouseButtonCallback@4 +glfwSetMousePos = glfwSetMousePos@8 +glfwSetMousePosCallback = glfwSetMousePosCallback@4 +glfwSetMouseWheel = glfwSetMouseWheel@4 +glfwSetMouseWheelCallback = glfwSetMouseWheelCallback@4 +glfwSetTime = glfwSetTime@8 +glfwSetWindowCloseCallback = glfwSetWindowCloseCallback@4 +glfwSetWindowRefreshCallback = glfwSetWindowRefreshCallback@4 +glfwSetWindowPos = glfwSetWindowPos@8 +glfwSetWindowSize = glfwSetWindowSize@8 +glfwSetWindowSizeCallback = glfwSetWindowSizeCallback@4 +glfwSetWindowTitle = glfwSetWindowTitle@4 +glfwSignalCond = glfwSignalCond@4 +glfwSleep = glfwSleep@8 +glfwSwapBuffers = glfwSwapBuffers@0 +glfwSwapInterval = glfwSwapInterval@4 +glfwTerminate = glfwTerminate@0 +glfwUnlockMutex = glfwUnlockMutex@4 +glfwWaitCond = glfwWaitCond@16 +glfwWaitEvents = glfwWaitEvents@0 +glfwWaitThread = glfwWaitThread@8 diff --git a/src/engine/external/glfw/lib/win32/glfwdll_mgw2.def b/src/engine/external/glfw/lib/win32/glfwdll_mgw2.def new file mode 100644 index 00000000..e42f664e --- /dev/null +++ b/src/engine/external/glfw/lib/win32/glfwdll_mgw2.def @@ -0,0 +1,67 @@ +LIBRARY GLFW.DLL + +EXPORTS +glfwBroadcastCond@4 +glfwCloseWindow@0 +glfwCreateCond@0 +glfwCreateMutex@0 +glfwCreateThread@8 +glfwDestroyCond@4 +glfwDestroyMutex@4 +glfwDestroyThread@4 +glfwDisable@4 +glfwEnable@4 +glfwExtensionSupported@4 +glfwFreeImage@4 +glfwGetDesktopMode@4 +glfwGetGLVersion@12 +glfwGetJoystickButtons@12 +glfwGetJoystickParam@8 +glfwGetJoystickPos@12 +glfwGetKey@4 +glfwGetMouseButton@4 +glfwGetMousePos@8 +glfwGetMouseWheel@0 +glfwGetNumberOfProcessors@0 +glfwGetProcAddress@4 +glfwGetThreadID@0 +glfwGetTime@0 +glfwGetVersion@12 +glfwGetVideoModes@8 +glfwGetWindowParam@4 +glfwGetWindowSize@8 +glfwIconifyWindow@0 +glfwInit@0 +glfwLoadMemoryTexture2D@12 +glfwLoadTexture2D@8 +glfwLoadTextureImage2D@8 +glfwLockMutex@4 +glfwOpenWindow@36 +glfwOpenWindowHint@8 +glfwPollEvents@0 +glfwReadImage@12 +glfwReadMemoryImage@16 +glfwRestoreWindow@0 +glfwSetCharCallback@4 +glfwSetKeyCallback@4 +glfwSetMouseButtonCallback@4 +glfwSetMousePos@8 +glfwSetMousePosCallback@4 +glfwSetMouseWheel@4 +glfwSetMouseWheelCallback@4 +glfwSetTime@8 +glfwSetWindowCloseCallback@4 +glfwSetWindowRefreshCallback@4 +glfwSetWindowPos@8 +glfwSetWindowSize@8 +glfwSetWindowSizeCallback@4 +glfwSetWindowTitle@4 +glfwSignalCond@4 +glfwSleep@8 +glfwSwapBuffers@0 +glfwSwapInterval@4 +glfwTerminate@0 +glfwUnlockMutex@4 +glfwWaitCond@16 +glfwWaitEvents@0 +glfwWaitThread@8 diff --git a/src/engine/external/glfw/lib/win32/glfwdll_pellesc.def b/src/engine/external/glfw/lib/win32/glfwdll_pellesc.def new file mode 100644 index 00000000..cbb214c8 --- /dev/null +++ b/src/engine/external/glfw/lib/win32/glfwdll_pellesc.def @@ -0,0 +1,65 @@ +LIBRARY GLFW + +EXPORTS +glfwBroadcastCond = glfwBroadcastCond@4 +glfwCloseWindow = glfwCloseWindow@0 +glfwCreateCond = glfwCreateCond@0 +glfwCreateMutex = glfwCreateMutex@0 +glfwCreateThread = glfwCreateThread@8 +glfwDestroyCond = glfwDestroyCond@4 +glfwDestroyMutex = glfwDestroyMutex@4 +glfwDestroyThread = glfwDestroyThread@4 +glfwDisable = glfwDisable@4 +glfwEnable = glfwEnable@4 +glfwExtensionSupported = glfwExtensionSupported@4 +glfwFreeImage = glfwFreeImage@4 +glfwGetDesktopMode = glfwGetDesktopMode@4 +glfwGetGLVersion = glfwGetGLVersion@12 +glfwGetJoystickButtons = glfwGetJoystickButtons@12 +glfwGetJoystickParam = glfwGetJoystickParam@8 +glfwGetJoystickPos = glfwGetJoystickPos@12 +glfwGetKey = glfwGetKey@4 +glfwGetMouseButton = glfwGetMouseButton@4 +glfwGetMousePos = glfwGetMousePos@8 +glfwGetMouseWheel = glfwGetMouseWheel@0 +glfwGetNumberOfProcessors = glfwGetNumberOfProcessors@0 +glfwGetProcAddress = glfwGetProcAddress@4 +glfwGetThreadID = glfwGetThreadID@0 +glfwGetTime = glfwGetTime@0 +glfwGetVersion = glfwGetVersion@12 +glfwGetVideoModes = glfwGetVideoModes@8 +glfwGetWindowParam = glfwGetWindowParam@4 +glfwGetWindowSize = glfwGetWindowSize@8 +glfwIconifyWindow = glfwIconifyWindow@0 +glfwInit = glfwInit@0 +glfwLoadTexture2D = glfwLoadTexture2D@8 +glfwLockMutex = glfwLockMutex@4 +glfwOpenWindow = glfwOpenWindow@36 +glfwOpenWindowHint = glfwOpenWindowHint@8 +glfwPollEvents = glfwPollEvents@0 +glfwReadImage = glfwReadImage@12 +glfwReadMemoryImage = glfwReadMemoryImage@16 +glfwRestoreWindow = glfwRestoreWindow@0 +glfwSetCharCallback = glfwSetCharCallback@4 +glfwSetKeyCallback = glfwSetKeyCallback@4 +glfwSetMouseButtonCallback = glfwSetMouseButtonCallback@4 +glfwSetMousePos = glfwSetMousePos@8 +glfwSetMousePosCallback = glfwSetMousePosCallback@4 +glfwSetMouseWheel = glfwSetMouseWheel@4 +glfwSetMouseWheelCallback = glfwSetMouseWheelCallback@4 +glfwSetTime = glfwSetTime@8 +glfwSetWindowCloseCallback = glfwSetWindowCloseCallback@4 +glfwSetWindowRefreshCallback = glfwSetWindowRefreshCallback@4 +glfwSetWindowPos = glfwSetWindowPos@8 +glfwSetWindowSize = glfwSetWindowSize@8 +glfwSetWindowSizeCallback = glfwSetWindowSizeCallback@4 +glfwSetWindowTitle = glfwSetWindowTitle@4 +glfwSignalCond = glfwSignalCond@4 +glfwSleep = glfwSleep@8 +glfwSwapBuffers = glfwSwapBuffers@0 +glfwSwapInterval = glfwSwapInterval@4 +glfwTerminate = glfwTerminate@0 +glfwUnlockMutex = glfwUnlockMutex@4 +glfwWaitCond = glfwWaitCond@16 +glfwWaitEvents = glfwWaitEvents@0 +glfwWaitThread = glfwWaitThread@8 diff --git a/src/engine/external/glfw/lib/win32/platform.h b/src/engine/external/glfw/lib/win32/platform.h new file mode 100644 index 00000000..25ada3b0 --- /dev/null +++ b/src/engine/external/glfw/lib/win32/platform.h @@ -0,0 +1,468 @@ +//======================================================================== +// GLFW - An OpenGL framework +// File: platform.h +// Platform: Windows +// 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 Windows version of GLFW +#define _GLFW_WIN32 + + +// Include files +#include <windows.h> +#include <mmsystem.h> +#include "../../include/GL/glfw.h" + + +//======================================================================== +// Hack: Define things that some <windows.h>'s do not define +//======================================================================== + +// Some old versions of w32api (used by MinGW and Cygwin) define +// WH_KEYBOARD_LL without typedef:ing KBDLLHOOKSTRUCT (!) +#if defined(__MINGW32__) || defined(__CYGWIN__) +#include <w32api.h> +#if defined(WH_KEYBOARD_LL) && (__W32API_MAJOR_VERSION == 1) && (__W32API_MINOR_VERSION <= 2) +#undef WH_KEYBOARD_LL +#endif +#endif + +//------------------------------------------------------------------------ +// ** NOTE ** If this gives you compiler errors and you are using MinGW +// (or Dev-C++), update to w32api version 1.3 or later: +// http://sourceforge.net/project/showfiles.php?group_id=2435 +//------------------------------------------------------------------------ +#ifndef WH_KEYBOARD_LL +#define WH_KEYBOARD_LL 13 +typedef struct tagKBDLLHOOKSTRUCT { + DWORD vkCode; + DWORD scanCode; + DWORD flags; + DWORD time; + DWORD dwExtraInfo; +} KBDLLHOOKSTRUCT, FAR *LPKBDLLHOOKSTRUCT, *PKBDLLHOOKSTRUCT; +#endif // WH_KEYBOARD_LL + +#ifndef LLKHF_ALTDOWN +#define LLKHF_ALTDOWN 0x00000020 +#endif + +#ifndef SPI_SETSCREENSAVERRUNNING +#define SPI_SETSCREENSAVERRUNNING 97 +#endif +#ifndef SPI_GETANIMATION +#define SPI_GETANIMATION 72 +#endif +#ifndef SPI_SETANIMATION +#define SPI_SETANIMATION 73 +#endif +#ifndef SPI_GETFOREGROUNDLOCKTIMEOUT +#define SPI_GETFOREGROUNDLOCKTIMEOUT 0x2000 +#endif +#ifndef SPI_SETFOREGROUNDLOCKTIMEOUT +#define SPI_SETFOREGROUNDLOCKTIMEOUT 0x2001 +#endif + +#ifndef CDS_FULLSCREEN +#define CDS_FULLSCREEN 4 +#endif + +#ifndef PFD_GENERIC_ACCELERATED +#define PFD_GENERIC_ACCELERATED 0x00001000 +#endif +#ifndef PFD_DEPTH_DONTCARE +#define PFD_DEPTH_DONTCARE 0x20000000 +#endif + +#ifndef ENUM_CURRENT_SETTINGS +#define ENUM_CURRENT_SETTINGS -1 +#endif +#ifndef ENUM_REGISTRY_SETTINGS +#define ENUM_REGISTRY_SETTINGS -2 +#endif + +#ifndef WM_MOUSEWHEEL +#define WM_MOUSEWHEEL 0x020A +#endif +#ifndef WHEEL_DELTA +#define WHEEL_DELTA 120 +#endif + +#ifndef WM_XBUTTONDOWN +#define WM_XBUTTONDOWN 0x020B +#endif +#ifndef WM_XBUTTONUP +#define WM_XBUTTONUP 0x020C +#endif +#ifndef XBUTTON1 +#define XBUTTON1 1 +#endif +#ifndef XBUTTON2 +#define XBUTTON2 2 +#endif + +// wglSwapIntervalEXT typedef (Win32 buffer-swap interval control) +typedef int (APIENTRY * WGLSWAPINTERVALEXT_T) (int interval); +// wglChoosePixelFormatARB typedef +typedef BOOL (WINAPI * WGLCHOOSEPIXELFORMATARB_T) (HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats); +// wglGetPixelFormatAttribivARB typedef +typedef BOOL (WINAPI * WGLGETPIXELFORMATATTRIBIVARB_T) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, int *piValues); + +#define WGL_DRAW_TO_WINDOW_ARB 0x2001 +#define WGL_SUPPORT_OPENGL_ARB 0x2010 +#define WGL_ACCELERATION_ARB 0x2003 +#define WGL_FULL_ACCELERATION_ARB 0x2027 +#define WGL_DOUBLE_BUFFER_ARB 0x2011 +#define WGL_STEREO_ARB 0x2012 +#define WGL_COLOR_BITS_ARB 0x2014 +#define WGL_RED_BITS_ARB 0x2015 +#define WGL_GREEN_BITS_ARB 0x2017 +#define WGL_BLUE_BITS_ARB 0x2019 +#define WGL_ALPHA_BITS_ARB 0x201B +#define WGL_ACCUM_BITS_ARB 0x201D +#define WGL_ACCUM_RED_BITS_ARB 0x201E +#define WGL_ACCUM_GREEN_BITS_ARB 0x201F +#define WGL_ACCUM_BLUE_BITS_ARB 0x2020 +#define WGL_ACCUM_ALPHA_BITS_ARB 0x2021 +#define WGL_DEPTH_BITS_ARB 0x2022 +#define WGL_STENCIL_BITS_ARB 0x2023 +#define WGL_AUX_BUFFERS_ARB 0x2024 +#define WGL_SAMPLE_BUFFERS_ARB 0x2041 +#define WGL_SAMPLES_ARB 0x2042 + + +//======================================================================== +// DLLs that are loaded at glfwInit() +//======================================================================== + +// gdi32.dll function pointer typedefs +#ifndef _GLFW_NO_DLOAD_GDI32 +typedef int (WINAPI * CHOOSEPIXELFORMAT_T) (HDC,CONST PIXELFORMATDESCRIPTOR*); +typedef int (WINAPI * DESCRIBEPIXELFORMAT_T) (HDC,int,UINT,LPPIXELFORMATDESCRIPTOR); +typedef int (WINAPI * GETPIXELFORMAT_T) (HDC); +typedef BOOL (WINAPI * SETPIXELFORMAT_T) (HDC,int,const PIXELFORMATDESCRIPTOR*); +typedef BOOL (WINAPI * SWAPBUFFERS_T) (HDC); +#endif // _GLFW_NO_DLOAD_GDI32 + +// winmm.dll function pointer typedefs +#ifndef _GLFW_NO_DLOAD_WINMM +typedef MMRESULT (WINAPI * JOYGETDEVCAPSA_T) (UINT,LPJOYCAPSA,UINT); +typedef MMRESULT (WINAPI * JOYGETPOS_T) (UINT,LPJOYINFO); +typedef MMRESULT (WINAPI * JOYGETPOSEX_T) (UINT,LPJOYINFOEX); +typedef DWORD (WINAPI * TIMEGETTIME_T) (void); +#endif // _GLFW_NO_DLOAD_WINMM + + +// gdi32.dll shortcuts +#ifndef _GLFW_NO_DLOAD_GDI32 +#define _glfw_ChoosePixelFormat _glfwLibrary.Libs.ChoosePixelFormat +#define _glfw_DescribePixelFormat _glfwLibrary.Libs.DescribePixelFormat +#define _glfw_GetPixelFormat _glfwLibrary.Libs.GetPixelFormat +#define _glfw_SetPixelFormat _glfwLibrary.Libs.SetPixelFormat +#define _glfw_SwapBuffers _glfwLibrary.Libs.SwapBuffers +#else +#define _glfw_ChoosePixelFormat ChoosePixelFormat +#define _glfw_DescribePixelFormat DescribePixelFormat +#define _glfw_GetPixelFormat GetPixelFormat +#define _glfw_SetPixelFormat SetPixelFormat +#define _glfw_SwapBuffers SwapBuffers +#endif // _GLFW_NO_DLOAD_GDI32 + +// winmm.dll shortcuts +#ifndef _GLFW_NO_DLOAD_WINMM +#define _glfw_joyGetDevCaps _glfwLibrary.Libs.joyGetDevCapsA +#define _glfw_joyGetPos _glfwLibrary.Libs.joyGetPos +#define _glfw_joyGetPosEx _glfwLibrary.Libs.joyGetPosEx +#define _glfw_timeGetTime _glfwLibrary.Libs.timeGetTime +#else +#define _glfw_joyGetDevCaps joyGetDevCapsA +#define _glfw_joyGetPos joyGetPos +#define _glfw_joyGetPosEx joyGetPosEx +#define _glfw_timeGetTime timeGetTime +#endif // _GLFW_NO_DLOAD_WINMM + + +//======================================================================== +// Global variables (GLFW internals) +//======================================================================== + +//------------------------------------------------------------------------ +// Window structure +//------------------------------------------------------------------------ +typedef struct _GLFWwin_struct _GLFWwin; + +struct _GLFWwin_struct { + +// ========= PLATFORM INDEPENDENT MANDATORY PART ========================= + + // User callback functions + GLFWwindowsizefun WindowSizeCallback; + GLFWwindowclosefun WindowCloseCallback; + GLFWwindowrefreshfun WindowRefreshCallback; + GLFWmousebuttonfun MouseButtonCallback; + GLFWmouseposfun MousePosCallback; + GLFWmousewheelfun MouseWheelCallback; + GLFWkeyfun KeyCallback; + GLFWcharfun CharCallback; + + // User selected window settings + int Fullscreen; // Fullscreen flag + int MouseLock; // Mouse-lock flag + int AutoPollEvents; // Auto polling flag + int SysKeysDisabled; // System keys disabled flag + int WindowNoResize; // Resize- and maximize gadgets disabled flag + + // Window status & parameters + int Opened; // Flag telling if window is opened or not + int Active; // Application active flag + int Iconified; // Window iconified flag + int Width, Height; // Window width and heigth + int Accelerated; // GL_TRUE if window is HW accelerated + 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; // Vertical monitor refresh rate + int Samples; + + // Extensions & OpenGL version + int Has_GL_SGIS_generate_mipmap; + int Has_GL_ARB_texture_non_power_of_two; + int GLVerMajor,GLVerMinor; + + +// ========= PLATFORM SPECIFIC PART ====================================== + + // Platform specific window resources + HDC DC; // Private GDI device context + HGLRC RC; // Permanent rendering context + HWND Wnd; // Window handle + ATOM ClassAtom; // Window class atom + int ModeID; // Mode ID for fullscreen mode + HHOOK KeyboardHook; // Keyboard hook handle + DWORD dwStyle; // Window styles used for window creation + DWORD dwExStyle; // --"-- + + // Platform specific extensions (context specific) + WGLSWAPINTERVALEXT_T SwapInterval; + WGLCHOOSEPIXELFORMATARB_T ChoosePixelFormat; + WGLGETPIXELFORMATATTRIBIVARB_T GetPixelFormatAttribiv; + + // Various platform specific internal variables + int OldMouseLock; // Old mouse-lock flag (used for remembering + // mouse-lock state when iconifying) + int OldMouseLockValid; + int DesiredRefreshRate; // Desired vertical monitor refresh rate + +}; + +GLFWGLOBAL _GLFWwin _glfwWin; + + +//------------------------------------------------------------------------ +// User input status (most 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 ====================================== + + // Platform specific internal variables + int MouseMoved, OldMouseX, OldMouseY; + +} _glfwInput; + + +//------------------------------------------------------------------------ +// Library global data +//------------------------------------------------------------------------ +GLFWGLOBAL struct { + +// ========= PLATFORM SPECIFIC PART ====================================== + + HINSTANCE Instance; // Instance of the application + + // Timer data + struct { + int HasPerformanceCounter; + double Resolution; + unsigned int t0_32; + __int64 t0_64; + } Timer; + + // System information + struct { + int WinVer; + int HasUnicode; + DWORD ForegroundLockTimeout; + } Sys; + +#if !defined(_GLFW_NO_DLOAD_WINMM) || !defined(_GLFW_NO_DLOAD_GDI32) + // Library handles and function pointers + struct { +#ifndef _GLFW_NO_DLOAD_GDI32 + // gdi32.dll + HINSTANCE gdi32; + CHOOSEPIXELFORMAT_T ChoosePixelFormat; + DESCRIBEPIXELFORMAT_T DescribePixelFormat; + GETPIXELFORMAT_T GetPixelFormat; + SETPIXELFORMAT_T SetPixelFormat; + SWAPBUFFERS_T SwapBuffers; +#endif // _GLFW_NO_DLOAD_GDI32 + + // winmm.dll +#ifndef _GLFW_NO_DLOAD_WINMM + HINSTANCE winmm; + JOYGETDEVCAPSA_T joyGetDevCapsA; + JOYGETPOS_T joyGetPos; + JOYGETPOSEX_T joyGetPosEx; + TIMEGETTIME_T timeGetTime; +#endif // _GLFW_NO_DLOAD_WINMM + } Libs; +#endif + +} _glfwLibrary; + + +//------------------------------------------------------------------------ +// Thread record (one for each thread) +//------------------------------------------------------------------------ +typedef struct _GLFWthread_struct _GLFWthread; + +struct _GLFWthread_struct { + +// ========= PLATFORM INDEPENDENT MANDATORY PART ========================= + + // Pointer to previous and next threads in linked list + _GLFWthread *Previous, *Next; + + // GLFW user side thread information + GLFWthread ID; + GLFWthreadfun Function; + +// ========= PLATFORM SPECIFIC PART ====================================== + + // System side thread information + HANDLE Handle; + DWORD WinID; + +}; + + +//------------------------------------------------------------------------ +// General thread information +//------------------------------------------------------------------------ +GLFWGLOBAL struct { + +// ========= PLATFORM INDEPENDENT MANDATORY PART ========================= + + // Next thread ID to use (increments for every created thread) + GLFWthread NextID; + + // First thread in linked list (always the main thread) + _GLFWthread First; + +// ========= PLATFORM SPECIFIC PART ====================================== + + // Critical section lock + CRITICAL_SECTION CriticalSection; + +} _glfwThrd; + + + +//======================================================================== +// Macros for encapsulating critical code sections (i.e. making parts +// of GLFW thread safe) +//======================================================================== + +// Thread list management +#define ENTER_THREAD_CRITICAL_SECTION \ + EnterCriticalSection( &_glfwThrd.CriticalSection ); +#define LEAVE_THREAD_CRITICAL_SECTION \ + LeaveCriticalSection( &_glfwThrd.CriticalSection ); + + +//======================================================================== +// Various Windows version constants +//======================================================================== + +#define _GLFW_WIN_UNKNOWN 0x0000 // Earlier than 95 or NT4 +#define _GLFW_WIN_95 0x0001 +#define _GLFW_WIN_98 0x0002 +#define _GLFW_WIN_ME 0x0003 +#define _GLFW_WIN_UNKNOWN_9x 0x0004 // Later than ME +#define _GLFW_WIN_NT4 0x0101 +#define _GLFW_WIN_2K 0x0102 +#define _GLFW_WIN_XP 0x0103 +#define _GLFW_WIN_NET_SERVER 0x0104 +#define _GLFW_WIN_UNKNOWN_NT 0x0105 // Later than .NET Server + + +//======================================================================== +// Prototypes for platform specific internal functions +//======================================================================== + +// Time +void _glfwInitTimer( void ); + +// Fullscreen support +int _glfwGetClosestVideoModeBPP( int *w, int *h, int *bpp, int *refresh ); +int _glfwGetClosestVideoMode( int *w, int *h, int *r, int *g, int *b, int *refresh ); +void _glfwSetVideoModeMODE( int mode ); +void _glfwSetVideoMode( int *w, int *h, int r, int g, int b, int refresh ); + + +#endif // _platform_h_ diff --git a/src/engine/external/glfw/lib/win32/win32_dllmain.c b/src/engine/external/glfw/lib/win32/win32_dllmain.c new file mode 100644 index 00000000..0cfed043 --- /dev/null +++ b/src/engine/external/glfw/lib/win32/win32_dllmain.c @@ -0,0 +1,60 @@ +//======================================================================== +// GLFW - An OpenGL framework +// File: win32_dllmain.c +// Platform: Windows +// 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" + + +#if defined(GLFW_BUILD_DLL) + +//======================================================================== +// DllMain() +//======================================================================== + +int WINAPI DllMain( HINSTANCE hinst, unsigned long reason, void *x ) +{ + // NOTE: Some compilers complains about hinst and x never being used - + // never mind that (we don't want to use them)! + + switch( reason ) + { + case DLL_PROCESS_ATTACH: + // Initializations + //glfwInit(); // We don't want to do that now! + break; + case DLL_PROCESS_DETACH: + // Do some cleanup + glfwTerminate(); + break; + }; + + return 1; +} + +#endif // GLFW_BUILD_DLL diff --git a/src/engine/external/glfw/lib/win32/win32_enable.c b/src/engine/external/glfw/lib/win32/win32_enable.c new file mode 100644 index 00000000..5b0d3294 --- /dev/null +++ b/src/engine/external/glfw/lib/win32/win32_enable.c @@ -0,0 +1,155 @@ +//======================================================================== +// GLFW - An OpenGL framework +// File: win32_enable.c +// Platform: Windows +// 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 **** +//************************************************************************ + +//======================================================================== +// _glfwLLKeyboardProc() - Low level keyboard callback function (used to +// disable system keys under Windows NT). +//======================================================================== + +LRESULT CALLBACK _glfwLLKeyboardProc( int nCode, WPARAM wParam, + LPARAM lParam ) +{ + BOOL syskeys = 0; + PKBDLLHOOKSTRUCT p; + + // We are only looking for keyboard events - interpret lParam as a + // pointer to a KBDLLHOOKSTRUCT + p = (PKBDLLHOOKSTRUCT) lParam; + + // If nCode == HC_ACTION, then we have a keyboard event + if( nCode == HC_ACTION ) + { + switch( wParam ) + { + case WM_KEYDOWN: + case WM_SYSKEYDOWN: + case WM_KEYUP: + case WM_SYSKEYUP: + // Detect: ALT+TAB, ALT+ESC, ALT+F4, CTRL+ESC, + // LWIN, RWIN, APPS (mysterious menu key) + syskeys = ( p->vkCode == VK_TAB && + p->flags & LLKHF_ALTDOWN ) || + ( p->vkCode == VK_ESCAPE && + p->flags & LLKHF_ALTDOWN ) || + ( p->vkCode == VK_F4 && + p->flags & LLKHF_ALTDOWN ) || + ( p->vkCode == VK_ESCAPE && + (GetKeyState(VK_CONTROL) & 0x8000)) || + p->vkCode == VK_LWIN || + p->vkCode == VK_RWIN || + p->vkCode == VK_APPS; + break; + + default: + break; + } + } + + // Was it a system key combination (e.g. ALT+TAB)? + if( syskeys ) + { + // Pass the key event to our window message loop + if( _glfwWin.Opened ) + { + PostMessage( _glfwWin.Wnd, (UINT) wParam, p->vkCode, 0 ); + } + + // We've taken care of it - don't let the system know about this + // key event + return 1; + } + else + { + // It's a harmless key press, let the system deal with it + return CallNextHookEx( _glfwWin.KeyboardHook, nCode, wParam, + lParam ); + } +} + + + +//************************************************************************ +//**** Platform implementation functions **** +//************************************************************************ + +//======================================================================== +// _glfwPlatformEnableSystemKeys() - Enable system keys +// _glfwPlatformDisableSystemKeys() - Disable system keys +//======================================================================== + +void _glfwPlatformEnableSystemKeys( void ) +{ + BOOL bOld; + + // Use different methods depending on operating system version + if( _glfwLibrary.Sys.WinVer >= _GLFW_WIN_NT4 ) + { + if( _glfwWin.KeyboardHook != NULL ) + { + UnhookWindowsHookEx( _glfwWin.KeyboardHook ); + _glfwWin.KeyboardHook = NULL; + } + } + else + { + (void) SystemParametersInfo( SPI_SETSCREENSAVERRUNNING, FALSE, + &bOld, 0 ); + } +} + +void _glfwPlatformDisableSystemKeys( void ) +{ + BOOL bOld; + + // Use different methods depending on operating system version + if( _glfwLibrary.Sys.WinVer >= _GLFW_WIN_NT4 ) + { + // Under Windows NT, install a low level keyboard hook + _glfwWin.KeyboardHook = SetWindowsHookEx( WH_KEYBOARD_LL, + _glfwLLKeyboardProc, + _glfwLibrary.Instance, + 0 ); + } + else + { + // Under Windows 95/98/ME, fool Windows that a screensaver + // is running => prevents ALT+TAB, CTRL+ESC and CTRL+ALT+DEL + (void) SystemParametersInfo( SPI_SETSCREENSAVERRUNNING, TRUE, + &bOld, 0 ); + } +} + diff --git a/src/engine/external/glfw/lib/win32/win32_fullscreen.c b/src/engine/external/glfw/lib/win32/win32_fullscreen.c new file mode 100644 index 00000000..fcecee67 --- /dev/null +++ b/src/engine/external/glfw/lib/win32/win32_fullscreen.c @@ -0,0 +1,317 @@ +//======================================================================== +// GLFW - An OpenGL framework +// File: win32_fullscreen.c +// Platform: Windows +// 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 **** +//************************************************************************ + +//======================================================================== +// _glfwBPP2RGB() - Convert BPP to RGB bits (based on "best guess") +//======================================================================== + +static void _glfwBPP2RGB( int bpp, int *r, int *g, int *b ) +{ + int delta; + + // Special case: BPP = 32 + if( bpp == 32 ) bpp = 24; + + // Convert "bits per pixel" to red, green & blue sizes + *r = *g = *b = bpp / 3; + delta = bpp - (*r * 3); + if( delta >= 1 ) + { + *g = *g + 1; + } + if( delta == 2 ) + { + *r = *r + 1; + } +} + + +//======================================================================== +// _glfwGetClosestVideoModeBPP() +//======================================================================== + +int _glfwGetClosestVideoModeBPP( int *w, int *h, int *bpp, int *refresh ) +{ + int mode, bestmode, match, bestmatch, rr, bestrr, success; + DEVMODE dm; + + // Find best match + bestmatch = 0x7fffffff; + bestrr = 0x7fffffff; + mode = bestmode = 0; + do + { + dm.dmSize = sizeof( DEVMODE ); + success = EnumDisplaySettings( NULL, mode, &dm ); + if( success ) + { + match = dm.dmBitsPerPel - *bpp; + if( match < 0 ) match = -match; + match = ( match << 25 ) | + ( (dm.dmPelsWidth - *w) * + (dm.dmPelsWidth - *w) + + (dm.dmPelsHeight - *h) * + (dm.dmPelsHeight - *h) ); + if( match < bestmatch ) + { + bestmatch = match; + bestmode = mode; + bestrr = (dm.dmDisplayFrequency - *refresh) * + (dm.dmDisplayFrequency - *refresh); + } + else if( match == bestmatch && *refresh > 0 ) + { + rr = (dm.dmDisplayFrequency - *refresh) * + (dm.dmDisplayFrequency - *refresh); + if( rr < bestrr ) + { + bestmatch = match; + bestmode = mode; + bestrr = rr; + } + } + } + mode ++; + } + while( success ); + + // Get the parameters for the best matching display mode + dm.dmSize = sizeof( DEVMODE ); + (void) EnumDisplaySettings( NULL, bestmode, &dm ); + + // Fill out actual width and height + *w = dm.dmPelsWidth; + *h = dm.dmPelsHeight; + + // Return bits per pixel + *bpp = dm.dmBitsPerPel; + + // Return vertical refresh rate + *refresh = dm.dmDisplayFrequency; + + return bestmode; +} + + +//======================================================================== +// _glfwGetClosestVideoMode() +//======================================================================== + +int _glfwGetClosestVideoMode( int *w, int *h, int *r, int *g, int *b, + int *refresh ) +{ + int bpp, bestmode; + + // Colorbits = sum of red/green/blue bits + bpp = *r + *g + *b; + + // If colorbits < 15 (e.g. 0) or >= 24, default to 32 bpp + if( bpp < 15 || bpp >= 24 ) + { + bpp = 32; + } + + // Find best match + bestmode = _glfwGetClosestVideoModeBPP( w, h, &bpp, refresh ); + + // Convert "bits per pixel" to red, green & blue sizes + _glfwBPP2RGB( bpp, r, g, b ); + + return bestmode; +} + + +//======================================================================== +// Change the current video mode +//======================================================================== + +void _glfwSetVideoModeMODE( int mode ) +{ + DEVMODE dm; + int success; + + // Get the parameters for the best matching display mode + dm.dmSize = sizeof( DEVMODE ); + (void) EnumDisplaySettings( NULL, mode, &dm ); + + // Set which fields we want to specify + dm.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL; + + // Do we have a prefered refresh rate? + if( _glfwWin.DesiredRefreshRate > 0 ) + { + dm.dmFields = dm.dmFields | DM_DISPLAYFREQUENCY; + dm.dmDisplayFrequency = _glfwWin.DesiredRefreshRate; + } + + // Change display setting + dm.dmSize = sizeof( DEVMODE ); + success = ChangeDisplaySettings( &dm, CDS_FULLSCREEN ); + + // If the mode change was not possible, query the current display + // settings (we'll use the desktop resolution for fullscreen mode) + if( success == DISP_CHANGE_SUCCESSFUL ) + { + _glfwWin.ModeID = mode; + } + else + { + _glfwWin.ModeID = ENUM_REGISTRY_SETTINGS; + EnumDisplaySettings( NULL, ENUM_REGISTRY_SETTINGS, &dm ); + } + + // Set the window size to that of the display mode + _glfwWin.Width = dm.dmPelsWidth; + _glfwWin.Height = dm.dmPelsHeight; +} + + +//======================================================================== +// _glfwSetVideoMode() - Change the current video mode +//======================================================================== + +void _glfwSetVideoMode( int *w, int *h, int r, int g, int b, int refresh ) +{ + int bestmode; + + // Find a best match mode + bestmode = _glfwGetClosestVideoMode( w, h, &r, &g, &b, &refresh ); + + // Change mode + _glfwSetVideoModeMODE( bestmode ); +} + + +//************************************************************************ +//**** GLFW user functions **** +//************************************************************************ + +//======================================================================== +// _glfwPlatformGetVideoModes() - Get a list of available video modes +//======================================================================== + +int _glfwPlatformGetVideoModes( GLFWvidmode *list, int maxcount ) +{ + int count, success, mode, i, j; + int m1, m2, bpp, r, g, b; + DEVMODE dm; + + // Loop through all video modes and extract all the UNIQUE modes + count = 0; + mode = 0; + do + { + // Get video mode properties + dm.dmSize = sizeof( DEVMODE ); + success = EnumDisplaySettings( NULL, mode, &dm ); + + // Is it a valid mode? (only list depths >= 15 bpp) + if( success && dm.dmBitsPerPel >= 15 ) + { + // Convert to RGB, and back to bpp ("mask out" alpha bits etc) + _glfwBPP2RGB( dm.dmBitsPerPel, &r, &g, &b ); + bpp = r + g + b; + + // Mode "code" for this mode + m1 = (bpp << 25) | (dm.dmPelsWidth * dm.dmPelsHeight); + + // Insert mode in list (sorted), and avoid duplicates + for( i = 0; i < count; i ++ ) + { + // Mode "code" for already listed mode + bpp = list[i].RedBits + list[i].GreenBits + + list[i].BlueBits; + m2 = (bpp << 25) | (list[i].Width * list[i].Height); + if( m1 <= m2 ) + { + break; + } + } + + // New entry at the end of the list? + if( i >= count ) + { + list[count].Width = dm.dmPelsWidth; + list[count].Height = dm.dmPelsHeight; + list[count].RedBits = r; + list[count].GreenBits = g; + list[count].BlueBits = b; + count ++; + } + // Insert new entry in the list? + else if( m1 < m2 ) + { + for( j = count; j > i; j -- ) + { + list[j] = list[j-1]; + } + list[i].Width = dm.dmPelsWidth; + list[i].Height = dm.dmPelsHeight; + list[i].RedBits = r; + list[i].GreenBits = g; + list[i].BlueBits = b; + count ++; + } + } + mode ++; + } + while( success && (count < maxcount) ); + + return count; +} + + +//======================================================================== +// _glfwPlatformGetDesktopMode() - Get the desktop video mode +//======================================================================== + +void _glfwPlatformGetDesktopMode( GLFWvidmode *mode ) +{ + DEVMODE dm; + + // Get desktop display mode + dm.dmSize = sizeof( DEVMODE ); + (void) EnumDisplaySettings( NULL, ENUM_REGISTRY_SETTINGS, &dm ); + + // Return desktop mode parameters + mode->Width = dm.dmPelsWidth; + mode->Height = dm.dmPelsHeight; + _glfwBPP2RGB( dm.dmBitsPerPel, &mode->RedBits, &mode->GreenBits, + &mode->BlueBits ); +} + + diff --git a/src/engine/external/glfw/lib/win32/win32_glext.c b/src/engine/external/glfw/lib/win32/win32_glext.c new file mode 100644 index 00000000..00d2767d --- /dev/null +++ b/src/engine/external/glfw/lib/win32/win32_glext.c @@ -0,0 +1,101 @@ +//======================================================================== +// GLFW - An OpenGL framework +// File: win32_glext.c +// Platform: Windows +// 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" + + +//======================================================================== +// We use the WGL_EXT_extensions_string if it is available, or +// WGL_ARB_extensions_string if it is available. +//======================================================================== + +typedef const char *(APIENTRY * WGLGETEXTENSIONSSTRINGEXT_T)( void ); +typedef const char *(APIENTRY * WGLGETEXTENSIONSSTRINGARB_T)( HDC hdc ); + + + +//************************************************************************ +//**** Platform implementation functions **** +//************************************************************************ + +//======================================================================== +// Check if an OpenGL extension is available at runtime (Windows version checks +// for WGL extensions) +//======================================================================== + +int _glfwPlatformExtensionSupported( const char *extension ) +{ + const GLubyte *extensions; + WGLGETEXTENSIONSSTRINGEXT_T _wglGetExtensionsStringEXT; + WGLGETEXTENSIONSSTRINGARB_T _wglGetExtensionsStringARB; + + // Try wglGetExtensionsStringEXT + _wglGetExtensionsStringEXT = (WGLGETEXTENSIONSSTRINGEXT_T) + wglGetProcAddress( "wglGetExtensionsStringEXT" ); + if( _wglGetExtensionsStringEXT != NULL ) + { + extensions = (GLubyte *) _wglGetExtensionsStringEXT(); + if( extensions != NULL ) + { + if( _glfwStringInExtensionString( extension, extensions ) ) + { + return GL_TRUE; + } + } + } + + // Try wglGetExtensionsStringARB + _wglGetExtensionsStringARB = (WGLGETEXTENSIONSSTRINGARB_T) + wglGetProcAddress( "wglGetExtensionsStringARB" ); + if( _wglGetExtensionsStringARB != NULL ) + { + extensions = (GLubyte *) _wglGetExtensionsStringARB(_glfwWin.DC); + if( extensions != NULL ) + { + if( _glfwStringInExtensionString( extension, extensions ) ) + { + return GL_TRUE; + } + } + } + + return GL_FALSE; +} + + +//======================================================================== +// Get the function pointer to an OpenGL function +//======================================================================== + +void * _glfwPlatformGetProcAddress( const char *procname ) +{ + return (void *) wglGetProcAddress( procname ); +} + diff --git a/src/engine/external/glfw/lib/win32/win32_init.c b/src/engine/external/glfw/lib/win32/win32_init.c new file mode 100644 index 00000000..41d7150a --- /dev/null +++ b/src/engine/external/glfw/lib/win32/win32_init.c @@ -0,0 +1,356 @@ +//======================================================================== +// GLFW - An OpenGL framework +// File: win32_init.c +// Platform: Windows +// 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" + +// With the Borland C++ compiler, we want to disable FPU exceptions +#ifdef __BORLANDC__ +#include <float.h> +#endif // __BORLANDC__ + + + +//************************************************************************ +//**** GLFW internal functions **** +//************************************************************************ + +//======================================================================== +// _glfwInitLibraries() - Load necessary libraries (DLLs) +//======================================================================== + +static int _glfwInitLibraries( void ) +{ + // gdi32.dll (OpenGL pixel format functions & SwapBuffers) +#ifndef _GLFW_NO_DLOAD_GDI32 + _glfwLibrary.Libs.gdi32 = LoadLibrary( "gdi32.dll" ); + if( _glfwLibrary.Libs.gdi32 != NULL ) + { + _glfwLibrary.Libs.ChoosePixelFormat = (CHOOSEPIXELFORMAT_T) + GetProcAddress( _glfwLibrary.Libs.gdi32, "ChoosePixelFormat" ); + _glfwLibrary.Libs.DescribePixelFormat = (DESCRIBEPIXELFORMAT_T) + GetProcAddress( _glfwLibrary.Libs.gdi32, "DescribePixelFormat" ); + _glfwLibrary.Libs.GetPixelFormat = (GETPIXELFORMAT_T) + GetProcAddress( _glfwLibrary.Libs.gdi32, "GetPixelFormat" ); + _glfwLibrary.Libs.SetPixelFormat = (SETPIXELFORMAT_T) + GetProcAddress( _glfwLibrary.Libs.gdi32, "SetPixelFormat" ); + _glfwLibrary.Libs.SwapBuffers = (SWAPBUFFERS_T) + GetProcAddress( _glfwLibrary.Libs.gdi32, "SwapBuffers" ); + if( _glfwLibrary.Libs.ChoosePixelFormat == NULL || + _glfwLibrary.Libs.DescribePixelFormat == NULL || + _glfwLibrary.Libs.GetPixelFormat == NULL || + _glfwLibrary.Libs.SetPixelFormat == NULL || + _glfwLibrary.Libs.SwapBuffers == NULL ) + { + FreeLibrary( _glfwLibrary.Libs.gdi32 ); + _glfwLibrary.Libs.gdi32 = NULL; + return GL_FALSE; + } + } + else + { + return GL_FALSE; + } +#endif // _GLFW_NO_DLOAD_GDI32 + + // winmm.dll (for joystick and timer support) +#ifndef _GLFW_NO_DLOAD_WINMM + _glfwLibrary.Libs.winmm = LoadLibrary( "winmm.dll" ); + if( _glfwLibrary.Libs.winmm != NULL ) + { + _glfwLibrary.Libs.joyGetDevCapsA = (JOYGETDEVCAPSA_T) + GetProcAddress( _glfwLibrary.Libs.winmm, "joyGetDevCapsA" ); + _glfwLibrary.Libs.joyGetPos = (JOYGETPOS_T) + GetProcAddress( _glfwLibrary.Libs.winmm, "joyGetPos" ); + _glfwLibrary.Libs.joyGetPosEx = (JOYGETPOSEX_T) + GetProcAddress( _glfwLibrary.Libs.winmm, "joyGetPosEx" ); + _glfwLibrary.Libs.timeGetTime = (TIMEGETTIME_T) + GetProcAddress( _glfwLibrary.Libs.winmm, "timeGetTime" ); + if( _glfwLibrary.Libs.joyGetDevCapsA == NULL || + _glfwLibrary.Libs.joyGetPos == NULL || + _glfwLibrary.Libs.joyGetPosEx == NULL || + _glfwLibrary.Libs.timeGetTime == NULL ) + { + FreeLibrary( _glfwLibrary.Libs.winmm ); + _glfwLibrary.Libs.winmm = NULL; + return GL_FALSE; + } + } + else + { + return GL_FALSE; + } +#endif // _GLFW_NO_DLOAD_WINMM + + return GL_TRUE; +} + + +//======================================================================== +// _glfwFreeLibraries() - Unload used libraries (DLLs) +//======================================================================== + +static void _glfwFreeLibraries( void ) +{ + // gdi32.dll +#ifndef _GLFW_NO_DLOAD_GDI32 + if( _glfwLibrary.Libs.gdi32 != NULL ) + { + FreeLibrary( _glfwLibrary.Libs.gdi32 ); + _glfwLibrary.Libs.gdi32 = NULL; + } +#endif // _GLFW_NO_DLOAD_GDI32 + + // winmm.dll +#ifndef _GLFW_NO_DLOAD_WINMM + if( _glfwLibrary.Libs.winmm != NULL ) + { + FreeLibrary( _glfwLibrary.Libs.winmm ); + _glfwLibrary.Libs.winmm = NULL; + } +#endif // _GLFW_NO_DLOAD_WINMM +} + + +//======================================================================== +// _glfwInitThreads() - Initialize GLFW thread package +//======================================================================== + +static void _glfwInitThreads( void ) +{ + // Initialize critical section handle + InitializeCriticalSection( &_glfwThrd.CriticalSection ); + + // 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.Handle = GetCurrentThread(); + _glfwThrd.First.WinID = GetCurrentThreadId(); + _glfwThrd.First.Previous = NULL; + _glfwThrd.First.Next = NULL; +} + + +//======================================================================== +// _glfwTerminateThreads() - Terminate GLFW thread package +//======================================================================== + +static void _glfwTerminateThreads( void ) +{ + _GLFWthread *t, *t_next; + + // Enter critical section + ENTER_THREAD_CRITICAL_SECTION + + // Kill all threads (NOTE: THE USER SHOULD WAIT FOR ALL THREADS TO + // DIE, _BEFORE_ CALLING glfwTerminate()!!!) + t = _glfwThrd.First.Next; + while( t != NULL ) + { + // Get pointer to next thread + t_next = t->Next; + + // Simply murder the process, no mercy! + if( TerminateThread( t->Handle, 0 ) ) + { + // Close thread handle + CloseHandle( t->Handle ); + + // Free memory allocated for this thread + free( (void *) t ); + } + + // Select next thread in list + t = t_next; + } + + // Leave critical section + LEAVE_THREAD_CRITICAL_SECTION + + // Delete critical section handle + DeleteCriticalSection( &_glfwThrd.CriticalSection ); +} + + +//======================================================================== +// _glfwTerminate_atexit() - Terminate GLFW when exiting application +//======================================================================== + +void _glfwTerminate_atexit( void ) +{ + glfwTerminate(); +} + + + +//************************************************************************ +//**** Platform implementation functions **** +//************************************************************************ + +//======================================================================== +// _glfwPlatformInit() - Initialize various GLFW state +//======================================================================== + +int _glfwPlatformInit( void ) +{ + OSVERSIONINFO osi; + + // To make SetForegroundWindow() work as we want, we need to fiddle + // with the FOREGROUNDLOCKTIMEOUT system setting (we do this as early + // as possible in the hope of still being the foreground process) + SystemParametersInfo( SPI_GETFOREGROUNDLOCKTIMEOUT, 0, + &_glfwLibrary.Sys.ForegroundLockTimeout, 0 ); + SystemParametersInfo( SPI_SETFOREGROUNDLOCKTIMEOUT, 0, (LPVOID)0, + SPIF_SENDCHANGE ); + + // Check which OS version we are running + osi.dwOSVersionInfoSize = sizeof( OSVERSIONINFO ); + GetVersionEx( &osi ); + _glfwLibrary.Sys.WinVer = _GLFW_WIN_UNKNOWN; + if( osi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS ) + { + if( osi.dwMajorVersion == 4 && osi.dwMinorVersion < 10 ) + { + _glfwLibrary.Sys.WinVer = _GLFW_WIN_95; + } + else if( osi.dwMajorVersion == 4 && osi.dwMinorVersion < 90 ) + { + _glfwLibrary.Sys.WinVer = _GLFW_WIN_98; + } + else if( osi.dwMajorVersion == 4 && osi.dwMinorVersion == 90 ) + { + _glfwLibrary.Sys.WinVer = _GLFW_WIN_ME; + } + else if( osi.dwMajorVersion >= 4 ) + { + _glfwLibrary.Sys.WinVer = _GLFW_WIN_UNKNOWN_9x; + } + } + else if( osi.dwPlatformId == VER_PLATFORM_WIN32_NT ) + { + if( osi.dwMajorVersion == 4 && osi.dwMinorVersion == 0 ) + { + _glfwLibrary.Sys.WinVer = _GLFW_WIN_NT4; + } + else if( osi.dwMajorVersion == 5 && osi.dwMinorVersion == 0 ) + { + _glfwLibrary.Sys.WinVer = _GLFW_WIN_2K; + } + else if( osi.dwMajorVersion == 5 && osi.dwMinorVersion == 1 ) + { + _glfwLibrary.Sys.WinVer = _GLFW_WIN_XP; + } + else if( osi.dwMajorVersion == 5 && osi.dwMinorVersion == 2 ) + { + _glfwLibrary.Sys.WinVer = _GLFW_WIN_NET_SERVER; + } + else if( osi.dwMajorVersion >= 5 ) + { + _glfwLibrary.Sys.WinVer = _GLFW_WIN_UNKNOWN_NT; + } + } + + // Do we have Unicode support? + if( _glfwLibrary.Sys.WinVer >= _GLFW_WIN_NT4 ) + { + // Windows NT/2000/XP/.NET has Unicode support + _glfwLibrary.Sys.HasUnicode = GL_TRUE; + } + else + { + // Windows 9x/ME does not have Unicode support + _glfwLibrary.Sys.HasUnicode = GL_FALSE; + } + + // Load libraries (DLLs) + if( !_glfwInitLibraries() ) + { + return GL_FALSE; + } + + // With the Borland C++ compiler, we want to disable FPU exceptions + // (this is recommended for OpenGL applications under Windows) +#ifdef __BORLANDC__ + _control87( MCW_EM, MCW_EM ); +#endif + + // Retrieve GLFW instance handle + _glfwLibrary.Instance = GetModuleHandle( NULL ); + + // System keys are not disabled + _glfwWin.KeyboardHook = NULL; + + // Initialise thread package + _glfwInitThreads(); + + // Install atexit() routine + atexit( _glfwTerminate_atexit ); + + // Start the timer + _glfwInitTimer(); + + return GL_TRUE; +} + + +//======================================================================== +// _glfwPlatformTerminate() - Close window and kill all threads +//======================================================================== + +int _glfwPlatformTerminate( void ) +{ + // Only the main thread is allowed to do this... + if( GetCurrentThreadId() != _glfwThrd.First.WinID ) + { + return GL_FALSE; + } + + // Close OpenGL window + glfwCloseWindow(); + + // Kill thread package + _glfwTerminateThreads(); + + // Enable system keys again (if they were disabled) + glfwEnable( GLFW_SYSTEM_KEYS ); + + // Unload libraries (DLLs) + _glfwFreeLibraries(); + + // Restore FOREGROUNDLOCKTIMEOUT system setting + SystemParametersInfo( SPI_SETFOREGROUNDLOCKTIMEOUT, 0, + (LPVOID)_glfwLibrary.Sys.ForegroundLockTimeout, + SPIF_SENDCHANGE ); + + return GL_TRUE; +} + diff --git a/src/engine/external/glfw/lib/win32/win32_joystick.c b/src/engine/external/glfw/lib/win32/win32_joystick.c new file mode 100644 index 00000000..5ab00319 --- /dev/null +++ b/src/engine/external/glfw/lib/win32/win32_joystick.c @@ -0,0 +1,234 @@ +//======================================================================== +// GLFW - An OpenGL framework +// File: win32_joystick.c +// Platform: Windows +// 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 **** +//************************************************************************ + +//======================================================================== +// _glfwJoystickPresent() - Return GL_TRUE if joystick is present, +// else return GL_FALSE. +//======================================================================== + +static int _glfwJoystickPresent( int joy ) +{ + JOYINFO ji; + + // Windows NT 4.0 MMSYSTEM only supports 2 sticks (other Windows + // versions support 16 sticks) + if( _glfwLibrary.Sys.WinVer == _GLFW_WIN_NT4 && joy > GLFW_JOYSTICK_2 ) + { + return GL_FALSE; + } + + // Is it a valid stick ID (Windows don't support more than 16 sticks)? + if( joy < GLFW_JOYSTICK_1 || joy > GLFW_JOYSTICK_16 ) + { + return GL_FALSE; + } + + // Is the joystick present? + if( _glfw_joyGetPos( joy - GLFW_JOYSTICK_1, &ji ) != JOYERR_NOERROR ) + { + return GL_FALSE; + } + + return GL_TRUE; +} + + +//======================================================================== +// _glfwCalcJoystickPos() - Calculate joystick position +//======================================================================== + +static float _glfwCalcJoystickPos( DWORD pos, DWORD min, DWORD max ) +{ + float fpos = (float) pos; + float fmin = (float) min; + float fmax = (float) max; + return (2.0f*(fpos - fmin) / (fmax - fmin)) - 1.0f; +} + + + +//************************************************************************ +//**** Platform implementation functions **** +//************************************************************************ + +//======================================================================== +// _glfwPlatformGetJoystickParam() - Determine joystick capabilities +//======================================================================== + +int _glfwPlatformGetJoystickParam( int joy, int param ) +{ + JOYCAPS jc; + +// return 0; + + // Is joystick present? + if( !_glfwJoystickPresent( joy ) ) + { + return 0; + } + + // We got this far, the joystick is present + if( param == GLFW_PRESENT ) + { + return GL_TRUE; + } + + // Get joystick capabilities + _glfw_joyGetDevCaps( joy - GLFW_JOYSTICK_1, &jc, sizeof(JOYCAPS) ); + + switch( param ) + { + case GLFW_AXES: + // Return number of joystick axes + return jc.wNumAxes; + + case GLFW_BUTTONS: + // Return number of joystick axes + return jc.wNumButtons; + + default: + break; + } + + return 0; +} + + +//======================================================================== +// _glfwPlatformGetJoystickPos() - Get joystick axis positions +//======================================================================== + +int _glfwPlatformGetJoystickPos( int joy, float *pos, int numaxes ) +{ + JOYCAPS jc; + JOYINFOEX ji; + int axis; + +// return 0; + + // Is joystick present? + if( !_glfwJoystickPresent( joy ) ) + { + return 0; + } + + // Get joystick capabilities + _glfw_joyGetDevCaps( joy - GLFW_JOYSTICK_1, &jc, sizeof(JOYCAPS) ); + + // Get joystick state + ji.dwSize = sizeof( JOYINFOEX ); + ji.dwFlags = JOY_RETURNX | JOY_RETURNY | JOY_RETURNZ | + JOY_RETURNR | JOY_RETURNU | JOY_RETURNV; + _glfw_joyGetPosEx( joy - GLFW_JOYSTICK_1, &ji ); + + // Get position values for all axes + axis = 0; + if( axis < numaxes ) + { + pos[ axis++ ] = _glfwCalcJoystickPos( ji.dwXpos, jc.wXmin, + jc.wXmax ); + } + if( axis < numaxes ) + { + pos[ axis++ ] = -_glfwCalcJoystickPos( ji.dwYpos, jc.wYmin, + jc.wYmax ); + } + if( axis < numaxes && jc.wCaps & JOYCAPS_HASZ ) + { + pos[ axis++ ] = _glfwCalcJoystickPos( ji.dwZpos, jc.wZmin, + jc.wZmax ); + } + if( axis < numaxes && jc.wCaps & JOYCAPS_HASR ) + { + pos[ axis++ ] = _glfwCalcJoystickPos( ji.dwRpos, jc.wRmin, + jc.wRmax ); + } + if( axis < numaxes && jc.wCaps & JOYCAPS_HASU ) + { + pos[ axis++ ] = _glfwCalcJoystickPos( ji.dwUpos, jc.wUmin, + jc.wUmax ); + } + if( axis < numaxes && jc.wCaps & JOYCAPS_HASV ) + { + pos[ axis++ ] = -_glfwCalcJoystickPos( ji.dwVpos, jc.wVmin, + jc.wVmax ); + } + + // Return number of returned axes + return axis; +} + + +//======================================================================== +// _glfwPlatformGetJoystickButtons() - Get joystick button states +//======================================================================== + +int _glfwPlatformGetJoystickButtons( int joy, unsigned char *buttons, + int numbuttons ) +{ + JOYCAPS jc; + JOYINFOEX ji; + int button; + +// return 0; + + // Is joystick present? + if( !_glfwJoystickPresent( joy ) ) + { + return 0; + } + + // Get joystick capabilities + _glfw_joyGetDevCaps( joy - GLFW_JOYSTICK_1, &jc, sizeof(JOYCAPS) ); + + // Get joystick state + ji.dwSize = sizeof( JOYINFOEX ); + ji.dwFlags = JOY_RETURNBUTTONS; + _glfw_joyGetPosEx( joy - GLFW_JOYSTICK_1, &ji ); + + // Get states of all requested buttons + button = 0; + while( button < numbuttons && button < (int) jc.wNumButtons ) + { + buttons[ button ] = (unsigned char) + (ji.dwButtons & (1UL << button) ? GLFW_PRESS : GLFW_RELEASE); + button ++; + } + + return button; +} + diff --git a/src/engine/external/glfw/lib/win32/win32_thread.c b/src/engine/external/glfw/lib/win32/win32_thread.c new file mode 100644 index 00000000..159347a7 --- /dev/null +++ b/src/engine/external/glfw/lib/win32/win32_thread.c @@ -0,0 +1,511 @@ +//======================================================================== +// GLFW - An OpenGL framework +// File: win32_thread.c +// Platform: Windows +// 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" + + +//************************************************************************ +// This is an implementation of POSIX "compatible" condition variables for +// Win32, as described by Douglas C. Schmidt and Irfan Pyarali: +// http://www.cs.wustl.edu/~schmidt/win32-cv-1.html +//************************************************************************ + +enum { + _GLFW_COND_SIGNAL = 0, + _GLFW_COND_BROADCAST = 1 +}; + +typedef struct { + // Signal and broadcast event HANDLEs + HANDLE events[ 2 ]; + + // Count of the number of waiters + unsigned int waiters_count; + + // Serialize access to <waiters_count> + CRITICAL_SECTION waiters_count_lock; +} _GLFWcond; + + + +//************************************************************************ +//**** GLFW internal functions **** +//************************************************************************ + +//======================================================================== +// _glfwNewThread() - This is simply a "wrapper" for calling the user +// thread function. +//======================================================================== + +DWORD WINAPI _glfwNewThread( LPVOID lpParam ) +{ + GLFWthreadfun threadfun; + _GLFWthread *t; + + // Get pointer to thread information for current thread + t = _glfwGetThreadPointer( _glfwPlatformGetThreadID() ); + if( t == NULL ) + { + return 0; + } + + // Get user thread function pointer + threadfun = t->Function; + + // Call the user thread function + threadfun( (void *) lpParam ); + + // 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 0; +} + + + +//************************************************************************ +//**** GLFW user functions **** +//************************************************************************ + +//======================================================================== +// _glfwPlatformCreateThread() - Create a new thread +//======================================================================== + +GLFWthread _glfwPlatformCreateThread( GLFWthreadfun fun, void *arg ) +{ + GLFWthread ID; + _GLFWthread *t, *t_tmp; + HANDLE hThread; + DWORD dwThreadId; + + // 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 + hThread = CreateThread( + NULL, // Default security attributes + 0, // Default stack size (1 MB) + _glfwNewThread, // Thread function (a wrapper function) + (LPVOID)arg, // Argument to thread is the user argument + 0, // Default creation flags + &dwThreadId // Returned thread identifier + ); + + // Did the thread creation fail? + if( hThread == NULL ) + { + free( (void *) t ); + LEAVE_THREAD_CRITICAL_SECTION + return -1; + } + + // Store more thread information in the thread list + t->Handle = hThread; + t->WinID = dwThreadId; + + // Append thread to thread list + t_tmp = &_glfwThrd.First; + while( t_tmp->Next != NULL ) + { + t_tmp = t_tmp->Next; + } + t_tmp->Next = t; + t->Previous = t_tmp; + t->Next = NULL; + + // 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! + if( TerminateThread( t->Handle, 0 ) ) + { + // Close thread handle + CloseHandle( t->Handle ); + + // 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 ) +{ + DWORD result; + HANDLE hThread; + _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; + } + + // Get thread handle + hThread = t->Handle; + + // Leave critical section + LEAVE_THREAD_CRITICAL_SECTION + + // Wait for thread to die + if( waitmode == GLFW_WAIT ) + { + result = WaitForSingleObject( hThread, INFINITE ); + } + else if( waitmode == GLFW_NOWAIT ) + { + result = WaitForSingleObject( hThread, 0 ); + } + else + { + return GL_FALSE; + } + + // Did we have a time-out? + if( result == WAIT_TIMEOUT ) + { + return GL_FALSE; + } + return GL_TRUE; +} + + +//======================================================================== +// _glfwPlatformGetThreadID() - Return the thread ID for the current +// thread +//======================================================================== + +GLFWthread _glfwPlatformGetThreadID( void ) +{ + _GLFWthread *t; + GLFWthread ID = -1; + DWORD WinID; + + // Get Windows thread ID + WinID = GetCurrentThreadId(); + + // Enter critical section (to avoid an inconsistent thread list) + ENTER_THREAD_CRITICAL_SECTION + + // Loop through entire list of threads to find the matching Windows + // thread ID + for( t = &_glfwThrd.First; t != NULL; t = t->Next ) + { + if( t->WinID == WinID ) + { + 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 ) +{ + CRITICAL_SECTION *mutex; + + // Allocate memory for mutex + mutex = (CRITICAL_SECTION *) malloc( sizeof(CRITICAL_SECTION) ); + if( !mutex ) + { + return NULL; + } + + // Initialize mutex + InitializeCriticalSection( mutex ); + + // Cast to GLFWmutex and return + return (GLFWmutex) mutex; +} + + +//======================================================================== +// glfwDestroyMutex() - Destroy a mutual exclusion object +//======================================================================== + +void _glfwPlatformDestroyMutex( GLFWmutex mutex ) +{ + // Destroy mutex + DeleteCriticalSection( (CRITICAL_SECTION *) mutex ); + free( mutex ); +} + + +//======================================================================== +// _glfwPlatformLockMutex() - Request access to a mutex +//======================================================================== + +void _glfwPlatformLockMutex( GLFWmutex mutex ) +{ + // Wait for mutex to be released + EnterCriticalSection( (CRITICAL_SECTION *) mutex ); +} + + +//======================================================================== +// _glfwPlatformUnlockMutex() - Release a mutex +//======================================================================== + +void _glfwPlatformUnlockMutex( GLFWmutex mutex ) +{ + // Release mutex + LeaveCriticalSection( (CRITICAL_SECTION *) mutex ); +} + + +//======================================================================== +// _glfwPlatformCreateCond() - Create a new condition variable object +//======================================================================== + +GLFWcond _glfwPlatformCreateCond( void ) +{ + _GLFWcond *cond; + + // Allocate memory for condition variable + cond = (_GLFWcond *) malloc( sizeof(_GLFWcond) ); + if( !cond ) + { + return NULL; + } + + // Initialize condition variable + cond->waiters_count = 0; + cond->events[ _GLFW_COND_SIGNAL ] = CreateEvent( NULL, FALSE, + FALSE, NULL ); + cond->events[ _GLFW_COND_BROADCAST ] = CreateEvent( NULL, TRUE, + FALSE, NULL ); + InitializeCriticalSection( &cond->waiters_count_lock ); + + // Cast to GLFWcond and return + return (GLFWcond) cond; +} + + +//======================================================================== +// _glfwPlatformDestroyCond() - Destroy a condition variable object +//======================================================================== + +void _glfwPlatformDestroyCond( GLFWcond cond ) +{ + // Close the condition variable handles + CloseHandle( ((_GLFWcond *)cond)->events[ _GLFW_COND_SIGNAL ] ); + CloseHandle( ((_GLFWcond *)cond)->events[ _GLFW_COND_BROADCAST ] ); + + // Delete critical section + DeleteCriticalSection( &((_GLFWcond *)cond)->waiters_count_lock ); + + // Free memory for condition variable + free( (void *) cond ); +} + + +//======================================================================== +// _glfwPlatformWaitCond() - Wait for a condition to be raised +//======================================================================== + +void _glfwPlatformWaitCond( GLFWcond cond, GLFWmutex mutex, + double timeout ) +{ + _GLFWcond *cv = (_GLFWcond *) cond; + int result, last_waiter; + DWORD timeout_ms; + + // Avoid race conditions + EnterCriticalSection( &cv->waiters_count_lock ); + cv->waiters_count ++; + LeaveCriticalSection( &cv->waiters_count_lock ); + + // It's ok to release the mutex here since Win32 manual-reset events + // maintain state when used with SetEvent() + LeaveCriticalSection( (CRITICAL_SECTION *) mutex ); + + // Translate timeout into milliseconds + if( timeout >= GLFW_INFINITY ) + { + timeout_ms = INFINITE; + } + else + { + timeout_ms = (DWORD) (1000.0 * timeout + 0.5); + if( timeout_ms <= 0 ) + { + timeout_ms = 1; + } + } + + // Wait for either event to become signaled due to glfwSignalCond or + // glfwBroadcastCond being called + result = WaitForMultipleObjects( 2, cv->events, FALSE, timeout_ms ); + + // Check if we are the last waiter + EnterCriticalSection( &cv->waiters_count_lock ); + cv->waiters_count --; + last_waiter = (result == WAIT_OBJECT_0 + _GLFW_COND_BROADCAST) && + (cv->waiters_count == 0); + LeaveCriticalSection( &cv->waiters_count_lock ); + + // Some thread called glfwBroadcastCond + if( last_waiter ) + { + // We're the last waiter to be notified or to stop waiting, so + // reset the manual event + ResetEvent( cv->events[ _GLFW_COND_BROADCAST ] ); + } + + // Reacquire the mutex + EnterCriticalSection( (CRITICAL_SECTION *) mutex ); +} + + +//======================================================================== +// _glfwPlatformSignalCond() - Signal a condition to one waiting thread +//======================================================================== + +void _glfwPlatformSignalCond( GLFWcond cond ) +{ + _GLFWcond *cv = (_GLFWcond *) cond; + int have_waiters; + + // Avoid race conditions + EnterCriticalSection( &cv->waiters_count_lock ); + have_waiters = cv->waiters_count > 0; + LeaveCriticalSection( &cv->waiters_count_lock ); + + if( have_waiters ) + { + SetEvent( cv->events[ _GLFW_COND_SIGNAL ] ); + } +} + + +//======================================================================== +// _glfwPlatformBroadcastCond() - Broadcast a condition to all waiting +// threads +//======================================================================== + +void _glfwPlatformBroadcastCond( GLFWcond cond ) +{ + _GLFWcond *cv = (_GLFWcond *) cond; + int have_waiters; + + // Avoid race conditions + EnterCriticalSection( &cv->waiters_count_lock ); + have_waiters = cv->waiters_count > 0; + LeaveCriticalSection( &cv->waiters_count_lock ); + + if( have_waiters ) + { + SetEvent( cv->events[ _GLFW_COND_BROADCAST ] ); + } +} + + +//======================================================================== +// _glfwPlatformGetNumberOfProcessors() - Return the number of processors +// in the system. +//======================================================================== + +int _glfwPlatformGetNumberOfProcessors( void ) +{ + SYSTEM_INFO si; + + // Get hardware system information + GetSystemInfo( &si ); + + return (int) si.dwNumberOfProcessors; +} diff --git a/src/engine/external/glfw/lib/win32/win32_time.c b/src/engine/external/glfw/lib/win32/win32_time.c new file mode 100644 index 00000000..ea35a8e5 --- /dev/null +++ b/src/engine/external/glfw/lib/win32/win32_time.c @@ -0,0 +1,146 @@ +//======================================================================== +// GLFW - An OpenGL framework +// File: win32_time.c +// Platform: Windows +// 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 **** +//************************************************************************ + +//======================================================================== +// _glfwInitTimer() - Initialise timer +//======================================================================== + +void _glfwInitTimer( void ) +{ + __int64 freq; + + // Check if we have a performance counter + if( QueryPerformanceFrequency( (LARGE_INTEGER *)&freq ) ) + { + // Performance counter is available => use it! + _glfwLibrary.Timer.HasPerformanceCounter = GL_TRUE; + + // Counter resolution is 1 / counter frequency + _glfwLibrary.Timer.Resolution = 1.0 / (double)freq; + + // Set start time for timer + QueryPerformanceCounter( (LARGE_INTEGER *)&_glfwLibrary.Timer.t0_64 ); + } + else + { + // No performace counter available => use the tick counter + _glfwLibrary.Timer.HasPerformanceCounter = GL_FALSE; + + // Counter resolution is 1 ms + _glfwLibrary.Timer.Resolution = 0.001; + + // Set start time for timer + _glfwLibrary.Timer.t0_32 = _glfw_timeGetTime(); + } +} + + +//************************************************************************ +//**** Platform implementation functions **** +//************************************************************************ + +//======================================================================== +// Return timer value in seconds +//======================================================================== + +double _glfwPlatformGetTime( void ) +{ + double t; + __int64 t_64; + + if( _glfwLibrary.Timer.HasPerformanceCounter ) + { + QueryPerformanceCounter( (LARGE_INTEGER *)&t_64 ); + t = (double)(t_64 - _glfwLibrary.Timer.t0_64); + } + else + { + t = (double)(_glfw_timeGetTime() - _glfwLibrary.Timer.t0_32); + } + + // Calculate the current time in seconds + return t * _glfwLibrary.Timer.Resolution; +} + + +//======================================================================== +// Set timer value in seconds +//======================================================================== + +void _glfwPlatformSetTime( double t ) +{ + __int64 t_64; + + if( _glfwLibrary.Timer.HasPerformanceCounter ) + { + QueryPerformanceCounter( (LARGE_INTEGER *)&t_64 ); + _glfwLibrary.Timer.t0_64 = t_64 - (__int64)(t/_glfwLibrary.Timer.Resolution); + } + else + { + _glfwLibrary.Timer.t0_32 = _glfw_timeGetTime() - (int)(t*1000.0); + } +} + + +//======================================================================== +// Put a thread to sleep for a specified amount of time +//======================================================================== + +void _glfwPlatformSleep( double time ) +{ + DWORD t; + + if( time == 0.0 ) + { + t = 0; + } + else if( time < 0.001 ) + { + t = 1; + } + else if( time > 2147483647.0 ) + { + t = 2147483647; + } + else + { + t = (DWORD)(time*1000.0 + 0.5); + } + Sleep( t ); +} + diff --git a/src/engine/external/glfw/lib/win32/win32_window.c b/src/engine/external/glfw/lib/win32/win32_window.c new file mode 100644 index 00000000..83c0eeae --- /dev/null +++ b/src/engine/external/glfw/lib/win32/win32_window.c @@ -0,0 +1,1697 @@ +//======================================================================== +// GLFW - An OpenGL framework +// File: win32_window.c +// Platform: Windows +// 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 **** +//************************************************************************ + +#define _GLFW_WNDCLASSNAME "GLFW26" + + +//======================================================================== +// Enable/disable minimize/restore animations +//======================================================================== + +static int _glfwMinMaxAnimations( int enable ) +{ + ANIMATIONINFO AI; + int old_enable; + + // Get old animation setting + AI.cbSize = sizeof( ANIMATIONINFO ); + SystemParametersInfo( SPI_GETANIMATION, AI.cbSize, &AI, 0 ); + old_enable = AI.iMinAnimate; + + // If requested, change setting + if( old_enable != enable ) + { + AI.iMinAnimate = enable; + SystemParametersInfo( SPI_SETANIMATION, AI.cbSize, &AI, + SPIF_SENDCHANGE ); + } + + return old_enable; +} + + +//======================================================================== +// Function for bringing a window into focus and placing it on top of the +// window z stack. Due to some nastiness with how Win98/ME/2k/XP handles +// SetForegroundWindow, we have to go through some really bizarre measures to +// achieve this (thanks again, MS, for making life so much easier)! +//======================================================================== + +static void _glfwSetForegroundWindow( HWND hWnd ) +{ + int try_count = 0; + int old_animate; + + // Try the standard approach first... + BringWindowToTop( hWnd ); + SetForegroundWindow( hWnd ); + + // If it worked, return now + if( hWnd == GetForegroundWindow() ) + { + // Try to modify the system settings (since this is the foreground + // process, we are allowed to do this) + SystemParametersInfo( SPI_SETFOREGROUNDLOCKTIMEOUT, 0, (LPVOID)0, + SPIF_SENDCHANGE ); + return; + } + + // For other Windows versions than 95 & NT4.0, the standard approach + // may not work, so if we failed we have to "trick" Windows into + // making our window the foureground window: Iconify and restore + // again. It is ugly, but it seems to work (we turn off those annoying + // zoom animations to make it look a bit better at least). + + // Turn off minimize/restore animations + old_animate = _glfwMinMaxAnimations( 0 ); + + // We try this a few times, just to be on the safe side of things... + do + { + // Iconify & restore + ShowWindow( hWnd, SW_HIDE ); + ShowWindow( hWnd, SW_SHOWMINIMIZED ); + ShowWindow( hWnd, SW_SHOWNORMAL ); + + // Try to get focus + BringWindowToTop( hWnd ); + SetForegroundWindow( hWnd ); + + // We do not want to keep going on forever, so we keep track of + // how many times we tried + try_count ++; + } + while( hWnd != GetForegroundWindow() && try_count <= 3 ); + + // Restore the system minimize/restore animation setting + (void) _glfwMinMaxAnimations( old_animate ); + + // Try to modify the system settings (since this is now hopefully the + // foreground process, we are probably allowed to do this) + SystemParametersInfo( SPI_SETFOREGROUNDLOCKTIMEOUT, 0, (LPVOID)0, + SPIF_SENDCHANGE ); +} + + +//======================================================================== +// Sets the device context pixel format using a PFD +//======================================================================== + +static int _glfwSetPixelFormatPFD( int redbits, int greenbits, int bluebits, + int alphabits, int depthbits, int stencilbits, + int mode, _GLFWhints* hints ) +{ + int PixelFormat; + PIXELFORMATDESCRIPTOR pfd; + + // Set required pixel format + pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR); + pfd.nVersion = 1; + pfd.dwFlags = PFD_DRAW_TO_WINDOW | // Draw to window + PFD_SUPPORT_OPENGL | // Support OpenGL + PFD_DOUBLEBUFFER; // Double buffered window + pfd.iPixelType = PFD_TYPE_RGBA; // Request an RGBA format + pfd.cColorBits = (BYTE) (redbits + + greenbits + + bluebits); // Color bits (ex. alpha) + pfd.cRedBits = (BYTE) redbits; // Red bits + pfd.cRedShift = 0; // Red shift ignored + pfd.cGreenBits = (BYTE) greenbits; // Green bits + pfd.cGreenShift = 0; // Green shift ignored + pfd.cBlueBits = (BYTE) bluebits; // Blue bits + pfd.cBlueShift = 0; // Blue shift ignored + pfd.cAlphaBits = (BYTE) alphabits; // Alpha bits + pfd.cAlphaShift = 0; // Alpha shift ignored + pfd.cAccumBits = (BYTE) (hints->AccumRedBits + + hints->AccumGreenBits + + hints->AccumBlueBits + + hints->AccumAlphaBits); // Accum. bits + pfd.cAccumRedBits = (BYTE) hints->AccumRedBits; // Accum. red bits + pfd.cAccumGreenBits = (BYTE) hints->AccumGreenBits; // Accum. green bits + pfd.cAccumBlueBits = (BYTE) hints->AccumBlueBits; // Accum. blue bits + pfd.cAccumAlphaBits = (BYTE) hints->AccumAlphaBits; // Accum. alpha bits + pfd.cDepthBits = (BYTE) depthbits; // Depth buffer bits + pfd.cStencilBits = (BYTE) stencilbits; // Stencil buffer bits + pfd.cAuxBuffers = (BYTE) hints->AuxBuffers; // No. of aux buffers + pfd.iLayerType = PFD_MAIN_PLANE; // Drawing layer: main + pfd.bReserved = 0; // (reserved) + pfd.dwLayerMask = 0; // Ignored + pfd.dwVisibleMask = 0; // " + pfd.dwDamageMask = 0; // " + + if( depthbits <= 0 ) + { + // We do not need a depth buffer + pfd.dwFlags |= PFD_DEPTH_DONTCARE; + } + + if( hints->Stereo ) + { + // Request a stereo mode + pfd.dwFlags |= PFD_STEREO; + } + + // Find a matching pixel format + PixelFormat = _glfw_ChoosePixelFormat( _glfwWin.DC, &pfd ); + if( !PixelFormat ) + { + return GL_FALSE; + } + + // Get actual pixel format description + if( !_glfw_DescribePixelFormat( _glfwWin.DC, PixelFormat, sizeof(pfd), &pfd ) ) + { + return GL_FALSE; + } + + // "stereo" is a strict requirement + if( hints->Stereo && !(pfd.dwFlags & PFD_STEREO) ) + { + return GL_FALSE; + } + + // Set the pixel-format + if( !_glfw_SetPixelFormat( _glfwWin.DC, PixelFormat, &pfd ) ) + { + return GL_FALSE; + } + + return GL_TRUE; +} + + +//======================================================================== +// Sets the device context pixel format using attributes +//======================================================================== + +#define _glfwSetWGLAttribute( _glfwName, _glfwValue ) \ + attribs[ count++ ] = _glfwName; \ + attribs[ count++ ] = _glfwValue; + +static int _glfwSetPixelFormatAttrib( int redbits, int greenbits, int bluebits, + int alphabits, int depthbits, int stencilbits, + int mode, _GLFWhints* hints ) +{ + int PixelFormat, dummy, count = 0; + int attribs[128]; + PIXELFORMATDESCRIPTOR pfd; + + int accumredbits = hints->AccumRedBits; + int accumgreenbits = hints->AccumGreenBits; + int accumbluebits = hints->AccumBlueBits; + int accumalphabits = hints->AccumAlphaBits; + + _glfwSetWGLAttribute( WGL_DRAW_TO_WINDOW_ARB, GL_TRUE ); + _glfwSetWGLAttribute( WGL_ACCELERATION_ARB, WGL_FULL_ACCELERATION_ARB ); + _glfwSetWGLAttribute( WGL_SUPPORT_OPENGL_ARB, GL_TRUE ); + _glfwSetWGLAttribute( WGL_DOUBLE_BUFFER_ARB, GL_TRUE ); + _glfwSetWGLAttribute( WGL_COLOR_BITS_ARB, redbits + greenbits + bluebits ); + _glfwSetWGLAttribute( WGL_RED_BITS_ARB, redbits ); + _glfwSetWGLAttribute( WGL_GREEN_BITS_ARB, greenbits ); + _glfwSetWGLAttribute( WGL_BLUE_BITS_ARB, bluebits ); + _glfwSetWGLAttribute( WGL_ALPHA_BITS_ARB, alphabits ); + _glfwSetWGLAttribute( WGL_DEPTH_BITS_ARB, depthbits ); + _glfwSetWGLAttribute( WGL_STENCIL_BITS_ARB, stencilbits ); + _glfwSetWGLAttribute( WGL_AUX_BUFFERS_ARB, hints->AuxBuffers ); + + if( accumredbits || accumgreenbits || accumbluebits || accumalphabits ) + { + _glfwSetWGLAttribute( WGL_ACCUM_BITS_ARB, accumredbits + + accumgreenbits + + accumbluebits + + accumalphabits ); + + _glfwSetWGLAttribute( WGL_ACCUM_RED_BITS_ARB, accumredbits ); + _glfwSetWGLAttribute( WGL_ACCUM_GREEN_BITS_ARB, accumgreenbits ); + _glfwSetWGLAttribute( WGL_ACCUM_BLUE_BITS_ARB, accumbluebits ); + _glfwSetWGLAttribute( WGL_ACCUM_ALPHA_BITS_ARB, accumalphabits ); + } + + if( hints->Stereo ) + { + _glfwSetWGLAttribute( WGL_STEREO_ARB, GL_TRUE ); + } + + if( hints->Samples > 0 ) + { + _glfwSetWGLAttribute( WGL_SAMPLE_BUFFERS_ARB, 1 ); + _glfwSetWGLAttribute( WGL_SAMPLES_ARB, hints->Samples ); + } + + _glfwSetWGLAttribute( 0, 0 ); + + if( !_glfwWin.ChoosePixelFormat( _glfwWin.DC, attribs, NULL, 1, &PixelFormat, &dummy ) ) + { + return GL_FALSE; + } + + if( !_glfw_DescribePixelFormat( _glfwWin.DC, PixelFormat, sizeof(pfd), &pfd ) ) + { + return GL_FALSE; + } + + // Set the pixel-format + if( !_glfw_SetPixelFormat( _glfwWin.DC, PixelFormat, &pfd ) ) + { + return GL_FALSE; + } + + return GL_TRUE; +} + +#undef _glfwSetWGLAttribute + + +//======================================================================== +// Translates a Windows key to the corresponding GLFW key +//======================================================================== + +static int _glfwTranslateKey( WPARAM wParam, LPARAM lParam ) +{ + MSG next_msg; + DWORD msg_time; + DWORD scan_code; + + // Check which key was pressed or released + switch( wParam ) + { + // The SHIFT keys require special handling + case VK_SHIFT: + // Compare scan code for this key with that of VK_RSHIFT in + // order to determine which shift key was pressed (left or + // right) + scan_code = MapVirtualKey( VK_RSHIFT, 0 ); + if( ((lParam & 0x01ff0000) >> 16) == scan_code ) + { + return GLFW_KEY_RSHIFT; + } + return GLFW_KEY_LSHIFT; + + // The CTRL keys require special handling + case VK_CONTROL: + // Is this an extended key (i.e. right key)? + if( lParam & 0x01000000 ) + { + return GLFW_KEY_RCTRL; + } + // Here is a trick: "Alt Gr" sends LCTRL, then RALT. We only + // want the RALT message, so we try to see if the next message + // is a RALT message. In that case, this is a false LCTRL! + msg_time = GetMessageTime(); + if( PeekMessage( &next_msg, NULL, 0, 0, PM_NOREMOVE ) ) + { + if( next_msg.message == WM_KEYDOWN || + next_msg.message == WM_SYSKEYDOWN ) + { + if( next_msg.wParam == VK_MENU && + (next_msg.lParam & 0x01000000) && + next_msg.time == msg_time ) + { + // Next message is a RALT down message, which + // means that this is NOT a proper LCTRL message! + return GLFW_KEY_UNKNOWN; + } + } + } + return GLFW_KEY_LCTRL; + + // The ALT keys require special handling + case VK_MENU: + // Is this an extended key (i.e. right key)? + if( lParam & 0x01000000 ) + { + return GLFW_KEY_RALT; + } + return GLFW_KEY_LALT; + + // The ENTER keys require special handling + case VK_RETURN: + // Is this an extended key (i.e. right key)? + if( lParam & 0x01000000 ) + { + return GLFW_KEY_KP_ENTER; + } + return GLFW_KEY_ENTER; + + // Special keys (non character keys) + case VK_ESCAPE: return GLFW_KEY_ESC; + case VK_TAB: return GLFW_KEY_TAB; + case VK_BACK: return GLFW_KEY_BACKSPACE; + case VK_HOME: return GLFW_KEY_HOME; + case VK_END: return GLFW_KEY_END; + case VK_PRIOR: return GLFW_KEY_PAGEUP; + case VK_NEXT: return GLFW_KEY_PAGEDOWN; + case VK_INSERT: return GLFW_KEY_INSERT; + case VK_DELETE: return GLFW_KEY_DEL; + case VK_LEFT: return GLFW_KEY_LEFT; + case VK_UP: return GLFW_KEY_UP; + case VK_RIGHT: return GLFW_KEY_RIGHT; + case VK_DOWN: return GLFW_KEY_DOWN; + case VK_F1: return GLFW_KEY_F1; + case VK_F2: return GLFW_KEY_F2; + case VK_F3: return GLFW_KEY_F3; + case VK_F4: return GLFW_KEY_F4; + case VK_F5: return GLFW_KEY_F5; + case VK_F6: return GLFW_KEY_F6; + case VK_F7: return GLFW_KEY_F7; + case VK_F8: return GLFW_KEY_F8; + case VK_F9: return GLFW_KEY_F9; + case VK_F10: return GLFW_KEY_F10; + case VK_F11: return GLFW_KEY_F11; + case VK_F12: return GLFW_KEY_F12; + case VK_F13: return GLFW_KEY_F13; + case VK_F14: return GLFW_KEY_F14; + case VK_F15: return GLFW_KEY_F15; + case VK_F16: return GLFW_KEY_F16; + case VK_F17: return GLFW_KEY_F17; + case VK_F18: return GLFW_KEY_F18; + case VK_F19: return GLFW_KEY_F19; + case VK_F20: return GLFW_KEY_F20; + case VK_F21: return GLFW_KEY_F21; + case VK_F22: return GLFW_KEY_F22; + case VK_F23: return GLFW_KEY_F23; + case VK_F24: return GLFW_KEY_F24; + case VK_SPACE: return GLFW_KEY_SPACE; + + // Numeric keypad + case VK_NUMPAD0: return GLFW_KEY_KP_0; + case VK_NUMPAD1: return GLFW_KEY_KP_1; + case VK_NUMPAD2: return GLFW_KEY_KP_2; + case VK_NUMPAD3: return GLFW_KEY_KP_3; + case VK_NUMPAD4: return GLFW_KEY_KP_4; + case VK_NUMPAD5: return GLFW_KEY_KP_5; + case VK_NUMPAD6: return GLFW_KEY_KP_6; + case VK_NUMPAD7: return GLFW_KEY_KP_7; + case VK_NUMPAD8: return GLFW_KEY_KP_8; + case VK_NUMPAD9: return GLFW_KEY_KP_9; + case VK_DIVIDE: return GLFW_KEY_KP_DIVIDE; + case VK_MULTIPLY: return GLFW_KEY_KP_MULTIPLY; + case VK_SUBTRACT: return GLFW_KEY_KP_SUBTRACT; + case VK_ADD: return GLFW_KEY_KP_ADD; + case VK_DECIMAL: return GLFW_KEY_KP_DECIMAL; + + // The rest (should be printable keys) + default: + // Convert to printable character (ISO-8859-1 or Unicode) + wParam = MapVirtualKey( (UINT) wParam, 2 ) & 0x0000FFFF; + + // Make sure that the character is uppercase + if( _glfwLibrary.Sys.HasUnicode ) + { + wParam = (WPARAM) CharUpperW( (LPWSTR) wParam ); + } + else + { + wParam = (WPARAM) CharUpperA( (LPSTR) wParam ); + } + + // Valid ISO-8859-1 character? + if( (wParam >= 32 && wParam <= 126) || + (wParam >= 160 && wParam <= 255) ) + { + return (int) wParam; + } + return GLFW_KEY_UNKNOWN; + } +} + + +//======================================================================== +// Translates a windows key to Unicode +//======================================================================== + +static void _glfwTranslateChar( DWORD wParam, DWORD lParam, int action ) +{ + BYTE keyboard_state[ 256 ]; + UCHAR char_buf[ 10 ]; + WCHAR unicode_buf[ 10 ]; + UINT scan_code; + int i, num_chars, unicode; + + // Get keyboard state + GetKeyboardState( keyboard_state ); + + // Derive scan code from lParam and action + scan_code = (lParam & 0x01ff0000) >> 16; + if( action == GLFW_RELEASE ) + { + scan_code |= 0x8000000; + } + + // Do we have Unicode support? + if( _glfwLibrary.Sys.HasUnicode ) + { + // Convert to Unicode + num_chars = ToUnicode( + wParam, // virtual-key code + scan_code, // scan code + keyboard_state, // key-state array + unicode_buf, // buffer for translated key + 10, // size of translated key buffer + 0 // active-menu flag + ); + unicode = 1; + } + else + { + // Convert to ISO-8859-1 + num_chars = ToAscii( + wParam, // virtual-key code + scan_code, // scan code + keyboard_state, // key-state array + (LPWORD) char_buf, // buffer for translated key + 0 // active-menu flag + ); + unicode = 0; + } + + // Report characters + for( i = 0; i < num_chars; i++ ) + { + // Get next character from buffer + if( unicode ) + { + _glfwInputChar( (int) unicode_buf[ i ], action ); + } + else + { + _glfwInputChar( (int) char_buf[ i ], action ); + } + } +} + + +//======================================================================== +// Window callback function (handles window events) +//======================================================================== + +static LRESULT CALLBACK _glfwWindowCallback( HWND hWnd, UINT uMsg, + WPARAM wParam, LPARAM lParam ) +{ + int WheelDelta, Iconified; + + // Handle certain window messages + switch( uMsg ) + { + // Window activate message? (iconification?) + case WM_ACTIVATE: + { + _glfwWin.Active = LOWORD(wParam) != WA_INACTIVE ? GL_TRUE : GL_FALSE; + + Iconified = HIWORD(wParam) ? GL_TRUE : GL_FALSE; + + // Were we deactivated/iconified? + if( (!_glfwWin.Active || Iconified) && !_glfwWin.Iconified ) + { + _glfwInputDeactivation(); + + // If we are in fullscreen mode we need to iconify + if( _glfwWin.Opened && _glfwWin.Fullscreen ) + { + // Do we need to manually iconify? + if( !Iconified ) + { + // Minimize window + CloseWindow( _glfwWin.Wnd ); + + // The window is now iconified + Iconified = GL_TRUE; + } + + // Change display settings to the desktop resolution + ChangeDisplaySettings( NULL, CDS_FULLSCREEN ); + } + + // Unlock mouse + if( !_glfwWin.OldMouseLockValid ) + { + _glfwWin.OldMouseLock = _glfwWin.MouseLock; + _glfwWin.OldMouseLockValid = GL_TRUE; + glfwEnable( GLFW_MOUSE_CURSOR ); + } + } + else if( _glfwWin.Active || !Iconified ) + { + // If we are in fullscreen mode we need to maximize + if( _glfwWin.Opened && _glfwWin.Fullscreen && _glfwWin.Iconified ) + { + // Change display settings to the user selected mode + _glfwSetVideoModeMODE( _glfwWin.ModeID ); + + // Do we need to manually restore window? + if( Iconified ) + { + // Restore window + OpenIcon( _glfwWin.Wnd ); + + // The window is no longer iconified + Iconified = GL_FALSE; + + // Activate window + ShowWindow( hWnd, SW_SHOW ); + _glfwSetForegroundWindow( _glfwWin.Wnd ); + SetFocus( _glfwWin.Wnd ); + } + } + + // Lock mouse, if necessary + if( _glfwWin.OldMouseLockValid && _glfwWin.OldMouseLock ) + { + glfwDisable( GLFW_MOUSE_CURSOR ); + } + _glfwWin.OldMouseLockValid = GL_FALSE; + } + + _glfwWin.Iconified = Iconified; + return 0; + } + + // Intercept system commands (forbid certain actions/events) + case WM_SYSCOMMAND: + { + switch( wParam ) + { + // Screensaver trying to start or monitor trying to enter + // powersave? + case SC_SCREENSAVE: + case SC_MONITORPOWER: + if( _glfwWin.Fullscreen ) + { + return 0; + } + else + { + break; + } + + // User trying to access application menu using ALT? + case SC_KEYMENU: + return 0; + } + break; + } + + // Did we receive a close message? + case WM_CLOSE: + PostQuitMessage( 0 ); + return 0; + + // Is a key being pressed? + case WM_KEYDOWN: + case WM_SYSKEYDOWN: + { + // Translate and report key press + _glfwInputKey( _glfwTranslateKey( wParam, lParam ), + GLFW_PRESS ); + + // Translate and report character input + if( _glfwWin.CharCallback ) + { + _glfwTranslateChar( (DWORD) wParam, (DWORD) lParam, GLFW_PRESS ); + } + return 0; + } + + // Is a key being released? + case WM_KEYUP: + case WM_SYSKEYUP: + { + // Special trick: release both shift keys on SHIFT up event + if( wParam == VK_SHIFT ) + { + _glfwInputKey( GLFW_KEY_LSHIFT, GLFW_RELEASE ); + _glfwInputKey( GLFW_KEY_RSHIFT, GLFW_RELEASE ); + } + else + { + // Translate and report key release + _glfwInputKey( _glfwTranslateKey( wParam, lParam ), + GLFW_RELEASE ); + } + + // Translate and report character input + if( _glfwWin.CharCallback ) + { + _glfwTranslateChar( (DWORD) wParam, (DWORD) lParam, GLFW_RELEASE ); + } + + return 0; + } + + // Were any of the mouse-buttons pressed? + case WM_LBUTTONDOWN: + SetCapture(hWnd); + _glfwInputMouseClick( GLFW_MOUSE_BUTTON_LEFT, GLFW_PRESS ); + return 0; + case WM_RBUTTONDOWN: + SetCapture(hWnd); + _glfwInputMouseClick( GLFW_MOUSE_BUTTON_RIGHT, GLFW_PRESS ); + return 0; + case WM_MBUTTONDOWN: + SetCapture(hWnd); + _glfwInputMouseClick( GLFW_MOUSE_BUTTON_MIDDLE, GLFW_PRESS ); + return 0; + case WM_XBUTTONDOWN: + { + if( HIWORD(wParam) == XBUTTON1 ) + { + SetCapture(hWnd); + _glfwInputMouseClick( GLFW_MOUSE_BUTTON_4, GLFW_PRESS ); + } + else if( HIWORD(wParam) == XBUTTON2 ) + { + SetCapture(hWnd); + _glfwInputMouseClick( GLFW_MOUSE_BUTTON_5, GLFW_PRESS ); + } + return 1; + } + + // Were any of the mouse-buttons released? + case WM_LBUTTONUP: + ReleaseCapture(); + _glfwInputMouseClick( GLFW_MOUSE_BUTTON_LEFT, GLFW_RELEASE ); + return 0; + case WM_RBUTTONUP: + ReleaseCapture(); + _glfwInputMouseClick( GLFW_MOUSE_BUTTON_RIGHT, GLFW_RELEASE ); + return 0; + case WM_MBUTTONUP: + ReleaseCapture(); + _glfwInputMouseClick( GLFW_MOUSE_BUTTON_MIDDLE, GLFW_RELEASE ); + return 0; + case WM_XBUTTONUP: + { + if( HIWORD(wParam) == XBUTTON1 ) + { + ReleaseCapture(); + _glfwInputMouseClick( GLFW_MOUSE_BUTTON_4, GLFW_RELEASE ); + } + else if( HIWORD(wParam) == XBUTTON2 ) + { + ReleaseCapture(); + _glfwInputMouseClick( GLFW_MOUSE_BUTTON_5, GLFW_RELEASE ); + } + return 1; + } + + // Did the mouse move? + case WM_MOUSEMOVE: + { + { + int NewMouseX, NewMouseY; + + // Get signed (!) mouse position + NewMouseX = (int)((short)LOWORD(lParam)); + NewMouseY = (int)((short)HIWORD(lParam)); + + if( NewMouseX != _glfwInput.OldMouseX || + NewMouseY != _glfwInput.OldMouseY ) + { + if( _glfwWin.MouseLock ) + { + _glfwInput.MousePosX += NewMouseX - + _glfwInput.OldMouseX; + _glfwInput.MousePosY += NewMouseY - + _glfwInput.OldMouseY; + } + else + { + _glfwInput.MousePosX = NewMouseX; + _glfwInput.MousePosY = NewMouseY; + } + _glfwInput.OldMouseX = NewMouseX; + _glfwInput.OldMouseY = NewMouseY; + _glfwInput.MouseMoved = GL_TRUE; + + // Call user callback function + if( _glfwWin.MousePosCallback ) + { + _glfwWin.MousePosCallback( _glfwInput.MousePosX, + _glfwInput.MousePosY ); + } + } + } + return 0; + } + + // Mouse wheel action? + case WM_MOUSEWHEEL: + { + // WM_MOUSEWHEEL is not supported under Windows 95 + if( _glfwLibrary.Sys.WinVer != _GLFW_WIN_95 ) + { + WheelDelta = (((int)wParam) >> 16) / WHEEL_DELTA; + _glfwInput.WheelPos += WheelDelta; + if( _glfwWin.MouseWheelCallback ) + { + _glfwWin.MouseWheelCallback( _glfwInput.WheelPos ); + } + return 0; + } + break; + } + + // Resize the window? + case WM_SIZE: + { + // get the new size + _glfwWin.Width = LOWORD(lParam); + _glfwWin.Height = HIWORD(lParam); + + // If the mouse is locked, update the clipping rect + if( _glfwWin.MouseLock ) + { + RECT ClipWindowRect; + if( GetWindowRect( _glfwWin.Wnd, &ClipWindowRect ) ) + { + ClipCursor( &ClipWindowRect ); + } + } + + // Call the user-supplied callback, if it exists + if( _glfwWin.WindowSizeCallback ) + { + _glfwWin.WindowSizeCallback( LOWORD(lParam), + HIWORD(lParam) ); + } + return 0; + } + + // Move the window? + case WM_MOVE: + { + // If the mouse is locked, update the clipping rect + if( _glfwWin.MouseLock ) + { + RECT ClipWindowRect; + if( GetWindowRect( _glfwWin.Wnd, &ClipWindowRect ) ) + { + ClipCursor( &ClipWindowRect ); + } + } + return 0; + } + + // Was the window contents damaged? + case WM_PAINT: + { + // Call user callback function + if( _glfwWin.WindowRefreshCallback ) + { + _glfwWin.WindowRefreshCallback(); + } + break; + } + + case WM_DISPLAYCHANGE: + { + // TODO: Do stuff here. + + break; + } + } + + // Pass all unhandled messages to DefWindowProc + return DefWindowProc( hWnd, uMsg, wParam, lParam ); +} + + +//======================================================================== +// Translate client window size to full window size (including window borders) +//======================================================================== + +static void _glfwGetFullWindowSize( int w, int h, int *w2, int *h2 ) +{ + RECT rect; + + // Create a window rectangle + rect.left = (long)0; + rect.right = (long)w-1; + rect.top = (long)0; + rect.bottom = (long)h-1; + + // Adjust according to window styles + AdjustWindowRectEx( &rect, _glfwWin.dwStyle, FALSE, + _glfwWin.dwExStyle ); + + // Calculate width and height of full window + *w2 = rect.right-rect.left+1; + *h2 = rect.bottom-rect.top+1; +} + + +//======================================================================== +// Initialize WGL-specific extensions +//======================================================================== + +static void _glfwInitWGLExtensions( void ) +{ + GLubyte *extensions; + int has_swap_control, has_pixel_format; + + // Initialize OpenGL extension: WGL_EXT_swap_control + has_swap_control = GL_FALSE; + has_pixel_format = GL_FALSE; + extensions = (GLubyte *) glGetString( GL_EXTENSIONS ); + + if( extensions != NULL ) + { + has_swap_control = _glfwStringInExtensionString( + "WGL_EXT_swap_control", + extensions + ); + has_pixel_format = _glfwStringInExtensionString( + "WGL_ARB_pixel_format", + extensions + ); + } + + if( !has_swap_control ) + { + has_swap_control = _glfwPlatformExtensionSupported( + "WGL_EXT_swap_control" + ); + } + + if( !has_pixel_format ) + { + has_pixel_format = _glfwPlatformExtensionSupported( + "WGL_ARB_pixel_format" + ); + } + + if( has_swap_control ) + { + _glfwWin.SwapInterval = (WGLSWAPINTERVALEXT_T) + wglGetProcAddress( "wglSwapIntervalEXT" ); + } + else + { + _glfwWin.SwapInterval = NULL; + } + + if( has_pixel_format ) + { + _glfwWin.ChoosePixelFormat = (WGLCHOOSEPIXELFORMATARB_T) + wglGetProcAddress( "wglChoosePixelFormatARB" ); + _glfwWin.GetPixelFormatAttribiv = (WGLGETPIXELFORMATATTRIBIVARB_T) + wglGetProcAddress( "wglGetPixelFormatAttribivARB" ); + } + else + { + _glfwWin.ChoosePixelFormat = NULL; + _glfwWin.GetPixelFormatAttribiv = NULL; + } +} + + +//======================================================================== +// Creates the GLFW window and rendering context +//======================================================================== + +static int _glfwCreateWindow( int redbits, int greenbits, int bluebits, + int alphabits, int depthbits, int stencilbits, + int mode, _GLFWhints* hints ) +{ + int full_width, full_height; + RECT wa; + + _glfwWin.DC = NULL; + _glfwWin.RC = NULL; + _glfwWin.Wnd = NULL; + + // Set window size to true requested size (adjust for window borders) + _glfwGetFullWindowSize( _glfwWin.Width, _glfwWin.Height, &full_width, + &full_height ); + + // Adjust window position to working area (e.g. if the task bar is at + // the top of the display). Fullscreen windows are always opened in + // the upper left corner regardless of the desktop working area. + if( _glfwWin.Fullscreen ) + { + wa.left = wa.top = 0; + } + else + { + SystemParametersInfo( SPI_GETWORKAREA, 0, &wa, 0 ); + } + + // Create window + _glfwWin.Wnd = CreateWindowEx( + _glfwWin.dwExStyle, // Extended style + _GLFW_WNDCLASSNAME, // Class name + "GLFW Window", // Window title + _glfwWin.dwStyle, // Defined window style + wa.left, wa.top, // Window position + full_width, // Decorated window width + full_height, // Decorated window height + NULL, // No parent window + NULL, // No menu + _glfwLibrary.Instance, // Instance + NULL ); // Nothing to WM_CREATE + + if( !_glfwWin.Wnd ) + { + return GL_FALSE; + } + + // Get a device context + _glfwWin.DC = GetDC( _glfwWin.Wnd ); + if( !_glfwWin.DC ) + { + return GL_FALSE; + } + + if( _glfwWin.ChoosePixelFormat ) + { + if( !_glfwSetPixelFormatAttrib( redbits, greenbits, bluebits, alphabits, + depthbits, stencilbits, mode, hints ) ) + { + return GL_FALSE; + } + } + else + { + if( !_glfwSetPixelFormatPFD( redbits, greenbits, bluebits, alphabits, + depthbits, stencilbits, mode, hints ) ) + { + return GL_FALSE; + } + } + + // Get a rendering context + _glfwWin.RC = wglCreateContext( _glfwWin.DC ); + if( !_glfwWin.RC ) + { + return GL_FALSE; + } + + // Activate the OpenGL rendering context + if( !wglMakeCurrent( _glfwWin.DC, _glfwWin.RC ) ) + { + return GL_FALSE; + } + + // Initialize WGL-specific OpenGL extensions + _glfwInitWGLExtensions(); + + return GL_TRUE; +} + + +//======================================================================== +// Destroys the GLFW window and rendering context +//======================================================================== + +static void _glfwDestroyWindow( void ) +{ + // Do we have a rendering context? + if( _glfwWin.RC ) + { + // Release the DC and RC contexts + wglMakeCurrent( NULL, NULL ); + + // Delete the rendering context + wglDeleteContext( _glfwWin.RC ); + _glfwWin.RC = NULL; + } + + // Do we have a device context? + if( _glfwWin.DC ) + { + // Release the device context + ReleaseDC( _glfwWin.Wnd, _glfwWin.DC ); + _glfwWin.DC = NULL; + } + + // Do we have a window? + if( _glfwWin.Wnd ) + { + // Destroy the window + if( _glfwLibrary.Sys.WinVer <= _GLFW_WIN_NT4 ) + { + // Note: Hiding the window first fixes an annoying W98/NT4 + // remaining icon bug for fullscreen displays + ShowWindow( _glfwWin.Wnd, SW_HIDE ); + } + + DestroyWindow( _glfwWin.Wnd ); + _glfwWin.Wnd = NULL; + } +} + + + +//************************************************************************ +//**** Platform implementation functions **** +//************************************************************************ + +//======================================================================== +// Here is where the window is created, and the OpenGL rendering context is +// created +//======================================================================== + +int _glfwPlatformOpenWindow( int width, int height, + int redbits, int greenbits, int bluebits, + int alphabits, int depthbits, int stencilbits, + int mode, _GLFWhints* hints ) +{ + WNDCLASS wc; + DWORD dwStyle, dwExStyle; + + // Clear platform specific GLFW window state + _glfwWin.ClassAtom = 0; + _glfwWin.OldMouseLockValid = GL_FALSE; + _glfwWin.ChoosePixelFormat = NULL; + _glfwWin.GetPixelFormatAttribiv = NULL; + + // Remember desired refresh rate for this window (used only in + // fullscreen mode) + _glfwWin.DesiredRefreshRate = hints->RefreshRate; + + // Set window class parameters + wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; // Redraw on... + wc.lpfnWndProc = (WNDPROC)_glfwWindowCallback; // Message handler + wc.cbClsExtra = 0; // No extra class data + wc.cbWndExtra = 0; // No extra window data + wc.hInstance = _glfwLibrary.Instance; // Set instance + wc.hCursor = LoadCursor( NULL, IDC_ARROW ); // Load arrow pointer + wc.hbrBackground = NULL; // No background + wc.lpszMenuName = NULL; // No menu + wc.lpszClassName = _GLFW_WNDCLASSNAME; // Set class name + + // Load user-provided icon if available + wc.hIcon = LoadIcon( _glfwLibrary.Instance, "GLFW_ICON" ); + if( !wc.hIcon ) + { + // Load default icon + wc.hIcon = LoadIcon( NULL, IDI_WINLOGO ); + } + + // Register the window class + _glfwWin.ClassAtom = RegisterClass( &wc ); + if( !_glfwWin.ClassAtom ) + { + _glfwPlatformCloseWindow(); + return GL_FALSE; + } + + // Do we want full-screen mode? + if( _glfwWin.Fullscreen ) + { + _glfwSetVideoMode( &_glfwWin.Width, &_glfwWin.Height, + redbits, greenbits, bluebits, + hints->RefreshRate ); + } + + // Set common window styles + dwStyle = WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_VISIBLE; + dwExStyle = WS_EX_APPWINDOW; + + // Set window style, depending on fullscreen mode + if( _glfwWin.Fullscreen ) + { + dwStyle |= WS_POPUP; + + // Here's a trick for helping us getting window focus + // (SetForegroundWindow doesn't work properly under + // Win98/ME/2K/XP/.NET/+) + + /* + if( _glfwLibrary.Sys.WinVer == _GLFW_WIN_95 || + _glfwLibrary.Sys.WinVer == _GLFW_WIN_NT4 || + _glfwLibrary.Sys.WinVer == _GLFW_WIN_XP ) + { + dwStyle |= WS_VISIBLE; + } + else + { + dwStyle |= WS_MINIMIZE; + } + */ + } + else + { + dwStyle |= WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX; + + if( !hints->WindowNoResize ) + { + dwStyle |= ( WS_MAXIMIZEBOX | WS_SIZEBOX ); + dwExStyle |= WS_EX_WINDOWEDGE; + } + } + + // Remember window styles (used by _glfwGetFullWindowSize) + _glfwWin.dwStyle = dwStyle; + _glfwWin.dwExStyle = dwExStyle; + + if( !_glfwCreateWindow( redbits, greenbits, bluebits, alphabits, + depthbits, stencilbits, mode, hints ) ) + { + _glfwPlatformCloseWindow(); + return GL_FALSE; + } + + if( _glfwWin.ChoosePixelFormat && hints->Samples > 0 ) + { + for (;;) + { + _glfwDestroyWindow(); + + if( _glfwCreateWindow( redbits, greenbits, bluebits, alphabits, + depthbits, stencilbits, mode, hints ) ) + { + break; + } + + if( hints->Samples > 0 ) + { + hints->Samples--; + } + else + { + _glfwPlatformCloseWindow(); + return GL_FALSE; + } + } + } + + // Make sure that our window ends up on top of things + if( _glfwWin.Fullscreen ) + { + // Place the window above all topmost windows + SetWindowPos( _glfwWin.Wnd, HWND_TOPMOST, 0,0,0,0, + SWP_NOMOVE | SWP_NOSIZE ); + } + _glfwSetForegroundWindow( _glfwWin.Wnd ); + SetFocus( _glfwWin.Wnd ); + + // Start by clearing the front buffer to black (avoid ugly desktop + // remains in our OpenGL window) + glClear( GL_COLOR_BUFFER_BIT ); + _glfw_SwapBuffers( _glfwWin.DC ); + + return GL_TRUE; +} + + +//======================================================================== +// Properly kill the window / video display +//======================================================================== + +void _glfwPlatformCloseWindow( void ) +{ + _glfwDestroyWindow(); + + // Do we have an instance? + if( _glfwWin.ClassAtom ) + { + // Unregister class + UnregisterClass( _GLFW_WNDCLASSNAME, _glfwLibrary.Instance ); + _glfwWin.ClassAtom = 0; + } + + // Are we in fullscreen mode? + if( _glfwWin.Fullscreen ) + { + // Switch back to desktop resolution + ChangeDisplaySettings( NULL, CDS_FULLSCREEN ); + } + +} + + +//======================================================================== +// Set the window title +//======================================================================== + +void _glfwPlatformSetWindowTitle( const char *title ) +{ + // Set window title + (void) SetWindowText( _glfwWin.Wnd, title ); +} + + +//======================================================================== +// Set the window size. +//======================================================================== + +void _glfwPlatformSetWindowSize( int width, int height ) +{ + int bpp, mode = 0, refresh; + int sizechanged = GL_FALSE; + GLint drawbuffer; + GLfloat clearcolor[4]; + + // If we are in fullscreen mode, get some info about the current mode + if( _glfwWin.Fullscreen ) + { + DEVMODE dm; + + // Get current BPP settings + dm.dmSize = sizeof( DEVMODE ); + if( EnumDisplaySettings( NULL, _glfwWin.ModeID, &dm ) ) + { + // Get bpp + bpp = dm.dmBitsPerPel; + + // Get closest match for target video mode + refresh = _glfwWin.DesiredRefreshRate; + mode = _glfwGetClosestVideoModeBPP( &width, &height, &bpp, + &refresh ); + } + else + { + mode = _glfwWin.ModeID; + } + } + else + { + // If we are in windowed mode, adjust the window size to + // compensate for window decorations + _glfwGetFullWindowSize( width, height, &width, &height ); + } + + // Change window size before changing fullscreen mode? + if( _glfwWin.Fullscreen && (width > _glfwWin.Width) ) + { + SetWindowPos( _glfwWin.Wnd, HWND_TOP, 0, 0, width, height, + SWP_NOOWNERZORDER | SWP_NOMOVE | SWP_NOZORDER ); + sizechanged = GL_TRUE; + } + + // Change fullscreen video mode? + if( _glfwWin.Fullscreen && mode != _glfwWin.ModeID ) + { + // Change video mode + _glfwSetVideoModeMODE( mode ); + + // Clear the front buffer to black (avoid ugly desktop remains in + // our OpenGL window) + glGetIntegerv( GL_DRAW_BUFFER, &drawbuffer ); + glGetFloatv( GL_COLOR_CLEAR_VALUE, clearcolor ); + glClearColor( 0.0f, 0.0f, 0.0f, 0.0f ); + glClear( GL_COLOR_BUFFER_BIT ); + if( drawbuffer == GL_BACK ) + { + _glfw_SwapBuffers( _glfwWin.DC ); + } + glClearColor( clearcolor[0], clearcolor[1], clearcolor[2], + clearcolor[3] ); + } + + // Set window size (if not already changed) + if( !sizechanged ) + { + SetWindowPos( _glfwWin.Wnd, HWND_TOP, 0, 0, width, height, + SWP_NOOWNERZORDER | SWP_NOMOVE | SWP_NOZORDER ); + } +} + + +//======================================================================== +// Set the window position +//======================================================================== + +void _glfwPlatformSetWindowPos( int x, int y ) +{ + // Set window position + (void) SetWindowPos( _glfwWin.Wnd, HWND_TOP, x, y, 0, 0, + SWP_NOOWNERZORDER | SWP_NOSIZE | SWP_NOZORDER ); +} + + +//======================================================================== +// Window iconification +//======================================================================== + +void _glfwPlatformIconifyWindow( void ) +{ + // Iconify window + CloseWindow( _glfwWin.Wnd ); + + // Window is now iconified + _glfwWin.Iconified = GL_TRUE; + + // If we are in fullscreen mode we need to change video modes + if( _glfwWin.Fullscreen ) + { + // Change display settings to the desktop resolution + ChangeDisplaySettings( NULL, CDS_FULLSCREEN ); + } + + // Unlock mouse + if( !_glfwWin.OldMouseLockValid ) + { + _glfwWin.OldMouseLock = _glfwWin.MouseLock; + _glfwWin.OldMouseLockValid = GL_TRUE; + glfwEnable( GLFW_MOUSE_CURSOR ); + } +} + + +//======================================================================== +// Window un-iconification +//======================================================================== + +void _glfwPlatformRestoreWindow( void ) +{ + // If we are in fullscreen mode we need to change video modes + if( _glfwWin.Fullscreen ) + { + // Change display settings to the user selected mode + _glfwSetVideoModeMODE( _glfwWin.ModeID ); + } + + // Un-iconify window + OpenIcon( _glfwWin.Wnd ); + + // Make sure that our window ends up on top of things + ShowWindow( _glfwWin.Wnd, SW_SHOW ); + _glfwSetForegroundWindow( _glfwWin.Wnd ); + SetFocus( _glfwWin.Wnd ); + + // Window is no longer iconified + _glfwWin.Iconified = GL_FALSE; + + // Lock mouse, if necessary + if( _glfwWin.OldMouseLockValid && _glfwWin.OldMouseLock ) + { + glfwDisable( GLFW_MOUSE_CURSOR ); + } + _glfwWin.OldMouseLockValid = GL_FALSE; +} + + +//======================================================================== +// Swap buffers (double-buffering) +//======================================================================== + +void _glfwPlatformSwapBuffers( void ) +{ + _glfw_SwapBuffers( _glfwWin.DC ); +} + + +//======================================================================== +// Set double buffering swap interval +//======================================================================== + +void _glfwPlatformSwapInterval( int interval ) +{ + if( _glfwWin.SwapInterval ) + { + _glfwWin.SwapInterval( interval ); + } +} + + +//======================================================================== +// Write back window parameters into GLFW window structure +//======================================================================== + +void _glfwPlatformRefreshWindowParams( void ) +{ + PIXELFORMATDESCRIPTOR pfd; + DEVMODE dm; + int PixelFormat, mode; + + // Obtain a detailed description of current pixel format + PixelFormat = _glfw_GetPixelFormat( _glfwWin.DC ); + + if( !_glfwWin.GetPixelFormatAttribiv ) + { + _glfw_DescribePixelFormat( _glfwWin.DC, PixelFormat, + sizeof(PIXELFORMATDESCRIPTOR), &pfd ); + + // Is current OpenGL context accelerated? + _glfwWin.Accelerated = (pfd.dwFlags & PFD_GENERIC_ACCELERATED) || + !(pfd.dwFlags & PFD_GENERIC_FORMAT) ? 1 : 0; + + // "Standard" window parameters + _glfwWin.RedBits = pfd.cRedBits; + _glfwWin.GreenBits = pfd.cGreenBits; + _glfwWin.BlueBits = pfd.cBlueBits; + _glfwWin.AlphaBits = pfd.cAlphaBits; + _glfwWin.DepthBits = pfd.cDepthBits; + _glfwWin.StencilBits = pfd.cStencilBits; + _glfwWin.AccumRedBits = pfd.cAccumRedBits; + _glfwWin.AccumGreenBits = pfd.cAccumGreenBits; + _glfwWin.AccumBlueBits = pfd.cAccumBlueBits; + _glfwWin.AccumAlphaBits = pfd.cAccumAlphaBits; + _glfwWin.AuxBuffers = pfd.cAuxBuffers; + _glfwWin.Stereo = pfd.dwFlags & PFD_STEREO ? 1 : 0; + _glfwWin.Samples = 0; + } + else + { + const int attribs[] = { + WGL_ACCELERATION_ARB, + WGL_RED_BITS_ARB, + WGL_GREEN_BITS_ARB, + WGL_BLUE_BITS_ARB, + WGL_ALPHA_BITS_ARB, + WGL_DEPTH_BITS_ARB, + WGL_STENCIL_BITS_ARB, + WGL_ACCUM_RED_BITS_ARB, + WGL_ACCUM_GREEN_BITS_ARB, + WGL_ACCUM_BLUE_BITS_ARB, + WGL_ACCUM_ALPHA_BITS_ARB, + WGL_AUX_BUFFERS_ARB, + WGL_STEREO_ARB, + WGL_SAMPLES_ARB + }; + + int values[sizeof(attribs) / sizeof(attribs[0])]; + + _glfwWin.GetPixelFormatAttribiv( _glfwWin.DC, PixelFormat, 0, + sizeof(attribs) / sizeof(attribs[0]), + attribs, values); + + // Is current OpenGL context accelerated? + _glfwWin.Accelerated = (values[0] == WGL_FULL_ACCELERATION_ARB); + + // "Standard" window parameters + _glfwWin.RedBits = values[1]; + _glfwWin.GreenBits = values[2]; + _glfwWin.BlueBits = values[3]; + _glfwWin.AlphaBits = values[4]; + _glfwWin.DepthBits = values[5]; + _glfwWin.StencilBits = values[6]; + _glfwWin.AccumRedBits = values[7]; + _glfwWin.AccumGreenBits = values[8]; + _glfwWin.AccumBlueBits = values[9]; + _glfwWin.AccumAlphaBits = values[10]; + _glfwWin.AuxBuffers = values[11]; + _glfwWin.Stereo = values[12]; + _glfwWin.Samples = values[13]; + } + + // Get refresh rate + mode = _glfwWin.Fullscreen ? _glfwWin.ModeID : ENUM_CURRENT_SETTINGS; + dm.dmSize = sizeof( DEVMODE ); + + if( EnumDisplaySettings( NULL, mode, &dm ) ) + { + _glfwWin.RefreshRate = dm.dmDisplayFrequency; + if( _glfwWin.RefreshRate <= 1 ) + { + _glfwWin.RefreshRate = 0; + } + } + else + { + _glfwWin.RefreshRate = 0; + } +} + + +//======================================================================== +// Poll for new window and input events +//======================================================================== + +void _glfwPlatformPollEvents( void ) +{ + MSG msg; + int winclosed = GL_FALSE; + + // Flag: mouse was not moved (will be changed by _glfwGetNextEvent if + // there was a mouse move event) + _glfwInput.MouseMoved = GL_FALSE; + if( _glfwWin.MouseLock ) + { + _glfwInput.OldMouseX = _glfwWin.Width/2; + _glfwInput.OldMouseY = _glfwWin.Height/2; + } + else + { + _glfwInput.OldMouseX = _glfwInput.MousePosX; + _glfwInput.OldMouseY = _glfwInput.MousePosY; + } + + // Check for new window messages + while( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) ) + { + switch( msg.message ) + { + // QUIT-message (from close window)? + case WM_QUIT: + winclosed = GL_TRUE; + break; + + // Ok, send it to the window message handler + default: + DispatchMessage( &msg ); + break; + } + } + + // LSHIFT/RSHIFT fixup (keys tend to "stick" without this fix) + // This is the only async event handling in GLFW, but it solves some + // nasty problems. + // Caveat: Does not work under Win 9x/ME. + if( _glfwLibrary.Sys.WinVer >= _GLFW_WIN_NT4 ) + { + int lshift_down, rshift_down; + + // Get current state of left and right shift keys + lshift_down = (GetAsyncKeyState( VK_LSHIFT ) >> 15) & 1; + rshift_down = (GetAsyncKeyState( VK_RSHIFT ) >> 15) & 1; + + // See if this differs from our belief of what has happened + // (we only have to check for lost key up events) + if( !lshift_down && _glfwInput.Key[ GLFW_KEY_LSHIFT ] == 1 ) + { + _glfwInputKey( GLFW_KEY_LSHIFT, GLFW_RELEASE ); + } + if( !rshift_down && _glfwInput.Key[ GLFW_KEY_RSHIFT ] == 1 ) + { + _glfwInputKey( GLFW_KEY_RSHIFT, GLFW_RELEASE ); + } + } + + // Did we have mouse movement in locked cursor mode? + if( _glfwInput.MouseMoved && _glfwWin.MouseLock ) + { + _glfwPlatformSetMouseCursorPos( _glfwWin.Width / 2, + _glfwWin.Height / 2 ); + } + + // Was there a window close request? + if( winclosed && _glfwWin.WindowCloseCallback ) + { + // Check if the program wants us to close the window + winclosed = _glfwWin.WindowCloseCallback(); + } + if( winclosed ) + { + glfwCloseWindow(); + } +} + + +//======================================================================== +// _glfwPlatformWaitEvents() - Wait for new window and input events +//======================================================================== + +void _glfwPlatformWaitEvents( void ) +{ + // Wait for new events + WaitMessage(); + + // Poll new events + _glfwPlatformPollEvents(); +} + + +//======================================================================== +// Hide mouse cursor (lock it) +//======================================================================== + +void _glfwPlatformHideMouseCursor( void ) +{ + RECT ClipWindowRect; + + // Hide cursor + ShowCursor( FALSE ); + + // Clip cursor to the window + if( GetWindowRect( _glfwWin.Wnd, &ClipWindowRect ) ) + { + ClipCursor( &ClipWindowRect ); + } + + // Capture cursor to user window + SetCapture( _glfwWin.Wnd ); +} + + +//======================================================================== +// Show mouse cursor (unlock it) +//======================================================================== + +void _glfwPlatformShowMouseCursor( void ) +{ + // Un-capture cursor + ReleaseCapture(); + + // Disable cursor clipping + ClipCursor( NULL ); + + // Show cursor + ShowCursor( TRUE ); +} + + +//======================================================================== +// Set physical mouse cursor position +//======================================================================== + +void _glfwPlatformSetMouseCursorPos( int x, int y ) +{ + POINT pos; + + // Convert client coordinates to screen coordinates + pos.x = x; + pos.y = y; + ClientToScreen( _glfwWin.Wnd, &pos ); + + // Change cursor position + SetCursorPos( pos.x, pos.y ); +} + diff --git a/src/engine/external/glfw/lib/window.c b/src/engine/external/glfw/lib/window.c new file mode 100644 index 00000000..a878c5f7 --- /dev/null +++ b/src/engine/external/glfw/lib/window.c @@ -0,0 +1,727 @@ +//======================================================================== +// GLFW - An OpenGL framework +// File: window.c +// Platform: Any +// 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 **** +//************************************************************************ + +//======================================================================== +// Clear all open window hints +//======================================================================== + +void _glfwClearWindowHints( void ) +{ + _glfwWinHints.RefreshRate = 0; + _glfwWinHints.AccumRedBits = 0; + _glfwWinHints.AccumGreenBits = 0; + _glfwWinHints.AccumBlueBits = 0; + _glfwWinHints.AccumAlphaBits = 0; + _glfwWinHints.AuxBuffers = 0; + _glfwWinHints.Stereo = 0; + _glfwWinHints.WindowNoResize = 0; + _glfwWinHints.Samples = 0; +} + + +//======================================================================== +// Handle the input tracking part of window deactivation +//======================================================================== + +void _glfwInputDeactivation( void ) +{ + int i; + + // Release all keyboard keys + for( i = 0; i <= GLFW_KEY_LAST; i ++ ) + { + if( _glfwInput.Key[ i ] == GLFW_PRESS ) + { + _glfwInputKey( i, GLFW_RELEASE ); + } + } + + // Release all mouse buttons + for( i = 0; i <= GLFW_MOUSE_BUTTON_LAST; i ++ ) + { + if( _glfwInput.MouseButton[ i ] == GLFW_PRESS ) + { + _glfwInputMouseClick( i, GLFW_RELEASE ); + } + } +} + + +//======================================================================== +// _glfwClearInput() - Clear all input state +//======================================================================== + +void _glfwClearInput( void ) +{ + int i; + + // Release all keyboard keys + for( i = 0; i <= GLFW_KEY_LAST; i ++ ) + { + _glfwInput.Key[ i ] = GLFW_RELEASE; + } + + // Clear last character + _glfwInput.LastChar = 0; + + // Release all mouse buttons + for( i = 0; i <= GLFW_MOUSE_BUTTON_LAST; i ++ ) + { + _glfwInput.MouseButton[ i ] = GLFW_RELEASE; + } + + // Set mouse position to (0,0) + _glfwInput.MousePosX = 0; + _glfwInput.MousePosY = 0; + + // Set mouse wheel position to 0 + _glfwInput.WheelPos = 0; + + // The default is to use non sticky keys and mouse buttons + _glfwInput.StickyKeys = GL_FALSE; + _glfwInput.StickyMouseButtons = GL_FALSE; + + // The default is to disable key repeat + _glfwInput.KeyRepeat = GL_FALSE; +} + + +//======================================================================== +// _glfwInputKey() - Register keyboard activity +//======================================================================== + +void _glfwInputKey( int key, int action ) +{ + int keyrepeat = 0; + + if( key < 0 || key > GLFW_KEY_LAST ) + { + return; + } + + // Are we trying to release an already released key? + if( action == GLFW_RELEASE && _glfwInput.Key[ key ] != GLFW_PRESS ) + { + return; + } + + // Register key action + if( action == GLFW_RELEASE && _glfwInput.StickyKeys ) + { + _glfwInput.Key[ key ] = GLFW_STICK; + } + else + { + keyrepeat = (_glfwInput.Key[ key ] == GLFW_PRESS) && + (action == GLFW_PRESS); + _glfwInput.Key[ key ] = (char) action; + } + + // Call user callback function + if( _glfwWin.KeyCallback && (_glfwInput.KeyRepeat || !keyrepeat) ) + { + _glfwWin.KeyCallback( key, action ); + } +} + + +//======================================================================== +// _glfwInputChar() - Register (keyboard) character activity +//======================================================================== + +void _glfwInputChar( int character, int action ) +{ + int keyrepeat = 0; + + // Valid Unicode (ISO 10646) character? + if( !( (character >= 32 && character <= 126) || character >= 160 ) ) + { + return; + } + + // Is this a key repeat? + if( action == GLFW_PRESS && _glfwInput.LastChar == character ) + { + keyrepeat = 1; + } + + // Store this character as last character (or clear it, if released) + if( action == GLFW_PRESS ) + { + _glfwInput.LastChar = character; + } + else + { + _glfwInput.LastChar = 0; + } + + // Call user callback function + if( _glfwWin.CharCallback && (_glfwInput.KeyRepeat || !keyrepeat) ) + { + _glfwWin.CharCallback( character, action ); + } +} + + +//======================================================================== +// _glfwInputMouseClick() - Register mouse button clicks +//======================================================================== + +void _glfwInputMouseClick( int button, int action ) +{ + if( button >= 0 && button <= GLFW_MOUSE_BUTTON_LAST ) + { + // Register mouse button action + if( action == GLFW_RELEASE && _glfwInput.StickyMouseButtons ) + { + _glfwInput.MouseButton[ button ] = GLFW_STICK; + } + else + { + _glfwInput.MouseButton[ button ] = (char) action; + } + + // Call user callback function + if( _glfwWin.MouseButtonCallback ) + { + _glfwWin.MouseButtonCallback( button, action ); + } + } +} + + + +//************************************************************************ +//**** GLFW user functions **** +//************************************************************************ + +//======================================================================== +// glfwOpenWindow() - Here is where the window is created, and the OpenGL +// rendering context is created +//======================================================================== + +GLFWAPI int GLFWAPIENTRY glfwOpenWindow( int width, int height, + int redbits, int greenbits, int bluebits, int alphabits, + int depthbits, int stencilbits, int mode ) +{ + int x; + _GLFWhints hints; + + // Is GLFW initialized? + if( !_glfwInitialized || _glfwWin.Opened ) + { + return GL_FALSE; + } + + // Copy and clear window hints + hints = _glfwWinHints; + _glfwClearWindowHints(); + + // Check input arguments + if( mode != GLFW_WINDOW && mode != GLFW_FULLSCREEN ) + { + return GL_FALSE; + } + + // Clear GLFW window state + _glfwWin.Active = GL_TRUE; + _glfwWin.Iconified = GL_FALSE; + _glfwWin.MouseLock = GL_FALSE; + _glfwWin.AutoPollEvents = GL_TRUE; + _glfwClearInput(); + + // Unregister all callback functions + _glfwWin.WindowSizeCallback = NULL; + _glfwWin.WindowCloseCallback = NULL; + _glfwWin.WindowRefreshCallback = NULL; + _glfwWin.KeyCallback = NULL; + _glfwWin.CharCallback = NULL; + _glfwWin.MousePosCallback = NULL; + _glfwWin.MouseButtonCallback = NULL; + _glfwWin.MouseWheelCallback = NULL; + + // Check width & height + if( width > 0 && height <= 0 ) + { + // Set the window aspect ratio to 4:3 + height = (width * 3) / 4; + } + else if( width <= 0 && height > 0 ) + { + // Set the window aspect ratio to 4:3 + width = (height * 4) / 3; + } + else if( width <= 0 && height <= 0 ) + { + // Default window size + width = 640; + height = 480; + } + + // Remember window settings + _glfwWin.Width = width; + _glfwWin.Height = height; + _glfwWin.Fullscreen = (mode == GLFW_FULLSCREEN ? 1 : 0); + + // Platform specific window opening routine + if( !_glfwPlatformOpenWindow( width, height, redbits, greenbits, + bluebits, alphabits, depthbits, stencilbits, mode, &hints ) ) + { + return GL_FALSE; + } + + // Flag that window is now opened + _glfwWin.Opened = GL_TRUE; + + // Get window parameters (such as color buffer bits etc) + _glfwPlatformRefreshWindowParams(); + + // Get OpenGL version + glfwGetGLVersion( &_glfwWin.GLVerMajor, &_glfwWin.GLVerMinor, &x ); + + // Do we have non-power-of-two textures? + _glfwWin.Has_GL_ARB_texture_non_power_of_two = + glfwExtensionSupported( "GL_ARB_texture_non_power_of_two" ); + + // Do we have automatic mipmap generation? + _glfwWin.Has_GL_SGIS_generate_mipmap = + (_glfwWin.GLVerMajor >= 2) || (_glfwWin.GLVerMinor >= 4) || + glfwExtensionSupported( "GL_SGIS_generate_mipmap" ); + + // If full-screen mode was requested, disable mouse cursor + if( mode == GLFW_FULLSCREEN ) + { + glfwDisable( GLFW_MOUSE_CURSOR ); + } + + return GL_TRUE; +} + + +//======================================================================== +// glfwOpenWindowHint() - Set hints for opening the window +//======================================================================== + +GLFWAPI void GLFWAPIENTRY glfwOpenWindowHint( int target, int hint ) +{ + // Is GLFW initialized? + if( !_glfwInitialized ) + { + return; + } + + switch( target ) + { + case GLFW_REFRESH_RATE: + _glfwWinHints.RefreshRate = hint; + break; + case GLFW_ACCUM_RED_BITS: + _glfwWinHints.AccumRedBits = hint; + break; + case GLFW_ACCUM_GREEN_BITS: + _glfwWinHints.AccumGreenBits = hint; + break; + case GLFW_ACCUM_BLUE_BITS: + _glfwWinHints.AccumBlueBits = hint; + break; + case GLFW_ACCUM_ALPHA_BITS: + _glfwWinHints.AccumAlphaBits = hint; + break; + case GLFW_AUX_BUFFERS: + _glfwWinHints.AuxBuffers = hint; + break; + case GLFW_STEREO: + _glfwWinHints.Stereo = hint; + break; + case GLFW_WINDOW_NO_RESIZE: + _glfwWinHints.WindowNoResize = hint; + break; + case GLFW_FSAA_SAMPLES: + _glfwWinHints.Samples = hint; + break; + default: + break; + } +} + + +//======================================================================== +// glfwCloseWindow() - Properly kill the window / video display +//======================================================================== + +GLFWAPI void GLFWAPIENTRY glfwCloseWindow( void ) +{ + // Is GLFW initialized? + if( !_glfwInitialized ) + { + return; + } + + // Show mouse pointer again (if hidden) + glfwEnable( GLFW_MOUSE_CURSOR ); + + // Close window + _glfwPlatformCloseWindow(); + + // Window is no longer opened + _glfwWin.Opened = GL_FALSE; +} + + +//======================================================================== +// glfwSetWindowTitle() - Set the window title +//======================================================================== + +GLFWAPI void GLFWAPIENTRY glfwSetWindowTitle( const char *title ) +{ + // Is GLFW initialized? + if( !_glfwInitialized || !_glfwWin.Opened ) + { + return; + } + + // Set window title + _glfwPlatformSetWindowTitle( title ); +} + + +//======================================================================== +// glfwGetWindowSize() - Get the window size +//======================================================================== + +GLFWAPI void GLFWAPIENTRY glfwGetWindowSize( int *width, int *height ) +{ + if( width != NULL ) + { + *width = _glfwWin.Width; + } + if( height != NULL ) + { + *height = _glfwWin.Height; + } +} + + +//======================================================================== +// glfwSetWindowSize() - Set the window size +//======================================================================== + +GLFWAPI void GLFWAPIENTRY glfwSetWindowSize( int width, int height ) +{ + // Is GLFW initialized? + if( !_glfwInitialized || !_glfwWin.Opened || _glfwWin.Iconified ) + { + return; + } + + // Don't do anything if the window size did not change + if( width == _glfwWin.Width && height == _glfwWin.Height ) + { + return; + } + + // Change window size + _glfwPlatformSetWindowSize( width, height ); + + // Refresh window parameters (may have changed due to changed video + // modes) + _glfwPlatformRefreshWindowParams(); +} + + +//======================================================================== +// glfwSetWindowPos() - Set the window position +//======================================================================== + +GLFWAPI void GLFWAPIENTRY glfwSetWindowPos( int x, int y ) +{ + // Is GLFW initialized? + if( !_glfwInitialized || !_glfwWin.Opened || _glfwWin.Fullscreen || + _glfwWin.Iconified ) + { + return; + } + + // Set window position + _glfwPlatformSetWindowPos( x, y ); +} + + +//======================================================================== +// glfwIconfyWindow() - Window iconification +//======================================================================== + +GLFWAPI void GLFWAPIENTRY glfwIconifyWindow( void ) +{ + // Is GLFW initialized? + if( !_glfwInitialized || !_glfwWin.Opened || _glfwWin.Iconified ) + { + return; + } + + // Iconify window + _glfwPlatformIconifyWindow(); +} + + +//======================================================================== +// glfwRestoreWindow() - Window un-iconification +//======================================================================== + +GLFWAPI void GLFWAPIENTRY glfwRestoreWindow( void ) +{ + // Is GLFW initialized? + if( !_glfwInitialized || !_glfwWin.Opened || !_glfwWin.Iconified ) + { + return; + } + + // Restore iconified window + _glfwPlatformRestoreWindow(); + + // Refresh window parameters + _glfwPlatformRefreshWindowParams(); +} + + +//======================================================================== +// glfwSwapBuffers() - Swap buffers (double-buffering) and poll any new +// events +//======================================================================== + +GLFWAPI void GLFWAPIENTRY glfwSwapBuffers( void ) +{ + // Is GLFW initialized? + if( !_glfwInitialized || !_glfwWin.Opened ) + { + return; + } + + // Check for window messages + if( _glfwWin.AutoPollEvents ) + { + glfwPollEvents(); + } + + // Update display-buffer + if( _glfwWin.Opened ) + { + _glfwPlatformSwapBuffers(); + } +} + + +//======================================================================== +// glfwSwapInterval() - Set double buffering swap interval (0 = vsync off) +//======================================================================== + +GLFWAPI void GLFWAPIENTRY glfwSwapInterval( int interval ) +{ + // Is GLFW initialized? + if( !_glfwInitialized || !_glfwWin.Opened ) + { + return; + } + + // Set double buffering swap interval + _glfwPlatformSwapInterval( interval ); +} + + +//======================================================================== +// glfwGetWindowParam() - Get window parameter +//======================================================================== + +GLFWAPI int GLFWAPIENTRY glfwGetWindowParam( int param ) +{ + // Is GLFW initialized? + if( !_glfwInitialized ) + { + return 0; + } + + // Is the window opened? + if( !_glfwWin.Opened ) + { + if( param == GLFW_OPENED ) + { + return GL_FALSE; + } + return 0; + } + + // Window parameters + switch( param ) + { + case GLFW_OPENED: + return GL_TRUE; + case GLFW_ACTIVE: + return _glfwWin.Active; + case GLFW_ICONIFIED: + return _glfwWin.Iconified; + case GLFW_ACCELERATED: + return _glfwWin.Accelerated; + case GLFW_RED_BITS: + return _glfwWin.RedBits; + case GLFW_GREEN_BITS: + return _glfwWin.GreenBits; + case GLFW_BLUE_BITS: + return _glfwWin.BlueBits; + case GLFW_ALPHA_BITS: + return _glfwWin.AlphaBits; + case GLFW_DEPTH_BITS: + return _glfwWin.DepthBits; + case GLFW_STENCIL_BITS: + return _glfwWin.StencilBits; + case GLFW_ACCUM_RED_BITS: + return _glfwWin.AccumRedBits; + case GLFW_ACCUM_GREEN_BITS: + return _glfwWin.AccumGreenBits; + case GLFW_ACCUM_BLUE_BITS: + return _glfwWin.AccumBlueBits; + case GLFW_ACCUM_ALPHA_BITS: + return _glfwWin.AccumAlphaBits; + case GLFW_AUX_BUFFERS: + return _glfwWin.AuxBuffers; + case GLFW_STEREO: + return _glfwWin.Stereo; + case GLFW_REFRESH_RATE: + return _glfwWin.RefreshRate; + case GLFW_WINDOW_NO_RESIZE: + return _glfwWin.WindowNoResize; + case GLFW_FSAA_SAMPLES: + return _glfwWin.Samples; + default: + return 0; + } +} + + +//======================================================================== +// glfwSetWindowSizeCallback() - Set callback function for window size +// changes +//======================================================================== + +GLFWAPI void GLFWAPIENTRY glfwSetWindowSizeCallback( GLFWwindowsizefun cbfun ) +{ + // Is GLFW initialized? + if( !_glfwInitialized || !_glfwWin.Opened ) + { + return; + } + + // Set callback function + _glfwWin.WindowSizeCallback = cbfun; + + // Call the callback function to let the application know the current + // window size + if( cbfun ) + { + cbfun( _glfwWin.Width, _glfwWin.Height ); + } +} + +//======================================================================== +// glfwSetWindowCloseCallback() - Set callback function for window close +// events +//======================================================================== + +GLFWAPI void GLFWAPIENTRY glfwSetWindowCloseCallback( GLFWwindowclosefun cbfun ) +{ + // Is GLFW initialized? + if( !_glfwInitialized || !_glfwWin.Opened ) + { + return; + } + + // Set callback function + _glfwWin.WindowCloseCallback = cbfun; +} + + +//======================================================================== +// glfwSetWindowRefreshCallback() - Set callback function for window +// refresh events +//======================================================================== + +GLFWAPI void GLFWAPIENTRY glfwSetWindowRefreshCallback( GLFWwindowrefreshfun cbfun ) +{ + // Is GLFW initialized? + if( !_glfwInitialized || !_glfwWin.Opened ) + { + return; + } + + // Set callback function + _glfwWin.WindowRefreshCallback = cbfun; +} + + +//======================================================================== +// glfwPollEvents() - Poll for new window and input events +//======================================================================== + +GLFWAPI void GLFWAPIENTRY glfwPollEvents( void ) +{ + // Is GLFW initialized? + if( !_glfwInitialized || !_glfwWin.Opened ) + { + return; + } + + // Poll for new events + _glfwPlatformPollEvents(); +} + + +//======================================================================== +// glfwWaitEvents() - Wait for new window and input events +//======================================================================== + +GLFWAPI void GLFWAPIENTRY glfwWaitEvents( void ) +{ + // Is GLFW initialized? + if( !_glfwInitialized || !_glfwWin.Opened ) + { + return; + } + + // Poll for new events + _glfwPlatformWaitEvents(); +} + diff --git a/src/engine/external/glfw/lib/x11/platform.h b/src/engine/external/glfw/lib/x11/platform.h new file mode 100644 index 00000000..d03d3582 --- /dev/null +++ b/src/engine/external/glfw/lib/x11/platform.h @@ -0,0 +1,415 @@ +//======================================================================== +// GLFW - An OpenGL framework +// File: platform.h +// Platform: X11 (Unix) +// 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 X11 version of GLFW +#define _GLFW_X11 + + +// Include files +#include <sys/time.h> +#include <unistd.h> +#include <signal.h> +#include <X11/Xlib.h> +#include <X11/keysym.h> +#include <X11/Xatom.h> +#include <GL/glx.h> +#include "../../include/GL/glfw.h" + +// Do we have pthread support? +#ifdef _GLFW_HAS_PTHREAD + #include <pthread.h> + #include <sched.h> +#endif + +// With XFree86, we can use the XF86VidMode extension +#if defined( _GLFW_HAS_XF86VIDMODE ) + #include <X11/extensions/xf86vmode.h> +#endif + +#if defined( _GLFW_HAS_XRANDR ) + #include <X11/extensions/Xrandr.h> +#endif + +// Do we have support for dlopen/dlsym? +#if defined( _GLFW_HAS_DLOPEN ) + #include <dlfcn.h> +#endif + +// We support two different ways for getting the number of processors in +// the system: sysconf (POSIX) and sysctl (BSD?) +#if defined( _GLFW_HAS_SYSCONF ) + + // Use a single constant for querying number of online processors using + // the sysconf function (e.g. SGI defines _SC_NPROC_ONLN instead of + // _SC_NPROCESSORS_ONLN) + #ifndef _SC_NPROCESSORS_ONLN + #ifdef _SC_NPROC_ONLN + #define _SC_NPROCESSORS_ONLN _SC_NPROC_ONLN + #else + #error POSIX constant _SC_NPROCESSORS_ONLN not defined! + #endif + #endif + + // Macro for querying the number of processors + #define _glfw_numprocessors(n) n=(int)sysconf(_SC_NPROCESSORS_ONLN) + +#elif defined( _GLFW_HAS_SYSCTL ) + + #include <sys/types.h> + #include <sys/sysctl.h> + + // Macro for querying the number of processors + #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; \ + } \ + } \ + } + +#else + + // If neither sysconf nor sysctl is supported, assume single processor + // system + #define _glfw_numprocessors(n) n=1 + +#endif + +void (*glXGetProcAddress(const GLubyte *procName))(); +void (*glXGetProcAddressARB(const GLubyte *procName))(); +void (*glXGetProcAddressEXT(const GLubyte *procName))(); + +// We support four different ways for getting addresses for GL/GLX +// extension functions: glXGetProcAddress, glXGetProcAddressARB, +// glXGetProcAddressEXT, and dlsym +#if defined( _GLFW_HAS_GLXGETPROCADDRESSARB ) + #define _glfw_glXGetProcAddress(x) glXGetProcAddressARB(x) +#elif defined( _GLFW_HAS_GLXGETPROCADDRESS ) + #define _glfw_glXGetProcAddress(x) glXGetProcAddress(x) +#elif defined( _GLFW_HAS_GLXGETPROCADDRESSEXT ) + #define _glfw_glXGetProcAddress(x) glXGetProcAddressEXT(x) +#elif defined( _GLFW_HAS_DLOPEN ) + #define _glfw_glXGetProcAddress(x) dlsym(_glfwLibs.libGL,x) + #define _GLFW_DLOPEN_LIBGL +#else +#define _glfw_glXGetProcAddress(x) NULL +#endif + +// glXSwapIntervalSGI typedef (X11 buffer-swap interval control) +typedef int ( * GLXSWAPINTERVALSGI_T) (int interval); + + +//======================================================================== +// Global variables (GLFW internals) +//======================================================================== + +//------------------------------------------------------------------------ +// Window structure +//------------------------------------------------------------------------ +typedef struct _GLFWwin_struct _GLFWwin; + +struct _GLFWwin_struct { + +// ========= PLATFORM INDEPENDENT MANDATORY PART ========================= + + // User callback functions + GLFWwindowsizefun WindowSizeCallback; + GLFWwindowclosefun WindowCloseCallback; + GLFWwindowrefreshfun WindowRefreshCallback; + GLFWmousebuttonfun MouseButtonCallback; + GLFWmouseposfun MousePosCallback; + GLFWmousewheelfun MouseWheelCallback; + GLFWkeyfun KeyCallback; + GLFWcharfun CharCallback; + + // User selected window settings + int Fullscreen; // Fullscreen flag + int MouseLock; // Mouse-lock flag + int AutoPollEvents; // Auto polling flag + int SysKeysDisabled; // System keys disabled flag + int WindowNoResize; // Resize- and maximize gadgets disabled flag + + // Window status & parameters + int Opened; // Flag telling if window is opened or not + int Active; // Application active flag + int Iconified; // Window iconified flag + int Width, Height; // Window width and heigth + int Accelerated; // GL_TRUE if window is HW accelerated + 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; // Vertical monitor refresh rate + int Samples; + + // Extensions & OpenGL version + int Has_GL_SGIS_generate_mipmap; + int Has_GL_ARB_texture_non_power_of_two; + int GLVerMajor,GLVerMinor; + + +// ========= PLATFORM SPECIFIC PART ====================================== + + // Platform specific window resources + Window Win; // Window + int Scrn; // Screen ID + XVisualInfo *VI; // Visual + GLXContext CX; // OpenGL rendering context + Atom WMDeleteWindow; // For WM close detection + Atom WMPing; // For WM ping response + XSizeHints *Hints; // WM size hints + + // Platform specific extensions + GLXSWAPINTERVALSGI_T SwapInterval; + + // Various platform specific internal variables + int OverrideRedirect; // True if window is OverrideRedirect + int KeyboardGrabbed; // True if keyboard is currently grabbed + int PointerGrabbed; // True if pointer is currently grabbed + int PointerHidden; // True if pointer is currently hidden + int MapNotifyCount; // Used for during processing + int FocusInCount; // Used for during processing + + // Screensaver data + struct { + int Changed; + int Timeout; + int Interval; + int Blanking; + int Exposure; + } Saver; + + // Fullscreen data + struct { + int ModeChanged; +#if defined( _GLFW_HAS_XF86VIDMODE ) + XF86VidModeModeInfo OldMode; +#endif +#if defined( _GLFW_HAS_XRANDR ) + SizeID OldSizeID; + int OldWidth; + int OldHeight; + Rotation OldRotation; +#endif + } FS; +}; + +GLFWGLOBAL _GLFWwin _glfwWin; + + +//------------------------------------------------------------------------ +// User input status (most 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 ====================================== + + // Platform specific internal variables + int MouseMoved, CursorPosX, CursorPosY; + +} _glfwInput; + + +//------------------------------------------------------------------------ +// Library global data +//------------------------------------------------------------------------ +GLFWGLOBAL struct { + +// ========= PLATFORM SPECIFIC PART ====================================== + + Display *Dpy; + int NumScreens; + int DefaultScreen; + + struct { + int Available; + int EventBase; + int ErrorBase; + } XF86VidMode; + + struct { + int Available; + int EventBase; + int ErrorBase; + } XRandR; + + // Timer data + struct { + double Resolution; + long long t0; + } Timer; + +#if defined(_GLFW_DLOPEN_LIBGL) + struct { + void *libGL; // dlopen handle for libGL.so + } Libs; +#endif +} _glfwLibrary; + + +//------------------------------------------------------------------------ +// Thread record (one for each thread) +//------------------------------------------------------------------------ +typedef struct _GLFWthread_struct _GLFWthread; + +struct _GLFWthread_struct { + +// ========= PLATFORM INDEPENDENT MANDATORY PART ========================= + + // Pointer to previous and next threads in linked list + _GLFWthread *Previous, *Next; + + // GLFW user side thread information + GLFWthread ID; + GLFWthreadfun Function; + +// ========= PLATFORM SPECIFIC PART ====================================== + + // System side thread information +#ifdef _GLFW_HAS_PTHREAD + pthread_t PosixID; +#endif + +}; + + +//------------------------------------------------------------------------ +// General thread information +//------------------------------------------------------------------------ +GLFWGLOBAL struct { + +// ========= PLATFORM INDEPENDENT MANDATORY PART ========================= + + // Next thread ID to use (increments for every created thread) + GLFWthread NextID; + + // First thread in linked list (always the main thread) + _GLFWthread First; + +// ========= PLATFORM SPECIFIC PART ====================================== + + // Critical section lock +#ifdef _GLFW_HAS_PTHREAD + pthread_mutex_t CriticalSection; +#endif + +} _glfwThrd; + + +//------------------------------------------------------------------------ +// Joystick information & state +//------------------------------------------------------------------------ +GLFWGLOBAL struct { + int Present; + int fd; + int NumAxes; + int NumButtons; + float *Axis; + unsigned char *Button; +} _glfwJoy[ GLFW_JOYSTICK_LAST + 1 ]; + + +//======================================================================== +// Macros for encapsulating critical code sections (i.e. making parts +// of GLFW thread safe) +//======================================================================== + +// Thread list management +#ifdef _GLFW_HAS_PTHREAD + #define ENTER_THREAD_CRITICAL_SECTION \ + pthread_mutex_lock( &_glfwThrd.CriticalSection ); + #define LEAVE_THREAD_CRITICAL_SECTION \ + pthread_mutex_unlock( &_glfwThrd.CriticalSection ); +#else + #define ENTER_THREAD_CRITICAL_SECTION + #define LEAVE_THREAD_CRITICAL_SECTION +#endif + + +//======================================================================== +// Prototypes for platform specific internal functions +//======================================================================== + +// Time +void _glfwInitTimer( void ); + +// Fullscreen support +int _glfwGetClosestVideoMode( int screen, int *width, int *height, int *rate ); +void _glfwSetVideoModeMODE( int screen, int mode, int rate ); +void _glfwSetVideoMode( int screen, int *width, int *height, int *rate ); + +// Cursor handling +Cursor _glfwCreateNULLCursor( Display *display, Window root ); + +// Joystick input +void _glfwInitJoysticks( void ); +void _glfwTerminateJoysticks( void ); + +// Unicode support +long _glfwKeySym2Unicode( KeySym keysym ); + + +#endif // _platform_h_ diff --git a/src/engine/external/glfw/lib/x11/x11_enable.c b/src/engine/external/glfw/lib/x11/x11_enable.c new file mode 100644 index 00000000..486833f7 --- /dev/null +++ b/src/engine/external/glfw/lib/x11/x11_enable.c @@ -0,0 +1,51 @@ +//======================================================================== +// GLFW - An OpenGL framework +// File: x11_enable.c +// Platform: X11 (Unix) +// 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 **** +//************************************************************************ + +//======================================================================== +// _glfwPlatformEnableSystemKeys() - Enable system keys +// _glfwPlatformDisableSystemKeys() - Disable system keys +//======================================================================== + +void _glfwPlatformEnableSystemKeys( void ) +{ + // Not supported under X11 (yet) +} + +void _glfwPlatformDisableSystemKeys( void ) +{ + // Not supported under X11 (yet) +} diff --git a/src/engine/external/glfw/lib/x11/x11_fullscreen.c b/src/engine/external/glfw/lib/x11/x11_fullscreen.c new file mode 100644 index 00000000..2eb3cf75 --- /dev/null +++ b/src/engine/external/glfw/lib/x11/x11_fullscreen.c @@ -0,0 +1,524 @@ +//======================================================================== +// GLFW - An OpenGL framework +// File: x11_fullscreen.c +// Platform: X11 (Unix) +// 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 **** +//************************************************************************ + +//======================================================================== +// _glfwBPP2RGB() - Convert BPP to RGB bits (based on "best guess") +//======================================================================== + +static void _glfwBPP2RGB( int bpp, int *r, int *g, int *b ) +{ + int delta; + + // Special case: BPP = 32 (I don't think this is necessary for X11??) + if( bpp == 32 ) + bpp = 24; + + // Convert "bits per pixel" to red, green & blue sizes + *r = *g = *b = bpp / 3; + delta = bpp - (*r * 3); + if( delta >= 1 ) + { + *g = *g + 1; + } + if( delta == 2 ) + { + *r = *r + 1; + } +} + + +//======================================================================== +// Finds the video mode closest in size to the specified desired size +//======================================================================== + +int _glfwGetClosestVideoMode( int screen, int *width, int *height, int *rate ) +{ +#if defined( _GLFW_HAS_XRANDR ) + int i, match, bestmatch; + int sizecount, bestsize; + int ratecount, bestrate; + short *ratelist; + XRRScreenConfiguration *sc; + XRRScreenSize *sizelist; + + if( _glfwLibrary.XRandR.Available ) + { + sc = XRRGetScreenInfo( _glfwLibrary.Dpy, + RootWindow( _glfwLibrary.Dpy, screen ) ); + + sizelist = XRRConfigSizes( sc, &sizecount ); + + // Find the best matching mode + bestsize = -1; + bestmatch = 999999; + for( i = 0; i < sizecount; i++ ) + { + match = (*width - sizelist[i].width) * + (*width - sizelist[i].width) + + (*height - sizelist[i].height) * + (*height - sizelist[i].height); + if( match < bestmatch ) + { + bestmatch = match; + bestsize = i; + } + } + + if( bestsize != -1 ) + { + // Report width & height of best matching mode + *width = sizelist[bestsize].width; + *height = sizelist[bestsize].height; + + if( *rate > 0 ) + { + ratelist = XRRConfigRates( sc, bestsize, &ratecount ); + + bestrate = -1; + bestmatch = 999999; + for( i = 0; i < ratecount; i++ ) + { + match = abs( ratelist[i] - *rate ); + if( match < bestmatch ) + { + bestmatch = match; + bestrate = ratelist[i]; + } + } + + if( bestrate != -1 ) + { + *rate = bestrate; + } + } + } + + // Free modelist + XRRFreeScreenConfigInfo( sc ); + + if( bestsize != -1 ) + { + return bestsize; + } + } +#elif defined( _GLFW_HAS_XF86VIDMODE ) + XF86VidModeModeInfo **modelist; + int modecount, i, bestmode, bestmatch, match; + + // Use the XF86VidMode extension to control video resolution + if( _glfwLibrary.XF86VidMode.Available ) + { + // Get a list of all available display modes + XF86VidModeGetAllModeLines( _glfwLibrary.Dpy, screen, + &modecount, &modelist ); + + // Find the best matching mode + bestmode = -1; + bestmatch = 999999; + for( i = 0; i < modecount; i++ ) + { + match = (*width - modelist[i]->hdisplay) * + (*width - modelist[i]->hdisplay) + + (*height - modelist[i]->vdisplay) * + (*height - modelist[i]->vdisplay); + if( match < bestmatch ) + { + bestmatch = match; + bestmode = i; + } + } + + if( bestmode != -1 ) + { + // Report width & height of best matching mode + *width = modelist[ bestmode ]->hdisplay; + *h = modelist[ bestmode ]->vdisplay; + } + + // Free modelist + XFree( modelist ); + + if( bestmode != -1 ) + { + return bestmode; + } + } +#endif + + // Default: Simply use the screen resolution + *width = DisplayWidth( _glfwLibrary.Dpy, screen ); + *height = DisplayHeight( _glfwLibrary.Dpy, screen ); + + return 0; +} + + +//======================================================================== +// Change the current video mode +//======================================================================== + +void _glfwSetVideoModeMODE( int screen, int mode, int rate ) +{ +#if defined( _GLFW_HAS_XRANDR ) + XRRScreenConfiguration *sc; + Window root; + + if( _glfwLibrary.XRandR.Available ) + { + root = RootWindow( _glfwLibrary.Dpy, screen ); + sc = XRRGetScreenInfo( _glfwLibrary.Dpy, root ); + + // Remember old size and flag that we have changed the mode + if( !_glfwWin.FS.ModeChanged ) + { + _glfwWin.FS.OldSizeID = XRRConfigCurrentConfiguration( sc, &_glfwWin.FS.OldRotation ); + _glfwWin.FS.OldWidth = DisplayWidth( _glfwLibrary.Dpy, screen ); + _glfwWin.FS.OldHeight = DisplayHeight( _glfwLibrary.Dpy, screen ); + + _glfwWin.FS.ModeChanged = GL_TRUE; + } + + if( rate > 0 ) + { + // Set desired configuration + XRRSetScreenConfigAndRate( _glfwLibrary.Dpy, + sc, + root, + mode, + RR_Rotate_0, + (short) rate, + CurrentTime ); + } + else + { + // Set desired configuration + XRRSetScreenConfig( _glfwLibrary.Dpy, + sc, + root, + mode, + RR_Rotate_0, + CurrentTime ); + } + + XRRFreeScreenConfigInfo( sc ); + } +#elif defined( _GLFW_HAS_XF86VIDMODE ) + XF86VidModeModeInfo **modelist; + int modecount; + + // Use the XF86VidMode extension to control video resolution + if( _glfwLibrary.XF86VidMode.Available ) + { + // Get a list of all available display modes + XF86VidModeGetAllModeLines( _glfwLibrary.Dpy, screen, + &modecount, &modelist ); + + // Unlock mode switch if necessary + if( _glfwWin.FS.ModeChanged ) + { + XF86VidModeLockModeSwitch( _glfwLibrary.Dpy, screen, 0 ); + } + + // Change the video mode to the desired mode + XF86VidModeSwitchToMode( _glfwLibrary.Dpy, screen, + modelist[ mode ] ); + + // Set viewport to upper left corner (where our window will be) + XF86VidModeSetViewPort( _glfwLibrary.Dpy, screen, 0, 0 ); + + // Lock mode switch + XF86VidModeLockModeSwitch( _glfwLibrary.Dpy, screen, 1 ); + + // Remember old mode and flag that we have changed the mode + if( !_glfwWin.FS.ModeChanged ) + { + _glfwWin.FS.OldMode = *modelist[ 0 ]; + _glfwWin.FS.ModeChanged = GL_TRUE; + } + + // Free mode list + XFree( modelist ); + } +#endif +} + + +//======================================================================== +// Change the current video mode +//======================================================================== + +void _glfwSetVideoMode( int screen, int *width, int *height, int *rate ) +{ + int bestmode; + + // Find a best match mode + bestmode = _glfwGetClosestVideoMode( screen, width, height, rate ); + + // Change mode + _glfwSetVideoModeMODE( screen, bestmode, *rate ); +} + + + +//************************************************************************ +//**** Platform implementation functions **** +//************************************************************************ + +struct _glfwResolution { + int width; + int height; +}; + +//======================================================================== +// List available video modes +//======================================================================== + +int _glfwPlatformGetVideoModes( GLFWvidmode *list, int maxcount ) +{ + int count, k, l, r, g, b, rgba, gl; + int depth, screen; + Display *dpy; + XVisualInfo *vislist, dummy; + int viscount, rgbcount, rescount; + int *rgbarray; + struct _glfwResolution *resarray; +#if defined( _GLFW_HAS_XRANDR ) + XRRScreenConfiguration *sc; + XRRScreenSize *sizelist; + int sizecount; +#elif defined( _GLFW_HAS_XF86VIDMODE ) + XF86VidModeModeInfo **modelist; + int modecount, width, height; +#endif + + // Get display and screen + dpy = _glfwLibrary.Dpy; + screen = DefaultScreen( dpy ); + + // Get list of visuals + vislist = XGetVisualInfo( dpy, 0, &dummy, &viscount ); + if( vislist == NULL ) + { + return 0; + } + + rgbarray = (int*) malloc( sizeof(int) * viscount ); + rgbcount = 0; + + // Build RGB array + for( k = 0; k < viscount; k++ ) + { + // Does the visual support OpenGL & true color? + glXGetConfig( dpy, &vislist[k], GLX_USE_GL, &gl ); + glXGetConfig( dpy, &vislist[k], GLX_RGBA, &rgba ); + if( gl && rgba ) + { + // Get color depth for this visual + depth = vislist[k].depth; + + // Convert to RGB + _glfwBPP2RGB( depth, &r, &g, &b ); + depth = (r<<16) | (g<<8) | b; + + // Is this mode unique? + for( l = 0; l < rgbcount; l++ ) + { + if( depth == rgbarray[ l ] ) + { + break; + } + } + if( l >= rgbcount ) + { + rgbarray[ rgbcount ] = depth; + rgbcount++; + } + } + } + + rescount = 0; + resarray = NULL; + + // Build resolution array +#if defined( _GLFW_HAS_XRANDR ) + if( _glfwLibrary.XRandR.Available ) + { + sc = XRRGetScreenInfo( dpy, RootWindow( dpy, screen ) ); + sizelist = XRRConfigSizes( sc, &sizecount ); + + resarray = (struct _glfwResolution*) malloc( sizeof(struct _glfwResolution) * sizecount ); + + for( k = 0; k < sizecount; k++ ) + { + resarray[ rescount ].width = sizelist[ k ].width; + resarray[ rescount ].height = sizelist[ k ].height; + rescount++; + } + + XRRFreeScreenConfigInfo( sc ); + } +#elif defined( _GLFW_HAS_XF86VIDMODE ) + if( _glfwLibrary.XF86VidMode.Available ) + { + XF86VidModeGetAllModeLines( dpy, screen, &modecount, &modelist ); + + resarray = (struct _glfwResolution*) malloc( sizeof(struct _glfwResolution) * modecount ); + + for( k = 0; k < modecount; k++ ) + { + width = modelist[ k ]->hdisplay; + height = modelist[ k ]->vdisplay; + + // Is this mode unique? + for( l = 0; l < rescount; l++ ) + { + if( width == resarray[ l ].width && height == resarray[ l ].height ) + { + break; + } + } + if( l >= rescount ) + { + resarray[ rescount ].width = width; + resarray[ rescount ].height = height; + rescount++; + } + } + + XFree( modelist ); + } +#endif + + if( !resarray ) + { + rescount = 1; + resarray = (struct _glfwResolution*) malloc( sizeof(struct _glfwResolution) * rescount ); + + resarray[ 0 ].width = DisplayWidth( dpy, screen ); + resarray[ 0 ].height = DisplayHeight( dpy, screen ); + } + + // Build permutations of colors and resolutions + count = 0; + for( k = 0; k < rgbcount && count < maxcount; k++ ) + { + for( l = 0; l < rescount && count < maxcount; l++ ) + { + list[count].Width = resarray[ l ].width; + list[count].Height = resarray[ l ].height; + list[count].RedBits = (rgbarray[ k ] >> 16) & 255; + list[count].GreenBits = (rgbarray[ k ] >> 8) & 255; + list[count].BlueBits = rgbarray[ k ] & 255; + count++; + } + } + + // Free visuals list + XFree( vislist ); + + free( resarray ); + free( rgbarray ); + + return count; +} + + +//======================================================================== +// Get the desktop video mode +//======================================================================== + +void _glfwPlatformGetDesktopMode( GLFWvidmode *mode ) +{ + Display *dpy; + int bpp, screen; +#if defined( _GLFW_HAS_XF86VIDMODE ) + XF86VidModeModeInfo **modelist; + int modecount; +#endif + + // Get display and screen + dpy = _glfwLibrary.Dpy; + screen = DefaultScreen( dpy ); + + // Get display depth + bpp = DefaultDepth( dpy, screen ); + + // Convert BPP to RGB bits + _glfwBPP2RGB( bpp, &mode->RedBits, &mode->GreenBits, &mode->BlueBits ); + +#if defined( _GLFW_HAS_XRANDR ) + if( _glfwLibrary.XRandR.Available ) + { + if( _glfwWin.FS.ModeChanged ) + { + mode->Width = _glfwWin.FS.OldWidth; + mode->Height = _glfwWin.FS.OldHeight; + return; + } + } +#elif defined( _GLFW_HAS_XF86VIDMODE ) + if( _glfwLibrary.XF86VidMode.Available ) + { + if( _glfwWin.FS.ModeChanged ) + { + // The old (desktop) mode is stored in _glfwWin.FS.OldMode + mode->Width = _glfwWin.FS.OldMode.hdisplay; + mode->Height = _glfwWin.FS.OldMode.vdisplay; + } + else + { + // Use the XF86VidMode extension to get list of video modes + XF86VidModeGetAllModeLines( dpy, screen, &modecount, + &modelist ); + + // The first mode in the list is the current (desktio) mode + mode->Width = modelist[ 0 ]->hdisplay; + mode->Height = modelist[ 0 ]->vdisplay; + + // Free list + XFree( modelist ); + } + + return; + } +#endif + + // Get current display width and height + mode->Width = DisplayWidth( dpy, screen ); + mode->Height = DisplayHeight( dpy, screen ); +} + diff --git a/src/engine/external/glfw/lib/x11/x11_glext.c b/src/engine/external/glfw/lib/x11/x11_glext.c new file mode 100644 index 00000000..242c9eb1 --- /dev/null +++ b/src/engine/external/glfw/lib/x11/x11_glext.c @@ -0,0 +1,69 @@ +//======================================================================== +// GLFW - An OpenGL framework +// File: x11_glext.c +// Platform: X11 (Unix) +// 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 **** +//************************************************************************ + +//======================================================================== +// Check if an OpenGL extension is available at runtime +//======================================================================== + +int _glfwPlatformExtensionSupported( const char *extension ) +{ + const GLubyte *extensions; + + // Get list of GLX extensions + extensions = (const GLubyte*) glXQueryExtensionsString( _glfwLibrary.Dpy, + _glfwWin.Scrn ); + if( extensions != NULL ) + { + if( _glfwStringInExtensionString( extension, extensions ) ) + { + return GL_TRUE; + } + } + + return GL_FALSE; +} + + +//======================================================================== +// Get the function pointer to an OpenGL function +//======================================================================== + +void * _glfwPlatformGetProcAddress( const char *procname ) +{ + return (void *) _glfw_glXGetProcAddress( (const GLubyte *) procname ); +} + diff --git a/src/engine/external/glfw/lib/x11/x11_init.c b/src/engine/external/glfw/lib/x11/x11_init.c new file mode 100644 index 00000000..9e406156 --- /dev/null +++ b/src/engine/external/glfw/lib/x11/x11_init.c @@ -0,0 +1,275 @@ +//======================================================================== +// GLFW - An OpenGL framework +// File: x11_init.c +// Platform: X11 (Unix) +// 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 **** +//************************************************************************ + +//======================================================================== +// Initialize GLFW thread package +//======================================================================== + +static void _glfwInitThreads( void ) +{ + // Initialize critical section handle +#ifdef _GLFW_HAS_PTHREAD + (void) pthread_mutex_init( &_glfwThrd.CriticalSection, NULL ); +#endif + + // 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.Previous = NULL; + _glfwThrd.First.Next = NULL; +#ifdef _GLFW_HAS_PTHREAD + _glfwThrd.First.PosixID = pthread_self(); +#endif +} + + +//======================================================================== +// Terminate GLFW thread package +//======================================================================== + +static void _glfwTerminateThreads( void ) +{ +#ifdef _GLFW_HAS_PTHREAD + + _GLFWthread *t, *t_next; + + // Enter critical section + ENTER_THREAD_CRITICAL_SECTION + + // Kill all threads (NOTE: THE USER SHOULD WAIT FOR ALL THREADS TO + // DIE, _BEFORE_ CALLING glfwTerminate()!!!) + t = _glfwThrd.First.Next; + while( t != NULL ) + { + // Get pointer to next thread + t_next = t->Next; + + // Simply murder the process, no mercy! + pthread_kill( t->PosixID, SIGKILL ); + + // Free memory allocated for this thread + free( (void *) t ); + + // Select next thread in list + t = t_next; + } + + // Leave critical section + LEAVE_THREAD_CRITICAL_SECTION + + // Delete critical section handle + pthread_mutex_destroy( &_glfwThrd.CriticalSection ); + +#endif // _GLFW_HAS_PTHREAD +} + + +//======================================================================== +// Dynamically load libraries +//======================================================================== + +#ifdef _GLFW_DLOPEN_LIBGL +static char * _glfw_libGL_name[ ] = +{ + "libGL.so", + "libGL.so.1", + "/usr/lib/libGL.so", + "/usr/lib/libGL.so.1", + NULL +}; +#endif + +static void _glfwInitLibraries( void ) +{ +#ifdef _GLFW_DLOPEN_LIBGL + int i; + + _glfwLibrary.Libs.libGL = NULL; + for( i = 0; !_glfw_libGL_name[ i ] != NULL; i ++ ) + { + _glfwLibrary.Libs.libGL = dlopen( _glfw_libGL_name[ i ], + RTLD_LAZY | RTLD_GLOBAL ); + if( _glfwLibrary.Libs.libGL ) + break; + } +#endif +} + + +//======================================================================== +// Terminate GLFW when exiting application +//======================================================================== + +void _glfwTerminate_atexit( void ) +{ + glfwTerminate(); +} + + +//======================================================================== +// Initialize X11 display +//======================================================================== + +static int _glfwInitDisplay( void ) +{ + // Open display + _glfwLibrary.Dpy = XOpenDisplay( 0 ); + if( !_glfwLibrary.Dpy ) + { + return GL_FALSE; + } + + // Check screens + _glfwLibrary.NumScreens = ScreenCount( _glfwLibrary.Dpy ); + _glfwLibrary.DefaultScreen = DefaultScreen( _glfwLibrary.Dpy ); + + // Check for XF86VidMode extension +#ifdef _GLFW_HAS_XF86VIDMODE + _glfwLibrary.XF86VidMode.Available = + XF86VidModeQueryExtension( _glfwLibrary.Dpy, + &_glfwLibrary.XF86VidMode.EventBase, + &_glfwLibrary.XF86VidMode.ErrorBase); +#else + _glfwLibrary.XF86VidMode.Available = 0; +#endif + + // Check for XRandR extension +#ifdef _GLFW_HAS_XRANDR + _glfwLibrary.XRandR.Available = + XRRQueryExtension( _glfwLibrary.Dpy, + &_glfwLibrary.XRandR.EventBase, + &_glfwLibrary.XRandR.ErrorBase ); +#else + _glfwLibrary.XRandR.Available = 0; +#endif + + return GL_TRUE; +} + + +//======================================================================== +// Terminate X11 display +//======================================================================== + +static void _glfwTerminateDisplay( void ) +{ + // Open display + if( _glfwLibrary.Dpy ) + { + XCloseDisplay( _glfwLibrary.Dpy ); + _glfwLibrary.Dpy = NULL; + } +} + + +//************************************************************************ +//**** Platform implementation functions **** +//************************************************************************ + +//======================================================================== +// Initialize various GLFW state +//======================================================================== + +int _glfwPlatformInit( void ) +{ + // Initialize display + if( !_glfwInitDisplay() ) + { + return GL_FALSE; + } + + // Initialize thread package + _glfwInitThreads(); + + // Try to load libGL.so if necessary + _glfwInitLibraries(); + + // Install atexit() routine + atexit( _glfwTerminate_atexit ); + + // Initialize joysticks + _glfwInitJoysticks(); + + // Start the timer + _glfwInitTimer(); + + return GL_TRUE; +} + + +//======================================================================== +// Close window and kill all threads +//======================================================================== + +int _glfwPlatformTerminate( void ) +{ +#ifdef _GLFW_HAS_PTHREAD + // Only the main thread is allowed to do this... + if( pthread_self() != _glfwThrd.First.PosixID ) + { + return GL_FALSE; + } +#endif // _GLFW_HAS_PTHREAD + + // Close OpenGL window + glfwCloseWindow(); + + // Kill thread package + _glfwTerminateThreads(); + + // Terminate display + _glfwTerminateDisplay(); + + // Terminate joysticks + _glfwTerminateJoysticks(); + + // Unload libGL.so if necessary +#ifdef _GLFW_DLOPEN_LIBGL + if( _glfwLibrary.Libs.libGL != NULL ) + { + dlclose( _glfwLibrary.Libs.libGL ); + _glfwLibrary.Libs.libGL = NULL; + } +#endif + + return GL_TRUE; +} + diff --git a/src/engine/external/glfw/lib/x11/x11_joystick.c b/src/engine/external/glfw/lib/x11/x11_joystick.c new file mode 100644 index 00000000..26d67d8c --- /dev/null +++ b/src/engine/external/glfw/lib/x11/x11_joystick.c @@ -0,0 +1,371 @@ +//======================================================================== +// GLFW - An OpenGL framework +// File: x11_joystick.c +// Platform: X11 (Unix) +// 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" + + +//======================================================================== +// Note: Only Linux joystick input is supported at the moment. Other +// systems will behave as if there are no joysticks connected. +//======================================================================== + +#ifdef linux +#define _GLFW_USE_LINUX_JOYSTICKS +#endif // linux + + + +//************************************************************************ +//**** GLFW internal functions **** +//************************************************************************ + +#ifdef _GLFW_USE_LINUX_JOYSTICKS + +//------------------------------------------------------------------------ +// Here are the Linux joystick driver v1.x interface definitions that we +// use (we do not want to rely on <linux/joystick.h>): +//------------------------------------------------------------------------ + +#include <sys/ioctl.h> +#include <fcntl.h> +#include <errno.h> + +// Joystick event types +#define JS_EVENT_BUTTON 0x01 /* button pressed/released */ +#define JS_EVENT_AXIS 0x02 /* joystick moved */ +#define JS_EVENT_INIT 0x80 /* initial state of device */ + +// Joystick event structure +struct js_event { + unsigned int time; /* (u32) event timestamp in milliseconds */ + signed short value; /* (s16) value */ + unsigned char type; /* (u8) event type */ + unsigned char number; /* (u8) axis/button number */ +}; + +// Joystick IOCTL commands +#define JSIOCGVERSION _IOR('j', 0x01, int) /* get driver version (u32) */ +#define JSIOCGAXES _IOR('j', 0x11, char) /* get number of axes (u8) */ +#define JSIOCGBUTTONS _IOR('j', 0x12, char) /* get number of buttons (u8) */ + +#endif // _GLFW_USE_LINUX_JOYSTICKS + + +//======================================================================== +// _glfwInitJoysticks() - Initialize joystick interface +//======================================================================== + +void _glfwInitJoysticks( void ) +{ +#ifdef _GLFW_USE_LINUX_JOYSTICKS + int k, n, fd, joy_count; + char *joy_base_name, joy_dev_name[ 20 ]; + int driver_version = 0x000800; + char ret_data; +#endif // _GLFW_USE_LINUX_JOYSTICKS + int i; + + // Start by saying that there are no sticks + for( i = 0; i <= GLFW_JOYSTICK_LAST; ++ i ) + { + _glfwJoy[ i ].Present = GL_FALSE; + } + +#ifdef _GLFW_USE_LINUX_JOYSTICKS + + // Try to open joysticks (nonblocking) + joy_count = 0; + for( k = 0; k <= 1 && joy_count <= GLFW_JOYSTICK_LAST; ++ k ) + { + // Pick joystick base name + switch( k ) + { + case 0: + joy_base_name = "/dev/input/js"; // USB sticks + break; + case 1: + joy_base_name = "/dev/js"; // "Legacy" sticks + break; + default: + continue; // (should never happen) + } + + // Try to open a few of these sticks + for( i = 0; i <= 50 && joy_count <= GLFW_JOYSTICK_LAST; ++ i ) + { + sprintf( joy_dev_name, "%s%d", joy_base_name, i ); + fd = open( joy_dev_name, O_NONBLOCK ); + if( fd != -1 ) + { + // Remember fd + _glfwJoy[ joy_count ].fd = fd; + + // Check that the joystick driver version is 1.0+ + ioctl( fd, JSIOCGVERSION, &driver_version ); + if( driver_version < 0x010000 ) + { + // It's an old 0.x interface (we don't support it) + close( fd ); + continue; + } + + // Get number of joystick axes + ioctl( fd, JSIOCGAXES, &ret_data ); + _glfwJoy[ joy_count ].NumAxes = (int) ret_data; + + // Get number of joystick buttons + ioctl( fd, JSIOCGBUTTONS, &ret_data ); + _glfwJoy[ joy_count ].NumButtons = (int) ret_data; + + // Allocate memory for joystick state + _glfwJoy[ joy_count ].Axis = + (float *) malloc( sizeof(float) * + _glfwJoy[ joy_count ].NumAxes ); + if( _glfwJoy[ joy_count ].Axis == NULL ) + { + close( fd ); + continue; + } + _glfwJoy[ joy_count ].Button = + (char *) malloc( sizeof(char) * + _glfwJoy[ joy_count ].NumButtons ); + if( _glfwJoy[ joy_count ].Button == NULL ) + { + free( _glfwJoy[ joy_count ].Axis ); + close( fd ); + continue; + } + + // Clear joystick state + for( n = 0; n < _glfwJoy[ joy_count ].NumAxes; ++ n ) + { + _glfwJoy[ joy_count ].Axis[ n ] = 0.0f; + } + for( n = 0; n < _glfwJoy[ joy_count ].NumButtons; ++ n ) + { + _glfwJoy[ joy_count ].Button[ n ] = GLFW_RELEASE; + } + + // The joystick is supported and connected + _glfwJoy[ joy_count ].Present = GL_TRUE; + joy_count ++; + } + } + } + +#endif // _GLFW_USE_LINUX_JOYSTICKS + +} + + +//======================================================================== +// _glfwTerminateJoysticks() - Close all opened joystick handles +//======================================================================== + +void _glfwTerminateJoysticks( void ) +{ + +#ifdef _GLFW_USE_LINUX_JOYSTICKS + + int i; + + // Close any opened joysticks + for( i = 0; i <= GLFW_JOYSTICK_LAST; ++ i ) + { + if( _glfwJoy[ i ].Present ) + { + close( _glfwJoy[ i ].fd ); + free( _glfwJoy[ i ].Axis ); + free( _glfwJoy[ i ].Button ); + _glfwJoy[ i ].Present = GL_FALSE; + } + } + +#endif // _GLFW_USE_LINUX_JOYSTICKS + +} + + +//======================================================================== +// _glfwPollJoystickEvents() - Empty joystick event queue +//======================================================================== + +static void _glfwPollJoystickEvents( void ) +{ + +#ifdef _GLFW_USE_LINUX_JOYSTICKS + + struct js_event e; + int i; + + // Get joystick events for all GLFW joysticks + for( i = 0; i <= GLFW_JOYSTICK_LAST; ++ i ) + { + // Is the stick present? + if( _glfwJoy[ i ].Present ) + { + // Read all queued events (non-blocking) + while( read(_glfwJoy[i].fd, &e, sizeof(struct js_event)) > 0 ) + { + // We don't care if it's an init event or not + e.type &= ~JS_EVENT_INIT; + + // Check event type + switch( e.type ) + { + case JS_EVENT_AXIS: + _glfwJoy[ i ].Axis[ e.number ] = (float) e.value / + 32767.0f; + // We need to change the sign for the Y axes, so that + // positive = up/forward, according to the GLFW spec. + if( e.number & 1 ) + { + _glfwJoy[ i ].Axis[ e.number ] = + -_glfwJoy[ i ].Axis[ e.number ]; + } + break; + + case JS_EVENT_BUTTON: + _glfwJoy[ i ].Button[ e.number ] = + e.value ? GLFW_PRESS : GLFW_RELEASE; + break; + + default: + break; + } + } + } + } + +#endif // _GLFW_USE_LINUX_JOYSTICKS + +} + + +//************************************************************************ +//**** Platform implementation functions **** +//************************************************************************ + +//======================================================================== +// _glfwPlatformGetJoystickParam() - Determine joystick capabilities +//======================================================================== + +int _glfwPlatformGetJoystickParam( int joy, int param ) +{ + // Is joystick present? + if( !_glfwJoy[ joy ].Present ) + { + return 0; + } + + switch( param ) + { + case GLFW_PRESENT: + return GL_TRUE; + + case GLFW_AXES: + return _glfwJoy[ joy ].NumAxes; + + case GLFW_BUTTONS: + return _glfwJoy[ joy ].NumButtons; + + default: + break; + } + + return 0; +} + + +//======================================================================== +// _glfwPlatformGetJoystickPos() - Get joystick axis positions +//======================================================================== + +int _glfwPlatformGetJoystickPos( int joy, float *pos, int numaxes ) +{ + int i; + + // Is joystick present? + if( !_glfwJoy[ joy ].Present ) + { + return 0; + } + + // Update joystick state + _glfwPollJoystickEvents(); + + // Does the joystick support less axes than requested? + if( _glfwJoy[ joy ].NumAxes < numaxes ) + { + numaxes = _glfwJoy[ joy ].NumAxes; + } + + // Copy axis positions from internal state + for( i = 0; i < numaxes; ++ i ) + { + pos[ i ] = _glfwJoy[ joy ].Axis[ i ]; + } + + return numaxes; +} + + +//======================================================================== +// _glfwPlatformGetJoystickButtons() - Get joystick button states +//======================================================================== + +int _glfwPlatformGetJoystickButtons( int joy, unsigned char *buttons, + int numbuttons ) +{ + int i; + + // Is joystick present? + if( !_glfwJoy[ joy ].Present ) + { + return 0; + } + + // Update joystick state + _glfwPollJoystickEvents(); + + // Does the joystick support less buttons than requested? + if( _glfwJoy[ joy ].NumButtons < numbuttons ) + { + numbuttons = _glfwJoy[ joy ].NumButtons; + } + + // Copy button states from internal state + for( i = 0; i < numbuttons; ++ i ) + { + buttons[ i ] = _glfwJoy[ joy ].Button[ i ]; + } + + return numbuttons; +} diff --git a/src/engine/external/glfw/lib/x11/x11_keysym2unicode.c b/src/engine/external/glfw/lib/x11/x11_keysym2unicode.c new file mode 100644 index 00000000..6a308734 --- /dev/null +++ b/src/engine/external/glfw/lib/x11/x11_keysym2unicode.c @@ -0,0 +1,902 @@ +//======================================================================== +// GLFW - An OpenGL framework +// File: x11_keysym2unicode.c +// Platform: X11 (Unix) +// 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" + + +/* + * Marcus: This code was originally written by Markus G. Kuhn. + * I have made some slight changes (trimmed it down a bit from >60 KB to + * 20 KB), but the functionality is the same. + */ + +/* + * This module converts keysym values into the corresponding ISO 10646 + * (UCS, Unicode) values. + * + * The array keysymtab[] contains pairs of X11 keysym values for graphical + * characters and the corresponding Unicode value. The function + * _glfwKeySym2Unicode() maps a keysym onto a Unicode value using a binary + * search, therefore keysymtab[] must remain SORTED by keysym value. + * + * We allow to represent any UCS character in the range U-00000000 to + * U-00FFFFFF by a keysym value in the range 0x01000000 to 0x01ffffff. + * This admittedly does not cover the entire 31-bit space of UCS, but + * it does cover all of the characters up to U-10FFFF, which can be + * represented by UTF-16, and more, and it is very unlikely that higher + * UCS codes will ever be assigned by ISO. So to get Unicode character + * U+ABCD you can directly use keysym 0x0100abcd. + * + * Original author: Markus G. Kuhn <mkuhn@acm.org>, University of + * Cambridge, April 2001 + * + * Special thanks to Richard Verhoeven <river@win.tue.nl> for preparing + * an initial draft of the mapping table. + * + */ + + +//************************************************************************ +//**** KeySym to Unicode mapping table **** +//************************************************************************ + +static struct codepair { + unsigned short keysym; + unsigned short ucs; +} keysymtab[] = { + { 0x01a1, 0x0104 }, + { 0x01a2, 0x02d8 }, + { 0x01a3, 0x0141 }, + { 0x01a5, 0x013d }, + { 0x01a6, 0x015a }, + { 0x01a9, 0x0160 }, + { 0x01aa, 0x015e }, + { 0x01ab, 0x0164 }, + { 0x01ac, 0x0179 }, + { 0x01ae, 0x017d }, + { 0x01af, 0x017b }, + { 0x01b1, 0x0105 }, + { 0x01b2, 0x02db }, + { 0x01b3, 0x0142 }, + { 0x01b5, 0x013e }, + { 0x01b6, 0x015b }, + { 0x01b7, 0x02c7 }, + { 0x01b9, 0x0161 }, + { 0x01ba, 0x015f }, + { 0x01bb, 0x0165 }, + { 0x01bc, 0x017a }, + { 0x01bd, 0x02dd }, + { 0x01be, 0x017e }, + { 0x01bf, 0x017c }, + { 0x01c0, 0x0154 }, + { 0x01c3, 0x0102 }, + { 0x01c5, 0x0139 }, + { 0x01c6, 0x0106 }, + { 0x01c8, 0x010c }, + { 0x01ca, 0x0118 }, + { 0x01cc, 0x011a }, + { 0x01cf, 0x010e }, + { 0x01d0, 0x0110 }, + { 0x01d1, 0x0143 }, + { 0x01d2, 0x0147 }, + { 0x01d5, 0x0150 }, + { 0x01d8, 0x0158 }, + { 0x01d9, 0x016e }, + { 0x01db, 0x0170 }, + { 0x01de, 0x0162 }, + { 0x01e0, 0x0155 }, + { 0x01e3, 0x0103 }, + { 0x01e5, 0x013a }, + { 0x01e6, 0x0107 }, + { 0x01e8, 0x010d }, + { 0x01ea, 0x0119 }, + { 0x01ec, 0x011b }, + { 0x01ef, 0x010f }, + { 0x01f0, 0x0111 }, + { 0x01f1, 0x0144 }, + { 0x01f2, 0x0148 }, + { 0x01f5, 0x0151 }, + { 0x01f8, 0x0159 }, + { 0x01f9, 0x016f }, + { 0x01fb, 0x0171 }, + { 0x01fe, 0x0163 }, + { 0x01ff, 0x02d9 }, + { 0x02a1, 0x0126 }, + { 0x02a6, 0x0124 }, + { 0x02a9, 0x0130 }, + { 0x02ab, 0x011e }, + { 0x02ac, 0x0134 }, + { 0x02b1, 0x0127 }, + { 0x02b6, 0x0125 }, + { 0x02b9, 0x0131 }, + { 0x02bb, 0x011f }, + { 0x02bc, 0x0135 }, + { 0x02c5, 0x010a }, + { 0x02c6, 0x0108 }, + { 0x02d5, 0x0120 }, + { 0x02d8, 0x011c }, + { 0x02dd, 0x016c }, + { 0x02de, 0x015c }, + { 0x02e5, 0x010b }, + { 0x02e6, 0x0109 }, + { 0x02f5, 0x0121 }, + { 0x02f8, 0x011d }, + { 0x02fd, 0x016d }, + { 0x02fe, 0x015d }, + { 0x03a2, 0x0138 }, + { 0x03a3, 0x0156 }, + { 0x03a5, 0x0128 }, + { 0x03a6, 0x013b }, + { 0x03aa, 0x0112 }, + { 0x03ab, 0x0122 }, + { 0x03ac, 0x0166 }, + { 0x03b3, 0x0157 }, + { 0x03b5, 0x0129 }, + { 0x03b6, 0x013c }, + { 0x03ba, 0x0113 }, + { 0x03bb, 0x0123 }, + { 0x03bc, 0x0167 }, + { 0x03bd, 0x014a }, + { 0x03bf, 0x014b }, + { 0x03c0, 0x0100 }, + { 0x03c7, 0x012e }, + { 0x03cc, 0x0116 }, + { 0x03cf, 0x012a }, + { 0x03d1, 0x0145 }, + { 0x03d2, 0x014c }, + { 0x03d3, 0x0136 }, + { 0x03d9, 0x0172 }, + { 0x03dd, 0x0168 }, + { 0x03de, 0x016a }, + { 0x03e0, 0x0101 }, + { 0x03e7, 0x012f }, + { 0x03ec, 0x0117 }, + { 0x03ef, 0x012b }, + { 0x03f1, 0x0146 }, + { 0x03f2, 0x014d }, + { 0x03f3, 0x0137 }, + { 0x03f9, 0x0173 }, + { 0x03fd, 0x0169 }, + { 0x03fe, 0x016b }, + { 0x047e, 0x203e }, + { 0x04a1, 0x3002 }, + { 0x04a2, 0x300c }, + { 0x04a3, 0x300d }, + { 0x04a4, 0x3001 }, + { 0x04a5, 0x30fb }, + { 0x04a6, 0x30f2 }, + { 0x04a7, 0x30a1 }, + { 0x04a8, 0x30a3 }, + { 0x04a9, 0x30a5 }, + { 0x04aa, 0x30a7 }, + { 0x04ab, 0x30a9 }, + { 0x04ac, 0x30e3 }, + { 0x04ad, 0x30e5 }, + { 0x04ae, 0x30e7 }, + { 0x04af, 0x30c3 }, + { 0x04b0, 0x30fc }, + { 0x04b1, 0x30a2 }, + { 0x04b2, 0x30a4 }, + { 0x04b3, 0x30a6 }, + { 0x04b4, 0x30a8 }, + { 0x04b5, 0x30aa }, + { 0x04b6, 0x30ab }, + { 0x04b7, 0x30ad }, + { 0x04b8, 0x30af }, + { 0x04b9, 0x30b1 }, + { 0x04ba, 0x30b3 }, + { 0x04bb, 0x30b5 }, + { 0x04bc, 0x30b7 }, + { 0x04bd, 0x30b9 }, + { 0x04be, 0x30bb }, + { 0x04bf, 0x30bd }, + { 0x04c0, 0x30bf }, + { 0x04c1, 0x30c1 }, + { 0x04c2, 0x30c4 }, + { 0x04c3, 0x30c6 }, + { 0x04c4, 0x30c8 }, + { 0x04c5, 0x30ca }, + { 0x04c6, 0x30cb }, + { 0x04c7, 0x30cc }, + { 0x04c8, 0x30cd }, + { 0x04c9, 0x30ce }, + { 0x04ca, 0x30cf }, + { 0x04cb, 0x30d2 }, + { 0x04cc, 0x30d5 }, + { 0x04cd, 0x30d8 }, + { 0x04ce, 0x30db }, + { 0x04cf, 0x30de }, + { 0x04d0, 0x30df }, + { 0x04d1, 0x30e0 }, + { 0x04d2, 0x30e1 }, + { 0x04d3, 0x30e2 }, + { 0x04d4, 0x30e4 }, + { 0x04d5, 0x30e6 }, + { 0x04d6, 0x30e8 }, + { 0x04d7, 0x30e9 }, + { 0x04d8, 0x30ea }, + { 0x04d9, 0x30eb }, + { 0x04da, 0x30ec }, + { 0x04db, 0x30ed }, + { 0x04dc, 0x30ef }, + { 0x04dd, 0x30f3 }, + { 0x04de, 0x309b }, + { 0x04df, 0x309c }, + { 0x05ac, 0x060c }, + { 0x05bb, 0x061b }, + { 0x05bf, 0x061f }, + { 0x05c1, 0x0621 }, + { 0x05c2, 0x0622 }, + { 0x05c3, 0x0623 }, + { 0x05c4, 0x0624 }, + { 0x05c5, 0x0625 }, + { 0x05c6, 0x0626 }, + { 0x05c7, 0x0627 }, + { 0x05c8, 0x0628 }, + { 0x05c9, 0x0629 }, + { 0x05ca, 0x062a }, + { 0x05cb, 0x062b }, + { 0x05cc, 0x062c }, + { 0x05cd, 0x062d }, + { 0x05ce, 0x062e }, + { 0x05cf, 0x062f }, + { 0x05d0, 0x0630 }, + { 0x05d1, 0x0631 }, + { 0x05d2, 0x0632 }, + { 0x05d3, 0x0633 }, + { 0x05d4, 0x0634 }, + { 0x05d5, 0x0635 }, + { 0x05d6, 0x0636 }, + { 0x05d7, 0x0637 }, + { 0x05d8, 0x0638 }, + { 0x05d9, 0x0639 }, + { 0x05da, 0x063a }, + { 0x05e0, 0x0640 }, + { 0x05e1, 0x0641 }, + { 0x05e2, 0x0642 }, + { 0x05e3, 0x0643 }, + { 0x05e4, 0x0644 }, + { 0x05e5, 0x0645 }, + { 0x05e6, 0x0646 }, + { 0x05e7, 0x0647 }, + { 0x05e8, 0x0648 }, + { 0x05e9, 0x0649 }, + { 0x05ea, 0x064a }, + { 0x05eb, 0x064b }, + { 0x05ec, 0x064c }, + { 0x05ed, 0x064d }, + { 0x05ee, 0x064e }, + { 0x05ef, 0x064f }, + { 0x05f0, 0x0650 }, + { 0x05f1, 0x0651 }, + { 0x05f2, 0x0652 }, + { 0x06a1, 0x0452 }, + { 0x06a2, 0x0453 }, + { 0x06a3, 0x0451 }, + { 0x06a4, 0x0454 }, + { 0x06a5, 0x0455 }, + { 0x06a6, 0x0456 }, + { 0x06a7, 0x0457 }, + { 0x06a8, 0x0458 }, + { 0x06a9, 0x0459 }, + { 0x06aa, 0x045a }, + { 0x06ab, 0x045b }, + { 0x06ac, 0x045c }, + { 0x06ae, 0x045e }, + { 0x06af, 0x045f }, + { 0x06b0, 0x2116 }, + { 0x06b1, 0x0402 }, + { 0x06b2, 0x0403 }, + { 0x06b3, 0x0401 }, + { 0x06b4, 0x0404 }, + { 0x06b5, 0x0405 }, + { 0x06b6, 0x0406 }, + { 0x06b7, 0x0407 }, + { 0x06b8, 0x0408 }, + { 0x06b9, 0x0409 }, + { 0x06ba, 0x040a }, + { 0x06bb, 0x040b }, + { 0x06bc, 0x040c }, + { 0x06be, 0x040e }, + { 0x06bf, 0x040f }, + { 0x06c0, 0x044e }, + { 0x06c1, 0x0430 }, + { 0x06c2, 0x0431 }, + { 0x06c3, 0x0446 }, + { 0x06c4, 0x0434 }, + { 0x06c5, 0x0435 }, + { 0x06c6, 0x0444 }, + { 0x06c7, 0x0433 }, + { 0x06c8, 0x0445 }, + { 0x06c9, 0x0438 }, + { 0x06ca, 0x0439 }, + { 0x06cb, 0x043a }, + { 0x06cc, 0x043b }, + { 0x06cd, 0x043c }, + { 0x06ce, 0x043d }, + { 0x06cf, 0x043e }, + { 0x06d0, 0x043f }, + { 0x06d1, 0x044f }, + { 0x06d2, 0x0440 }, + { 0x06d3, 0x0441 }, + { 0x06d4, 0x0442 }, + { 0x06d5, 0x0443 }, + { 0x06d6, 0x0436 }, + { 0x06d7, 0x0432 }, + { 0x06d8, 0x044c }, + { 0x06d9, 0x044b }, + { 0x06da, 0x0437 }, + { 0x06db, 0x0448 }, + { 0x06dc, 0x044d }, + { 0x06dd, 0x0449 }, + { 0x06de, 0x0447 }, + { 0x06df, 0x044a }, + { 0x06e0, 0x042e }, + { 0x06e1, 0x0410 }, + { 0x06e2, 0x0411 }, + { 0x06e3, 0x0426 }, + { 0x06e4, 0x0414 }, + { 0x06e5, 0x0415 }, + { 0x06e6, 0x0424 }, + { 0x06e7, 0x0413 }, + { 0x06e8, 0x0425 }, + { 0x06e9, 0x0418 }, + { 0x06ea, 0x0419 }, + { 0x06eb, 0x041a }, + { 0x06ec, 0x041b }, + { 0x06ed, 0x041c }, + { 0x06ee, 0x041d }, + { 0x06ef, 0x041e }, + { 0x06f0, 0x041f }, + { 0x06f1, 0x042f }, + { 0x06f2, 0x0420 }, + { 0x06f3, 0x0421 }, + { 0x06f4, 0x0422 }, + { 0x06f5, 0x0423 }, + { 0x06f6, 0x0416 }, + { 0x06f7, 0x0412 }, + { 0x06f8, 0x042c }, + { 0x06f9, 0x042b }, + { 0x06fa, 0x0417 }, + { 0x06fb, 0x0428 }, + { 0x06fc, 0x042d }, + { 0x06fd, 0x0429 }, + { 0x06fe, 0x0427 }, + { 0x06ff, 0x042a }, + { 0x07a1, 0x0386 }, + { 0x07a2, 0x0388 }, + { 0x07a3, 0x0389 }, + { 0x07a4, 0x038a }, + { 0x07a5, 0x03aa }, + { 0x07a7, 0x038c }, + { 0x07a8, 0x038e }, + { 0x07a9, 0x03ab }, + { 0x07ab, 0x038f }, + { 0x07ae, 0x0385 }, + { 0x07af, 0x2015 }, + { 0x07b1, 0x03ac }, + { 0x07b2, 0x03ad }, + { 0x07b3, 0x03ae }, + { 0x07b4, 0x03af }, + { 0x07b5, 0x03ca }, + { 0x07b6, 0x0390 }, + { 0x07b7, 0x03cc }, + { 0x07b8, 0x03cd }, + { 0x07b9, 0x03cb }, + { 0x07ba, 0x03b0 }, + { 0x07bb, 0x03ce }, + { 0x07c1, 0x0391 }, + { 0x07c2, 0x0392 }, + { 0x07c3, 0x0393 }, + { 0x07c4, 0x0394 }, + { 0x07c5, 0x0395 }, + { 0x07c6, 0x0396 }, + { 0x07c7, 0x0397 }, + { 0x07c8, 0x0398 }, + { 0x07c9, 0x0399 }, + { 0x07ca, 0x039a }, + { 0x07cb, 0x039b }, + { 0x07cc, 0x039c }, + { 0x07cd, 0x039d }, + { 0x07ce, 0x039e }, + { 0x07cf, 0x039f }, + { 0x07d0, 0x03a0 }, + { 0x07d1, 0x03a1 }, + { 0x07d2, 0x03a3 }, + { 0x07d4, 0x03a4 }, + { 0x07d5, 0x03a5 }, + { 0x07d6, 0x03a6 }, + { 0x07d7, 0x03a7 }, + { 0x07d8, 0x03a8 }, + { 0x07d9, 0x03a9 }, + { 0x07e1, 0x03b1 }, + { 0x07e2, 0x03b2 }, + { 0x07e3, 0x03b3 }, + { 0x07e4, 0x03b4 }, + { 0x07e5, 0x03b5 }, + { 0x07e6, 0x03b6 }, + { 0x07e7, 0x03b7 }, + { 0x07e8, 0x03b8 }, + { 0x07e9, 0x03b9 }, + { 0x07ea, 0x03ba }, + { 0x07eb, 0x03bb }, + { 0x07ec, 0x03bc }, + { 0x07ed, 0x03bd }, + { 0x07ee, 0x03be }, + { 0x07ef, 0x03bf }, + { 0x07f0, 0x03c0 }, + { 0x07f1, 0x03c1 }, + { 0x07f2, 0x03c3 }, + { 0x07f3, 0x03c2 }, + { 0x07f4, 0x03c4 }, + { 0x07f5, 0x03c5 }, + { 0x07f6, 0x03c6 }, + { 0x07f7, 0x03c7 }, + { 0x07f8, 0x03c8 }, + { 0x07f9, 0x03c9 }, + { 0x08a1, 0x23b7 }, + { 0x08a2, 0x250c }, + { 0x08a3, 0x2500 }, + { 0x08a4, 0x2320 }, + { 0x08a5, 0x2321 }, + { 0x08a6, 0x2502 }, + { 0x08a7, 0x23a1 }, + { 0x08a8, 0x23a3 }, + { 0x08a9, 0x23a4 }, + { 0x08aa, 0x23a6 }, + { 0x08ab, 0x239b }, + { 0x08ac, 0x239d }, + { 0x08ad, 0x239e }, + { 0x08ae, 0x23a0 }, + { 0x08af, 0x23a8 }, + { 0x08b0, 0x23ac }, + { 0x08bc, 0x2264 }, + { 0x08bd, 0x2260 }, + { 0x08be, 0x2265 }, + { 0x08bf, 0x222b }, + { 0x08c0, 0x2234 }, + { 0x08c1, 0x221d }, + { 0x08c2, 0x221e }, + { 0x08c5, 0x2207 }, + { 0x08c8, 0x223c }, + { 0x08c9, 0x2243 }, + { 0x08cd, 0x21d4 }, + { 0x08ce, 0x21d2 }, + { 0x08cf, 0x2261 }, + { 0x08d6, 0x221a }, + { 0x08da, 0x2282 }, + { 0x08db, 0x2283 }, + { 0x08dc, 0x2229 }, + { 0x08dd, 0x222a }, + { 0x08de, 0x2227 }, + { 0x08df, 0x2228 }, + { 0x08ef, 0x2202 }, + { 0x08f6, 0x0192 }, + { 0x08fb, 0x2190 }, + { 0x08fc, 0x2191 }, + { 0x08fd, 0x2192 }, + { 0x08fe, 0x2193 }, + { 0x09e0, 0x25c6 }, + { 0x09e1, 0x2592 }, + { 0x09e2, 0x2409 }, + { 0x09e3, 0x240c }, + { 0x09e4, 0x240d }, + { 0x09e5, 0x240a }, + { 0x09e8, 0x2424 }, + { 0x09e9, 0x240b }, + { 0x09ea, 0x2518 }, + { 0x09eb, 0x2510 }, + { 0x09ec, 0x250c }, + { 0x09ed, 0x2514 }, + { 0x09ee, 0x253c }, + { 0x09ef, 0x23ba }, + { 0x09f0, 0x23bb }, + { 0x09f1, 0x2500 }, + { 0x09f2, 0x23bc }, + { 0x09f3, 0x23bd }, + { 0x09f4, 0x251c }, + { 0x09f5, 0x2524 }, + { 0x09f6, 0x2534 }, + { 0x09f7, 0x252c }, + { 0x09f8, 0x2502 }, + { 0x0aa1, 0x2003 }, + { 0x0aa2, 0x2002 }, + { 0x0aa3, 0x2004 }, + { 0x0aa4, 0x2005 }, + { 0x0aa5, 0x2007 }, + { 0x0aa6, 0x2008 }, + { 0x0aa7, 0x2009 }, + { 0x0aa8, 0x200a }, + { 0x0aa9, 0x2014 }, + { 0x0aaa, 0x2013 }, + { 0x0aae, 0x2026 }, + { 0x0aaf, 0x2025 }, + { 0x0ab0, 0x2153 }, + { 0x0ab1, 0x2154 }, + { 0x0ab2, 0x2155 }, + { 0x0ab3, 0x2156 }, + { 0x0ab4, 0x2157 }, + { 0x0ab5, 0x2158 }, + { 0x0ab6, 0x2159 }, + { 0x0ab7, 0x215a }, + { 0x0ab8, 0x2105 }, + { 0x0abb, 0x2012 }, + { 0x0abc, 0x2329 }, + { 0x0abe, 0x232a }, + { 0x0ac3, 0x215b }, + { 0x0ac4, 0x215c }, + { 0x0ac5, 0x215d }, + { 0x0ac6, 0x215e }, + { 0x0ac9, 0x2122 }, + { 0x0aca, 0x2613 }, + { 0x0acc, 0x25c1 }, + { 0x0acd, 0x25b7 }, + { 0x0ace, 0x25cb }, + { 0x0acf, 0x25af }, + { 0x0ad0, 0x2018 }, + { 0x0ad1, 0x2019 }, + { 0x0ad2, 0x201c }, + { 0x0ad3, 0x201d }, + { 0x0ad4, 0x211e }, + { 0x0ad6, 0x2032 }, + { 0x0ad7, 0x2033 }, + { 0x0ad9, 0x271d }, + { 0x0adb, 0x25ac }, + { 0x0adc, 0x25c0 }, + { 0x0add, 0x25b6 }, + { 0x0ade, 0x25cf }, + { 0x0adf, 0x25ae }, + { 0x0ae0, 0x25e6 }, + { 0x0ae1, 0x25ab }, + { 0x0ae2, 0x25ad }, + { 0x0ae3, 0x25b3 }, + { 0x0ae4, 0x25bd }, + { 0x0ae5, 0x2606 }, + { 0x0ae6, 0x2022 }, + { 0x0ae7, 0x25aa }, + { 0x0ae8, 0x25b2 }, + { 0x0ae9, 0x25bc }, + { 0x0aea, 0x261c }, + { 0x0aeb, 0x261e }, + { 0x0aec, 0x2663 }, + { 0x0aed, 0x2666 }, + { 0x0aee, 0x2665 }, + { 0x0af0, 0x2720 }, + { 0x0af1, 0x2020 }, + { 0x0af2, 0x2021 }, + { 0x0af3, 0x2713 }, + { 0x0af4, 0x2717 }, + { 0x0af5, 0x266f }, + { 0x0af6, 0x266d }, + { 0x0af7, 0x2642 }, + { 0x0af8, 0x2640 }, + { 0x0af9, 0x260e }, + { 0x0afa, 0x2315 }, + { 0x0afb, 0x2117 }, + { 0x0afc, 0x2038 }, + { 0x0afd, 0x201a }, + { 0x0afe, 0x201e }, + { 0x0ba3, 0x003c }, + { 0x0ba6, 0x003e }, + { 0x0ba8, 0x2228 }, + { 0x0ba9, 0x2227 }, + { 0x0bc0, 0x00af }, + { 0x0bc2, 0x22a5 }, + { 0x0bc3, 0x2229 }, + { 0x0bc4, 0x230a }, + { 0x0bc6, 0x005f }, + { 0x0bca, 0x2218 }, + { 0x0bcc, 0x2395 }, + { 0x0bce, 0x22a4 }, + { 0x0bcf, 0x25cb }, + { 0x0bd3, 0x2308 }, + { 0x0bd6, 0x222a }, + { 0x0bd8, 0x2283 }, + { 0x0bda, 0x2282 }, + { 0x0bdc, 0x22a2 }, + { 0x0bfc, 0x22a3 }, + { 0x0cdf, 0x2017 }, + { 0x0ce0, 0x05d0 }, + { 0x0ce1, 0x05d1 }, + { 0x0ce2, 0x05d2 }, + { 0x0ce3, 0x05d3 }, + { 0x0ce4, 0x05d4 }, + { 0x0ce5, 0x05d5 }, + { 0x0ce6, 0x05d6 }, + { 0x0ce7, 0x05d7 }, + { 0x0ce8, 0x05d8 }, + { 0x0ce9, 0x05d9 }, + { 0x0cea, 0x05da }, + { 0x0ceb, 0x05db }, + { 0x0cec, 0x05dc }, + { 0x0ced, 0x05dd }, + { 0x0cee, 0x05de }, + { 0x0cef, 0x05df }, + { 0x0cf0, 0x05e0 }, + { 0x0cf1, 0x05e1 }, + { 0x0cf2, 0x05e2 }, + { 0x0cf3, 0x05e3 }, + { 0x0cf4, 0x05e4 }, + { 0x0cf5, 0x05e5 }, + { 0x0cf6, 0x05e6 }, + { 0x0cf7, 0x05e7 }, + { 0x0cf8, 0x05e8 }, + { 0x0cf9, 0x05e9 }, + { 0x0cfa, 0x05ea }, + { 0x0da1, 0x0e01 }, + { 0x0da2, 0x0e02 }, + { 0x0da3, 0x0e03 }, + { 0x0da4, 0x0e04 }, + { 0x0da5, 0x0e05 }, + { 0x0da6, 0x0e06 }, + { 0x0da7, 0x0e07 }, + { 0x0da8, 0x0e08 }, + { 0x0da9, 0x0e09 }, + { 0x0daa, 0x0e0a }, + { 0x0dab, 0x0e0b }, + { 0x0dac, 0x0e0c }, + { 0x0dad, 0x0e0d }, + { 0x0dae, 0x0e0e }, + { 0x0daf, 0x0e0f }, + { 0x0db0, 0x0e10 }, + { 0x0db1, 0x0e11 }, + { 0x0db2, 0x0e12 }, + { 0x0db3, 0x0e13 }, + { 0x0db4, 0x0e14 }, + { 0x0db5, 0x0e15 }, + { 0x0db6, 0x0e16 }, + { 0x0db7, 0x0e17 }, + { 0x0db8, 0x0e18 }, + { 0x0db9, 0x0e19 }, + { 0x0dba, 0x0e1a }, + { 0x0dbb, 0x0e1b }, + { 0x0dbc, 0x0e1c }, + { 0x0dbd, 0x0e1d }, + { 0x0dbe, 0x0e1e }, + { 0x0dbf, 0x0e1f }, + { 0x0dc0, 0x0e20 }, + { 0x0dc1, 0x0e21 }, + { 0x0dc2, 0x0e22 }, + { 0x0dc3, 0x0e23 }, + { 0x0dc4, 0x0e24 }, + { 0x0dc5, 0x0e25 }, + { 0x0dc6, 0x0e26 }, + { 0x0dc7, 0x0e27 }, + { 0x0dc8, 0x0e28 }, + { 0x0dc9, 0x0e29 }, + { 0x0dca, 0x0e2a }, + { 0x0dcb, 0x0e2b }, + { 0x0dcc, 0x0e2c }, + { 0x0dcd, 0x0e2d }, + { 0x0dce, 0x0e2e }, + { 0x0dcf, 0x0e2f }, + { 0x0dd0, 0x0e30 }, + { 0x0dd1, 0x0e31 }, + { 0x0dd2, 0x0e32 }, + { 0x0dd3, 0x0e33 }, + { 0x0dd4, 0x0e34 }, + { 0x0dd5, 0x0e35 }, + { 0x0dd6, 0x0e36 }, + { 0x0dd7, 0x0e37 }, + { 0x0dd8, 0x0e38 }, + { 0x0dd9, 0x0e39 }, + { 0x0dda, 0x0e3a }, + { 0x0ddf, 0x0e3f }, + { 0x0de0, 0x0e40 }, + { 0x0de1, 0x0e41 }, + { 0x0de2, 0x0e42 }, + { 0x0de3, 0x0e43 }, + { 0x0de4, 0x0e44 }, + { 0x0de5, 0x0e45 }, + { 0x0de6, 0x0e46 }, + { 0x0de7, 0x0e47 }, + { 0x0de8, 0x0e48 }, + { 0x0de9, 0x0e49 }, + { 0x0dea, 0x0e4a }, + { 0x0deb, 0x0e4b }, + { 0x0dec, 0x0e4c }, + { 0x0ded, 0x0e4d }, + { 0x0df0, 0x0e50 }, + { 0x0df1, 0x0e51 }, + { 0x0df2, 0x0e52 }, + { 0x0df3, 0x0e53 }, + { 0x0df4, 0x0e54 }, + { 0x0df5, 0x0e55 }, + { 0x0df6, 0x0e56 }, + { 0x0df7, 0x0e57 }, + { 0x0df8, 0x0e58 }, + { 0x0df9, 0x0e59 }, + { 0x0ea1, 0x3131 }, + { 0x0ea2, 0x3132 }, + { 0x0ea3, 0x3133 }, + { 0x0ea4, 0x3134 }, + { 0x0ea5, 0x3135 }, + { 0x0ea6, 0x3136 }, + { 0x0ea7, 0x3137 }, + { 0x0ea8, 0x3138 }, + { 0x0ea9, 0x3139 }, + { 0x0eaa, 0x313a }, + { 0x0eab, 0x313b }, + { 0x0eac, 0x313c }, + { 0x0ead, 0x313d }, + { 0x0eae, 0x313e }, + { 0x0eaf, 0x313f }, + { 0x0eb0, 0x3140 }, + { 0x0eb1, 0x3141 }, + { 0x0eb2, 0x3142 }, + { 0x0eb3, 0x3143 }, + { 0x0eb4, 0x3144 }, + { 0x0eb5, 0x3145 }, + { 0x0eb6, 0x3146 }, + { 0x0eb7, 0x3147 }, + { 0x0eb8, 0x3148 }, + { 0x0eb9, 0x3149 }, + { 0x0eba, 0x314a }, + { 0x0ebb, 0x314b }, + { 0x0ebc, 0x314c }, + { 0x0ebd, 0x314d }, + { 0x0ebe, 0x314e }, + { 0x0ebf, 0x314f }, + { 0x0ec0, 0x3150 }, + { 0x0ec1, 0x3151 }, + { 0x0ec2, 0x3152 }, + { 0x0ec3, 0x3153 }, + { 0x0ec4, 0x3154 }, + { 0x0ec5, 0x3155 }, + { 0x0ec6, 0x3156 }, + { 0x0ec7, 0x3157 }, + { 0x0ec8, 0x3158 }, + { 0x0ec9, 0x3159 }, + { 0x0eca, 0x315a }, + { 0x0ecb, 0x315b }, + { 0x0ecc, 0x315c }, + { 0x0ecd, 0x315d }, + { 0x0ece, 0x315e }, + { 0x0ecf, 0x315f }, + { 0x0ed0, 0x3160 }, + { 0x0ed1, 0x3161 }, + { 0x0ed2, 0x3162 }, + { 0x0ed3, 0x3163 }, + { 0x0ed4, 0x11a8 }, + { 0x0ed5, 0x11a9 }, + { 0x0ed6, 0x11aa }, + { 0x0ed7, 0x11ab }, + { 0x0ed8, 0x11ac }, + { 0x0ed9, 0x11ad }, + { 0x0eda, 0x11ae }, + { 0x0edb, 0x11af }, + { 0x0edc, 0x11b0 }, + { 0x0edd, 0x11b1 }, + { 0x0ede, 0x11b2 }, + { 0x0edf, 0x11b3 }, + { 0x0ee0, 0x11b4 }, + { 0x0ee1, 0x11b5 }, + { 0x0ee2, 0x11b6 }, + { 0x0ee3, 0x11b7 }, + { 0x0ee4, 0x11b8 }, + { 0x0ee5, 0x11b9 }, + { 0x0ee6, 0x11ba }, + { 0x0ee7, 0x11bb }, + { 0x0ee8, 0x11bc }, + { 0x0ee9, 0x11bd }, + { 0x0eea, 0x11be }, + { 0x0eeb, 0x11bf }, + { 0x0eec, 0x11c0 }, + { 0x0eed, 0x11c1 }, + { 0x0eee, 0x11c2 }, + { 0x0eef, 0x316d }, + { 0x0ef0, 0x3171 }, + { 0x0ef1, 0x3178 }, + { 0x0ef2, 0x317f }, + { 0x0ef3, 0x3181 }, + { 0x0ef4, 0x3184 }, + { 0x0ef5, 0x3186 }, + { 0x0ef6, 0x318d }, + { 0x0ef7, 0x318e }, + { 0x0ef8, 0x11eb }, + { 0x0ef9, 0x11f0 }, + { 0x0efa, 0x11f9 }, + { 0x0eff, 0x20a9 }, + { 0x13a4, 0x20ac }, + { 0x13bc, 0x0152 }, + { 0x13bd, 0x0153 }, + { 0x13be, 0x0178 }, + { 0x20ac, 0x20ac }, + // Numeric keypad with numlock on + { XK_KP_Space, ' ' }, + { XK_KP_Equal, '=' }, + { XK_KP_Multiply, '*' }, + { XK_KP_Add, '+' }, + { XK_KP_Separator, ',' }, + { XK_KP_Subtract, '-' }, + { XK_KP_Decimal, '.' }, + { XK_KP_Divide, '/' }, + { XK_KP_0, 0x0030 }, + { XK_KP_1, 0x0031 }, + { XK_KP_2, 0x0032 }, + { XK_KP_3, 0x0033 }, + { XK_KP_4, 0x0034 }, + { XK_KP_5, 0x0035 }, + { XK_KP_6, 0x0036 }, + { XK_KP_7, 0x0037 }, + { XK_KP_8, 0x0038 }, + { XK_KP_9, 0x0039 } +}; + + +//************************************************************************ +//**** GLFW internal functions **** +//************************************************************************ + +//======================================================================== +// _glfwKeySym2Unicode() - Convert X11 KeySym to Unicode +//======================================================================== + +long _glfwKeySym2Unicode( KeySym keysym ) +{ + int min = 0; + int max = sizeof(keysymtab) / sizeof(struct codepair) - 1; + int mid; + + /* First check for Latin-1 characters (1:1 mapping) */ + if( (keysym >= 0x0020 && keysym <= 0x007e) || + (keysym >= 0x00a0 && keysym <= 0x00ff) ) + { + return keysym; + } + + /* Also check for directly encoded 24-bit UCS characters */ + if( (keysym & 0xff000000) == 0x01000000 ) + { + return keysym & 0x00ffffff; + } + + /* Binary search in table */ + while( max >= min ) + { + mid = (min + max) / 2; + if( keysymtab[mid].keysym < keysym ) + { + min = mid + 1; + } + else if( keysymtab[mid].keysym > keysym ) + { + max = mid - 1; + } + else + { + /* Found it! */ + return keysymtab[mid].ucs; + } + } + + /* No matching Unicode value found */ + return -1; +} diff --git a/src/engine/external/glfw/lib/x11/x11_thread.c b/src/engine/external/glfw/lib/x11/x11_thread.c new file mode 100644 index 00000000..1a5db7e7 --- /dev/null +++ b/src/engine/external/glfw/lib/x11/x11_thread.c @@ -0,0 +1,507 @@ +//======================================================================== +// GLFW - An OpenGL framework +// File: x11_thread.c +// Platform: X11 (Unix) +// 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 **** +//************************************************************************ + +#ifdef _GLFW_HAS_PTHREAD + +//======================================================================== +// _glfwNewThread() - This is simply a "wrapper" for calling the user +// thread function. +//======================================================================== + +void * _glfwNewThread( void * arg ) +{ + GLFWthreadfun threadfun; + _GLFWthread *t; + 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 ) + { + break; + } + } + if( t == NULL ) + { + LEAVE_THREAD_CRITICAL_SECTION + return NULL; + } + + // Get user thread function pointer + threadfun = t->Function; + + // Leave critical section + LEAVE_THREAD_CRITICAL_SECTION + + // 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; +} + +#endif // _GLFW_HAS_PTHREAD + + + +//************************************************************************ +//**** Platform implementation functions **** +//************************************************************************ + +//======================================================================== +// _glfwPlatformCreateThread() - Create a new thread +//======================================================================== + +GLFWthread _glfwPlatformCreateThread( GLFWthreadfun fun, void *arg ) +{ +#ifdef _GLFW_HAS_PTHREAD + + 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; + +#else + + return -1; + +#endif // _GLFW_HAS_PTHREAD +} + + +//======================================================================== +// _glfwPlatformDestroyThread() - Kill a thread. NOTE: THIS IS A VERY +// DANGEROUS OPERATION, AND SHOULD NOT BE USED EXCEPT IN EXTREME +// SITUATIONS! +//======================================================================== + +void _glfwPlatformDestroyThread( GLFWthread ID ) +{ +#ifdef _GLFW_HAS_PTHREAD + + _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 + +#endif // _GLFW_HAS_PTHREAD +} + + +//======================================================================== +// _glfwPlatformWaitThread() - Wait for a thread to die +//======================================================================== + +int _glfwPlatformWaitThread( GLFWthread ID, int waitmode ) +{ +#ifdef _GLFW_HAS_PTHREAD + + 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; + +#else + + return GL_TRUE; + +#endif // _GLFW_HAS_PTHREAD +} + + +//======================================================================== +// _glfwPlatformGetThreadID() - Return the thread ID for the current +// thread +//======================================================================== + +GLFWthread _glfwPlatformGetThreadID( void ) +{ +#ifdef _GLFW_HAS_PTHREAD + + _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; + +#else + + return 0; + +#endif // _GLFW_HAS_PTHREAD +} + + +//======================================================================== +// _glfwPlatformCreateMutex() - Create a mutual exclusion object +//======================================================================== + +GLFWmutex _glfwPlatformCreateMutex( void ) +{ +#ifdef _GLFW_HAS_PTHREAD + + 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; + +#else + + return (GLFWmutex) 0; + +#endif // _GLFW_HAS_PTHREAD +} + + +//======================================================================== +// _glfwPlatformDestroyMutex() - Destroy a mutual exclusion object +//======================================================================== + +void _glfwPlatformDestroyMutex( GLFWmutex mutex ) +{ +#ifdef _GLFW_HAS_PTHREAD + + // Destroy the mutex object + pthread_mutex_destroy( (pthread_mutex_t *) mutex ); + + // Free memory for mutex object + free( (void *) mutex ); + +#endif // _GLFW_HAS_PTHREAD +} + + +//======================================================================== +// _glfwPlatformLockMutex() - Request access to a mutex +//======================================================================== + +void _glfwPlatformLockMutex( GLFWmutex mutex ) +{ +#ifdef _GLFW_HAS_PTHREAD + + // Wait for mutex to be released + (void) pthread_mutex_lock( (pthread_mutex_t *) mutex ); + +#endif // _GLFW_HAS_PTHREAD +} + + +//======================================================================== +// _glfwPlatformUnlockMutex() - Release a mutex +//======================================================================== + +void _glfwPlatformUnlockMutex( GLFWmutex mutex ) +{ +#ifdef _GLFW_HAS_PTHREAD + + // Release mutex + pthread_mutex_unlock( (pthread_mutex_t *) mutex ); + +#endif // _GLFW_HAS_PTHREAD +} + + +//======================================================================== +// _glfwPlatformCreateCond() - Create a new condition variable object +//======================================================================== + +GLFWcond _glfwPlatformCreateCond( void ) +{ +#ifdef _GLFW_HAS_PTHREAD + + 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; + +#else + + return (GLFWcond) 0; + +#endif // _GLFW_HAS_PTHREAD +} + + +//======================================================================== +// _glfwPlatformDestroyCond() - Destroy a condition variable object +//======================================================================== + +void _glfwPlatformDestroyCond( GLFWcond cond ) +{ +#ifdef _GLFW_HAS_PTHREAD + + // Destroy the condition variable object + (void) pthread_cond_destroy( (pthread_cond_t *) cond ); + + // Free memory for condition variable object + free( (void *) cond ); + +#endif // _GLFW_HAS_PTHREAD +} + + +//======================================================================== +// _glfwPlatformWaitCond() - Wait for a condition to be raised +//======================================================================== + +void _glfwPlatformWaitCond( GLFWcond cond, GLFWmutex mutex, + double timeout ) +{ +#ifdef _GLFW_HAS_PTHREAD + + 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 ); + } + +#endif // _GLFW_HAS_PTHREAD +} + + +//======================================================================== +// _glfwPlatformSignalCond() - Signal a condition to one waiting thread +//======================================================================== + +void _glfwPlatformSignalCond( GLFWcond cond ) +{ +#ifdef _GLFW_HAS_PTHREAD + + // Signal condition + (void) pthread_cond_signal( (pthread_cond_t *) cond ); + +#endif // _GLFW_HAS_PTHREAD +} + + +//======================================================================== +// _glfwPlatformBroadcastCond() - Broadcast a condition to all waiting +// threads +//======================================================================== + +void _glfwPlatformBroadcastCond( GLFWcond cond ) +{ +#ifdef _GLFW_HAS_PTHREAD + + // Broadcast condition + (void) pthread_cond_broadcast( (pthread_cond_t *) cond ); + +#endif // _GLFW_HAS_PTHREAD +} + + +//======================================================================== +// _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/x11/x11_time.c b/src/engine/external/glfw/lib/x11/x11_time.c new file mode 100644 index 00000000..32ae9d9d --- /dev/null +++ b/src/engine/external/glfw/lib/x11/x11_time.c @@ -0,0 +1,154 @@ +//======================================================================== +// GLFW - An OpenGL framework +// File: x11_time.c +// Platform: X11 (Unix) +// 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" + + +//======================================================================== +// Initialise timer +//======================================================================== + +void _glfwInitTimer( void ) +{ + struct timeval tv; + + // "Resolution" is 1 us + _glfwLibrary.Timer.Resolution = 1e-6; + + // Set start-time for timer + gettimeofday( &tv, NULL ); + _glfwLibrary.Timer.t0 = (long long) tv.tv_sec * (long long) 1000000 + + (long long) tv.tv_usec; +} + + +//************************************************************************ +//**** Platform implementation functions **** +//************************************************************************ + +//======================================================================== +// Return timer value in seconds +//======================================================================== + +double _glfwPlatformGetTime( void ) +{ + long long t; + struct timeval tv; + + gettimeofday( &tv, NULL ); + t = (long long) tv.tv_sec * (long long) 1000000 + + (long long) tv.tv_usec; + + return (double)(t - _glfwLibrary.Timer.t0) * _glfwLibrary.Timer.Resolution; +} + + +//======================================================================== +// Set timer value in seconds +//======================================================================== + +void _glfwPlatformSetTime( double t ) +{ + long long t0; + struct timeval tv; + + gettimeofday( &tv, NULL ); + t0 = (long long) tv.tv_sec * (long long) 1000000 + + (long long) tv.tv_usec; + + // Calulate new starting time + _glfwLibrary.Timer.t0 = t0 - (long long)(t/_glfwLibrary.Timer.Resolution); +} + + +//======================================================================== +// Put a thread to sleep for a specified amount of time +//======================================================================== + +void _glfwPlatformSleep( double time ) +{ +#ifdef _GLFW_HAS_PTHREAD + + if( time == 0.0 ) + { +#ifdef _GLFW_HAS_SCHED_YIELD + sched_yield(); +#endif + 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 ); + +#else + + // For systems without PTHREAD, use unistd usleep + if( time > 0 ) + { + usleep( (unsigned int) (time*1000000) ); + } + +#endif // _GLFW_HAS_PTHREAD +} + diff --git a/src/engine/external/glfw/lib/x11/x11_window.c b/src/engine/external/glfw/lib/x11/x11_window.c new file mode 100644 index 00000000..d9d97be4 --- /dev/null +++ b/src/engine/external/glfw/lib/x11/x11_window.c @@ -0,0 +1,1746 @@ +//======================================================================== +// GLFW - An OpenGL framework +// File: x11_window.c +// Platform: X11 (Unix) +// 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" + + +/* Defines some GLX FSAA tokens if not yet defined */ +#ifndef GLX_SAMPLE_BUFFERS +# define GLX_SAMPLE_BUFFERS 100000 +#endif +#ifndef GLX_SAMPLES +# define GLX_SAMPLES 100001 +#endif + + +/* KDE decoration values */ +enum { + KDE_noDecoration = 0, + KDE_normalDecoration = 1, + KDE_tinyDecoration = 2, + KDE_noFocus = 256, + KDE_standaloneMenuBar = 512, + KDE_desktopIcon = 1024 , + KDE_staysOnTop = 2048 +}; + + +//************************************************************************ +//**** GLFW internal functions **** +//************************************************************************ + +//======================================================================== +// _glfwWaitForMapNotify() +//======================================================================== + +Bool _glfwWaitForMapNotify( Display *d, XEvent *e, char *arg ) +{ + return (e->type == MapNotify) && (e->xmap.window == (Window)arg); +} + + +//======================================================================== +// _glfwWaitForUnmapNotify() +//======================================================================== + +Bool _glfwWaitForUnmapNotify( Display *d, XEvent *e, char *arg ) +{ + return (e->type == UnmapNotify) && (e->xmap.window == (Window)arg); +} + + +//======================================================================== +// _glfwDisableDecorations() - Turn off window decorations +// Based on xawdecode: src/wmhooks.c +//======================================================================== + +#define MWM_HINTS_DECORATIONS (1L << 1) + +static void _glfwDisableDecorations( void ) +{ + int RemovedDecorations; + Atom HintAtom; + XSetWindowAttributes attributes; + + RemovedDecorations = 0; + + // First try to set MWM hints + HintAtom = XInternAtom( _glfwLibrary.Dpy, "_MOTIF_WM_HINTS", True ); + if ( HintAtom != None ) + { + struct { + unsigned long flags; + unsigned long functions; + unsigned long decorations; + long input_mode; + unsigned long status; + } MWMHints = { MWM_HINTS_DECORATIONS, 0, 0, 0, 0 }; + + XChangeProperty( _glfwLibrary.Dpy, _glfwWin.Win, HintAtom, HintAtom, + 32, PropModeReplace, (unsigned char *)&MWMHints, + sizeof(MWMHints)/4 ); + RemovedDecorations = 1; + } + + // Now try to set KWM hints + HintAtom = XInternAtom( _glfwLibrary.Dpy, "KWM_WIN_DECORATION", True ); + if ( HintAtom != None ) + { + long KWMHints = KDE_tinyDecoration; + + XChangeProperty( _glfwLibrary.Dpy, _glfwWin.Win, HintAtom, HintAtom, + 32, PropModeReplace, (unsigned char *)&KWMHints, + sizeof(KWMHints)/4 ); + RemovedDecorations = 1; + } + + // Now try to set GNOME hints + HintAtom = XInternAtom(_glfwLibrary.Dpy, "_WIN_HINTS", True ); + if ( HintAtom != None ) + { + long GNOMEHints = 0; + + XChangeProperty( _glfwLibrary.Dpy, _glfwWin.Win, HintAtom, HintAtom, + 32, PropModeReplace, (unsigned char *)&GNOMEHints, + sizeof(GNOMEHints)/4 ); + RemovedDecorations = 1; + } + + // Now try to set KDE NET_WM hints + HintAtom = XInternAtom( _glfwLibrary.Dpy, "_NET_WM_WINDOW_TYPE", True ); + if ( HintAtom != None ) + { + Atom NET_WMHints[2]; + + NET_WMHints[0] = XInternAtom( _glfwLibrary.Dpy, "_KDE_NET_WM_WINDOW_TYPE_OVERRIDE", True ); + /* define a fallback... */ + NET_WMHints[1] = XInternAtom( _glfwLibrary.Dpy, "_NET_WM_WINDOW_TYPE_NORMAL", True ); + + XChangeProperty( _glfwLibrary.Dpy, _glfwWin.Win, HintAtom, XA_ATOM, + 32, PropModeReplace, (unsigned char *)&NET_WMHints, + 2 ); + RemovedDecorations = 1; + } + + // Set ICCCM fullscreen WM hint + HintAtom = XInternAtom( _glfwLibrary.Dpy, "_NET_WM_STATE", True ); + if ( HintAtom != None ) + { + Atom NET_WMHints[1]; + + NET_WMHints[0] = XInternAtom( _glfwLibrary.Dpy, "_NET_WM_STATE_FULLSCREEN", True ); + + XChangeProperty( _glfwLibrary.Dpy, _glfwWin.Win, HintAtom, XA_ATOM, + 32, PropModeReplace, (unsigned char *)&NET_WMHints, 1 ); + } + + + // Did we sucessfully remove the window decorations? + if( RemovedDecorations ) + { + // Finally set the transient hints + XSetTransientForHint( _glfwLibrary.Dpy, _glfwWin.Win, RootWindow(_glfwLibrary.Dpy, _glfwWin.Scrn) ); + XUnmapWindow( _glfwLibrary.Dpy, _glfwWin.Win ); + XMapWindow( _glfwLibrary.Dpy, _glfwWin.Win ); + } + else + { + // The Butcher way of removing window decorations + attributes.override_redirect = True; + XChangeWindowAttributes( _glfwLibrary.Dpy, _glfwWin.Win, + CWOverrideRedirect, &attributes ); + _glfwWin.OverrideRedirect = GL_TRUE; + } +} + + +//======================================================================== +// _glfwEnableDecorations() - Turn on window decorations +//======================================================================== + +static void _glfwEnableDecorations( void ) +{ + int ActivatedDecorations; + Atom HintAtom; + + // If this is an override redirect window, skip it... + if( _glfwWin.OverrideRedirect ) + { + return; + } + + ActivatedDecorations = 0; + + // First try to unset MWM hints + HintAtom = XInternAtom( _glfwLibrary.Dpy, "_MOTIF_WM_HINTS", True ); + if ( HintAtom != None ) + { + XDeleteProperty( _glfwLibrary.Dpy, _glfwWin.Win, HintAtom ); + ActivatedDecorations = 1; + } + + // Now try to unset KWM hints + HintAtom = XInternAtom( _glfwLibrary.Dpy, "KWM_WIN_DECORATION", True ); + if ( HintAtom != None ) + { + XDeleteProperty( _glfwLibrary.Dpy, _glfwWin.Win, HintAtom ); + ActivatedDecorations = 1; + } + + // Now try to unset GNOME hints + HintAtom = XInternAtom( _glfwLibrary.Dpy, "_WIN_HINTS", True ); + if ( HintAtom != None ) + { + XDeleteProperty( _glfwLibrary.Dpy, _glfwWin.Win, HintAtom ); + ActivatedDecorations = 1; + } + + // Now try to unset NET_WM hints + HintAtom = XInternAtom( _glfwLibrary.Dpy, "_NET_WM_WINDOW_TYPE", True ); + if ( HintAtom != None ) + { + Atom NET_WMHints = XInternAtom( _glfwLibrary.Dpy, "_NET_WM_WINDOW_TYPE_NORMAL", True); + if( NET_WMHints != None ) + { + XChangeProperty( _glfwLibrary.Dpy, _glfwWin.Win, + HintAtom, XA_ATOM, 32, PropModeReplace, + (unsigned char *)&NET_WMHints, 1 ); + ActivatedDecorations = 1; + } + } + + // Finally unset the transient hints if necessary + if( ActivatedDecorations ) + { + // NOTE: Does this work? + XSetTransientForHint( _glfwLibrary.Dpy, _glfwWin.Win, None); + XUnmapWindow( _glfwLibrary.Dpy, _glfwWin.Win ); + XMapWindow( _glfwLibrary.Dpy, _glfwWin.Win ); + } +} + + +//======================================================================== +// _glfwChooseVisual() - We do our own function here, since +// glXChooseVisual does not behave as we want it to (not according to the +// GLFW specs) +//======================================================================== + +XVisualInfo * _glfwChooseVisual( Display *Dpy, int Screen, int r, int g, + int b, int a, int d, int s, int ar, int ag, int ab, int aa, int aux, + int fsaa, int stereo) +{ + XVisualInfo *VI, *VI_list, VI_tmp; + int nitems_return, i; + int vi_gl, vi_rgba, vi_double, vi_stereo; + int vi_r, vi_g, vi_b, vi_a, vi_d, vi_s, vi_ar, vi_ag, vi_ab, vi_aa; + int vi_aux; + int color, accum, vi_accum; + int missing, color_diff, extra_diff; + int best_vis, best_missing, best_color_diff, best_extra_diff; + int samples, samplebuffers, vi_samples, vi_samplebuffers; + + // Get list of visuals for this screen & display + VI_tmp.screen = Screen; + VI_list = XGetVisualInfo( Dpy, VisualScreenMask, &VI_tmp, + &nitems_return ); + if( VI_list == NULL ) + { + return NULL; + } + + // Pick some prefered color depth if the user did not request a + // specific depth (note: if the user did not request a specific color + // depth, this will not be a driving demand, it's only here to avoid + // selection randomness) + color = (r > 0 || g > 0 || b > 0); + if( !color ) + { + r = g = b = 8; + } + + // Make sure that stereo is 1 or 0 + stereo = stereo ? 1 : 0; + + // Convenience pre-calculation + accum = (ar > 0 || ag > 0 || ab > 0 || aa > 0); + + samples = fsaa; + samplebuffers = (fsaa > 0) ? 1 : 0; + + + + // Loop through list of visuals to find best match + best_vis = -1; + best_missing = 0x7fffffff; + best_color_diff = 0x7fffffff; + best_extra_diff = 0x7fffffff; + for( i = 0; i < nitems_return; i ++ ) + { + // We want GL, RGBA & DOUBLEBUFFER, and NOT STEREO / STEREO + glXGetConfig( Dpy, &VI_list[i], GLX_USE_GL, &vi_gl ); + glXGetConfig( Dpy, &VI_list[i], GLX_RGBA, &vi_rgba ); + glXGetConfig( Dpy, &VI_list[i], GLX_DOUBLEBUFFER, &vi_double ); + glXGetConfig( Dpy, &VI_list[i], GLX_STEREO, &vi_stereo ); + vi_stereo = vi_stereo ? 1 : 0; + if( vi_gl && vi_rgba && vi_double && (vi_stereo == stereo) ) + { + // Get visual color parameters + glXGetConfig( Dpy, &VI_list[i], GLX_RED_SIZE, &vi_r ); + glXGetConfig( Dpy, &VI_list[i], GLX_GREEN_SIZE, &vi_g ); + glXGetConfig( Dpy, &VI_list[i], GLX_BLUE_SIZE, &vi_b ); + + // Get visual "extra" parameters + glXGetConfig( Dpy, &VI_list[i], GLX_ALPHA_SIZE, &vi_a ); + glXGetConfig( Dpy, &VI_list[i], GLX_DEPTH_SIZE, &vi_d ); + glXGetConfig( Dpy, &VI_list[i], GLX_STENCIL_SIZE, &vi_s ); + glXGetConfig( Dpy, &VI_list[i], GLX_ACCUM_RED_SIZE, &vi_ar ); + glXGetConfig( Dpy, &VI_list[i], GLX_ACCUM_GREEN_SIZE, &vi_ag ); + glXGetConfig( Dpy, &VI_list[i], GLX_ACCUM_BLUE_SIZE, &vi_ab ); + glXGetConfig( Dpy, &VI_list[i], GLX_ACCUM_ALPHA_SIZE, &vi_aa ); + glXGetConfig( Dpy, &VI_list[i], GLX_AUX_BUFFERS, &vi_aux ); + glXGetConfig( Dpy, &VI_list[i], GLX_SAMPLE_BUFFERS, &vi_samplebuffers ); + glXGetConfig( Dpy, &VI_list[i], GLX_SAMPLES, &vi_samples ); + + vi_accum = (vi_ar > 0 || vi_ag > 0 || vi_ab > 0 || vi_aa > 0); + + // Check how many buffers are missing + missing = 0; + if( a > 0 && vi_a == 0 ) missing ++; + if( d > 0 && vi_d == 0 ) missing ++; + if( s > 0 && vi_s == 0 ) missing ++; + if( accum && !vi_accum ) missing ++; + if( aux > 0 && vi_aux == 0 ) missing ++; + if( samplebuffers > 0 && vi_samplebuffers == 0 ) missing ++; + + + // Calculate color diff + color_diff = (r - vi_r) * (r - vi_r) + + (g - vi_g) * (g - vi_g) + + (b - vi_b) * (b - vi_b); + + // Calculate "extra" diff + extra_diff = 0; + if( a > 0 ) + { + extra_diff += (a - vi_a) * (a - vi_a); + } + if( d > 0 ) + { + extra_diff += (d - vi_d) * (d - vi_d); + } + if( s > 0 ) + { + extra_diff += (s - vi_s) * (s - vi_s); + } + if( accum ) + { + extra_diff += (ar - vi_ar) * (ar - vi_ar) + + (ag - vi_ag) * (ag - vi_ag) + + (ab - vi_ab) * (ab - vi_ab) + + (aa - vi_aa) * (aa - vi_aa); + } + if( aux > 0 ) + { + extra_diff += (aux - vi_aux) * (aux - vi_aux); + } + if( samples > 0 ) + { + extra_diff += (samples - vi_samples) * (samples - vi_samples); + + } + // Check if this is a better match. We implement some + // complicated rules, by prioritizing in this order: + // 1) Visuals with the least number of missing buffers always + // have priority + // 2a) If (r,g,b)!=(0,0,0), color depth has priority over + // other buffers + // 2b) If (r,g,b)==(0,0,0), other buffers have priority over + // color depth + if( missing < best_missing ) + { + best_vis = i; + } + else if( missing == best_missing ) + { + if( color ) + { + if( (color_diff < best_color_diff) || + (color_diff == best_color_diff && + extra_diff < best_extra_diff) ) + { + best_vis = i; + } + } + else + { + if( (extra_diff < best_extra_diff) || + (extra_diff == best_extra_diff && + color_diff < best_color_diff) ) + { + best_vis = i; + } + } + } + if( best_vis == i ) + { + best_missing = missing; + best_color_diff = color_diff; + best_extra_diff = extra_diff; + } + } + } + + // Copy best visual to a visual to return + if( best_vis >= 0 ) + { + VI = XGetVisualInfo( Dpy, VisualIDMask, &VI_list[ best_vis ], + &nitems_return ); + } + else + { + VI = NULL; + } + + // Free visuals list + XFree( VI_list ); + + return VI; +} + + +//======================================================================== +// _glfwTranslateKey() - Translates an X Window key to internal coding +//======================================================================== + +static int _glfwTranslateKey( int keycode ) +{ + KeySym key, key_lc, key_uc; + + // Try secondary keysym, for numeric keypad keys + // Note: This way we always force "NumLock = ON", which at least + // enables GLFW users to detect numeric keypad keys + key = XKeycodeToKeysym( _glfwLibrary.Dpy, keycode, 1 ); + switch( key ) + { + // Numeric keypad + case XK_KP_0: return GLFW_KEY_KP_0; + case XK_KP_1: return GLFW_KEY_KP_1; + case XK_KP_2: return GLFW_KEY_KP_2; + case XK_KP_3: return GLFW_KEY_KP_3; + case XK_KP_4: return GLFW_KEY_KP_4; + case XK_KP_5: return GLFW_KEY_KP_5; + case XK_KP_6: return GLFW_KEY_KP_6; + case XK_KP_7: return GLFW_KEY_KP_7; + case XK_KP_8: return GLFW_KEY_KP_8; + case XK_KP_9: return GLFW_KEY_KP_9; + case XK_KP_Separator: + case XK_KP_Decimal: return GLFW_KEY_KP_DECIMAL; + case XK_KP_Equal: return GLFW_KEY_KP_EQUAL; + case XK_KP_Enter: return GLFW_KEY_KP_ENTER; + default: break; + } + + // Now try pimary keysym + key = XKeycodeToKeysym( _glfwLibrary.Dpy, keycode, 0 ); + switch( key ) + { + // Special keys (non character keys) + case XK_Escape: return GLFW_KEY_ESC; + case XK_Tab: return GLFW_KEY_TAB; + case XK_Shift_L: return GLFW_KEY_LSHIFT; + case XK_Shift_R: return GLFW_KEY_RSHIFT; + case XK_Control_L: return GLFW_KEY_LCTRL; + case XK_Control_R: return GLFW_KEY_RCTRL; + case XK_Meta_L: + case XK_Alt_L: return GLFW_KEY_LALT; + case XK_Mode_switch: // Mapped to Alt_R on many keyboards + case XK_Meta_R: + case XK_Alt_R: return GLFW_KEY_RALT; + case XK_KP_Delete: + case XK_Delete: return GLFW_KEY_DEL; + case XK_BackSpace: return GLFW_KEY_BACKSPACE; + case XK_Return: return GLFW_KEY_ENTER; + case XK_KP_Home: + case XK_Home: return GLFW_KEY_HOME; + case XK_KP_End: + case XK_End: return GLFW_KEY_END; + case XK_KP_Page_Up: + case XK_Page_Up: return GLFW_KEY_PAGEUP; + case XK_KP_Page_Down: + case XK_Page_Down: return GLFW_KEY_PAGEDOWN; + case XK_KP_Insert: + case XK_Insert: return GLFW_KEY_INSERT; + case XK_KP_Left: + case XK_Left: return GLFW_KEY_LEFT; + case XK_KP_Right: + case XK_Right: return GLFW_KEY_RIGHT; + case XK_KP_Down: + case XK_Down: return GLFW_KEY_DOWN; + case XK_KP_Up: + case XK_Up: return GLFW_KEY_UP; + case XK_F1: return GLFW_KEY_F1; + case XK_F2: return GLFW_KEY_F2; + case XK_F3: return GLFW_KEY_F3; + case XK_F4: return GLFW_KEY_F4; + case XK_F5: return GLFW_KEY_F5; + case XK_F6: return GLFW_KEY_F6; + case XK_F7: return GLFW_KEY_F7; + case XK_F8: return GLFW_KEY_F8; + case XK_F9: return GLFW_KEY_F9; + case XK_F10: return GLFW_KEY_F10; + case XK_F11: return GLFW_KEY_F11; + case XK_F12: return GLFW_KEY_F12; + case XK_F13: return GLFW_KEY_F13; + case XK_F14: return GLFW_KEY_F14; + case XK_F15: return GLFW_KEY_F15; + case XK_F16: return GLFW_KEY_F16; + case XK_F17: return GLFW_KEY_F17; + case XK_F18: return GLFW_KEY_F18; + case XK_F19: return GLFW_KEY_F19; + case XK_F20: return GLFW_KEY_F20; + case XK_F21: return GLFW_KEY_F21; + case XK_F22: return GLFW_KEY_F22; + case XK_F23: return GLFW_KEY_F23; + case XK_F24: return GLFW_KEY_F24; + case XK_F25: return GLFW_KEY_F25; + + // Numeric keypad (should have been detected in secondary keysym!) + case XK_KP_Divide: return GLFW_KEY_KP_DIVIDE; + case XK_KP_Multiply: return GLFW_KEY_KP_MULTIPLY; + case XK_KP_Subtract: return GLFW_KEY_KP_SUBTRACT; + case XK_KP_Add: return GLFW_KEY_KP_ADD; + case XK_KP_Equal: return GLFW_KEY_KP_EQUAL; + case XK_KP_Enter: return GLFW_KEY_KP_ENTER; + + // The rest (should be printable keys) + default: + // Make uppercase + XConvertCase( key, &key_lc, &key_uc ); + key = key_uc; + + // Valid ISO 8859-1 character? + if( (key >= 32 && key <= 126) || + (key >= 160 && key <= 255) ) + { + return (int) key; + } + return GLFW_KEY_UNKNOWN; + } +} + + +//======================================================================== +// _glfwTranslateChar() - Translates an X Window event to Unicode +//======================================================================== + +static int _glfwTranslateChar( XKeyEvent *event ) +{ + KeySym keysym; + + // Get X11 keysym + XLookupString( event, NULL, 0, &keysym, NULL ); + + // Convert to Unicode (see x11_keysym2unicode.c) + return (int) _glfwKeySym2Unicode( keysym ); +} + + + +//======================================================================== +// Get next X event (called by glfwPollEvents) +//======================================================================== + +static int _glfwGetNextEvent( void ) +{ + XEvent event, next_event; + + // Pull next event from event queue + XNextEvent( _glfwLibrary.Dpy, &event ); + + // Handle certain window messages + switch( event.type ) + { + // Is a key being pressed? + case KeyPress: + { + // Translate and report key press + _glfwInputKey( _glfwTranslateKey( event.xkey.keycode ), GLFW_PRESS ); + + // Translate and report character input + if( _glfwWin.CharCallback ) + { + _glfwInputChar( _glfwTranslateChar( &event.xkey ), GLFW_PRESS ); + } + break; + } + + // Is a key being released? + case KeyRelease: + { + // Do not report key releases for key repeats. For key repeats + // we will get KeyRelease/KeyPress pairs with identical time + // stamps. User selected key repeat filtering is handled in + // _glfwInputKey()/_glfwInputChar(). + if( XEventsQueued( _glfwLibrary.Dpy, QueuedAfterReading ) ) + { + XPeekEvent( _glfwLibrary.Dpy, &next_event ); + if( next_event.type == KeyPress && + next_event.xkey.window == event.xkey.window && + next_event.xkey.keycode == event.xkey.keycode && + next_event.xkey.time == event.xkey.time ) + { + // Do not report anything for this event + break; + } + } + + // Translate and report key release + _glfwInputKey( _glfwTranslateKey( event.xkey.keycode ), GLFW_RELEASE ); + + // Translate and report character input + if( _glfwWin.CharCallback ) + { + _glfwInputChar( _glfwTranslateChar( &event.xkey ), GLFW_RELEASE ); + } + break; + } + + // Were any of the mouse-buttons pressed? + case ButtonPress: + { + if( event.xbutton.button == Button1 ) + { + _glfwInputMouseClick( GLFW_MOUSE_BUTTON_LEFT, GLFW_PRESS ); + } + else if( event.xbutton.button == Button2 ) + { + _glfwInputMouseClick( GLFW_MOUSE_BUTTON_MIDDLE, GLFW_PRESS ); + } + else if( event.xbutton.button == Button3 ) + { + _glfwInputMouseClick( GLFW_MOUSE_BUTTON_RIGHT, GLFW_PRESS ); + } + + // XFree86 3.3.2 and later translates mouse wheel up/down into + // mouse button 4 & 5 presses + else if( event.xbutton.button == Button4 ) + { + _glfwInput.WheelPos++; // To verify: is this up or down? + if( _glfwWin.MouseWheelCallback ) + { + _glfwWin.MouseWheelCallback( _glfwInput.WheelPos ); + } + } + else if( event.xbutton.button == Button5 ) + { + _glfwInput.WheelPos--; + if( _glfwWin.MouseWheelCallback ) + { + _glfwWin.MouseWheelCallback( _glfwInput.WheelPos ); + } + } + break; + } + + // Were any of the mouse-buttons released? + case ButtonRelease: + { + if( event.xbutton.button == Button1 ) + { + _glfwInputMouseClick( GLFW_MOUSE_BUTTON_LEFT, + GLFW_RELEASE ); + } + else if( event.xbutton.button == Button2 ) + { + _glfwInputMouseClick( GLFW_MOUSE_BUTTON_MIDDLE, + GLFW_RELEASE ); + } + else if( event.xbutton.button == Button3 ) + { + _glfwInputMouseClick( GLFW_MOUSE_BUTTON_RIGHT, + GLFW_RELEASE ); + } + break; + } + + // Was the mouse moved? + case MotionNotify: + { + if( event.xmotion.x != _glfwInput.CursorPosX || + event.xmotion.y != _glfwInput.CursorPosY ) + { + if( _glfwWin.MouseLock ) + { + _glfwInput.MousePosX += event.xmotion.x - + _glfwInput.CursorPosX; + _glfwInput.MousePosY += event.xmotion.y - + _glfwInput.CursorPosY; + } + else + { + _glfwInput.MousePosX = event.xmotion.x; + _glfwInput.MousePosY = event.xmotion.y; + } + _glfwInput.CursorPosX = event.xmotion.x; + _glfwInput.CursorPosY = event.xmotion.y; + _glfwInput.MouseMoved = GL_TRUE; + + // Call user callback function + if( _glfwWin.MousePosCallback ) + { + _glfwWin.MousePosCallback( _glfwInput.MousePosX, + _glfwInput.MousePosY ); + } + } + break; + } + + // Was the window resized? + case ConfigureNotify: + { + if( event.xconfigure.width != _glfwWin.Width || + event.xconfigure.height != _glfwWin.Height ) + { + _glfwWin.Width = event.xconfigure.width; + _glfwWin.Height = event.xconfigure.height; + if( _glfwWin.WindowSizeCallback ) + { + _glfwWin.WindowSizeCallback( _glfwWin.Width, + _glfwWin.Height ); + } + } + break; + } + + // Was the window closed by the window manager? + case ClientMessage: + { + if( (Atom) event.xclient.data.l[ 0 ] == _glfwWin.WMDeleteWindow ) + { + return GL_TRUE; + } + + if( (Atom) event.xclient.data.l[ 0 ] == _glfwWin.WMPing ) + { + XSendEvent( _glfwLibrary.Dpy, + RootWindow( _glfwLibrary.Dpy, _glfwWin.VI->screen ), + False, SubstructureNotifyMask | SubstructureRedirectMask, &event ); + } + break; + } + + // Was the window mapped (un-iconified)? + case MapNotify: + _glfwWin.MapNotifyCount++; + break; + + // Was the window unmapped (iconified)? + case UnmapNotify: + _glfwWin.MapNotifyCount--; + break; + + // Was the window activated? + case FocusIn: + _glfwWin.FocusInCount++; + break; + + // Was the window de-activated? + case FocusOut: + _glfwWin.FocusInCount--; + break; + + // Was the window contents damaged? + case Expose: + { + // Call user callback function + if( _glfwWin.WindowRefreshCallback ) + { + _glfwWin.WindowRefreshCallback(); + } + break; + } + + // Was the window destroyed? + case DestroyNotify: + return GL_TRUE; + + default: + { +#if defined( _GLFW_HAS_XRANDR ) + switch( event.type - _glfwLibrary.XRandR.EventBase ) + { + case RRScreenChangeNotify: + { + // Show XRandR that we really care + XRRUpdateConfiguration( &event ); + break; + } + } +#endif + break; + } + } + + // The window was not destroyed + return GL_FALSE; +} + + +//======================================================================== +// _glfwCreateNULLCursor() - Create a blank cursor (for locked mouse mode) +//======================================================================== + +Cursor _glfwCreateNULLCursor( Display *display, Window root ) +{ + Pixmap cursormask; + XGCValues xgc; + GC gc; + XColor col; + Cursor cursor; + + cursormask = XCreatePixmap( display, root, 1, 1, 1 ); + xgc.function = GXclear; + gc = XCreateGC( display, cursormask, GCFunction, &xgc ); + XFillRectangle( display, cursormask, gc, 0, 0, 1, 1 ); + col.pixel = 0; + col.red = 0; + col.flags = 4; + cursor = XCreatePixmapCursor( display, cursormask, cursormask, + &col,&col, 0,0 ); + XFreePixmap( display, cursormask ); + XFreeGC( display, gc ); + + return cursor; +} + + +//======================================================================== +// _glfwInitGLXExtensions() - Initialize GLX-specific extensions +//======================================================================== + +static void _glfwInitGLXExtensions( void ) +{ + int has_swap_control; + + // Initialize OpenGL extension: GLX_SGI_swap_control + has_swap_control = _glfwPlatformExtensionSupported( + "GLX_SGI_swap_control" + ); + + if( has_swap_control ) + { + _glfwWin.SwapInterval = (GLXSWAPINTERVALSGI_T) + _glfw_glXGetProcAddress( (GLubyte*) "glXSwapIntervalSGI" ); + } + else + { + _glfwWin.SwapInterval = NULL; + } +} + + + +//************************************************************************ +//**** Platform implementation functions **** +//************************************************************************ + +//======================================================================== +// _glfwPlatformOpenWindow() - Here is where the window is created, and +// the OpenGL rendering context is created +//======================================================================== + +int _glfwPlatformOpenWindow( int width, int height, int redbits, + int greenbits, int bluebits, int alphabits, int depthbits, + int stencilbits, int mode, _GLFWhints* hints ) +{ + Colormap cmap; + XSetWindowAttributes wa; + XEvent event; + Atom protocols[2]; + + // Clear platform specific GLFW window state + _glfwWin.VI = NULL; + _glfwWin.CX = (GLXContext)0; + _glfwWin.Win = (Window)0; + _glfwWin.Hints = NULL; + _glfwWin.PointerGrabbed = GL_FALSE; + _glfwWin.KeyboardGrabbed = GL_FALSE; + _glfwWin.OverrideRedirect = GL_FALSE; + _glfwWin.FS.ModeChanged = GL_FALSE; + _glfwWin.Saver.Changed = GL_FALSE; + _glfwWin.RefreshRate = hints->RefreshRate; + + // Fullscreen & screen saver settings + // Check if GLX is supported on this display + if( !glXQueryExtension( _glfwLibrary.Dpy, NULL, NULL ) ) + { + _glfwPlatformCloseWindow(); + return GL_FALSE; + } + + // Get screen ID for this window + _glfwWin.Scrn = _glfwLibrary.DefaultScreen; + + // Get an appropriate visual + _glfwWin.VI = _glfwChooseVisual( _glfwLibrary.Dpy, + _glfwWin.Scrn, + redbits, greenbits, bluebits, + alphabits, depthbits, stencilbits, + hints->AccumRedBits, hints->AccumGreenBits, + hints->AccumBlueBits, hints->AccumAlphaBits, + hints->AuxBuffers, hints->Samples, hints->Stereo ); + if( _glfwWin.VI == NULL ) + { + _glfwPlatformCloseWindow(); + return GL_FALSE; + } + + // Create a GLX context + _glfwWin.CX = glXCreateContext( _glfwLibrary.Dpy, _glfwWin.VI, 0, GL_TRUE ); + if( _glfwWin.CX == NULL ) + { + _glfwPlatformCloseWindow(); + return GL_FALSE; + } + + // Create a colormap + cmap = XCreateColormap( _glfwLibrary.Dpy, RootWindow( _glfwLibrary.Dpy, + _glfwWin.VI->screen), _glfwWin.VI->visual, AllocNone ); + + // Do we want fullscreen? + if( mode == GLFW_FULLSCREEN ) + { + // Change video mode + _glfwSetVideoMode( _glfwWin.Scrn, &_glfwWin.Width, + &_glfwWin.Height, &_glfwWin.RefreshRate ); + + // Remember old screen saver settings + XGetScreenSaver( _glfwLibrary.Dpy, &_glfwWin.Saver.Timeout, + &_glfwWin.Saver.Interval, &_glfwWin.Saver.Blanking, + &_glfwWin.Saver.Exposure ); + + // Disable screen saver + XSetScreenSaver( _glfwLibrary.Dpy, 0, 0, DontPreferBlanking, + DefaultExposures ); + } + + // Attributes for window + wa.colormap = cmap; + wa.border_pixel = 0; + wa.event_mask = StructureNotifyMask | KeyPressMask | KeyReleaseMask | + PointerMotionMask | ButtonPressMask | ButtonReleaseMask | + ExposureMask | FocusChangeMask | VisibilityChangeMask; + + // Create a window + _glfwWin.Win = XCreateWindow( + _glfwLibrary.Dpy, + RootWindow( _glfwLibrary.Dpy, _glfwWin.VI->screen ), + 0, 0, // Upper left corner + _glfwWin.Width, _glfwWin.Height, // Width, height + 0, // Borderwidth + _glfwWin.VI->depth, // Depth + InputOutput, + _glfwWin.VI->visual, + CWBorderPixel | CWColormap | CWEventMask, + &wa + ); + if( !_glfwWin.Win ) + { + _glfwPlatformCloseWindow(); + return GL_FALSE; + } + + // Get the delete window WM protocol atom + _glfwWin.WMDeleteWindow = XInternAtom( _glfwLibrary.Dpy, + "WM_DELETE_WINDOW", + False ); + + // Get the ping WM protocol atom + _glfwWin.WMPing = XInternAtom( _glfwLibrary.Dpy, "_NET_WM_PING", False ); + + protocols[0] = _glfwWin.WMDeleteWindow; + protocols[1] = _glfwWin.WMPing; + + // Allow us to trap the Window Close protocol + XSetWMProtocols( _glfwLibrary.Dpy, _glfwWin.Win, protocols, + sizeof(protocols) / sizeof(Atom) ); + + // Remove window decorations for fullscreen windows + if( mode == GLFW_FULLSCREEN ) + { + _glfwDisableDecorations(); + } + + _glfwWin.Hints = XAllocSizeHints(); + + if( hints->WindowNoResize ) + { + _glfwWin.Hints->flags |= (PMinSize | PMaxSize); + _glfwWin.Hints->min_width = _glfwWin.Hints->max_width = _glfwWin.Width; + _glfwWin.Hints->min_height = _glfwWin.Hints->max_height = _glfwWin.Height; + } + + if( mode == GLFW_FULLSCREEN ) + { + _glfwWin.Hints->flags |= PPosition; + _glfwWin.Hints->x = 0; + _glfwWin.Hints->y = 0; + } + + XSetWMNormalHints( _glfwLibrary.Dpy, _glfwWin.Win, _glfwWin.Hints ); + + // Map window + XMapWindow( _glfwLibrary.Dpy, _glfwWin.Win ); + + // Wait for map notification + XIfEvent( _glfwLibrary.Dpy, &event, _glfwWaitForMapNotify, + (char*)_glfwWin.Win ); + + // Make sure that our window ends up on top of things + XRaiseWindow( _glfwLibrary.Dpy, _glfwWin.Win ); + + // Fullscreen mode "post processing" + if( mode == GLFW_FULLSCREEN ) + { +#if defined( _GLFW_HAS_XRANDR ) + // Request screen change notifications + if( _glfwLibrary.XRandR.Available ) + { + XRRSelectInput( _glfwLibrary.Dpy, + _glfwWin.Win, + RRScreenChangeNotifyMask ); + } +#endif + + // Force window position/size (some WMs do their own window + // geometry, which we want to override) + XMoveWindow( _glfwLibrary.Dpy, _glfwWin.Win, 0, 0 ); + XResizeWindow( _glfwLibrary.Dpy, _glfwWin.Win, _glfwWin.Width, + _glfwWin.Height ); + + // Grab keyboard + if( XGrabKeyboard( _glfwLibrary.Dpy, _glfwWin.Win, True, + GrabModeAsync, GrabModeAsync, CurrentTime ) == + GrabSuccess ) + { + _glfwWin.KeyboardGrabbed = GL_TRUE; + } + + // Grab mouse cursor + if( XGrabPointer( _glfwLibrary.Dpy, _glfwWin.Win, True, + ButtonPressMask | ButtonReleaseMask | + PointerMotionMask, GrabModeAsync, GrabModeAsync, + _glfwWin.Win, None, CurrentTime ) == + GrabSuccess ) + { + _glfwWin.PointerGrabbed = GL_TRUE; + } + + // Try to get window inside viewport (for virtual displays) by + // moving the mouse cursor to the upper left corner (and then to + // the center) - this works for XFree86 + XWarpPointer( _glfwLibrary.Dpy, None, _glfwWin.Win, 0,0,0,0, 0,0 ); + XWarpPointer( _glfwLibrary.Dpy, None, _glfwWin.Win, 0,0,0,0, + _glfwWin.Width/2, _glfwWin.Height/2 ); + } + + // Set window & icon name + _glfwPlatformSetWindowTitle( "GLFW Window" ); + + // Connect the context to the window + glXMakeCurrent( _glfwLibrary.Dpy, _glfwWin.Win, _glfwWin.CX ); + + // Start by clearing the front buffer to black (avoid ugly desktop + // remains in our OpenGL window) + glClear( GL_COLOR_BUFFER_BIT ); + glXSwapBuffers( _glfwLibrary.Dpy, _glfwWin.Win ); + + // Initialize GLX-specific OpenGL extensions + _glfwInitGLXExtensions(); + + return GL_TRUE; +} + + +//======================================================================== +// Properly kill the window/video display +//======================================================================== + +void _glfwPlatformCloseWindow( void ) +{ +#if defined( _GLFW_HAS_XRANDR ) + XRRScreenConfiguration *sc; + Window root; +#endif + + // Free WM size hints + if( _glfwWin.Hints ) + { + XFree( _glfwWin.Hints ); + _glfwWin.Hints = NULL; + } + + // Do we have a rendering context? + if( _glfwWin.CX ) + { + // Release the context + glXMakeCurrent( _glfwLibrary.Dpy, None, NULL ); + + // Delete the context + glXDestroyContext( _glfwLibrary.Dpy, _glfwWin.CX ); + _glfwWin.CX = NULL; + } + + // Ungrab pointer and/or keyboard? + if( _glfwWin.KeyboardGrabbed ) + { + XUngrabKeyboard( _glfwLibrary.Dpy, CurrentTime ); + _glfwWin.KeyboardGrabbed = GL_FALSE; + } + if( _glfwWin.PointerGrabbed ) + { + XUngrabPointer( _glfwLibrary.Dpy, CurrentTime ); + _glfwWin.PointerGrabbed = GL_FALSE; + } + + // Do we have a window? + if( _glfwWin.Win ) + { + // Unmap the window + XUnmapWindow( _glfwLibrary.Dpy, _glfwWin.Win ); + + // Destroy the window + XDestroyWindow( _glfwLibrary.Dpy, _glfwWin.Win ); + _glfwWin.Win = (Window) 0; + } + + // Did we change the fullscreen resolution? + if( _glfwWin.FS.ModeChanged ) + { +#if defined( _GLFW_HAS_XRANDR ) + if( _glfwLibrary.XRandR.Available ) + { + root = RootWindow( _glfwLibrary.Dpy, _glfwWin.Scrn ); + sc = XRRGetScreenInfo( _glfwLibrary.Dpy, root ); + + XRRSetScreenConfig( _glfwLibrary.Dpy, + sc, + root, + _glfwWin.FS.OldSizeID, + _glfwWin.FS.OldRotation, + CurrentTime ); + + XRRFreeScreenConfigInfo( sc ); + } +#elif defined( _GLFW_HAS_XF86VIDMODE ) + if( _glfwLibrary.XF86VidMode.Available ) + { + // Unlock mode switch + XF86VidModeLockModeSwitch( _glfwLibrary.Dpy, + _glfwWin.Scrn, + 0 ); + + // Change the video mode back to the old mode + XF86VidModeSwitchToMode( _glfwLibrary.Dpy, + _glfwWin.Scrn, &_glfwWin.FS.OldMode ); + } +#endif + _glfwWin.FS.ModeChanged = GL_FALSE; + } + + // Did we change the screen saver setting? + if( _glfwWin.Saver.Changed ) + { + // Restore old screen saver settings + XSetScreenSaver( _glfwLibrary.Dpy, _glfwWin.Saver.Timeout, + _glfwWin.Saver.Interval, _glfwWin.Saver.Blanking, + _glfwWin.Saver.Exposure ); + _glfwWin.Saver.Changed = GL_FALSE; + } + + XSync( _glfwLibrary.Dpy, True ); +} + + +//======================================================================== +// _glfwPlatformSetWindowTitle() - Set the window title. +//======================================================================== + +void _glfwPlatformSetWindowTitle( const char *title ) +{ + // Set window & icon title + XStoreName( _glfwLibrary.Dpy, _glfwWin.Win, title ); + XSetIconName( _glfwLibrary.Dpy, _glfwWin.Win, title ); +} + + +//======================================================================== +// _glfwPlatformSetWindowSize() - Set the window size. +//======================================================================== + +void _glfwPlatformSetWindowSize( int width, int height ) +{ + int mode = 0, rate, sizechanged = GL_FALSE; + GLint drawbuffer; + GLfloat clearcolor[4]; + + rate = _glfwWin.RefreshRate; + + // If we are in fullscreen mode, get some info about the current mode + if( _glfwWin.Fullscreen ) + { + // Get closest match for target video mode + mode = _glfwGetClosestVideoMode( _glfwWin.Scrn, &width, &height, &rate ); + } + + if( _glfwWin.WindowNoResize ) + { + _glfwWin.Hints->min_width = _glfwWin.Hints->max_width = width; + _glfwWin.Hints->min_height = _glfwWin.Hints->max_height = height; + } + + XSetWMNormalHints( _glfwLibrary.Dpy, _glfwWin.Win, _glfwWin.Hints ); + + // Change window size before changing fullscreen mode? + if( _glfwWin.Fullscreen && (width > _glfwWin.Width) ) + { + XResizeWindow( _glfwLibrary.Dpy, _glfwWin.Win, width, height ); + sizechanged = GL_TRUE; + } + + // Change fullscreen video mode? + if( _glfwWin.Fullscreen ) + { + // Change video mode (keeping current rate) + _glfwSetVideoModeMODE( _glfwWin.Scrn, mode, _glfwWin.RefreshRate ); + + // Clear the front buffer to black (avoid ugly desktop remains in + // our OpenGL window) + glGetIntegerv( GL_DRAW_BUFFER, &drawbuffer ); + glGetFloatv( GL_COLOR_CLEAR_VALUE, clearcolor ); + glClearColor( 0.0f, 0.0f, 0.0f, 0.0f ); + glClear( GL_COLOR_BUFFER_BIT ); + if( drawbuffer == GL_BACK ) + { + glXSwapBuffers( _glfwLibrary.Dpy, _glfwWin.Win ); + } + glClearColor( clearcolor[0], clearcolor[1], clearcolor[2], + clearcolor[3] ); + } + + // Set window size (if not already changed) + if( !sizechanged ) + { + XResizeWindow( _glfwLibrary.Dpy, _glfwWin.Win, width, height ); + } +} + + +//======================================================================== +// _glfwPlatformSetWindowPos() - Set the window position. +//======================================================================== + +void _glfwPlatformSetWindowPos( int x, int y ) +{ + // Set window position + XMoveWindow( _glfwLibrary.Dpy, _glfwWin.Win, x, y ); +} + + +//======================================================================== +// _glfwPlatformIconfyWindow() - Window iconification +//======================================================================== + +void _glfwPlatformIconifyWindow( void ) +{ + // We can't do this for override redirect windows + if( _glfwWin.OverrideRedirect ) + { + return; + } + + // In fullscreen mode, we need to restore the desktop video mode + if( _glfwWin.Fullscreen ) + { +#if defined( _GLFW_HAS_XF86VIDMODE ) + if( _glfwLibrary.XF86VidMode.Available ) + { + // Unlock mode switch + XF86VidModeLockModeSwitch( _glfwLibrary.Dpy, + _glfwWin.Scrn, + 0 ); + + // Change the video mode back to the old mode + XF86VidModeSwitchToMode( _glfwLibrary.Dpy, + _glfwWin.Scrn, &_glfwWin.FS.OldMode ); + } +#endif + _glfwWin.FS.ModeChanged = GL_FALSE; + } + + // Show mouse pointer + if( _glfwWin.PointerHidden ) + { + XUndefineCursor( _glfwLibrary.Dpy, _glfwWin.Win ); + _glfwWin.PointerHidden = GL_FALSE; + } + + // Un-grab mouse pointer + if( _glfwWin.PointerGrabbed ) + { + XUngrabPointer( _glfwLibrary.Dpy, CurrentTime ); + _glfwWin.PointerGrabbed = GL_FALSE; + } + + // Iconify window + XIconifyWindow( _glfwLibrary.Dpy, _glfwWin.Win, + _glfwWin.Scrn ); + + // Window is now iconified + _glfwWin.Iconified = GL_TRUE; +} + + +//======================================================================== +// Window un-iconification +//======================================================================== + +void _glfwPlatformRestoreWindow( void ) +{ + // We can't do this for override redirect windows + if( _glfwWin.OverrideRedirect ) + { + return; + } + + // In fullscreen mode, change back video mode to user selected mode + if( _glfwWin.Fullscreen ) + { + _glfwSetVideoMode( _glfwWin.Scrn, + &_glfwWin.Width, &_glfwWin.Height, &_glfwWin.RefreshRate ); + } + + // Un-iconify window + XMapWindow( _glfwLibrary.Dpy, _glfwWin.Win ); + + // In fullscreen mode... + if( _glfwWin.Fullscreen ) + { + // Make sure window is in upper left corner + XMoveWindow( _glfwLibrary.Dpy, _glfwWin.Win, 0, 0 ); + + // Get input focus + XSetInputFocus( _glfwLibrary.Dpy, _glfwWin.Win, RevertToParent, + CurrentTime ); + } + + // Lock mouse, if necessary + if( _glfwWin.MouseLock ) + { + // Hide cursor + if( !_glfwWin.PointerHidden ) + { + XDefineCursor( _glfwLibrary.Dpy, _glfwWin.Win, + _glfwCreateNULLCursor( _glfwLibrary.Dpy, + _glfwWin.Win ) ); + _glfwWin.PointerHidden = GL_TRUE; + } + + // Grab cursor + if( !_glfwWin.PointerGrabbed ) + { + if( XGrabPointer( _glfwLibrary.Dpy, _glfwWin.Win, True, + ButtonPressMask | ButtonReleaseMask | + PointerMotionMask, GrabModeAsync, + GrabModeAsync, _glfwWin.Win, None, + CurrentTime ) == GrabSuccess ) + { + _glfwWin.PointerGrabbed = GL_TRUE; + } + } + } + + // Window is no longer iconified + _glfwWin.Iconified = GL_FALSE; +} + + +//======================================================================== +// _glfwPlatformSwapBuffers() - Swap buffers (double-buffering) and poll +// any new events. +//======================================================================== + +void _glfwPlatformSwapBuffers( void ) +{ + // Update display-buffer + glXSwapBuffers( _glfwLibrary.Dpy, _glfwWin.Win ); +} + + +//======================================================================== +// _glfwPlatformSwapInterval() - Set double buffering swap interval +//======================================================================== + +void _glfwPlatformSwapInterval( int interval ) +{ + if( _glfwWin.SwapInterval ) + { + _glfwWin.SwapInterval( interval ); + } +} + + +//======================================================================== +// _glfwPlatformRefreshWindowParams() +//======================================================================== + +void _glfwPlatformRefreshWindowParams( void ) +{ +#if defined( _GLFW_HAS_XRANDR ) + XRRScreenConfiguration *sc; +#elif defined( _GLFW_HAS_XF86VIDMODE ) + XF86VidModeModeLine modeline; + int dotclock; + float pixels_per_second, pixels_per_frame; +#endif + int sample_buffers; + + // AFAIK, there is no easy/sure way of knowing if OpenGL is hardware + // accelerated + _glfwWin.Accelerated = GL_TRUE; + + // "Standard" window parameters + glXGetConfig( _glfwLibrary.Dpy, _glfwWin.VI, GLX_RED_SIZE, + &_glfwWin.RedBits ); + glXGetConfig( _glfwLibrary.Dpy, _glfwWin.VI, GLX_GREEN_SIZE, + &_glfwWin.GreenBits ); + glXGetConfig( _glfwLibrary.Dpy, _glfwWin.VI, GLX_BLUE_SIZE, + &_glfwWin.BlueBits ); + glXGetConfig( _glfwLibrary.Dpy, _glfwWin.VI, GLX_ALPHA_SIZE, + &_glfwWin.AlphaBits ); + glXGetConfig( _glfwLibrary.Dpy, _glfwWin.VI, GLX_DEPTH_SIZE, + &_glfwWin.DepthBits ); + glXGetConfig( _glfwLibrary.Dpy, _glfwWin.VI, GLX_STENCIL_SIZE, + &_glfwWin.StencilBits ); + glXGetConfig( _glfwLibrary.Dpy, _glfwWin.VI, GLX_ACCUM_RED_SIZE, + &_glfwWin.AccumRedBits ); + glXGetConfig( _glfwLibrary.Dpy, _glfwWin.VI, GLX_ACCUM_GREEN_SIZE, + &_glfwWin.AccumGreenBits ); + glXGetConfig( _glfwLibrary.Dpy, _glfwWin.VI, GLX_ACCUM_BLUE_SIZE, + &_glfwWin.AccumBlueBits ); + glXGetConfig( _glfwLibrary.Dpy, _glfwWin.VI, GLX_ACCUM_ALPHA_SIZE, + &_glfwWin.AccumAlphaBits ); + glXGetConfig( _glfwLibrary.Dpy, _glfwWin.VI, GLX_AUX_BUFFERS, + &_glfwWin.AuxBuffers ); + + // Get stereo rendering setting + glXGetConfig( _glfwLibrary.Dpy, _glfwWin.VI, GLX_STEREO, + &_glfwWin.Stereo ); + _glfwWin.Stereo = _glfwWin.Stereo ? 1 : 0; + + // Get multisample buffer samples + glXGetConfig( _glfwLibrary.Dpy, _glfwWin.VI, GLX_SAMPLES, + &_glfwWin.Samples ); + glXGetConfig( _glfwLibrary.Dpy, _glfwWin.VI, GLX_SAMPLE_BUFFERS, + &sample_buffers ); + if( sample_buffers == 0 ) + _glfwWin.Samples = 0; + + // Default to refresh rate unknown (=0 according to GLFW spec) + _glfwWin.RefreshRate = 0; + + // Retrieve refresh rate, if possible +#if defined( _GLFW_HAS_XRANDR ) + if( _glfwLibrary.XRandR.Available ) + { + sc = XRRGetScreenInfo( _glfwLibrary.Dpy, + RootWindow( _glfwLibrary.Dpy, _glfwWin.Scrn ) ); + _glfwWin.RefreshRate = XRRConfigCurrentRate( sc ); + XRRFreeScreenConfigInfo( sc ); + } +#elif defined( _GLFW_HAS_XF86VIDMODE ) + if( _glfwLibrary.XF86VidMode.Available ) + { + // Use the XF86VidMode extension to get current video mode + XF86VidModeGetModeLine( _glfwLibrary.Dpy, _glfwWin.Scrn, + &dotclock, &modeline ); + pixels_per_second = 1000.0f * (float) dotclock; + pixels_per_frame = (float) modeline.htotal * modeline.vtotal; + _glfwWin.RefreshRate = (int)(pixels_per_second/pixels_per_frame+0.5); + } +#endif +} + + +//======================================================================== +// _glfwPlatformPollEvents() - Poll for new window and input events +//======================================================================== + +void _glfwPlatformPollEvents( void ) +{ + int winclosed = GL_FALSE; + + // Flag that the cursor has not moved + _glfwInput.MouseMoved = GL_FALSE; + + // Clear MapNotify and FocusIn counts + _glfwWin.MapNotifyCount = 0; + _glfwWin.FocusInCount = 0; + + // Use XSync to synchronise events to the X display. + // I don't know if this can have a serious performance impact. My + // benchmarks with a GeForce card under Linux shows no difference with + // or without XSync, but when the GL window is rendered over a slow + // network I have noticed bad event syncronisation problems when XSync + // is not used, so I decided to use it. + XSync( _glfwLibrary.Dpy, False ); + + // Empty the window event queue + while( XPending( _glfwLibrary.Dpy ) ) + { + if( _glfwGetNextEvent() ) + { + winclosed = GL_TRUE; + } + } + + // Did we get mouse movement in locked cursor mode? + if( _glfwInput.MouseMoved && _glfwWin.MouseLock ) + { + int maxx, minx, maxy, miny; + + // Calculate movement threshold + minx = _glfwWin.Width / 4; + maxx = (_glfwWin.Width * 3) / 4; + miny = _glfwWin.Height / 4; + maxy = (_glfwWin.Height * 3) / 4; + + // Did the mouse cursor move beyond our movement threshold + if(_glfwInput.CursorPosX < minx || _glfwInput.CursorPosX > maxx || + _glfwInput.CursorPosY < miny || _glfwInput.CursorPosY > maxy) + { + // Move the mouse pointer back to the window center so that it + // does not wander off... + _glfwPlatformSetMouseCursorPos( _glfwWin.Width/2, + _glfwWin.Height/2 ); + XSync( _glfwLibrary.Dpy, False ); + } + } + + // Was the window (un)iconified? + if( _glfwWin.MapNotifyCount < 0 && !_glfwWin.Iconified ) + { + // Show mouse pointer + if( _glfwWin.PointerHidden ) + { + XUndefineCursor( _glfwLibrary.Dpy, _glfwWin.Win ); + _glfwWin.PointerHidden = GL_FALSE; + } + + // Un-grab mouse pointer + if( _glfwWin.PointerGrabbed ) + { + XUngrabPointer( _glfwLibrary.Dpy, CurrentTime ); + _glfwWin.PointerGrabbed = GL_FALSE; + } + + _glfwWin.Iconified = GL_TRUE; + } + else if( _glfwWin.MapNotifyCount > 0 && _glfwWin.Iconified ) + { + // Restore fullscreen mode properties + if( _glfwWin.Fullscreen ) + { + // Change back video mode to user selected mode + _glfwSetVideoMode( _glfwWin.Scrn, &_glfwWin.Width, + &_glfwWin.Height, &_glfwWin.RefreshRate ); + + // Disable window manager decorations + _glfwEnableDecorations(); + + // Make sure window is in upper left corner + XMoveWindow( _glfwLibrary.Dpy, _glfwWin.Win, 0, 0 ); + + // Get input focus + XSetInputFocus( _glfwLibrary.Dpy, _glfwWin.Win, + RevertToParent, CurrentTime ); + } + + // Hide cursor if necessary + if( _glfwWin.MouseLock && !_glfwWin.PointerHidden ) + { + if( !_glfwWin.PointerHidden ) + { + XDefineCursor( _glfwLibrary.Dpy, _glfwWin.Win, + _glfwCreateNULLCursor( _glfwLibrary.Dpy, + _glfwWin.Win ) ); + _glfwWin.PointerHidden = GL_TRUE; + } + } + + // Grab cursor if necessary + if( (_glfwWin.MouseLock || _glfwWin.Fullscreen) && + !_glfwWin.PointerGrabbed ) + { + if( XGrabPointer( _glfwLibrary.Dpy, _glfwWin.Win, True, + ButtonPressMask | ButtonReleaseMask | + PointerMotionMask, GrabModeAsync, + GrabModeAsync, _glfwWin.Win, None, + CurrentTime ) == GrabSuccess ) + { + _glfwWin.PointerGrabbed = GL_TRUE; + } + } + + _glfwWin.Iconified = GL_FALSE; + } + + // Did the window get/lose focus + if( _glfwWin.FocusInCount > 0 && !_glfwWin.Active ) + { + // If we are in fullscreen mode, restore window + if( _glfwWin.Fullscreen && _glfwWin.Iconified ) + { + _glfwPlatformRestoreWindow(); + } + + // Window is now active + _glfwWin.Active = GL_TRUE; + } + else if( _glfwWin.FocusInCount < 0 && _glfwWin.Active ) + { + // If we are in fullscreen mode, iconfify window + if( _glfwWin.Fullscreen ) + { + _glfwPlatformIconifyWindow(); + } + + // Window is not active + _glfwWin.Active = GL_FALSE; + _glfwInputDeactivation(); + } + + // Was there a window close request? + if( winclosed && _glfwWin.WindowCloseCallback ) + { + // Check if the program wants us to close the window + winclosed = _glfwWin.WindowCloseCallback(); + } + if( winclosed ) + { + glfwCloseWindow(); + } +} + + +//======================================================================== +// _glfwPlatformWaitEvents() - Wait for new window and input events +//======================================================================== + +void _glfwPlatformWaitEvents( void ) +{ + XEvent event; + + // Wait for new events (blocking) + XNextEvent( _glfwLibrary.Dpy, &event ); + XPutBackEvent( _glfwLibrary.Dpy, &event ); + + // Poll events from queue + _glfwPlatformPollEvents(); +} + + +//======================================================================== +// _glfwPlatformHideMouseCursor() - Hide mouse cursor (lock it) +//======================================================================== + +void _glfwPlatformHideMouseCursor( void ) +{ + // Hide cursor + if( !_glfwWin.PointerHidden ) + { + XDefineCursor( _glfwLibrary.Dpy, _glfwWin.Win, + _glfwCreateNULLCursor( _glfwLibrary.Dpy, + _glfwWin.Win ) ); + _glfwWin.PointerHidden = GL_TRUE; + } + + // Grab cursor to user window + if( !_glfwWin.PointerGrabbed ) + { + if( XGrabPointer( _glfwLibrary.Dpy, _glfwWin.Win, True, + ButtonPressMask | ButtonReleaseMask | + PointerMotionMask, GrabModeAsync, GrabModeAsync, + _glfwWin.Win, None, CurrentTime ) == + GrabSuccess ) + { + _glfwWin.PointerGrabbed = GL_TRUE; + } + } +} + + +//======================================================================== +// _glfwPlatformShowMouseCursor() - Show mouse cursor (unlock it) +//======================================================================== + +void _glfwPlatformShowMouseCursor( void ) +{ + // Un-grab cursor (only in windowed mode: in fullscreen mode we still + // want the mouse grabbed in order to confine the cursor to the window + // area) + if( _glfwWin.PointerGrabbed && !_glfwWin.Fullscreen ) + { + XUngrabPointer( _glfwLibrary.Dpy, CurrentTime ); + _glfwWin.PointerGrabbed = GL_FALSE; + } + + // Show cursor + if( _glfwWin.PointerHidden ) + { + XUndefineCursor( _glfwLibrary.Dpy, _glfwWin.Win ); + _glfwWin.PointerHidden = GL_FALSE; + } +} + + +//======================================================================== +// _glfwPlatformSetMouseCursorPos() - Set physical mouse cursor position +//======================================================================== + +void _glfwPlatformSetMouseCursorPos( int x, int y ) +{ + // Change cursor position + _glfwInput.CursorPosX = x; + _glfwInput.CursorPosY = y; + XWarpPointer( _glfwLibrary.Dpy, None, _glfwWin.Win, 0,0,0,0, x, y ); +} + |