about summary refs log tree commit diff
path: root/src/engine/external/glfw/lib
diff options
context:
space:
mode:
authorMagnus Auvinen <magnus.auvinen@gmail.com>2007-08-22 07:52:33 +0000
committerMagnus Auvinen <magnus.auvinen@gmail.com>2007-08-22 07:52:33 +0000
commit8b3c16e6152a527f9aec1a88a9eed74119de7000 (patch)
treef0bde5cea15e696e42cade06a3b12ff6b13acc57 /src/engine/external/glfw/lib
parent9899666a7ce6679a3b9667ab09f615f4d0769c16 (diff)
downloadzcatch-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')
-rw-r--r--src/engine/external/glfw/lib/enable.c295
-rw-r--r--src/engine/external/glfw/lib/fullscreen.c95
-rw-r--r--src/engine/external/glfw/lib/glext.c201
-rw-r--r--src/engine/external/glfw/lib/image.c629
-rw-r--r--src/engine/external/glfw/lib/init.c108
-rw-r--r--src/engine/external/glfw/lib/input.c280
-rw-r--r--src/engine/external/glfw/lib/internal.h210
-rw-r--r--src/engine/external/glfw/lib/joystick.c101
-rw-r--r--src/engine/external/glfw/lib/macosx/macosx_enable.c42
-rw-r--r--src/engine/external/glfw/lib/macosx/macosx_fullscreen.c126
-rw-r--r--src/engine/external/glfw/lib/macosx/macosx_glext.c52
-rw-r--r--src/engine/external/glfw/lib/macosx/macosx_init.c194
-rw-r--r--src/engine/external/glfw/lib/macosx/macosx_joystick.c50
-rw-r--r--src/engine/external/glfw/lib/macosx/macosx_thread.c414
-rw-r--r--src/engine/external/glfw/lib/macosx/macosx_time.c112
-rw-r--r--src/engine/external/glfw/lib/macosx/macosx_window.c1279
-rw-r--r--src/engine/external/glfw/lib/macosx/platform.h349
-rw-r--r--src/engine/external/glfw/lib/stream.c194
-rw-r--r--src/engine/external/glfw/lib/tga.c405
-rw-r--r--src/engine/external/glfw/lib/thread.c340
-rw-r--r--src/engine/external/glfw/lib/time.c83
-rw-r--r--src/engine/external/glfw/lib/win32/glfwdll.def67
-rw-r--r--src/engine/external/glfw/lib/win32/glfwdll_mgw1.def67
-rw-r--r--src/engine/external/glfw/lib/win32/glfwdll_mgw2.def67
-rw-r--r--src/engine/external/glfw/lib/win32/glfwdll_pellesc.def65
-rw-r--r--src/engine/external/glfw/lib/win32/platform.h468
-rw-r--r--src/engine/external/glfw/lib/win32/win32_dllmain.c60
-rw-r--r--src/engine/external/glfw/lib/win32/win32_enable.c155
-rw-r--r--src/engine/external/glfw/lib/win32/win32_fullscreen.c317
-rw-r--r--src/engine/external/glfw/lib/win32/win32_glext.c101
-rw-r--r--src/engine/external/glfw/lib/win32/win32_init.c356
-rw-r--r--src/engine/external/glfw/lib/win32/win32_joystick.c234
-rw-r--r--src/engine/external/glfw/lib/win32/win32_thread.c511
-rw-r--r--src/engine/external/glfw/lib/win32/win32_time.c146
-rw-r--r--src/engine/external/glfw/lib/win32/win32_window.c1697
-rw-r--r--src/engine/external/glfw/lib/window.c727
-rw-r--r--src/engine/external/glfw/lib/x11/platform.h415
-rw-r--r--src/engine/external/glfw/lib/x11/x11_enable.c51
-rw-r--r--src/engine/external/glfw/lib/x11/x11_fullscreen.c524
-rw-r--r--src/engine/external/glfw/lib/x11/x11_glext.c69
-rw-r--r--src/engine/external/glfw/lib/x11/x11_init.c275
-rw-r--r--src/engine/external/glfw/lib/x11/x11_joystick.c371
-rw-r--r--src/engine/external/glfw/lib/x11/x11_keysym2unicode.c902
-rw-r--r--src/engine/external/glfw/lib/x11/x11_thread.c507
-rw-r--r--src/engine/external/glfw/lib/x11/x11_time.c154
-rw-r--r--src/engine/external/glfw/lib/x11/x11_window.c1746
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( &currenttime, 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( &currenttime, 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( &currenttime, 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( &currenttime, 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 );

+}

+