packages feed

GLFW-b (empty) → 0.0.1

raw patch · 44 files changed

+15937/−0 lines, 44 filesdep +basesetup-changed

Dependencies added: base

Files

+ GLFW-b.cabal view
@@ -0,0 +1,141 @@+name:         GLFW-b+version:      0.0.1++category:     Graphics++synopsis:     GLFW bindings+description:  Bindings to GLFW, a free, open source, multi-platform library for+              creating OpenGL contexts and managing input, including keyboard,+              mouse, joystick and time.+              .+              /GLFW-b does not currently work on Mac OS X./ Sorry.+              .+              Please see README.md+              (<http://github.com/bsl/GLFW-b/blob/master/README.md>) for+              information about how these bindings differ from the ones in the+              GLFW package (<http://hackage.haskell.org/package/GLFW>).+              .+              For more information about the library on which these bindings+              are based, please see <http://glfw.sourceforge.net>.++author:       Brian Lewis <brian@lorf.org>+maintainer:   Brian Lewis <brian@lorf.org>++license:      BSD3+license-file: LICENSE++-- -- -- -- -- -- -- -- -- --++cabal-version: >= 1.6+build-type:    Simple++-- -- -- -- -- -- -- -- -- --++extra-source-files:+  README.md+  glfw/include/GL/glfw.h++-- -- -- -- -- -- -- -- -- --++library+  exposed-modules:+    Graphics.UI.GLFW++  build-depends:+    base == 4.*++  hs-source-dirs:+    src++  include-dirs:+    glfw/include+    glfw/lib+  c-sources:+    glfw/lib/enable.c+    glfw/lib/fullscreen.c+    glfw/lib/glext.c+    glfw/lib/image.c+    glfw/lib/init.c+    glfw/lib/input.c+    glfw/lib/joystick.c+    glfw/lib/stream.c+    glfw/lib/tga.c+    glfw/lib/thread.c+    glfw/lib/time.c+    glfw/lib/window.c++  if os(linux)+    include-dirs:+      glfw/lib/x11+    c-sources:+      glfw/lib/x11/x11_enable.c+      glfw/lib/x11/x11_fullscreen.c+      glfw/lib/x11/x11_glext.c+      glfw/lib/x11/x11_init.c+      glfw/lib/x11/x11_joystick.c+      glfw/lib/x11/x11_keysym2unicode.c+      glfw/lib/x11/x11_thread.c+      glfw/lib/x11/x11_time.c+      glfw/lib/x11/x11_window.c+    cc-options:+      -D_GLFW_USE_LINUX_JOYSTICKS+      -D_GLFW_HAS_XRANDR+--    -D_GLFW_HAS_PTHREAD+--    -D_GLFW_HAS_SCHED_YIELD+      -D_GLFW_HAS_GLXGETPROCADDRESS+--    -D_GLFW_HAS_DLOPEN+--    -D_GLFW_HAS_SYSCONF+--    -pthread+      -O2+    extra-libraries:+      GL+      GLU+      X11+      Xrandr+  else+    if os(darwin)+      include-dirs:+        glfw/lib/cocoa+      c-sources:+        glfw/lib/cocoa/cocoa_enable.m+        glfw/lib/cocoa/cocoa_fullscreen.m+        glfw/lib/cocoa/cocoa_glext.m+        glfw/lib/cocoa/cocoa_init.m+        glfw/lib/cocoa/cocoa_joystick.m+        glfw/lib/cocoa/cocoa_thread.c+        glfw/lib/cocoa/cocoa_time.m+        glfw/lib/cocoa/cocoa_window.m+      cc-options:+        -O2+      frameworks:+        AGL+        Cocoa+        OpenGL+    else+      if os(mingw32)+        include-dirs:+          glfw/lib/win32+        c-sources:+          glfw/lib/win32/win32_dllmain.c+          glfw/lib/win32/win32_enable.c+          glfw/lib/win32/win32_fullscreen.c+          glfw/lib/win32/win32_glext.c+          glfw/lib/win32/win32_init.c+          glfw/lib/win32/win32_joystick.c+          glfw/lib/win32/win32_thread.c+          glfw/lib/win32/win32_time.c+          glfw/lib/win32/win32_window.c+        cc-options:+          -O2+        extra-libraries:+          opengl32++  ghc-options: -Wall -O2+  if impl(ghc >= 6.8)+    ghc-options: -fwarn-tabs++-- -- -- -- -- -- -- -- -- --++source-repository head+  type:     git+  location: git://github.com/bsl/GLFW-b.git
+ LICENSE view
@@ -0,0 +1,26 @@+Copyright Brian Lewis <brian@lorf.org> 2009++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++    * Redistributions of source code must retain the above copyright+      notice, this list of conditions and the following disclaimer.++    * Redistributions in binary form must reproduce the above+      copyright notice, this list of conditions and the following+      disclaimer in the documentation and/or other materials provided+      with the distribution.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ README.md view
@@ -0,0 +1,28 @@+Differences between GLFW and GLFW-b 2010.01+===========================================++* GLFW binds to version 2.6 of the GLFW C library. GLFW-b binds to 2.7. GLFW+  2.7 is partially written in Objective C. This is a problem for Cabal, so+  _GLFW-b does not currently work on Mac OS X._++* Some GLFW functions return OpenGL {Gettable,Settable}StateVars. I don't like+  this because it adds an extra step to extract a value and causes GLFW to be+  dependent on OpenGL. GLFW-b doesn't depend on OpenGL.++* GLFW sometimes depends on GLFW C library internally defined values. GLFW-b+  doesn't. For example, GLFW-b doesn't assume that GL\_FALSE = 0. I don't think+  this makes a difference in practice, but it makes me feel better.++* GLFW sometimes assumes that certain Haskell types are equivalent to certain C+  types, e.g. Int and int. GLFW-b doesn't. GLFW-b always uses the appropriate+  type from Foreign.C.Types. I don't think this makes a difference in practice,+  but it makes me feel better.++* GLFW contains workarounds for a bugs in GHC &lt; 6.10 FFI. GLFW-b doesn't.++* GLFW's API is pretty faithful to the C API. GLFW-b prefers to use full words+  and self-explanatory function names.++* In GLFW-b, registering hints and opening a window are combined into one step.++* GLFW has support for loading textures and rendering strings. GLFW-b doesn't.
+ Setup.hs view
@@ -0,0 +1,6 @@+module Main (main) where++import Distribution.Simple (defaultMain)++main :: IO ()+main = defaultMain
+ glfw/include/GL/glfw.h view
@@ -0,0 +1,509 @@+/************************************************************************+ * GLFW - An OpenGL framework+ * File:        glfw.h+ * API version: 2.7+ * WWW:         http://glfw.sourceforge.net+ *------------------------------------------------------------------------+ * Copyright (c) 2002-2006 Camilla Berglund+ *+ * This software is provided 'as-is', without any express or implied+ * warranty. In no event will the authors be held liable for any damages+ * arising from the use of this software.+ *+ * Permission is granted to anyone to use this software for any purpose,+ * including commercial applications, and to alter it and redistribute it+ * freely, subject to the following restrictions:+ *+ * 1. The origin of this software must not be misrepresented; you must not+ *    claim that you wrote the original software. If you use this software+ *    in a product, an acknowledgment in the product documentation would+ *    be appreciated but is not required.+ *+ * 2. Altered source versions must be plainly marked as such, and must not+ *    be misrepresented as being the original software.+ *+ * 3. This notice may not be removed or altered from any source+ *    distribution.+ *+ *************************************************************************/++#ifndef __glfw_h_+#define __glfw_h_++#ifdef __cplusplus+extern "C" {+#endif+++/*************************************************************************+ * Global definitions+ *************************************************************************/++/* We need a NULL pointer from time to time */+#ifndef NULL+ #ifdef __cplusplus+  #define NULL 0+ #else+  #define NULL ((void *)0)+ #endif+#endif /* NULL */+++/* ------------------- BEGIN SYSTEM/COMPILER SPECIFIC -------------------- */++/* Please report any probles that you find with your compiler, which may+ * be solved in this section! There are several compilers that I have not+ * been able to test this file with yet.+ *+ * First: If we are we on Windows, we want a single define for it (_WIN32)+ * (Note: For Cygwin the compiler flag -mwin32 should be used, but to+ * make sure that things run smoothly for Cygwin users, we add __CYGWIN__+ * to the list of "valid Win32 identifiers", which removes the need for+ * -mwin32)+ */+#if !defined(_WIN32) && (defined(__WIN32__) || defined(WIN32) || defined(__CYGWIN__))+ #define _WIN32+#endif /* _WIN32 */++/* In order for extension support to be portable, we need to define an+ * OpenGL function call method. We use the keyword APIENTRY, which is+ * defined for Win32. (Note: Windows also needs this for <GL/gl.h>)+ */+#ifndef APIENTRY+ #ifdef _WIN32+  #define APIENTRY __stdcall+ #else+  #define APIENTRY+ #endif+ #define GL_APIENTRY_DEFINED+#endif /* APIENTRY */+++/* The following three defines are here solely to make some Windows-based+ * <GL/gl.h> files happy. Theoretically we could include <windows.h>, but+ * it has the major drawback of severely polluting our namespace.+ */++/* Under Windows, we need WINGDIAPI defined */+#if !defined(WINGDIAPI) && defined(_WIN32)+ #if defined(_MSC_VER) || defined(__BORLANDC__) || defined(__POCC__)+  /* Microsoft Visual C++, Borland C++ Builder and Pelles C */+  #define WINGDIAPI __declspec(dllimport)+ #elif defined(__LCC__)+  /* LCC-Win32 */+  #define WINGDIAPI __stdcall+ #else+  /* Others (e.g. MinGW, Cygwin) */+  #define WINGDIAPI extern+ #endif+ #define GL_WINGDIAPI_DEFINED+#endif /* WINGDIAPI */++/* Some <GL/glu.h> files also need CALLBACK defined */+#if !defined(CALLBACK) && defined(_WIN32)+ #if defined(_MSC_VER)+  /* Microsoft Visual C++ */+  #if (defined(_M_MRX000) || defined(_M_IX86) || defined(_M_ALPHA) || defined(_M_PPC)) && !defined(MIDL_PASS)+   #define CALLBACK __stdcall+  #else+   #define CALLBACK+  #endif+ #else+  /* Other Windows compilers */+  #define CALLBACK __stdcall+ #endif+ #define GLU_CALLBACK_DEFINED+#endif /* CALLBACK */++/* Microsoft Visual C++, Borland C++ and Pelles C <GL*glu.h> needs wchar_t */+#if defined(_WIN32) && (defined(_MSC_VER) || defined(__BORLANDC__) || defined(__POCC__)) && !defined(_WCHAR_T_DEFINED)+ typedef unsigned short wchar_t;+ #define _WCHAR_T_DEFINED+#endif /* _WCHAR_T_DEFINED */+++/* ---------------- GLFW related system specific defines ----------------- */++#if defined(_WIN32) && defined(GLFW_BUILD_DLL)++ /* We are building a Win32 DLL */+ #define GLFWAPI      __declspec(dllexport)+ #define GLFWAPIENTRY __stdcall+ #define GLFWCALL     __stdcall++#elif defined(_WIN32) && defined(GLFW_DLL)++ /* We are calling a Win32 DLL */+ #if defined(__LCC__)+  #define GLFWAPI      extern+ #else+  #define GLFWAPI      __declspec(dllimport)+ #endif+ #define GLFWAPIENTRY __stdcall+ #define GLFWCALL     __stdcall++#else++ /* We are either building/calling a static lib or we are non-win32 */+ #define GLFWAPIENTRY+ #define GLFWAPI+ #define GLFWCALL++#endif++/* -------------------- END SYSTEM/COMPILER SPECIFIC --------------------- */++/* Include standard OpenGL headers: GLFW uses GL_FALSE/GL_TRUE, and it is+ * convenient for the user to only have to include <GL/glfw.h>. This also+ * solves the problem with Windows <GL/gl.h> and <GL/glu.h> needing some+ * special defines which normally requires the user to include <windows.h>+ * (which is not a nice solution for portable programs).+ */+#if defined(__APPLE_CC__)+ #include <OpenGL/gl.h>+ #ifndef GLFW_NO_GLU+  #include <OpenGL/glu.h>+ #endif+#else+ #include <GL/gl.h>+ #ifndef GLFW_NO_GLU+  #include <GL/glu.h>+ #endif+#endif+++/*************************************************************************+ * GLFW version+ *************************************************************************/++#define GLFW_VERSION_MAJOR    2+#define GLFW_VERSION_MINOR    7+#define GLFW_VERSION_REVISION 0+++/*************************************************************************+ * Input handling definitions+ *************************************************************************/++/* Key and button state/action definitions */+#define GLFW_RELEASE            0+#define GLFW_PRESS              1++/* Keyboard key definitions: 8-bit ISO-8859-1 (Latin 1) encoding is used+ * for printable keys (such as A-Z, 0-9 etc), and values above 256+ * represent special (non-printable) keys (e.g. F1, Page Up etc).+ */+#define GLFW_KEY_UNKNOWN      -1+#define GLFW_KEY_SPACE        32+#define GLFW_KEY_SPECIAL      256+#define GLFW_KEY_ESC          (GLFW_KEY_SPECIAL+1)+#define GLFW_KEY_F1           (GLFW_KEY_SPECIAL+2)+#define GLFW_KEY_F2           (GLFW_KEY_SPECIAL+3)+#define GLFW_KEY_F3           (GLFW_KEY_SPECIAL+4)+#define GLFW_KEY_F4           (GLFW_KEY_SPECIAL+5)+#define GLFW_KEY_F5           (GLFW_KEY_SPECIAL+6)+#define GLFW_KEY_F6           (GLFW_KEY_SPECIAL+7)+#define GLFW_KEY_F7           (GLFW_KEY_SPECIAL+8)+#define GLFW_KEY_F8           (GLFW_KEY_SPECIAL+9)+#define GLFW_KEY_F9           (GLFW_KEY_SPECIAL+10)+#define GLFW_KEY_F10          (GLFW_KEY_SPECIAL+11)+#define GLFW_KEY_F11          (GLFW_KEY_SPECIAL+12)+#define GLFW_KEY_F12          (GLFW_KEY_SPECIAL+13)+#define GLFW_KEY_F13          (GLFW_KEY_SPECIAL+14)+#define GLFW_KEY_F14          (GLFW_KEY_SPECIAL+15)+#define GLFW_KEY_F15          (GLFW_KEY_SPECIAL+16)+#define GLFW_KEY_F16          (GLFW_KEY_SPECIAL+17)+#define GLFW_KEY_F17          (GLFW_KEY_SPECIAL+18)+#define GLFW_KEY_F18          (GLFW_KEY_SPECIAL+19)+#define GLFW_KEY_F19          (GLFW_KEY_SPECIAL+20)+#define GLFW_KEY_F20          (GLFW_KEY_SPECIAL+21)+#define GLFW_KEY_F21          (GLFW_KEY_SPECIAL+22)+#define GLFW_KEY_F22          (GLFW_KEY_SPECIAL+23)+#define GLFW_KEY_F23          (GLFW_KEY_SPECIAL+24)+#define GLFW_KEY_F24          (GLFW_KEY_SPECIAL+25)+#define GLFW_KEY_F25          (GLFW_KEY_SPECIAL+26)+#define GLFW_KEY_UP           (GLFW_KEY_SPECIAL+27)+#define GLFW_KEY_DOWN         (GLFW_KEY_SPECIAL+28)+#define GLFW_KEY_LEFT         (GLFW_KEY_SPECIAL+29)+#define GLFW_KEY_RIGHT        (GLFW_KEY_SPECIAL+30)+#define GLFW_KEY_LSHIFT       (GLFW_KEY_SPECIAL+31)+#define GLFW_KEY_RSHIFT       (GLFW_KEY_SPECIAL+32)+#define GLFW_KEY_LCTRL        (GLFW_KEY_SPECIAL+33)+#define GLFW_KEY_RCTRL        (GLFW_KEY_SPECIAL+34)+#define GLFW_KEY_LALT         (GLFW_KEY_SPECIAL+35)+#define GLFW_KEY_RALT         (GLFW_KEY_SPECIAL+36)+#define GLFW_KEY_TAB          (GLFW_KEY_SPECIAL+37)+#define GLFW_KEY_ENTER        (GLFW_KEY_SPECIAL+38)+#define GLFW_KEY_BACKSPACE    (GLFW_KEY_SPECIAL+39)+#define GLFW_KEY_INSERT       (GLFW_KEY_SPECIAL+40)+#define GLFW_KEY_DEL          (GLFW_KEY_SPECIAL+41)+#define GLFW_KEY_PAGEUP       (GLFW_KEY_SPECIAL+42)+#define GLFW_KEY_PAGEDOWN     (GLFW_KEY_SPECIAL+43)+#define GLFW_KEY_HOME         (GLFW_KEY_SPECIAL+44)+#define GLFW_KEY_END          (GLFW_KEY_SPECIAL+45)+#define GLFW_KEY_KP_0         (GLFW_KEY_SPECIAL+46)+#define GLFW_KEY_KP_1         (GLFW_KEY_SPECIAL+47)+#define GLFW_KEY_KP_2         (GLFW_KEY_SPECIAL+48)+#define GLFW_KEY_KP_3         (GLFW_KEY_SPECIAL+49)+#define GLFW_KEY_KP_4         (GLFW_KEY_SPECIAL+50)+#define GLFW_KEY_KP_5         (GLFW_KEY_SPECIAL+51)+#define GLFW_KEY_KP_6         (GLFW_KEY_SPECIAL+52)+#define GLFW_KEY_KP_7         (GLFW_KEY_SPECIAL+53)+#define GLFW_KEY_KP_8         (GLFW_KEY_SPECIAL+54)+#define GLFW_KEY_KP_9         (GLFW_KEY_SPECIAL+55)+#define GLFW_KEY_KP_DIVIDE    (GLFW_KEY_SPECIAL+56)+#define GLFW_KEY_KP_MULTIPLY  (GLFW_KEY_SPECIAL+57)+#define GLFW_KEY_KP_SUBTRACT  (GLFW_KEY_SPECIAL+58)+#define GLFW_KEY_KP_ADD       (GLFW_KEY_SPECIAL+59)+#define GLFW_KEY_KP_DECIMAL   (GLFW_KEY_SPECIAL+60)+#define GLFW_KEY_KP_EQUAL     (GLFW_KEY_SPECIAL+61)+#define GLFW_KEY_KP_ENTER     (GLFW_KEY_SPECIAL+62)+#define GLFW_KEY_KP_NUM_LOCK  (GLFW_KEY_SPECIAL+63)+#define GLFW_KEY_CAPS_LOCK    (GLFW_KEY_SPECIAL+64)+#define GLFW_KEY_SCROLL_LOCK  (GLFW_KEY_SPECIAL+65)+#define GLFW_KEY_PAUSE        (GLFW_KEY_SPECIAL+66)+#define GLFW_KEY_LSUPER       (GLFW_KEY_SPECIAL+67)+#define GLFW_KEY_RSUPER       (GLFW_KEY_SPECIAL+68)+#define GLFW_KEY_MENU         (GLFW_KEY_SPECIAL+69)+#define GLFW_KEY_LAST         GLFW_KEY_MENU++/* Mouse button definitions */+#define GLFW_MOUSE_BUTTON_1      0+#define GLFW_MOUSE_BUTTON_2      1+#define GLFW_MOUSE_BUTTON_3      2+#define GLFW_MOUSE_BUTTON_4      3+#define GLFW_MOUSE_BUTTON_5      4+#define GLFW_MOUSE_BUTTON_6      5+#define GLFW_MOUSE_BUTTON_7      6+#define GLFW_MOUSE_BUTTON_8      7+#define GLFW_MOUSE_BUTTON_LAST   GLFW_MOUSE_BUTTON_8++/* Mouse button aliases */+#define GLFW_MOUSE_BUTTON_LEFT   GLFW_MOUSE_BUTTON_1+#define GLFW_MOUSE_BUTTON_RIGHT  GLFW_MOUSE_BUTTON_2+#define GLFW_MOUSE_BUTTON_MIDDLE GLFW_MOUSE_BUTTON_3+++/* Joystick identifiers */+#define GLFW_JOYSTICK_1          0+#define GLFW_JOYSTICK_2          1+#define GLFW_JOYSTICK_3          2+#define GLFW_JOYSTICK_4          3+#define GLFW_JOYSTICK_5          4+#define GLFW_JOYSTICK_6          5+#define GLFW_JOYSTICK_7          6+#define GLFW_JOYSTICK_8          7+#define GLFW_JOYSTICK_9          8+#define GLFW_JOYSTICK_10         9+#define GLFW_JOYSTICK_11         10+#define GLFW_JOYSTICK_12         11+#define GLFW_JOYSTICK_13         12+#define GLFW_JOYSTICK_14         13+#define GLFW_JOYSTICK_15         14+#define GLFW_JOYSTICK_16         15+#define GLFW_JOYSTICK_LAST       GLFW_JOYSTICK_16+++/*************************************************************************+ * Other definitions+ *************************************************************************/++/* glfwOpenWindow modes */+#define GLFW_WINDOW               0x00010001+#define GLFW_FULLSCREEN           0x00010002++/* glfwGetWindowParam tokens */+#define GLFW_OPENED               0x00020001+#define GLFW_ACTIVE               0x00020002+#define GLFW_ICONIFIED            0x00020003+#define GLFW_ACCELERATED          0x00020004+#define GLFW_RED_BITS             0x00020005+#define GLFW_GREEN_BITS           0x00020006+#define GLFW_BLUE_BITS            0x00020007+#define GLFW_ALPHA_BITS           0x00020008+#define GLFW_DEPTH_BITS           0x00020009+#define GLFW_STENCIL_BITS         0x0002000A++/* The following constants are used for both glfwGetWindowParam+ * and glfwOpenWindowHint+ */+#define GLFW_REFRESH_RATE         0x0002000B+#define GLFW_ACCUM_RED_BITS       0x0002000C+#define GLFW_ACCUM_GREEN_BITS     0x0002000D+#define GLFW_ACCUM_BLUE_BITS      0x0002000E+#define GLFW_ACCUM_ALPHA_BITS     0x0002000F+#define GLFW_AUX_BUFFERS          0x00020010+#define GLFW_STEREO               0x00020011+#define GLFW_WINDOW_NO_RESIZE     0x00020012+#define GLFW_FSAA_SAMPLES         0x00020013+#define GLFW_OPENGL_VERSION_MAJOR 0x00020014+#define GLFW_OPENGL_VERSION_MINOR 0x00020015+#define GLFW_OPENGL_FORWARD_COMPAT 0x00020016+#define GLFW_OPENGL_DEBUG_CONTEXT 0x00020017+#define GLFW_OPENGL_PROFILE       0x00020018++/* GLFW_OPENGL_PROFILE tokens */+#define GLFW_OPENGL_CORE_PROFILE  0x00050001+#define GLFW_OPENGL_COMPAT_PROFILE 0x00050002++/* glfwEnable/glfwDisable tokens */+#define GLFW_MOUSE_CURSOR         0x00030001+#define GLFW_STICKY_KEYS          0x00030002+#define GLFW_STICKY_MOUSE_BUTTONS 0x00030003+#define GLFW_SYSTEM_KEYS          0x00030004+#define GLFW_KEY_REPEAT           0x00030005+#define GLFW_AUTO_POLL_EVENTS     0x00030006++/* glfwWaitThread wait modes */+#define GLFW_WAIT                 0x00040001+#define GLFW_NOWAIT               0x00040002++/* glfwGetJoystickParam tokens */+#define GLFW_PRESENT              0x00050001+#define GLFW_AXES                 0x00050002+#define GLFW_BUTTONS              0x00050003++/* glfwReadImage/glfwLoadTexture2D flags */+#define GLFW_NO_RESCALE_BIT       0x00000001 /* Only for glfwReadImage */+#define GLFW_ORIGIN_UL_BIT        0x00000002+#define GLFW_BUILD_MIPMAPS_BIT    0x00000004 /* Only for glfwLoadTexture2D */+#define GLFW_ALPHA_MAP_BIT        0x00000008++/* Time spans longer than this (seconds) are considered to be infinity */+#define GLFW_INFINITY 100000.0+++/*************************************************************************+ * Typedefs+ *************************************************************************/++/* The video mode structure used by glfwGetVideoModes() */+typedef struct {+    int Width, Height;+    int RedBits, BlueBits, GreenBits;+} GLFWvidmode;++/* Image/texture information */+typedef struct {+    int Width, Height;+    int Format;+    int BytesPerPixel;+    unsigned char *Data;+} GLFWimage;++/* Thread ID */+typedef int GLFWthread;++/* Mutex object */+typedef void * GLFWmutex;++/* Condition variable object */+typedef void * GLFWcond;++/* Function pointer types */+typedef void (GLFWCALL * GLFWwindowsizefun)(int,int);+typedef int  (GLFWCALL * GLFWwindowclosefun)(void);+typedef void (GLFWCALL * GLFWwindowrefreshfun)(void);+typedef void (GLFWCALL * GLFWmousebuttonfun)(int,int);+typedef void (GLFWCALL * GLFWmouseposfun)(int,int);+typedef void (GLFWCALL * GLFWmousewheelfun)(int);+typedef void (GLFWCALL * GLFWkeyfun)(int,int);+typedef void (GLFWCALL * GLFWcharfun)(int,int);+typedef void (GLFWCALL * GLFWthreadfun)(void *);+++/*************************************************************************+ * Prototypes+ *************************************************************************/++/* GLFW initialization, termination and version querying */+GLFWAPI int  GLFWAPIENTRY glfwInit( void );+GLFWAPI void GLFWAPIENTRY glfwTerminate( void );+GLFWAPI void GLFWAPIENTRY glfwGetVersion( int *major, int *minor, int *rev );++/* Window handling */+GLFWAPI int  GLFWAPIENTRY glfwOpenWindow( int width, int height, int redbits, int greenbits, int bluebits, int alphabits, int depthbits, int stencilbits, int mode );+GLFWAPI void GLFWAPIENTRY glfwOpenWindowHint( int target, int hint );+GLFWAPI void GLFWAPIENTRY glfwCloseWindow( void );+GLFWAPI void GLFWAPIENTRY glfwSetWindowTitle( const char *title );+GLFWAPI void GLFWAPIENTRY glfwGetWindowSize( int *width, int *height );+GLFWAPI void GLFWAPIENTRY glfwSetWindowSize( int width, int height );+GLFWAPI void GLFWAPIENTRY glfwSetWindowPos( int x, int y );+GLFWAPI void GLFWAPIENTRY glfwIconifyWindow( void );+GLFWAPI void GLFWAPIENTRY glfwRestoreWindow( void );+GLFWAPI void GLFWAPIENTRY glfwSwapBuffers( void );+GLFWAPI void GLFWAPIENTRY glfwSwapInterval( int interval );+GLFWAPI int  GLFWAPIENTRY glfwGetWindowParam( int param );+GLFWAPI void GLFWAPIENTRY glfwSetWindowSizeCallback( GLFWwindowsizefun cbfun );+GLFWAPI void GLFWAPIENTRY glfwSetWindowCloseCallback( GLFWwindowclosefun cbfun );+GLFWAPI void GLFWAPIENTRY glfwSetWindowRefreshCallback( GLFWwindowrefreshfun cbfun );++/* Video mode functions */+GLFWAPI int  GLFWAPIENTRY glfwGetVideoModes( GLFWvidmode *list, int maxcount );+GLFWAPI void GLFWAPIENTRY glfwGetDesktopMode( GLFWvidmode *mode );++/* Input handling */+GLFWAPI void GLFWAPIENTRY glfwPollEvents( void );+GLFWAPI void GLFWAPIENTRY glfwWaitEvents( void );+GLFWAPI int  GLFWAPIENTRY glfwGetKey( int key );+GLFWAPI int  GLFWAPIENTRY glfwGetMouseButton( int button );+GLFWAPI void GLFWAPIENTRY glfwGetMousePos( int *xpos, int *ypos );+GLFWAPI void GLFWAPIENTRY glfwSetMousePos( int xpos, int ypos );+GLFWAPI int  GLFWAPIENTRY glfwGetMouseWheel( void );+GLFWAPI void GLFWAPIENTRY glfwSetMouseWheel( int pos );+GLFWAPI void GLFWAPIENTRY glfwSetKeyCallback( GLFWkeyfun cbfun );+GLFWAPI void GLFWAPIENTRY glfwSetCharCallback( GLFWcharfun cbfun );+GLFWAPI void GLFWAPIENTRY glfwSetMouseButtonCallback( GLFWmousebuttonfun cbfun );+GLFWAPI void GLFWAPIENTRY glfwSetMousePosCallback( GLFWmouseposfun cbfun );+GLFWAPI void GLFWAPIENTRY glfwSetMouseWheelCallback( GLFWmousewheelfun cbfun );++/* Joystick input */+GLFWAPI int GLFWAPIENTRY glfwGetJoystickParam( int joy, int param );+GLFWAPI int GLFWAPIENTRY glfwGetJoystickPos( int joy, float *pos, int numaxes );+GLFWAPI int GLFWAPIENTRY glfwGetJoystickButtons( int joy, unsigned char *buttons, int numbuttons );++/* Time */+GLFWAPI double GLFWAPIENTRY glfwGetTime( void );+GLFWAPI void   GLFWAPIENTRY glfwSetTime( double time );+GLFWAPI void   GLFWAPIENTRY glfwSleep( double time );++/* Extension support */+GLFWAPI int   GLFWAPIENTRY glfwExtensionSupported( const char *extension );+GLFWAPI void* GLFWAPIENTRY glfwGetProcAddress( const char *procname );+GLFWAPI void  GLFWAPIENTRY glfwGetGLVersion( int *major, int *minor, int *rev );++/* Threading support */+GLFWAPI GLFWthread GLFWAPIENTRY glfwCreateThread( GLFWthreadfun fun, void *arg );+GLFWAPI void GLFWAPIENTRY glfwDestroyThread( GLFWthread ID );+GLFWAPI int  GLFWAPIENTRY glfwWaitThread( GLFWthread ID, int waitmode );+GLFWAPI GLFWthread GLFWAPIENTRY glfwGetThreadID( void );+GLFWAPI GLFWmutex GLFWAPIENTRY glfwCreateMutex( void );+GLFWAPI void GLFWAPIENTRY glfwDestroyMutex( GLFWmutex mutex );+GLFWAPI void GLFWAPIENTRY glfwLockMutex( GLFWmutex mutex );+GLFWAPI void GLFWAPIENTRY glfwUnlockMutex( GLFWmutex mutex );+GLFWAPI GLFWcond GLFWAPIENTRY glfwCreateCond( void );+GLFWAPI void GLFWAPIENTRY glfwDestroyCond( GLFWcond cond );+GLFWAPI void GLFWAPIENTRY glfwWaitCond( GLFWcond cond, GLFWmutex mutex, double timeout );+GLFWAPI void GLFWAPIENTRY glfwSignalCond( GLFWcond cond );+GLFWAPI void GLFWAPIENTRY glfwBroadcastCond( GLFWcond cond );+GLFWAPI int  GLFWAPIENTRY glfwGetNumberOfProcessors( void );++/* Enable/disable functions */+GLFWAPI void GLFWAPIENTRY glfwEnable( int token );+GLFWAPI void GLFWAPIENTRY glfwDisable( int token );++/* Image/texture I/O support */+GLFWAPI int  GLFWAPIENTRY glfwReadImage( const char *name, GLFWimage *img, int flags );+GLFWAPI int  GLFWAPIENTRY glfwReadMemoryImage( const void *data, long size, GLFWimage *img, int flags );+GLFWAPI void GLFWAPIENTRY glfwFreeImage( GLFWimage *img );+GLFWAPI int  GLFWAPIENTRY glfwLoadTexture2D( const char *name, int flags );+GLFWAPI int  GLFWAPIENTRY glfwLoadMemoryTexture2D( const void *data, long size, int flags );+GLFWAPI int  GLFWAPIENTRY glfwLoadTextureImage2D( GLFWimage *img, int flags );+++#ifdef __cplusplus+}+#endif++#endif /* __glfw_h_ */+
+ glfw/lib/cocoa/cocoa_enable.m view
@@ -0,0 +1,52 @@+//========================================================================+// GLFW - An OpenGL framework+// File:        macosx_enable.m+// Platform:    Mac OS X+// API Version: 2.7+// WWW:         http://glfw.sourceforge.net+//------------------------------------------------------------------------+// Copyright (c) 2002-2006 Camilla Berglund+//+// This software is provided 'as-is', without any express or implied+// warranty. In no event will the authors be held liable for any damages+// arising from the use of this software.+//+// Permission is granted to anyone to use this software for any purpose,+// including commercial applications, and to alter it and redistribute it+// freely, subject to the following restrictions:+//+// 1. The origin of this software must not be misrepresented; you must not+//    claim that you wrote the original software. If you use this software+//    in a product, an acknowledgment in the product documentation would+//    be appreciated but is not required.+//+// 2. Altered source versions must be plainly marked as such, and must not+//    be misrepresented as being the original software.+//+// 3. This notice may not be removed or altered from any source+//    distribution.+//+//========================================================================++#include "internal.h"++//************************************************************************+//****               Platform implementation functions                ****+//************************************************************************++//========================================================================+// Enable and disable system keys+//========================================================================++void _glfwPlatformEnableSystemKeys( void )+{+    // This is checked in macosx_window.m; we take no action here+}++void _glfwPlatformDisableSystemKeys( void )+{+    // This is checked in macosx_window.m; we take no action here+    // I don't think it's really possible to disable stuff like Exposé+    // except in full-screen mode.+}+
+ glfw/lib/cocoa/cocoa_fullscreen.m view
@@ -0,0 +1,103 @@+//========================================================================+// GLFW - An OpenGL framework+// File:        macosx_fullscreen.m+// Platform:    Mac OS X+// API Version: 2.7+// WWW:         http://glfw.sourceforge.net+//------------------------------------------------------------------------+// Copyright (c) 2002-2006 Camilla Berglund+//+// This software is provided 'as-is', without any express or implied+// warranty. In no event will the authors be held liable for any damages+// arising from the use of this software.+//+// Permission is granted to anyone to use this software for any purpose,+// including commercial applications, and to alter it and redistribute it+// freely, subject to the following restrictions:+//+// 1. The origin of this software must not be misrepresented; you must not+//    claim that you wrote the original software. If you use this software+//    in a product, an acknowledgment in the product documentation would+//    be appreciated but is not required.+//+// 2. Altered source versions must be plainly marked as such, and must not+//    be misrepresented as being the original software.+//+// 3. This notice may not be removed or altered from any source+//    distribution.+//+//========================================================================++#include "internal.h"++//========================================================================+// Check whether the display mode should be included in enumeration+//========================================================================++static BOOL modeIsGood( NSDictionary *mode )+{+    // This is a bit controversial, if you've got something other than an+    // LCD computer monitor as an output device you might not want these+    // checks.  You might also want to reject modes which are interlaced,+    // or TV out.  There is no one-size-fits-all policy that can work here.+    // This seems like a decent compromise, but certain applications may+    // wish to patch this...+    return [[mode objectForKey:(id)kCGDisplayBitsPerPixel] intValue] >= 15 &&+           [mode objectForKey:(id)kCGDisplayModeIsSafeForHardware] != nil &&+           [mode objectForKey:(id)kCGDisplayModeIsStretched] == nil;+}++//========================================================================+// Convert Core Graphics display mode to GLFW video mode+//========================================================================++static GLFWvidmode vidmodeFromCGDisplayMode( NSDictionary *mode )+{+    unsigned int width = [[mode objectForKey:(id)kCGDisplayWidth] unsignedIntValue];+    unsigned int height = [[mode objectForKey:(id)kCGDisplayHeight] unsignedIntValue];+    unsigned int bps = [[mode objectForKey:(id)kCGDisplayBitsPerSample] unsignedIntValue];++    GLFWvidmode result;+    result.Width = width;+    result.Height = height;+    result.RedBits = bps;+    result.GreenBits = bps;+    result.BlueBits = bps;+    return result;+}+++//************************************************************************+//****               Platform implementation functions                ****+//************************************************************************++//========================================================================+// Get a list of available video modes+//========================================================================++int _glfwPlatformGetVideoModes( GLFWvidmode *list, int maxcount )+{+    NSArray *modes = (NSArray *)CGDisplayAvailableModes( CGMainDisplayID() );++    unsigned int i, j = 0, n = [modes count];+    for( i = 0; i < n && i < (unsigned)maxcount; i++ )+    {+        NSDictionary *mode = [modes objectAtIndex:i];+        if( modeIsGood( mode ) )+        {+            list[j++] = vidmodeFromCGDisplayMode( mode );+        }+    }++    return j;+}++//========================================================================+// Get the desktop video mode+//========================================================================++void _glfwPlatformGetDesktopMode( GLFWvidmode *mode )+{+    *mode = vidmodeFromCGDisplayMode( _glfwLibrary.DesktopMode );+}+
+ glfw/lib/cocoa/cocoa_glext.m view
@@ -0,0 +1,64 @@+//========================================================================+// GLFW - An OpenGL framework+// File:        macosx_glext.m+// Platform:    Mac OS X+// API Version: 2.7+// WWW:         http://glfw.sourceforge.net+//------------------------------------------------------------------------+// Copyright (c) 2002-2006 Camilla Berglund+//+// This software is provided 'as-is', without any express or implied+// warranty. In no event will the authors be held liable for any damages+// arising from the use of this software.+//+// Permission is granted to anyone to use this software for any purpose,+// including commercial applications, and to alter it and redistribute it+// freely, subject to the following restrictions:+//+// 1. The origin of this software must not be misrepresented; you must not+//    claim that you wrote the original software. If you use this software+//    in a product, an acknowledgment in the product documentation would+//    be appreciated but is not required.+//+// 2. Altered source versions must be plainly marked as such, and must not+//    be misrepresented as being the original software.+//+// 3. This notice may not be removed or altered from any source+//    distribution.+//+//========================================================================++#include "internal.h"++//************************************************************************+//****               Platform implementation functions                ****+//************************************************************************++//========================================================================+// Check if an OpenGL extension is available at runtime+//========================================================================++int _glfwPlatformExtensionSupported( const char *extension )+{+    // There are no AGL, CGL or NSGL extensions.+    return GL_FALSE;+}++//========================================================================+// Get the function pointer to an OpenGL function+//========================================================================++void * _glfwPlatformGetProcAddress( const char *procname )+{+    CFStringRef symbolName = CFStringCreateWithCString( kCFAllocatorDefault,+                                                        procname,+                                                        kCFStringEncodingASCII );++    void *symbol = CFBundleGetFunctionPointerForName( _glfwLibrary.OpenGLFramework,+                                                      symbolName );++    CFRelease( symbolName );++    return symbol;+}+
+ glfw/lib/cocoa/cocoa_init.m view
@@ -0,0 +1,241 @@+//========================================================================+// GLFW - An OpenGL framework+// File:        macosx_init.m+// Platform:    Mac OS X+// API Version: 2.7+// WWW:         http://glfw.sourceforge.net+//------------------------------------------------------------------------+// Copyright (c) 2002-2006 Camilla Berglund+//+// This software is provided 'as-is', without any express or implied+// warranty. In no event will the authors be held liable for any damages+// arising from the use of this software.+//+// Permission is granted to anyone to use this software for any purpose,+// including commercial applications, and to alter it and redistribute it+// freely, subject to the following restrictions:+//+// 1. The origin of this software must not be misrepresented; you must not+//    claim that you wrote the original software. If you use this software+//    in a product, an acknowledgment in the product documentation would+//    be appreciated but is not required.+//+// 2. Altered source versions must be plainly marked as such, and must not+//    be misrepresented as being the original software.+//+// 3. This notice may not be removed or altered from any source+//    distribution.+//+//========================================================================++// Needed for _NSGetProgname+#include <crt_externs.h>++#include "internal.h"++// Prior to Snow Leopard, we need to use this oddly-named semi-private API+// to get the application menu working properly.  Need to be careful in+// case it goes away in a future OS update.+@interface NSApplication (NSAppleMenu)+- (void)setAppleMenu:(NSMenu *)m;+@end++// Keys to search for as potential application names+NSString *GLFWNameKeys[] =+{+    @"CFBundleDisplayName",+    @"CFBundleName",+    @"CFBundleExecutable",+};++//========================================================================+// Try to figure out what the calling application is called+//========================================================================+static NSString *findAppName( void )+{+    NSDictionary *infoDictionary = [[NSBundle mainBundle] infoDictionary];++    unsigned int i;+    for( i = 0; i < sizeof(GLFWNameKeys) / sizeof(GLFWNameKeys[0]); i++ )+    {+        id name = [infoDictionary objectForKey:GLFWNameKeys[i]];+        if (name &&+            [name isKindOfClass:[NSString class]] &&+            ![@"" isEqualToString:name])+        {+            return name;+        }+    }++    // If we get here, we're unbundled+    if( !_glfwLibrary.Unbundled )+    {+        // Could do this only if we discover we're unbundled, but it should+        // do no harm...+        ProcessSerialNumber psn = { 0, kCurrentProcess };+        TransformProcessType( &psn, kProcessTransformToForegroundApplication );++        // Having the app in front of the terminal window is also generally+        // handy.  There is an NSApplication API to do this, but...+        SetFrontProcess( &psn );++        _glfwLibrary.Unbundled = GL_TRUE;+    }++    char **progname = _NSGetProgname();+    if( progname && *progname )+    {+        // TODO: UTF8?+        return [NSString stringWithUTF8String:*progname];+    }++    // Really shouldn't get here+    return @"GLFW Application";+}++//========================================================================+// Set up the menu bar (manually)+// This is nasty, nasty stuff -- calls to undocumented semi-private APIs that+// could go away at any moment, lots of stuff that really should be+// localize(d|able), etc.  Loading a nib would save us this horror, but that+// doesn't seem like a good thing to require of GLFW's clients.+//========================================================================+static void setUpMenuBar( void )+{+    NSString *appName = findAppName();++    NSMenu *bar = [[NSMenu alloc] init];+    [NSApp setMainMenu:bar];++    NSMenuItem *appMenuItem =+        [bar addItemWithTitle:@"" action:NULL keyEquivalent:@""];+    NSMenu *appMenu = [[NSMenu alloc] init];+    [appMenuItem setSubmenu:appMenu];++    [appMenu addItemWithTitle:[NSString stringWithFormat:@"About %@", appName]+                       action:@selector(orderFrontStandardAboutPanel:)+                keyEquivalent:@""];+    [appMenu addItem:[NSMenuItem separatorItem]];+    NSMenu *servicesMenu = [[NSMenu alloc] init];+    [NSApp setServicesMenu:servicesMenu];+    [[appMenu addItemWithTitle:@"Services"+                       action:NULL+                keyEquivalent:@""] setSubmenu:servicesMenu];+    [appMenu addItem:[NSMenuItem separatorItem]];+    [appMenu addItemWithTitle:[NSString stringWithFormat:@"Hide %@", appName]+                       action:@selector(hide:)+                keyEquivalent:@"h"];+    [[appMenu addItemWithTitle:@"Hide Others"+                       action:@selector(hideOtherApplications:)+                keyEquivalent:@"h"]+        setKeyEquivalentModifierMask:NSAlternateKeyMask | NSCommandKeyMask];+    [appMenu addItemWithTitle:@"Show All"+                       action:@selector(unhideAllApplications:)+                keyEquivalent:@""];+    [appMenu addItem:[NSMenuItem separatorItem]];+    [appMenu addItemWithTitle:[NSString stringWithFormat:@"Quit %@", appName]+                       action:@selector(terminate:)+                keyEquivalent:@"q"];++    NSMenuItem *windowMenuItem =+        [bar addItemWithTitle:@"" action:NULL keyEquivalent:@""];+    NSMenu *windowMenu = [[NSMenu alloc] initWithTitle:@"Window"];+    [NSApp setWindowsMenu:windowMenu];+    [windowMenuItem setSubmenu:windowMenu];++    [windowMenu addItemWithTitle:@"Miniaturize"+                          action:@selector(performMiniaturize:)+                   keyEquivalent:@"m"];+    [windowMenu addItemWithTitle:@"Zoom"+                          action:@selector(performZoom:)+                   keyEquivalent:@""];+    [windowMenu addItem:[NSMenuItem separatorItem]];+    [windowMenu addItemWithTitle:@"Bring All to Front"+                          action:@selector(arrangeInFront:)+                   keyEquivalent:@""];++    // At least guard the call to private API to avoid an exception if it+    // goes away.  Hopefully that means the worst we'll break in future is to+    // look ugly...+    if( [NSApp respondsToSelector:@selector(setAppleMenu:)] )+    {+        [NSApp setAppleMenu:appMenu];+    }+}++//========================================================================+// Initialize GLFW thread package+//========================================================================++static void initThreads( void )+{+    // Initialize critical section handle+    (void) pthread_mutex_init( &_glfwThrd.CriticalSection, NULL );++    // The first thread (the main thread) has ID 0+    _glfwThrd.NextID = 0;++    // Fill out information about the main thread (this thread)+    _glfwThrd.First.ID       = _glfwThrd.NextID ++;+    _glfwThrd.First.Function = NULL;+    _glfwThrd.First.PosixID  = pthread_self();+    _glfwThrd.First.Previous = NULL;+    _glfwThrd.First.Next     = NULL;+}++//************************************************************************+//****               Platform implementation functions                ****+//************************************************************************++//========================================================================+// Initialize the GLFW library+//========================================================================++int _glfwPlatformInit( void )+{+    _glfwLibrary.AutoreleasePool = [[NSAutoreleasePool alloc] init];++    // Implicitly create shared NSApplication instance+    [NSApplication sharedApplication];++    NSString* resourcePath = [[NSBundle mainBundle] resourcePath];++    if( access( [resourcePath cStringUsingEncoding:NSUTF8StringEncoding], R_OK ) == 0 )+    {+        chdir( [resourcePath cStringUsingEncoding:NSUTF8StringEncoding] );+    }++    // Setting up menu bar must go exactly here else weirdness ensues+    setUpMenuBar();++    [NSApp finishLaunching];++    initThreads();++    _glfwPlatformSetTime( 0.0 );++    _glfwLibrary.DesktopMode =+	(NSDictionary *)CGDisplayCurrentMode( CGMainDisplayID() );++    return GL_TRUE;+}++//========================================================================+// Close window, if open, and shut down GLFW+//========================================================================++int _glfwPlatformTerminate( void )+{+    // TODO: Fail unless this is the main thread++    glfwCloseWindow();++    // TODO: Kill all non-main threads?+    // TODO: Probably other cleanup++    [_glfwLibrary.AutoreleasePool release];+    _glfwLibrary.AutoreleasePool = nil;++    return GL_TRUE;+}+
+ glfw/lib/cocoa/cocoa_joystick.m view
@@ -0,0 +1,66 @@+//========================================================================+// GLFW - An OpenGL framework+// File:        macosx_joystick.m+// Platform:    Mac OS X+// API Version: 2.7+// WWW:         http://glfw.sourceforge.net+//------------------------------------------------------------------------+// Copyright (c) 2002-2006 Camilla Berglund+//+// This software is provided 'as-is', without any express or implied+// warranty. In no event will the authors be held liable for any damages+// arising from the use of this software.+//+// Permission is granted to anyone to use this software for any purpose,+// including commercial applications, and to alter it and redistribute it+// freely, subject to the following restrictions:+//+// 1. The origin of this software must not be misrepresented; you must not+//    claim that you wrote the original software. If you use this software+//    in a product, an acknowledgment in the product documentation would+//    be appreciated but is not required.+//+// 2. Altered source versions must be plainly marked as such, and must not+//    be misrepresented as being the original software.+//+// 3. This notice may not be removed or altered from any source+//    distribution.+//+//========================================================================++#include "internal.h"++//************************************************************************+//****               Platform implementation functions                ****+//************************************************************************++//========================================================================+// Determine joystick capabilities+//========================================================================++int _glfwPlatformGetJoystickParam( int joy, int param )+{+    // TODO: Implement this.+    return 0;+}++//========================================================================+// Get joystick axis positions+//========================================================================++int _glfwPlatformGetJoystickPos( int joy, float *pos, int numaxes )+{+    // TODO: Implement this.+    return 0;+}++//========================================================================+// Get joystick button states+//========================================================================++int _glfwPlatformGetJoystickButtons( int joy, unsigned char *buttons, int numbuttons )+{+    // TODO: Implement this.+    return 0;+}+
+ glfw/lib/cocoa/cocoa_thread.c view
@@ -0,0 +1,416 @@+//========================================================================+// GLFW - An OpenGL framework+// File:        macosx_thread.c+// Platform:    Mac OS X+// API Version: 2.7+// WWW:         http://glfw.sourceforge.net+//------------------------------------------------------------------------+// Copyright (c) 2002-2006 Camilla Berglund+//+// This software is provided 'as-is', without any express or implied+// warranty. In no event will the authors be held liable for any damages+// arising from the use of this software.+//+// Permission is granted to anyone to use this software for any purpose,+// including commercial applications, and to alter it and redistribute it+// freely, subject to the following restrictions:+//+// 1. The origin of this software must not be misrepresented; you must not+//    claim that you wrote the original software. If you use this software+//    in a product, an acknowledgment in the product documentation would+//    be appreciated but is not required.+//+// 2. Altered source versions must be plainly marked as such, and must not+//    be misrepresented as being the original software.+//+// 3. This notice may not be removed or altered from any source+//    distribution.+//+//========================================================================++#include "internal.h"++#include <sys/time.h>+#include <sys/sysctl.h>+++//************************************************************************+//****                  GLFW internal functions                       ****+//************************************************************************++//========================================================================+// _glfwNewThread() - This is simply a "wrapper" for calling the user+// thread function.+//========================================================================++void * _glfwNewThread( void * arg )+{+    GLFWthreadfun threadfun;+    _GLFWthread   *t;++    // Get pointer to thread information for current thread+    t = _glfwGetThreadPointer( glfwGetThreadID() );+    if( t == NULL )+    {+        return 0;+    }++    // Get user thread function pointer+    threadfun = t->Function;++    // Call the user thread function+    threadfun( arg );++    // Remove thread from thread list+    ENTER_THREAD_CRITICAL_SECTION+        _glfwRemoveThread( t );+    LEAVE_THREAD_CRITICAL_SECTION++    // When the thread function returns, the thread will die...+    return NULL;+}++++//************************************************************************+//****               Platform implementation functions                ****+//************************************************************************++//========================================================================+// _glfwPlatformCreateThread() - Create a new thread+//========================================================================++GLFWthread _glfwPlatformCreateThread( GLFWthreadfun fun, void *arg )+{+    GLFWthread  ID;+    _GLFWthread *t;+    int         result;++    // Enter critical section+    ENTER_THREAD_CRITICAL_SECTION++    // Create a new thread information memory area+    t = (_GLFWthread *) malloc( sizeof(_GLFWthread) );+    if( t == NULL )+    {+        // Leave critical section+        LEAVE_THREAD_CRITICAL_SECTION+        return -1;+    }++    // Get a new unique thread id+    ID = _glfwThrd.NextID ++;++    // Store thread information in the thread list+    t->Function = fun;+    t->ID       = ID;++    // Create thread+    result = pthread_create(+                            &t->PosixID,      // Thread handle+                            NULL,             // Default thread attributes+                            _glfwNewThread,   // Thread function (a wrapper function)+                            (void *)arg       // Argument to thread is user argument+                            );++    // Did the thread creation fail?+    if( result != 0 )+    {+        free( (void *) t );+        LEAVE_THREAD_CRITICAL_SECTION+        return -1;+    }++    // Append thread to thread list+    _glfwAppendThread( t );++    // Leave critical section+    LEAVE_THREAD_CRITICAL_SECTION++    // Return the GLFW thread ID+    return ID;+}+++//========================================================================+// _glfwPlatformDestroyThread() - Kill a thread. NOTE: THIS IS A VERY+// DANGEROUS OPERATION, AND SHOULD NOT BE USED EXCEPT IN EXTREME+// SITUATIONS!+//========================================================================++void _glfwPlatformDestroyThread( GLFWthread ID )+{+    _GLFWthread *t;++    // Enter critical section+    ENTER_THREAD_CRITICAL_SECTION++    // Get thread information pointer+    t = _glfwGetThreadPointer( ID );+    if( t == NULL )+    {+        LEAVE_THREAD_CRITICAL_SECTION+        return;+    }++    // Simply murder the process, no mercy!+    pthread_kill( t->PosixID, SIGKILL );++    // Remove thread from thread list+    _glfwRemoveThread( t );++    // Leave critical section+    LEAVE_THREAD_CRITICAL_SECTION+}+++//========================================================================+// _glfwPlatformWaitThread() - Wait for a thread to die+//========================================================================++int _glfwPlatformWaitThread( GLFWthread ID, int waitmode )+{+    pthread_t   thread;+    _GLFWthread *t;++    // Enter critical section+    ENTER_THREAD_CRITICAL_SECTION++    // Get thread information pointer+    t = _glfwGetThreadPointer( ID );++    // Is the thread already dead?+    if( t == NULL )+    {+        LEAVE_THREAD_CRITICAL_SECTION+        return GL_TRUE;+    }++    // If got this far, the thread is alive => polling returns FALSE+    if( waitmode == GLFW_NOWAIT )+    {+        LEAVE_THREAD_CRITICAL_SECTION+        return GL_FALSE;+    }++    // Get thread handle+    thread = t->PosixID;++    // Leave critical section+    LEAVE_THREAD_CRITICAL_SECTION++    // Wait for thread to die+    (void) pthread_join( thread, NULL );++    return GL_TRUE;+}+++//========================================================================+// _glfwPlatformGetThreadID() - Return the thread ID for the current+// thread+//========================================================================++GLFWthread _glfwPlatformGetThreadID( void )+{+    _GLFWthread *t;+    GLFWthread  ID = -1;+    pthread_t   posixID;++    // Get current thread ID+    posixID = pthread_self();++    // Enter critical section+    ENTER_THREAD_CRITICAL_SECTION++    // Loop through entire list of threads to find the matching POSIX+    // thread ID+    for( t = &_glfwThrd.First; t != NULL; t = t->Next )+    {+        if( t->PosixID == posixID )+        {+            ID = t->ID;+            break;+        }+    }++    // Leave critical section+    LEAVE_THREAD_CRITICAL_SECTION++    // Return the found GLFW thread identifier+    return ID;+}+++//========================================================================+// _glfwPlatformCreateMutex() - Create a mutual exclusion object+//========================================================================++GLFWmutex _glfwPlatformCreateMutex( void )+{+    pthread_mutex_t *mutex;++    // Allocate memory for mutex+    mutex = (pthread_mutex_t *) malloc( sizeof( pthread_mutex_t ) );+    if( !mutex )+    {+        return NULL;+    }++    // Initialise a mutex object+    (void) pthread_mutex_init( mutex, NULL );++    // Cast to GLFWmutex and return+    return (GLFWmutex) mutex;+}+++//========================================================================+// _glfwPlatformDestroyMutex() - Destroy a mutual exclusion object+//========================================================================++void _glfwPlatformDestroyMutex( GLFWmutex mutex )+{+    // Destroy the mutex object+    pthread_mutex_destroy( (pthread_mutex_t *) mutex );++    // Free memory for mutex object+    free( (void *) mutex );+}+++//========================================================================+// _glfwPlatformLockMutex() - Request access to a mutex+//========================================================================++void _glfwPlatformLockMutex( GLFWmutex mutex )+{+    // Wait for mutex to be released+    (void) pthread_mutex_lock( (pthread_mutex_t *) mutex );+}+++//========================================================================+// _glfwPlatformUnlockMutex() - Release a mutex+//========================================================================++void _glfwPlatformUnlockMutex( GLFWmutex mutex )+{+    // Release mutex+    pthread_mutex_unlock( (pthread_mutex_t *) mutex );+}+++//========================================================================+// _glfwPlatformCreateCond() - Create a new condition variable object+//========================================================================++GLFWcond _glfwPlatformCreateCond( void )+{+    pthread_cond_t *cond;++    // Allocate memory for condition variable+    cond = (pthread_cond_t *) malloc( sizeof(pthread_cond_t) );+    if( !cond )+    {+        return NULL;+    }++    // Initialise condition variable+    (void) pthread_cond_init( cond, NULL );++    // Cast to GLFWcond and return+    return (GLFWcond) cond;+}+++//========================================================================+// _glfwPlatformDestroyCond() - Destroy a condition variable object+//========================================================================++void _glfwPlatformDestroyCond( GLFWcond cond )+{+    // Destroy the condition variable object+    (void) pthread_cond_destroy( (pthread_cond_t *) cond );++    // Free memory for condition variable object+    free( (void *) cond );+}+++//========================================================================+// _glfwPlatformWaitCond() - Wait for a condition to be raised+//========================================================================++void _glfwPlatformWaitCond( GLFWcond cond, GLFWmutex mutex,+                            double timeout )+{+    struct timeval  currenttime;+    struct timespec wait;+    long dt_sec, dt_usec;++    // Select infinite or timed wait+    if( timeout >= GLFW_INFINITY )+    {+        // Wait for condition (infinite wait)+        (void) pthread_cond_wait( (pthread_cond_t *) cond,+                                  (pthread_mutex_t *) mutex );+    }+    else+    {+        // Set timeout time, relatvie to current time+        gettimeofday( &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;+}+
+ glfw/lib/cocoa/cocoa_time.m view
@@ -0,0 +1,106 @@+//========================================================================+// GLFW - An OpenGL framework+// File:        macosx_time.m+// Platform:    Mac OS X+// API Version: 2.7+// WWW:         http://glfw.sourceforge.net+//------------------------------------------------------------------------+// Copyright (c) 2002-2006 Camilla Berglund+//+// This software is provided 'as-is', without any express or implied+// warranty. In no event will the authors be held liable for any damages+// arising from the use of this software.+//+// Permission is granted to anyone to use this software for any purpose,+// including commercial applications, and to alter it and redistribute it+// freely, subject to the following restrictions:+//+// 1. The origin of this software must not be misrepresented; you must not+//    claim that you wrote the original software. If you use this software+//    in a product, an acknowledgment in the product documentation would+//    be appreciated but is not required.+//+// 2. Altered source versions must be plainly marked as such, and must not+//    be misrepresented as being the original software.+//+// 3. This notice may not be removed or altered from any source+//    distribution.+//+//========================================================================++#include "internal.h"++#include <sys/time.h>++//************************************************************************+//****               Platform implementation functions                ****+//************************************************************************++//========================================================================+// Return timer value in seconds+//========================================================================++double _glfwPlatformGetTime( void )+{+    return [NSDate timeIntervalSinceReferenceDate] - _glfwLibrary.Timer.t0;+}++//========================================================================+// Set timer value in seconds+//========================================================================++void _glfwPlatformSetTime( double time )+{+    _glfwLibrary.Timer.t0 = [NSDate timeIntervalSinceReferenceDate] - time;+}++//========================================================================+// Put a thread to sleep for a specified amount of time+//========================================================================++void _glfwPlatformSleep( double time )+{+    if( time == 0.0 )+    {+	sched_yield();+	return;+    }++    struct timeval  currenttime;+    struct timespec wait;+    pthread_mutex_t mutex;+    pthread_cond_t  cond;+    long dt_sec, dt_usec;++    // Not all pthread implementations have a pthread_sleep() function. We+    // do it the portable way, using a timed wait for a condition that we+    // will never signal. NOTE: The unistd functions sleep/usleep suspends+    // the entire PROCESS, not a signle thread, which is why we can not+    // use them to implement glfwSleep.++    // Set timeout time, relatvie to current time+    gettimeofday( &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 );+}+
+ glfw/lib/cocoa/cocoa_window.m view
@@ -0,0 +1,880 @@+//========================================================================+// GLFW - An OpenGL framework+// File:        macosx_window.m+// Platform:    Mac OS X+// API Version: 2.7+// WWW:         http://glfw.sourceforge.net+//------------------------------------------------------------------------+// Copyright (c) 2002-2006 Camilla Berglund+//+// This software is provided 'as-is', without any express or implied+// warranty. In no event will the authors be held liable for any damages+// arising from the use of this software.+//+// Permission is granted to anyone to use this software for any purpose,+// including commercial applications, and to alter it and redistribute it+// freely, subject to the following restrictions:+//+// 1. The origin of this software must not be misrepresented; you must not+//    claim that you wrote the original software. If you use this software+//    in a product, an acknowledgment in the product documentation would+//    be appreciated but is not required.+//+// 2. Altered source versions must be plainly marked as such, and must not+//    be misrepresented as being the original software.+//+// 3. This notice may not be removed or altered from any source+//    distribution.+//+//========================================================================++#include "internal.h"++//========================================================================+// Delegate for window related notifications+// (but also used as an application delegate)+//========================================================================++@interface GLFWWindowDelegate : NSObject+@end++@implementation GLFWWindowDelegate++- (BOOL)windowShouldClose:(id)window+{+    if( _glfwWin.windowCloseCallback )+    {+        if( !_glfwWin.windowCloseCallback() )+        {+            return NO;+        }+    }++    // This is horribly ugly, but it works+    glfwCloseWindow();+    return NO;+}++- (void)windowDidResize:(NSNotification *)notification+{+    [_glfwWin.context update];++    NSRect contentRect =+        [_glfwWin.window contentRectForFrameRect:[_glfwWin.window frame]];+    _glfwWin.width = contentRect.size.width;+    _glfwWin.height = contentRect.size.height;++    if( _glfwWin.windowSizeCallback )+    {+        _glfwWin.windowSizeCallback( _glfwWin.width, _glfwWin.height );+    }+}++- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender+{+    if( _glfwWin.windowCloseCallback )+    {+        if( !_glfwWin.windowCloseCallback() )+        {+            return NSTerminateCancel;+        }+    }++    // This is horribly ugly, but it works+    glfwCloseWindow();+    return NSTerminateCancel;+}++@end++// TODO: Need to find mappings for F13-F15, volume down/up/mute, and eject.+static const unsigned int MAC_TO_GLFW_KEYCODE_MAPPING[128] =+{+    /* 00 */ 'A',+    /* 01 */ 'S',+    /* 02 */ 'D',+    /* 03 */ 'F',+    /* 04 */ 'H',+    /* 05 */ 'G',+    /* 06 */ 'Z',+    /* 07 */ 'X',+    /* 08 */ 'C',+    /* 09 */ 'V',+    /* 0a */ -1,+    /* 0b */ 'B',+    /* 0c */ 'Q',+    /* 0d */ 'W',+    /* 0e */ 'E',+    /* 0f */ 'R',+    /* 10 */ 'Y',+    /* 11 */ 'T',+    /* 12 */ '1',+    /* 13 */ '2',+    /* 14 */ '3',+    /* 15 */ '4',+    /* 16 */ '6',+    /* 17 */ '5',+    /* 18 */ GLFW_KEY_KP_EQUAL,+    /* 19 */ '9',+    /* 1a */ '7',+    /* 1b */ '-',+    /* 1c */ '8',+    /* 1d */ '0',+    /* 1e */ ']',+    /* 1f */ 'O',+    /* 20 */ 'U',+    /* 21 */ '[',+    /* 22 */ 'I',+    /* 23 */ 'P',+    /* 24 */ GLFW_KEY_ENTER,+    /* 25 */ 'L',+    /* 26 */ 'J',+    /* 27 */ '\'',+    /* 28 */ 'K',+    /* 29 */ ';',+    /* 2a */ '\\',+    /* 2b */ ',',+    /* 2c */ '/',+    /* 2d */ 'N',+    /* 2e */ 'M',+    /* 2f */ '.',+    /* 30 */ GLFW_KEY_TAB,+    /* 31 */ GLFW_KEY_SPACE,+    /* 32 */ '`',+    /* 33 */ GLFW_KEY_BACKSPACE,+    /* 34 */ -1,+    /* 35 */ GLFW_KEY_ESC,+    /* 36 */ GLFW_KEY_RSUPER,+    /* 37 */ GLFW_KEY_LSUPER,+    /* 38 */ GLFW_KEY_LSHIFT,+    /* 39 */ GLFW_KEY_CAPS_LOCK,+    /* 3a */ GLFW_KEY_LALT,+    /* 3b */ GLFW_KEY_LCTRL,+    /* 3c */ GLFW_KEY_RSHIFT,+    /* 3d */ GLFW_KEY_RALT,+    /* 3e */ GLFW_KEY_RCTRL,+    /* 3f */ -1,+    /* 40 */ -1,+    /* 41 */ GLFW_KEY_KP_DECIMAL,+    /* 42 */ -1,+    /* 43 */ GLFW_KEY_KP_MULTIPLY,+    /* 44 */ -1,+    /* 45 */ GLFW_KEY_KP_ADD,+    /* 46 */ -1,+    /* 47 */ -1,+    /* 48 */ -1,+    /* 49 */ -1,+    /* 4a */ -1,+    /* 4b */ GLFW_KEY_KP_DIVIDE,+    /* 4c */ GLFW_KEY_KP_ENTER,+    /* 4d */ -1,+    /* 4e */ GLFW_KEY_KP_SUBTRACT,+    /* 4f */ -1,+    /* 50 */ -1,+    /* 51 */ -1,+    /* 52 */ GLFW_KEY_KP_0,+    /* 53 */ GLFW_KEY_KP_1,+    /* 54 */ GLFW_KEY_KP_2,+    /* 55 */ GLFW_KEY_KP_3,+    /* 56 */ GLFW_KEY_KP_4,+    /* 57 */ GLFW_KEY_KP_5,+    /* 58 */ GLFW_KEY_KP_6,+    /* 59 */ GLFW_KEY_KP_7,+    /* 5a */ -1,+    /* 5b */ GLFW_KEY_KP_8,+    /* 5c */ GLFW_KEY_KP_9,+    /* 5d */ -1,+    /* 5e */ -1,+    /* 5f */ -1,+    /* 60 */ GLFW_KEY_F5,+    /* 61 */ GLFW_KEY_F6,+    /* 62 */ GLFW_KEY_F7,+    /* 63 */ GLFW_KEY_F3,+    /* 64 */ GLFW_KEY_F8,+    /* 65 */ -1,+    /* 66 */ -1,+    /* 67 */ -1,+    /* 68 */ -1,+    /* 69 */ GLFW_KEY_F13,+    /* 6a */ GLFW_KEY_F16,+    /* 6b */ -1,+    /* 6c */ -1,+    /* 6d */ -1,+    /* 6e */ -1,+    /* 6f */ -1,+    /* 70 */ -1,+    /* 71 */ -1,+    /* 72 */ GLFW_KEY_INSERT,+    /* 73 */ GLFW_KEY_HOME,+    /* 74 */ GLFW_KEY_PAGEUP,+    /* 75 */ GLFW_KEY_DEL,+    /* 76 */ GLFW_KEY_F4,+    /* 77 */ GLFW_KEY_END,+    /* 78 */ GLFW_KEY_F2,+    /* 79 */ GLFW_KEY_PAGEDOWN,+    /* 7a */ GLFW_KEY_F1,+    /* 7b */ GLFW_KEY_LEFT,+    /* 7c */ GLFW_KEY_RIGHT,+    /* 7d */ GLFW_KEY_DOWN,+    /* 7e */ GLFW_KEY_UP,+    /* 7f */ -1,+};++//========================================================================+// Converts a Mac OS X keycode to a GLFW keycode+//========================================================================++static int convertMacKeyCode( unsigned int macKeyCode )+{+    if( macKeyCode >= 128 )+    {+        return -1;+    }++    // This treats keycodes as *positional*; that is, we'll return 'a'+    // for the key left of 's', even on an AZERTY keyboard.  The charInput+    // function should still get 'q' though.+    return MAC_TO_GLFW_KEYCODE_MAPPING[macKeyCode];+}++//========================================================================+// Content view class for the GLFW window+//========================================================================++@interface GLFWContentView : NSView+@end++@implementation GLFWContentView++- (BOOL)isOpaque+{+    return YES;+}++- (BOOL)canBecomeKeyView+{+    return YES;+}++- (BOOL)acceptsFirstResponder+{+    return YES;+}++- (void)mouseDown:(NSEvent *)event+{+    _glfwInputMouseClick( GLFW_MOUSE_BUTTON_LEFT, GLFW_PRESS );+}++- (void)mouseDragged:(NSEvent *)event+{+    [self mouseMoved:event];+}++- (void)mouseUp:(NSEvent *)event+{+    _glfwInputMouseClick( GLFW_MOUSE_BUTTON_LEFT, GLFW_RELEASE );+}++- (void)mouseMoved:(NSEvent *)event+{+    if( _glfwWin.mouseLock )+    {+        _glfwInput.MousePosX += [event deltaX];+        _glfwInput.MousePosY -= [event deltaY];+    }+    else+    {+        NSPoint p = [event locationInWindow];++        // Cocoa coordinate system has origin at lower left+        _glfwInput.MousePosX = p.x;+        _glfwInput.MousePosY = [[_glfwWin.window contentView] bounds].size.height - p.y;+    }++    if( _glfwWin.mousePosCallback )+    {+        _glfwWin.mousePosCallback( _glfwInput.MousePosX, _glfwInput.MousePosY );+    }+}++- (void)rightMouseDown:(NSEvent *)event+{+    _glfwInputMouseClick( GLFW_MOUSE_BUTTON_RIGHT, GLFW_PRESS );+}++- (void)rightMouseDragged:(NSEvent *)event+{+    [self mouseMoved:event];+}++- (void)rightMouseUp:(NSEvent *)event+{+    _glfwInputMouseClick( GLFW_MOUSE_BUTTON_RIGHT, GLFW_RELEASE );+}++- (void)otherMouseDown:(NSEvent *)event+{+    _glfwInputMouseClick( [event buttonNumber], GLFW_PRESS );+}++- (void)otherMouseDragged:(NSEvent *)event+{+    [self mouseMoved:event];+}++- (void)otherMouseUp:(NSEvent *)event+{+    _glfwInputMouseClick( [event buttonNumber], GLFW_RELEASE );+}++- (void)keyDown:(NSEvent *)event+{+    NSUInteger length;+    NSString* characters;+    int i, code = convertMacKeyCode( [event keyCode] );++    if( code != -1 )+    {+        _glfwInputKey( code, GLFW_PRESS );++        if( [event modifierFlags] & NSCommandKeyMask )+        {+            if( !_glfwWin.sysKeysDisabled )+            {+                [super keyDown:event];+            }+        }+        else+        {+            characters = [event characters];+            length = [characters length];++            for( i = 0;  i < length;  i++ )+            {+                _glfwInputChar( [characters characterAtIndex:i], GLFW_PRESS );+            }+        }+    }+}++- (void)flagsChanged:(NSEvent *)event+{+    unsigned int newModifierFlags = [event modifierFlags];+    int mode;++    if( newModifierFlags > _glfwWin.modifierFlags )+    {+        mode = GLFW_PRESS;+    }+    else+    {+        mode = GLFW_RELEASE;+    }++    _glfwWin.modifierFlags = newModifierFlags;+    _glfwInputKey( MAC_TO_GLFW_KEYCODE_MAPPING[[event keyCode]], mode );+}++- (void)keyUp:(NSEvent *)event+{+    NSUInteger length;+    NSString* characters;+    int i, code = convertMacKeyCode( [event keyCode] );++    if( code != -1 )+    {+        _glfwInputKey( code, GLFW_RELEASE );++        characters = [event characters];+        length = [characters length];++        for( i = 0;  i < length;  i++ )+        {+            _glfwInputChar( [characters characterAtIndex:i], GLFW_RELEASE );+        }+    }+}++- (void)scrollWheel:(NSEvent *)event+{+    _glfwInput.WheelPosFloating += [event deltaY];+    _glfwInput.WheelPos = lrint(_glfwInput.WheelPosFloating);++    if( _glfwWin.mouseWheelCallback )+    {+        _glfwWin.mouseWheelCallback( _glfwInput.WheelPos );+    }+}++@end++//************************************************************************+//****               Platform implementation functions                ****+//************************************************************************++//========================================================================+// Here is where the window is created, and the OpenGL rendering context is+// created+//========================================================================++int  _glfwPlatformOpenWindow( int width, int height,+                              const _GLFWwndconfig *wndconfig,+                              const _GLFWfbconfig *fbconfig )+{+    int colorBits;++    _glfwWin.pixelFormat = nil;+    _glfwWin.window = nil;+    _glfwWin.context = nil;+    _glfwWin.delegate = nil;++    _glfwWin.delegate = [[GLFWWindowDelegate alloc] init];+    if( _glfwWin.delegate == nil )+    {+        _glfwPlatformCloseWindow();+        return GL_FALSE;+    }++    [NSApp setDelegate:_glfwWin.delegate];++    // Mac OS X needs non-zero color size, so set resonable values+    colorBits = fbconfig->redBits + fbconfig->greenBits + fbconfig->blueBits;+    if( colorBits == 0 )+    {+        colorBits = 24;+    }+    else if( colorBits < 15 )+    {+        colorBits = 15;+    }++    // Ignored hints:+    // OpenGLMajor, OpenGLMinor, OpenGLForward:+    //     pending Mac OS X support for OpenGL 3.x+    // OpenGLDebug+    //     pending it meaning anything on Mac OS X++    // Don't use accumulation buffer support; it's not accelerated+    // Aux buffers probably aren't accelerated either++    CFDictionaryRef fullscreenMode = NULL;+    if( wndconfig->mode == GLFW_FULLSCREEN )+    {+        fullscreenMode =+            // I think it's safe to pass 0 to the refresh rate for this function+            // rather than conditionalizing the code to call the version which+            // doesn't specify refresh...+            CGDisplayBestModeForParametersAndRefreshRateWithProperty(+            CGMainDisplayID(),+            colorBits + fbconfig->alphaBits,+            width,+            height,+            wndconfig->refreshRate,+            // Controversial, see macosx_fullscreen.m for discussion+            kCGDisplayModeIsSafeForHardware,+            NULL);++        width = [[(id)fullscreenMode objectForKey:(id)kCGDisplayWidth] intValue];+        height = [[(id)fullscreenMode objectForKey:(id)kCGDisplayHeight] intValue];+    }++    unsigned int styleMask = 0;+    if( wndconfig->mode == GLFW_WINDOW )+    {+        styleMask = NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask;++        if( !wndconfig->windowNoResize )+        {+            styleMask |= NSResizableWindowMask;+        }+    }+    else+    {+        styleMask = NSBorderlessWindowMask;+    }++    _glfwWin.window = [[NSWindow alloc]+        initWithContentRect:NSMakeRect(0, 0, width, height)+                      styleMask:styleMask+                        backing:NSBackingStoreBuffered+                          defer:NO];+    [_glfwWin.window setContentView:[[GLFWContentView alloc] init]];+    [_glfwWin.window setDelegate:_glfwWin.delegate];+    [_glfwWin.window setAcceptsMouseMovedEvents:YES];+    [_glfwWin.window center];++    if( wndconfig->mode == GLFW_FULLSCREEN )+    {+        CGCaptureAllDisplays();+        CGDisplaySwitchToMode( CGMainDisplayID(), fullscreenMode );+    }++    unsigned int attribute_count = 0;+#define ADD_ATTR(x) attributes[attribute_count++] = x+#define ADD_ATTR2(x, y) (void)({ ADD_ATTR(x); ADD_ATTR(y); })+#define MAX_ATTRS 24 // urgh+    NSOpenGLPixelFormatAttribute attributes[MAX_ATTRS];++    ADD_ATTR( NSOpenGLPFADoubleBuffer );++    if( wndconfig->mode == GLFW_FULLSCREEN )+    {+        ADD_ATTR( NSOpenGLPFAFullScreen );+        ADD_ATTR( NSOpenGLPFANoRecovery );+        ADD_ATTR2( NSOpenGLPFAScreenMask,+                   CGDisplayIDToOpenGLDisplayMask( CGMainDisplayID() ) );+    }++    ADD_ATTR2( NSOpenGLPFAColorSize, colorBits );++    if( fbconfig->alphaBits > 0)+    {+        ADD_ATTR2( NSOpenGLPFAAlphaSize, fbconfig->alphaBits );+    }++    if( fbconfig->depthBits > 0)+    {+        ADD_ATTR2( NSOpenGLPFADepthSize, fbconfig->depthBits );+    }++    if( fbconfig->stencilBits > 0)+    {+        ADD_ATTR2( NSOpenGLPFAStencilSize, fbconfig->stencilBits );+    }++    int accumBits = fbconfig->accumRedBits + fbconfig->accumGreenBits ++                    fbconfig->accumBlueBits + fbconfig->accumAlphaBits;++    if( accumBits > 0)+    {+        ADD_ATTR2( NSOpenGLPFAAccumSize, accumBits );+    }++    if( fbconfig->auxBuffers > 0)+    {+        ADD_ATTR2( NSOpenGLPFAAuxBuffers, fbconfig->auxBuffers );+    }++    if( fbconfig->stereo)+    {+        ADD_ATTR( NSOpenGLPFAStereo );+    }++    if( fbconfig->samples > 0)+    {+        ADD_ATTR2( NSOpenGLPFASampleBuffers, 1 );+        ADD_ATTR2( NSOpenGLPFASamples, fbconfig->samples );+    }++    ADD_ATTR(0);++    _glfwWin.pixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:attributes];+    if( _glfwWin.pixelFormat == nil )+    {+        _glfwPlatformCloseWindow();+        return GL_FALSE;+    }++    _glfwWin.context = [[NSOpenGLContext alloc] initWithFormat:_glfwWin.pixelFormat+                                                  shareContext:nil];+    if( _glfwWin.context == nil )+    {+        _glfwPlatformCloseWindow();+        return GL_FALSE;+    }++    [_glfwWin.window makeKeyAndOrderFront:nil];+    [_glfwWin.context setView:[_glfwWin.window contentView]];++    if( wndconfig->mode == GLFW_FULLSCREEN )+    {+        // TODO: Make this work on pre-Leopard systems+        [[_glfwWin.window contentView] enterFullScreenMode:[NSScreen mainScreen]+                                               withOptions:nil];+    }++    [_glfwWin.context makeCurrentContext];++    NSPoint point = [[NSCursor currentCursor] hotSpot];+    _glfwInput.MousePosX = point.x;+    _glfwInput.MousePosY = point.y;++    return GL_TRUE;+}++//========================================================================+// Properly kill the window / video display+//========================================================================++void _glfwPlatformCloseWindow( void )+{+    [_glfwWin.window orderOut:nil];++    if( _glfwWin.fullscreen )+    {+        [[_glfwWin.window contentView] exitFullScreenModeWithOptions:nil];+        CGDisplaySwitchToMode( CGMainDisplayID(),+                               (CFDictionaryRef)_glfwLibrary.DesktopMode );+        CGReleaseAllDisplays();+    }++    [_glfwWin.pixelFormat release];+    _glfwWin.pixelFormat = nil;++    [NSOpenGLContext clearCurrentContext];+    [_glfwWin.context release];+    _glfwWin.context = nil;++    [_glfwWin.window setDelegate:nil];+    [NSApp setDelegate:nil];+    [_glfwWin.delegate release];+    _glfwWin.delegate = nil;++    [_glfwWin.window close];+    _glfwWin.window = nil;++    // TODO: Probably more cleanup+}++//========================================================================+// Set the window title+//========================================================================++void _glfwPlatformSetWindowTitle( const char *title )+{+    [_glfwWin.window setTitle:[NSString stringWithCString:title+                     encoding:NSISOLatin1StringEncoding]];+}++//========================================================================+// Set the window size+//========================================================================++void _glfwPlatformSetWindowSize( int width, int height )+{+    [_glfwWin.window setContentSize:NSMakeSize(width, height)];+}++//========================================================================+// Set the window position+//========================================================================++void _glfwPlatformSetWindowPos( int x, int y )+{+    NSRect contentRect = [_glfwWin.window contentRectForFrameRect:[_glfwWin.window frame]];++    // We assume here that the client code wants to position the window within the+    // screen the window currently occupies+    NSRect screenRect = [[_glfwWin.window screen] visibleFrame];+    contentRect.origin = NSMakePoint(screenRect.origin.x + x,+                                     screenRect.origin.y + screenRect.size.height -+                                         y - contentRect.size.height);++    [_glfwWin.window setFrame:[_glfwWin.window frameRectForContentRect:contentRect]+                      display:YES];+}++//========================================================================+// Iconify the window+//========================================================================++void _glfwPlatformIconifyWindow( void )+{+    [_glfwWin.window miniaturize:nil];+}++//========================================================================+// Restore (un-iconify) the window+//========================================================================++void _glfwPlatformRestoreWindow( void )+{+    [_glfwWin.window deminiaturize:nil];+}++//========================================================================+// Swap buffers+//========================================================================++void _glfwPlatformSwapBuffers( void )+{+    // ARP appears to be unnecessary, but this is future-proof+    [_glfwWin.context flushBuffer];+}++//========================================================================+// Set double buffering swap interval+//========================================================================++void _glfwPlatformSwapInterval( int interval )+{+    GLint sync = interval;+    [_glfwWin.context setValues:&sync forParameter:NSOpenGLCPSwapInterval];+}++//========================================================================+// Write back window parameters into GLFW window structure+//========================================================================++void _glfwPlatformRefreshWindowParams( void )+{+    GLint value;++    // Since GLFW 2.x doesn't understand screens, we use virtual screen zero++    [_glfwWin.pixelFormat getValues:&value+                       forAttribute:NSOpenGLPFAAccelerated+                   forVirtualScreen:0];+    _glfwWin.accelerated = value;++    [_glfwWin.pixelFormat getValues:&value+                       forAttribute:NSOpenGLPFAAlphaSize+                   forVirtualScreen:0];+    _glfwWin.alphaBits = value;++    // It seems that the color size includes the size of the alpha channel+    [_glfwWin.pixelFormat getValues:&value+                       forAttribute:NSOpenGLPFAColorSize+                   forVirtualScreen:0];+    value -= _glfwWin.alphaBits;+    _glfwWin.redBits = value / 3;+    _glfwWin.greenBits = value / 3;+    _glfwWin.blueBits = value / 3;++    [_glfwWin.pixelFormat getValues:&value+                       forAttribute:NSOpenGLPFADepthSize+                   forVirtualScreen:0];+    _glfwWin.depthBits = value;++    [_glfwWin.pixelFormat getValues:&value+                       forAttribute:NSOpenGLPFAStencilSize+                   forVirtualScreen:0];+    _glfwWin.stencilBits = value;++    [_glfwWin.pixelFormat getValues:&value+                       forAttribute:NSOpenGLPFAAccumSize+                   forVirtualScreen:0];+    _glfwWin.accumRedBits = value / 3;+    _glfwWin.accumGreenBits = value / 3;+    _glfwWin.accumBlueBits = value / 3;++    // TODO: Figure out what to set this value to+    _glfwWin.accumAlphaBits = 0;++    [_glfwWin.pixelFormat getValues:&value+                       forAttribute:NSOpenGLPFAAuxBuffers+                   forVirtualScreen:0];+    _glfwWin.auxBuffers = value;++    [_glfwWin.pixelFormat getValues:&value+                       forAttribute:NSOpenGLPFAStereo+                   forVirtualScreen:0];+    _glfwWin.stereo = value;++    [_glfwWin.pixelFormat getValues:&value+                       forAttribute:NSOpenGLPFASamples+                   forVirtualScreen:0];+    _glfwWin.samples = value;++    // These are forced to false as long as Mac OS X lacks support for OpenGL 3.0++    _glfwWin.glForward = GL_FALSE;+    _glfwWin.glDebug = GL_FALSE;+    _glfwWin.glProfile = 0;+}++//========================================================================+// Poll for new window and input events+//========================================================================++void _glfwPlatformPollEvents( void )+{+    NSEvent *event;++    do+    {+        event = [NSApp nextEventMatchingMask:NSAnyEventMask+                                   untilDate:[NSDate distantPast]+                                      inMode:NSDefaultRunLoopMode+                                     dequeue:YES];++        if (event)+        {+            [NSApp sendEvent:event];+        }+    }+    while (event);++    [_glfwLibrary.AutoreleasePool drain];+    _glfwLibrary.AutoreleasePool = [[NSAutoreleasePool alloc] init];+}++//========================================================================+// Wait for new window and input events+//========================================================================++void _glfwPlatformWaitEvents( void )+{+    // I wanted to pass NO to dequeue:, and rely on PollEvents to+    // dequeue and send.  For reasons not at all clear to me, passing+    // NO to dequeue: causes this method never to return.+    NSEvent *event = [NSApp nextEventMatchingMask:NSAnyEventMask+                                        untilDate:[NSDate distantFuture]+                                           inMode:NSDefaultRunLoopMode+                                          dequeue:YES];+    [NSApp sendEvent:event];++    _glfwPlatformPollEvents();+}++//========================================================================+// Hide mouse cursor (lock it)+//========================================================================++void _glfwPlatformHideMouseCursor( void )+{+    [NSCursor hide];+    CGAssociateMouseAndMouseCursorPosition( false );+}++//========================================================================+// Show mouse cursor (unlock it)+//========================================================================++void _glfwPlatformShowMouseCursor( void )+{+    [NSCursor unhide];+    CGAssociateMouseAndMouseCursorPosition( true );+}++//========================================================================+// Set physical mouse cursor position+//========================================================================++void _glfwPlatformSetMouseCursorPos( int x, int y )+{+    // The library seems to assume that after calling this the mouse won't move,+    // but obviously it will, and escape the app's window, and activate other apps,+    // and other badness in pain.  I think the API's just silly, but maybe I'm+    // misunderstanding it...++    // Also, (x, y) are window coords...++    // Also, it doesn't seem possible to write this robustly without+    // calculating the maximum y coordinate of all screens, since Cocoa's+    // "global coordinates" are upside down from CG's...++    // Without this (once per app run, but it's convenient to do it here)+    // events will be suppressed for a default of 0.25 seconds after we+    // move the cursor.+    CGSetLocalEventsSuppressionInterval( 0.0 );++    NSPoint localPoint = NSMakePoint( x, y );+    NSPoint globalPoint = [_glfwWin.window convertBaseToScreen:localPoint];+    CGPoint mainScreenOrigin = CGDisplayBounds( CGMainDisplayID() ).origin;+    double mainScreenHeight = CGDisplayBounds( CGMainDisplayID() ).size.height;+    CGPoint targetPoint = CGPointMake( globalPoint.x - mainScreenOrigin.x,+                                       mainScreenHeight - globalPoint.y - mainScreenOrigin.y );+    CGDisplayMoveCursorToPoint( CGMainDisplayID(), targetPoint );+}+
+ glfw/lib/enable.c view
@@ -0,0 +1,310 @@+//========================================================================+// GLFW - An OpenGL framework+// File:        enable.c+// Platform:    Any+// API version: 2.7+// WWW:         http://glfw.sourceforge.net+//------------------------------------------------------------------------+// Copyright (c) 2002-2006 Camilla Berglund+//+// This software is provided 'as-is', without any express or implied+// warranty. In no event will the authors be held liable for any damages+// arising from the use of this software.+//+// Permission is granted to anyone to use this software for any purpose,+// including commercial applications, and to alter it and redistribute it+// freely, subject to the following restrictions:+//+// 1. The origin of this software must not be misrepresented; you must not+//    claim that you wrote the original software. If you use this software+//    in a product, an acknowledgment in the product documentation would+//    be appreciated but is not required.+//+// 2. Altered source versions must be plainly marked as such, and must not+//    be misrepresented as being the original software.+//+// 3. This notice may not be removed or altered from any source+//    distribution.+//+//========================================================================++#include "internal.h"+++//************************************************************************+//****                  GLFW internal functions                       ****+//************************************************************************++//========================================================================+// Enable (show) mouse cursor+//========================================================================++static void enableMouseCursor( 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 disableMouseCursor( 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;+}+++//========================================================================+// Enable sticky keys+//========================================================================++static void enableStickyKeys( void )+{+    _glfwInput.StickyKeys = 1;+}++//========================================================================+// Disable sticky keys+//========================================================================++static void disableStickyKeys( 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;+        }+    }+}+++//========================================================================+// Enable sticky mouse buttons+//========================================================================++static void enableStickyMouseButtons( void )+{+    _glfwInput.StickyMouseButtons = 1;+}++//========================================================================+// Disable sticky mouse buttons+//========================================================================++static void disableStickyMouseButtons( 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;+        }+    }+}+++//========================================================================+// Enable system keys+//========================================================================++static void enableSystemKeys( void )+{+    if( !_glfwWin.sysKeysDisabled )+    {+        return;+    }++    _glfwPlatformEnableSystemKeys();++    // Indicate that system keys are no longer disabled+    _glfwWin.sysKeysDisabled = GL_FALSE;+}++//========================================================================+// Disable system keys+//========================================================================++static void disableSystemKeys( void )+{+    if( _glfwWin.sysKeysDisabled )+    {+        return;+    }++    _glfwPlatformDisableSystemKeys();++    // Indicate that system keys are now disabled+    _glfwWin.sysKeysDisabled = GL_TRUE;+}+++//========================================================================+// Enable key repeat+//========================================================================++static void enableKeyRepeat( void )+{+    _glfwInput.KeyRepeat = 1;+}++//========================================================================+// Disable key repeat+//========================================================================++static void disableKeyRepeat( void )+{+    _glfwInput.KeyRepeat = 0;+}+++//========================================================================+// Enable automatic event polling+//========================================================================++static void enableAutoPollEvents( void )+{+    _glfwWin.autoPollEvents = 1;+}++//========================================================================+// Disable automatic event polling+//========================================================================++static void disableAutoPollEvents( void )+{+    _glfwWin.autoPollEvents = 0;+}++++//************************************************************************+//****                    GLFW user functions                         ****+//************************************************************************++//========================================================================+// Enable certain GLFW/window/system functions.+//========================================================================++GLFWAPI void GLFWAPIENTRY glfwEnable( int token )+{+    // Is GLFW initialized?+    if( !_glfwInitialized )+    {+        return;+    }++    switch( token )+    {+        case GLFW_MOUSE_CURSOR:+            enableMouseCursor();+            break;+        case GLFW_STICKY_KEYS:+            enableStickyKeys();+            break;+        case GLFW_STICKY_MOUSE_BUTTONS:+            enableStickyMouseButtons();+            break;+        case GLFW_SYSTEM_KEYS:+            enableSystemKeys();+            break;+        case GLFW_KEY_REPEAT:+            enableKeyRepeat();+            break;+        case GLFW_AUTO_POLL_EVENTS:+            enableAutoPollEvents();+            break;+        default:+            break;+    }+}+++//========================================================================+// Disable certain GLFW/window/system functions.+//========================================================================++GLFWAPI void GLFWAPIENTRY glfwDisable( int token )+{+    // Is GLFW initialized?+    if( !_glfwInitialized )+    {+        return;+    }++    switch( token )+    {+        case GLFW_MOUSE_CURSOR:+            disableMouseCursor();+            break;+        case GLFW_STICKY_KEYS:+            disableStickyKeys();+            break;+        case GLFW_STICKY_MOUSE_BUTTONS:+            disableStickyMouseButtons();+            break;+        case GLFW_SYSTEM_KEYS:+            disableSystemKeys();+            break;+        case GLFW_KEY_REPEAT:+            disableKeyRepeat();+            break;+        case GLFW_AUTO_POLL_EVENTS:+            disableAutoPollEvents();+            break;+        default:+            break;+    }+}+
+ glfw/lib/fullscreen.c view
@@ -0,0 +1,95 @@+//========================================================================+// GLFW - An OpenGL framework+// File:        fullscreen.c+// Platform:    Any+// API version: 2.7+// WWW:         http://glfw.sourceforge.net+//------------------------------------------------------------------------+// Copyright (c) 2002-2006 Camilla Berglund+//+// This software is provided 'as-is', without any express or implied+// warranty. In no event will the authors be held liable for any damages+// arising from the use of this software.+//+// Permission is granted to anyone to use this software for any purpose,+// including commercial applications, and to alter it and redistribute it+// freely, subject to the following restrictions:+//+// 1. The origin of this software must not be misrepresented; you must not+//    claim that you wrote the original software. If you use this software+//    in a product, an acknowledgment in the product documentation would+//    be appreciated but is not required.+//+// 2. Altered source versions must be plainly marked as such, and must not+//    be misrepresented as being the original software.+//+// 3. This notice may not be removed or altered from any source+//    distribution.+//+//========================================================================++#include "internal.h"+++//************************************************************************+//****                    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 );+}+
+ glfw/lib/glext.c view
@@ -0,0 +1,211 @@+//========================================================================+// GLFW - An OpenGL framework+// File:        glext.c+// Platform:    Any+// API version: 2.7+// WWW:         http://glfw.sourceforge.net+//------------------------------------------------------------------------+// Copyright (c) 2002-2006 Camilla Berglund+//+// This software is provided 'as-is', without any express or implied+// warranty. In no event will the authors be held liable for any damages+// arising from the use of this software.+//+// Permission is granted to anyone to use this software for any purpose,+// including commercial applications, and to alter it and redistribute it+// freely, subject to the following restrictions:+//+// 1. The origin of this software must not be misrepresented; you must not+//    claim that you wrote the original software. If you use this software+//    in a product, an acknowledgment in the product documentation would+//    be appreciated but is not required.+//+// 2. Altered source versions must be plainly marked as such, and must not+//    be misrepresented as being the original software.+//+// 3. This notice may not be removed or altered from any source+//    distribution.+//+//========================================================================++#include "internal.h"+++//************************************************************************+//****                  GLFW internal functions                       ****+//************************************************************************++//========================================================================+// Parses the OpenGL version string and extracts the version number+//========================================================================++void _glfwParseGLVersion( int *major, int *minor, int *rev )+{+    GLuint _major, _minor = 0, _rev = 0;+    const GLubyte *version;+    const GLubyte *ptr;++    // Get OpenGL version string+    version = glGetString( GL_VERSION );+    if( !version )+    {+        return;+    }++    // Parse string+    ptr = 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+    *major = _major;+    *minor = _minor;+    *rev = _rev;+}++//========================================================================+// _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 = 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 );+}+++//========================================================================+// Returns the OpenGL version+//========================================================================++GLFWAPI void GLFWAPIENTRY glfwGetGLVersion( int *major, int *minor, int *rev )+{+    // Is GLFW initialized?+    if( !_glfwInitialized || !_glfwWin.opened )+    {+        return;+    }++    if( major != NULL )+    {+        *major = _glfwWin.glMajor;+    }+    if( minor != NULL )+    {+        *minor = _glfwWin.glMinor;+    }+    if( rev != NULL )+    {+        *rev = _glfwWin.glRevision;+    }+}+
+ glfw/lib/image.c view
@@ -0,0 +1,631 @@+//========================================================================+// GLFW - An OpenGL framework+// File:        image.c+// Platform:    Any+// API version: 2.7+// WWW:         http://glfw.sourceforge.net+//------------------------------------------------------------------------+// Copyright (c) 2002-2006 Camilla Berglund+//+// This software is provided 'as-is', without any express or implied+// warranty. In no event will the authors be held liable for any damages+// arising from the use of this software.+//+// Permission is granted to anyone to use this software for any purpose,+// including commercial applications, and to alter it and redistribute it+// freely, subject to the following restrictions:+//+// 1. The origin of this software must not be misrepresented; you must not+//    claim that you wrote the original software. If you use this software+//    in a product, an acknowledgment in the product documentation would+//    be appreciated but is not required.+//+// 2. Altered source versions must be plainly marked as such, and must not+//    be misrepresented as being the original software.+//+// 3. This notice may not be removed or altered from any source+//    distribution.+//+//========================================================================++//========================================================================+// 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                       ****+//************************************************************************++//========================================================================+// Upsample image, from size w1 x h1 to w2 x h2+//========================================================================++static void UpsampleImage( 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;+        }+    }+}+++//========================================================================+// Build the next mip-map level+//========================================================================++static int HalveImage( 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;+}+++//========================================================================+// Rescales an image into power-of-two dimensions+//========================================================================++static int RescaleImage( 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+        UpsampleImage( 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( !RescaleImage( 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( !RescaleImage( 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.glMajor == 1) && (_glfwWin.glMinor == 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.glMajor == 1 && _glfwWin.glMinor == 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 = HalveImage( 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;+}+
+ glfw/lib/init.c view
@@ -0,0 +1,111 @@+//========================================================================+// GLFW - An OpenGL framework+// File:        init.c+// Platform:    Any+// API version: 2.7+// WWW:         http://glfw.sourceforge.net+//------------------------------------------------------------------------+// Copyright (c) 2002-2006 Camilla Berglund+//+// This software is provided 'as-is', without any express or implied+// warranty. In no event will the authors be held liable for any damages+// arising from the use of this software.+//+// Permission is granted to anyone to use this software for any purpose,+// including commercial applications, and to alter it and redistribute it+// freely, subject to the following restrictions:+//+// 1. The origin of this software must not be misrepresented; you must not+//    claim that you wrote the original software. If you use this software+//    in a product, an acknowledgment in the product documentation would+//    be appreciated but is not required.+//+// 2. Altered source versions must be plainly marked as such, and must not+//    be misrepresented as being the original software.+//+// 3. This notice may not be removed or altered from any source+//    distribution.+//+//========================================================================++#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;+    }++    memset( &_glfwLibrary, 0, sizeof( _glfwLibrary ) );+    memset( &_glfwWin, 0, sizeof( _glfwWin ) );++    // 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;+}+
+ glfw/lib/input.c view
@@ -0,0 +1,280 @@+//========================================================================+// GLFW - An OpenGL framework+// File:        input.c+// Platform:    Any+// API version: 2.7+// WWW:         http://glfw.sourceforge.net+//------------------------------------------------------------------------+// Copyright (c) 2002-2006 Camilla Berglund+//+// This software is provided 'as-is', without any express or implied+// warranty. In no event will the authors be held liable for any damages+// arising from the use of this software.+//+// Permission is granted to anyone to use this software for any purpose,+// including commercial applications, and to alter it and redistribute it+// freely, subject to the following restrictions:+//+// 1. The origin of this software must not be misrepresented; you must not+//    claim that you wrote the original software. If you use this software+//    in a product, an acknowledgment in the product documentation would+//    be appreciated but is not required.+//+// 2. Altered source versions must be plainly marked as such, and must not+//    be misrepresented as being the original software.+//+// 3. This notice may not be removed or altered from any source+//    distribution.+//+//========================================================================++#include "internal.h"+++//========================================================================+// 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 );+    }+}+
+ glfw/lib/joystick.c view
@@ -0,0 +1,102 @@+//========================================================================+// GLFW - An OpenGL framework+// File:        joystick.c+// Platform:    Any+// API version: 2.7+// WWW:         http://glfw.sourceforge.net+//------------------------------------------------------------------------+// Copyright (c) 2002-2006 Camilla Berglund+//+// This software is provided 'as-is', without any express or implied+// warranty. In no event will the authors be held liable for any damages+// arising from the use of this software.+//+// Permission is granted to anyone to use this software for any purpose,+// including commercial applications, and to alter it and redistribute it+// freely, subject to the following restrictions:+//+// 1. The origin of this software must not be misrepresented; you must not+//    claim that you wrote the original software. If you use this software+//    in a product, an acknowledgment in the product documentation would+//    be appreciated but is not required.+//+// 2. Altered source versions must be plainly marked as such, and must not+//    be misrepresented as being the original software.+//+// 3. This notice may not be removed or altered from any source+//    distribution.+//+//========================================================================++#include "internal.h"+++//************************************************************************+//****                    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 );+}+
+ glfw/lib/stream.c view
@@ -0,0 +1,194 @@+//========================================================================+// GLFW - An OpenGL framework+// File:        stream.c+// Platform:    Any+// API version: 2.7+// WWW:         http://glfw.sourceforge.net+//------------------------------------------------------------------------+// Copyright (c) 2002-2006 Camilla Berglund+//+// This software is provided 'as-is', without any express or implied+// warranty. In no event will the authors be held liable for any damages+// arising from the use of this software.+//+// Permission is granted to anyone to use this software for any purpose,+// including commercial applications, and to alter it and redistribute it+// freely, subject to the following restrictions:+//+// 1. The origin of this software must not be misrepresented; you must not+//    claim that you wrote the original software. If you use this software+//    in a product, an acknowledgment in the product documentation would+//    be appreciated but is not required.+//+// 2. Altered source versions must be plainly marked as such, and must not+//    be misrepresented as being the original software.+//+// 3. This notice may not be removed or altered from any source+//    distribution.+//+//========================================================================+++#include "internal.h"+++//========================================================================+// 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) );+}+
+ glfw/lib/tga.c view
@@ -0,0 +1,405 @@+//========================================================================+// GLFW - An OpenGL framework+// File:        tga.c+// Platform:    Any+// API version: 2.7+// WWW:         http://glfw.sourceforge.net+//------------------------------------------------------------------------+// Copyright (c) 2002-2006 Camilla Berglund+//+// This software is provided 'as-is', without any express or implied+// warranty. In no event will the authors be held liable for any damages+// arising from the use of this software.+//+// Permission is granted to anyone to use this software for any purpose,+// including commercial applications, and to alter it and redistribute it+// freely, subject to the following restrictions:+//+// 1. The origin of this software must not be misrepresented; you must not+//    claim that you wrote the original software. If you use this software+//    in a product, an acknowledgment in the product documentation would+//    be appreciated but is not required.+//+// 2. Altered source versions must be plainly marked as such, and must not+//    be misrepresented as being the original software.+//+// 3. This notice may not be removed or altered from any source+//    distribution.+//+//========================================================================++//========================================================================+// 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 ReadTGAHeader( _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;+    }+}++//========================================================================+// Read Run-Length Encoded data+//========================================================================++static void ReadTGA_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( !ReadTGAHeader( 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 )+    {+        ReadTGA_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;+}+
+ glfw/lib/thread.c view
@@ -0,0 +1,340 @@+//========================================================================+// GLFW - An OpenGL framework+// File:        thread.c+// Platform:    Any+// API version: 2.7+// WWW:         http://glfw.sourceforge.net+//------------------------------------------------------------------------+// Copyright (c) 2002-2006 Camilla Berglund+//+// This software is provided 'as-is', without any express or implied+// warranty. In no event will the authors be held liable for any damages+// arising from the use of this software.+//+// Permission is granted to anyone to use this software for any purpose,+// including commercial applications, and to alter it and redistribute it+// freely, subject to the following restrictions:+//+// 1. The origin of this software must not be misrepresented; you must not+//    claim that you wrote the original software. If you use this software+//    in a product, an acknowledgment in the product documentation would+//    be appreciated but is not required.+//+// 2. Altered source versions must be plainly marked as such, and must not+//    be misrepresented as being the original software.+//+// 3. This notice may not be removed or altered from any source+//    distribution.+//+//========================================================================++#include "internal.h"++++//************************************************************************+//****                  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();+}
+ glfw/lib/time.c view
@@ -0,0 +1,83 @@+//========================================================================+// GLFW - An OpenGL framework+// File:        time.c+// Platform:    Any+// API version: 2.7+// WWW:         http://glfw.sourceforge.net+//------------------------------------------------------------------------+// Copyright (c) 2002-2006 Camilla Berglund+//+// This software is provided 'as-is', without any express or implied+// warranty. In no event will the authors be held liable for any damages+// arising from the use of this software.+//+// Permission is granted to anyone to use this software for any purpose,+// including commercial applications, and to alter it and redistribute it+// freely, subject to the following restrictions:+//+// 1. The origin of this software must not be misrepresented; you must not+//    claim that you wrote the original software. If you use this software+//    in a product, an acknowledgment in the product documentation would+//    be appreciated but is not required.+//+// 2. Altered source versions must be plainly marked as such, and must not+//    be misrepresented as being the original software.+//+// 3. This notice may not be removed or altered from any source+//    distribution.+//+//========================================================================++#include "internal.h"+++//************************************************************************+//****                    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 );+}
+ glfw/lib/win32/win32_dllmain.c view
@@ -0,0 +1,60 @@+//========================================================================+// GLFW - An OpenGL framework+// File:        win32_dllmain.c+// Platform:    Windows+// API version: 2.7+// WWW:         http://glfw.sourceforge.net+//------------------------------------------------------------------------+// Copyright (c) 2002-2006 Camilla Berglund+//+// This software is provided 'as-is', without any express or implied+// warranty. In no event will the authors be held liable for any damages+// arising from the use of this software.+//+// Permission is granted to anyone to use this software for any purpose,+// including commercial applications, and to alter it and redistribute it+// freely, subject to the following restrictions:+//+// 1. The origin of this software must not be misrepresented; you must not+//    claim that you wrote the original software. If you use this software+//    in a product, an acknowledgment in the product documentation would+//    be appreciated but is not required.+//+// 2. Altered source versions must be plainly marked as such, and must not+//    be misrepresented as being the original software.+//+// 3. This notice may not be removed or altered from any source+//    distribution.+//+//========================================================================++#include "internal.h"+++#if defined(GLFW_BUILD_DLL)++//========================================================================+// GLFW DLL entry point+//========================================================================++BOOL WINAPI DllMain( HINSTANCE instance, DWORD reason, LPVOID reserved )+{+    // NOTE: Some compilers complains about instance and x never being used -+    // never mind that (we don't want to use them)!++    switch( reason )+    {+        case DLL_PROCESS_ATTACH:+            // Initializations+            break;+        case DLL_PROCESS_DETACH:+            // Do some cleanup+            glfwTerminate();+            break;+    };++    return TRUE;+}++#endif // GLFW_BUILD_DLL+
+ glfw/lib/win32/win32_enable.c view
@@ -0,0 +1,155 @@+//========================================================================+// GLFW - An OpenGL framework+// File:        win32_enable.c+// Platform:    Windows+// API version: 2.7+// WWW:         http://glfw.sourceforge.net+//------------------------------------------------------------------------+// Copyright (c) 2002-2006 Camilla Berglund+//+// This software is provided 'as-is', without any express or implied+// warranty. In no event will the authors be held liable for any damages+// arising from the use of this software.+//+// Permission is granted to anyone to use this software for any purpose,+// including commercial applications, and to alter it and redistribute it+// freely, subject to the following restrictions:+//+// 1. The origin of this software must not be misrepresented; you must not+//    claim that you wrote the original software. If you use this software+//    in a product, an acknowledgment in the product documentation would+//    be appreciated but is not required.+//+// 2. Altered source versions must be plainly marked as such, and must not+//    be misrepresented as being the original software.+//+// 3. This notice may not be removed or altered from any source+//    distribution.+//+//========================================================================++#include "internal.h"+++//************************************************************************+//****                  GLFW internal functions                       ****+//************************************************************************++//========================================================================+// Low level keyboard hook (system callback) function+// Used to disable system keys under Windows NT+//========================================================================++static LRESULT CALLBACK keyboardHook( int nCode, WPARAM wParam, LPARAM lParam )+{+    BOOL syskeys = FALSE;+    PKBDLLHOOKSTRUCT p;++    // We are only looking for keyboard events - interpret lParam as a+    // pointer to a KBDLLHOOKSTRUCT+    p = (PKBDLLHOOKSTRUCT) lParam;++    if( nCode == HC_ACTION )+    {+        // We have a keyboard event++        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.window, (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                ****+//************************************************************************++//========================================================================+// Enable system keys+//========================================================================++void _glfwPlatformEnableSystemKeys( void )+{+    BOOL dummy;++    // 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, &dummy, 0 );+    }+}++//========================================================================+// Disable system keys+//========================================================================++void _glfwPlatformDisableSystemKeys( void )+{+    BOOL dummy;++    // 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,+                                                  keyboardHook,+                                                  _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, &dummy, 0 );+    }+}+
+ glfw/lib/win32/win32_fullscreen.c view
@@ -0,0 +1,320 @@+//========================================================================+// GLFW - An OpenGL framework+// File:        win32_fullscreen.c+// Platform:    Windows+// API version: 2.7+// WWW:         http://glfw.sourceforge.net+//------------------------------------------------------------------------+// Copyright (c) 2002-2006 Camilla Berglund+//+// This software is provided 'as-is', without any express or implied+// warranty. In no event will the authors be held liable for any damages+// arising from the use of this software.+//+// Permission is granted to anyone to use this software for any purpose,+// including commercial applications, and to alter it and redistribute it+// freely, subject to the following restrictions:+//+// 1. The origin of this software must not be misrepresented; you must not+//    claim that you wrote the original software. If you use this software+//    in a product, an acknowledgment in the product documentation would+//    be appreciated but is not required.+//+// 2. Altered source versions must be plainly marked as such, and must not+//    be misrepresented as being the original software.+//+// 3. This notice may not be removed or altered from any source+//    distribution.+//+//========================================================================++#include "internal.h"+++//************************************************************************+//****                  GLFW internal functions                       ****+//************************************************************************++//========================================================================+// Convert BPP to RGB bits based on "best guess"+//========================================================================++static void bpp2rgb( int bpp, int *r, int *g, int *b )+{+    int delta;++    // We assume that by 32 they really meant 24+    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;+    }+}+++//========================================================================+// Return closest video mode by dimensions, refresh rate and bits per pixel+//========================================================================++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;+}+++//========================================================================+// Return closest video mode by dimensions, refresh rate and channel sizes+//========================================================================++static int getClosestVideoMode( 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+    bpp2rgb( 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 = getClosestVideoMode( 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)+            bpp2rgb( 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;+}+++//========================================================================+// 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;+    bpp2rgb( dm.dmBitsPerPel, &mode->RedBits, &mode->GreenBits, &mode->BlueBits );+}+
+ glfw/lib/win32/win32_glext.c view
@@ -0,0 +1,82 @@+//========================================================================+// GLFW - An OpenGL framework+// File:        win32_glext.c+// Platform:    Windows+// API version: 2.7+// WWW:         http://glfw.sourceforge.net+//------------------------------------------------------------------------+// Copyright (c) 2002-2006 Camilla Berglund+//+// This software is provided 'as-is', without any express or implied+// warranty. In no event will the authors be held liable for any damages+// arising from the use of this software.+//+// Permission is granted to anyone to use this software for any purpose,+// including commercial applications, and to alter it and redistribute it+// freely, subject to the following restrictions:+//+// 1. The origin of this software must not be misrepresented; you must not+//    claim that you wrote the original software. If you use this software+//    in a product, an acknowledgment in the product documentation would+//    be appreciated but is not required.+//+// 2. Altered source versions must be plainly marked as such, and must not+//    be misrepresented as being the original software.+//+// 3. This notice may not be removed or altered from any source+//    distribution.+//+//========================================================================++#include "internal.h"+++//************************************************************************+//****               Platform implementation functions                ****+//************************************************************************++//========================================================================+// Check if the current context supports the specified WGL extension+//========================================================================++int _glfwPlatformExtensionSupported( const char *extension )+{+    const GLubyte *extensions;++    if( _glfwWin.GetExtensionsStringEXT != NULL )+    {+        extensions = (GLubyte *) _glfwWin.GetExtensionsStringEXT();+        if( extensions != NULL )+        {+            if( _glfwStringInExtensionString( extension, extensions ) )+            {+                return GL_TRUE;+            }+        }+    }++    if( _glfwWin.GetExtensionsStringARB != NULL )+    {+        extensions = (GLubyte *) _glfwWin.GetExtensionsStringARB( _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 );+}+
+ glfw/lib/win32/win32_init.c view
@@ -0,0 +1,356 @@+//========================================================================+// GLFW - An OpenGL framework+// File:        win32_init.c+// Platform:    Windows+// API version: 2.7+// WWW:         http://glfw.sourceforge.net+//------------------------------------------------------------------------+// Copyright (c) 2002-2006 Camilla Berglund+//+// This software is provided 'as-is', without any express or implied+// warranty. In no event will the authors be held liable for any damages+// arising from the use of this software.+//+// Permission is granted to anyone to use this software for any purpose,+// including commercial applications, and to alter it and redistribute it+// freely, subject to the following restrictions:+//+// 1. The origin of this software must not be misrepresented; you must not+//    claim that you wrote the original software. If you use this software+//    in a product, an acknowledgment in the product documentation would+//    be appreciated but is not required.+//+// 2. Altered source versions must be plainly marked as such, and must not+//    be misrepresented as being the original software.+//+// 3. This notice may not be removed or altered from any source+//    distribution.+//+//========================================================================++#include "internal.h"++// 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;+}+
+ glfw/lib/win32/win32_joystick.c view
@@ -0,0 +1,234 @@+//========================================================================+// GLFW - An OpenGL framework+// File:        win32_joystick.c+// Platform:    Windows+// API version: 2.7+// WWW:         http://glfw.sourceforge.net+//------------------------------------------------------------------------+// Copyright (c) 2002-2006 Camilla Berglund+//+// This software is provided 'as-is', without any express or implied+// warranty. In no event will the authors be held liable for any damages+// arising from the use of this software.+//+// Permission is granted to anyone to use this software for any purpose,+// including commercial applications, and to alter it and redistribute it+// freely, subject to the following restrictions:+//+// 1. The origin of this software must not be misrepresented; you must not+//    claim that you wrote the original software. If you use this software+//    in a product, an acknowledgment in the product documentation would+//    be appreciated but is not required.+//+// 2. Altered source versions must be plainly marked as such, and must not+//    be misrepresented as being the original software.+//+// 3. This notice may not be removed or altered from any source+//    distribution.+//+//========================================================================++#include "internal.h"+++//************************************************************************+//****                  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;+}+
+ glfw/lib/win32/win32_thread.c view
@@ -0,0 +1,511 @@+//========================================================================+// GLFW - An OpenGL framework+// File:        win32_thread.c+// Platform:    Windows+// API version: 2.7+// WWW:         http://glfw.sourceforge.net+//------------------------------------------------------------------------+// Copyright (c) 2002-2006 Camilla Berglund+//+// This software is provided 'as-is', without any express or implied+// warranty. In no event will the authors be held liable for any damages+// arising from the use of this software.+//+// Permission is granted to anyone to use this software for any purpose,+// including commercial applications, and to alter it and redistribute it+// freely, subject to the following restrictions:+//+// 1. The origin of this software must not be misrepresented; you must not+//    claim that you wrote the original software. If you use this software+//    in a product, an acknowledgment in the product documentation would+//    be appreciated but is not required.+//+// 2. Altered source versions must be plainly marked as such, and must not+//    be misrepresented as being the original software.+//+// 3. This notice may not be removed or altered from any source+//    distribution.+//+//========================================================================++#include "internal.h"+++//************************************************************************+// 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;+}
+ glfw/lib/win32/win32_time.c view
@@ -0,0 +1,146 @@+//========================================================================+// GLFW - An OpenGL framework+// File:        win32_time.c+// Platform:    Windows+// API version: 2.7+// WWW:         http://glfw.sourceforge.net+//------------------------------------------------------------------------+// Copyright (c) 2002-2006 Camilla Berglund+//+// This software is provided 'as-is', without any express or implied+// warranty. In no event will the authors be held liable for any damages+// arising from the use of this software.+//+// Permission is granted to anyone to use this software for any purpose,+// including commercial applications, and to alter it and redistribute it+// freely, subject to the following restrictions:+//+// 1. The origin of this software must not be misrepresented; you must not+//    claim that you wrote the original software. If you use this software+//    in a product, an acknowledgment in the product documentation would+//    be appreciated but is not required.+//+// 2. Altered source versions must be plainly marked as such, and must not+//    be misrepresented as being the original software.+//+// 3. This notice may not be removed or altered from any source+//    distribution.+//+//========================================================================++#include "internal.h"+++//************************************************************************+//****                  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 );+}+
+ glfw/lib/win32/win32_window.c view
@@ -0,0 +1,1822 @@+//========================================================================+// GLFW - An OpenGL framework+// File:        win32_window.c+// Platform:    Windows+// API version: 2.7+// WWW:         http://glfw.sourceforge.net+//------------------------------------------------------------------------+// Copyright (c) 2002-2006 Camilla Berglund+//+// This software is provided 'as-is', without any express or implied+// warranty. In no event will the authors be held liable for any damages+// arising from the use of this software.+//+// Permission is granted to anyone to use this software for any purpose,+// including commercial applications, and to alter it and redistribute it+// freely, subject to the following restrictions:+//+// 1. The origin of this software must not be misrepresented; you must not+//    claim that you wrote the original software. If you use this software+//    in a product, an acknowledgment in the product documentation would+//    be appreciated but is not required.+//+// 2. Altered source versions must be plainly marked as such, and must not+//    be misrepresented as being the original software.+//+// 3. This notice may not be removed or altered from any source+//    distribution.+//+//========================================================================++#include "internal.h"++++//************************************************************************+//****                  GLFW internal functions                       ****+//************************************************************************++// We use versioned window class names in order not to cause conflicts+// between applications using different versions of GLFW+#define _GLFW_WNDCLASSNAME "GLFW27"+++//========================================================================+// Enable/disable minimize/restore animations+//========================================================================++static int setMinMaxAnimations( 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;+}+++//========================================================================+// Focus the window and bring it to the top of the 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+//========================================================================++static void setForegroundWindow( 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 = setMinMaxAnimations( 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) setMinMaxAnimations( 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 );+}+++//========================================================================+// Returns the specified attribute of the specified pixel format+// NOTE: Do not call this unless we have found WGL_ARB_pixel_format+//========================================================================++static int getPixelFormatAttrib(int pixelFormat, int attrib)+{+    int value = 0;++    if( !_glfwWin.GetPixelFormatAttribivARB( _glfwWin.DC, pixelFormat, 0, 1, &attrib, &value) )+    {+        // NOTE: We should probably handle this error somehow+        return 0;+    }++    return value;+}+++//========================================================================+// Return a list of available and usable framebuffer configs+//========================================================================++static _GLFWfbconfig *getFBConfigs( unsigned int *found )+{+    _GLFWfbconfig *result;+    PIXELFORMATDESCRIPTOR pfd;+    int i, count;++    *found = 0;++    if( _glfwWin.has_WGL_ARB_pixel_format )+    {+        count = getPixelFormatAttrib( 1, WGL_NUMBER_PIXEL_FORMATS_ARB );+    }+    else+    {+        count = _glfw_DescribePixelFormat( _glfwWin.DC, 1, sizeof( PIXELFORMATDESCRIPTOR ), NULL );+    }++    if( !count )+    {+        fprintf( stderr, "No Win32 pixel formats available\n" );+        return NULL;+    }++    result = (_GLFWfbconfig*) malloc( sizeof( _GLFWfbconfig ) * count );+    if( !result )+    {+        fprintf(stderr, "Out of memory");+        return NULL;+    }++    for( i = 1;  i <= count;  i++ )+    {+        if( _glfwWin.has_WGL_ARB_pixel_format )+        {+            // Get pixel format attributes through WGL_ARB_pixel_format++            if( !getPixelFormatAttrib( i, WGL_SUPPORT_OPENGL_ARB ) ||+                !getPixelFormatAttrib( i, WGL_DRAW_TO_WINDOW_ARB ) ||+                !getPixelFormatAttrib( i, WGL_DOUBLE_BUFFER_ARB ) )+            {+                // Only consider doublebuffered OpenGL pixel formats for windows+                continue;+            }++            if( getPixelFormatAttrib( i, WGL_PIXEL_TYPE_ARB ) != WGL_TYPE_RGBA_ARB )+            {+                // Only consider RGBA pixel formats+                continue;+            }++            result[*found].redBits = getPixelFormatAttrib( i, WGL_RED_BITS_ARB );+            result[*found].greenBits = getPixelFormatAttrib( i, WGL_GREEN_BITS_ARB );+            result[*found].blueBits = getPixelFormatAttrib( i, WGL_BLUE_BITS_ARB );+            result[*found].alphaBits = getPixelFormatAttrib( i, WGL_ALPHA_BITS_ARB );++            result[*found].depthBits = getPixelFormatAttrib( i, WGL_DEPTH_BITS_ARB );+            result[*found].stencilBits = getPixelFormatAttrib( i, WGL_STENCIL_BITS_ARB );++            result[*found].accumRedBits = getPixelFormatAttrib( i, WGL_ACCUM_RED_BITS_ARB );+            result[*found].accumGreenBits = getPixelFormatAttrib( i, WGL_ACCUM_GREEN_BITS_ARB );+            result[*found].accumBlueBits = getPixelFormatAttrib( i, WGL_ACCUM_BLUE_BITS_ARB );+            result[*found].accumAlphaBits = getPixelFormatAttrib( i, WGL_ACCUM_ALPHA_BITS_ARB );++            result[*found].auxBuffers = getPixelFormatAttrib( i, WGL_AUX_BUFFERS_ARB );+            result[*found].stereo = getPixelFormatAttrib( i, WGL_STEREO_ARB );++            if( _glfwWin.has_WGL_ARB_multisample )+            {+                result[*found].samples = getPixelFormatAttrib( i, WGL_SAMPLES_ARB );+            }+            else+            {+                result[*found].samples = 0;+            }+        }+        else+        {+            // Get pixel format attributes through old-fashioned PFDs++            if( !_glfw_DescribePixelFormat( _glfwWin.DC, i, sizeof( PIXELFORMATDESCRIPTOR ), &pfd ) )+            {+                continue;+            }++            if( !( pfd.dwFlags & PFD_DRAW_TO_WINDOW ) ||+                !( pfd.dwFlags & PFD_SUPPORT_OPENGL ) ||+                !( pfd.dwFlags & PFD_DOUBLEBUFFER ) )+            {+                // Only consider doublebuffered OpenGL pixel formats for windows+                continue;+            }++            if( !( pfd.dwFlags & PFD_GENERIC_ACCELERATED ) &&+                ( pfd.dwFlags & PFD_GENERIC_FORMAT ) )+            {+                continue;+            }++            if( pfd.iPixelType != PFD_TYPE_RGBA )+            {+                // Only RGBA pixel formats considered+                continue;+            }++            result[*found].redBits = pfd.cRedBits;+            result[*found].greenBits = pfd.cGreenBits;+            result[*found].blueBits = pfd.cBlueBits;+            result[*found].alphaBits = pfd.cAlphaBits;++            result[*found].depthBits = pfd.cDepthBits;+            result[*found].stencilBits = pfd.cStencilBits;++            result[*found].accumRedBits = pfd.cAccumRedBits;+            result[*found].accumGreenBits = pfd.cAccumGreenBits;+            result[*found].accumBlueBits = pfd.cAccumBlueBits;+            result[*found].accumAlphaBits = pfd.cAccumAlphaBits;++            result[*found].auxBuffers = pfd.cAuxBuffers;+            result[*found].stereo = ( pfd.dwFlags & PFD_STEREO ) ? GL_TRUE : GL_FALSE;++            // PFD pixel formats do not support FSAA+            result[*found].samples = 0;+        }++        result[*found].platformID = i;++        (*found)++;+    }++    return result;+}+++//========================================================================+// Creates an OpenGL context on the specified device context+//========================================================================++static HGLRC createContext( HDC dc, const _GLFWwndconfig* wndconfig, int pixelFormat )+{+    PIXELFORMATDESCRIPTOR pfd;+    int flags, i = 0, attribs[7];++    if( !_glfw_DescribePixelFormat( dc, pixelFormat, sizeof(pfd), &pfd ) )+    {+        return NULL;+    }++    if( !_glfw_SetPixelFormat( dc, pixelFormat, &pfd ) )+    {+        return NULL;+    }++    if( _glfwWin.has_WGL_ARB_create_context )+    {+        // Use the newer wglCreateContextAttribsARB++        if( wndconfig->glMajor != 0 || wndconfig->glMinor != 0 )+        {+            // Request an explicitly versioned context++            attribs[i++] = WGL_CONTEXT_MAJOR_VERSION_ARB;+            attribs[i++] = wndconfig->glMajor;+            attribs[i++] = WGL_CONTEXT_MINOR_VERSION_ARB;+            attribs[i++] = wndconfig->glMinor;+        }++        if( wndconfig->glForward || wndconfig->glDebug )+        {+            flags = 0;++            if( wndconfig->glForward )+            {+                flags |= WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB;+            }++            if( wndconfig->glDebug )+            {+                flags |= WGL_CONTEXT_DEBUG_BIT_ARB;+            }++            attribs[i++] = WGL_CONTEXT_FLAGS_ARB;+            attribs[i++] = flags;+        }++        if( wndconfig->glProfile )+        {+            if( wndconfig->glProfile == GLFW_OPENGL_CORE_PROFILE )+            {+                flags = WGL_CONTEXT_CORE_PROFILE_BIT_ARB;+            }+            else+            {+                flags = WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB;+            }++            attribs[i++] = WGL_CONTEXT_PROFILE_MASK_ARB;+            attribs[i++] = flags;+        }++        attribs[i++] = 0;++        return _glfwWin.CreateContextAttribsARB( dc, NULL, attribs );+    }++    return wglCreateContext( dc );+}+++//========================================================================+// Translates a Windows key to the corresponding GLFW key+//========================================================================++static int translateKey( WPARAM wParam, LPARAM lParam )+{+    MSG next_msg;+    DWORD msg_time;+    DWORD scan_code;++    // Check for numeric keypad keys+    // Note: This way we always force "NumLock = ON", which at least+    // enables GLFW users to detect numeric keypad keys+    int hiFlags = HIWORD( lParam );++    if ( !( hiFlags & 0x100 ) )+    {+        switch( MapVirtualKey( hiFlags & 0xFF, 1 ) )+        {+            case VK_INSERT:   return GLFW_KEY_KP_0;+            case VK_END:      return GLFW_KEY_KP_1;+            case VK_DOWN:     return GLFW_KEY_KP_2;+            case VK_NEXT:     return GLFW_KEY_KP_3;+            case VK_LEFT:     return GLFW_KEY_KP_4;+            case VK_CLEAR:    return GLFW_KEY_KP_5;+            case VK_RIGHT:    return GLFW_KEY_KP_6;+            case VK_HOME:     return GLFW_KEY_KP_7;+            case VK_UP:       return GLFW_KEY_KP_8;+            case VK_PRIOR:    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_DELETE:   return GLFW_KEY_KP_DECIMAL;+        }+    }++    // 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;+        case VK_NUMLOCK:       return GLFW_KEY_KP_NUM_LOCK;++        case VK_CAPITAL:       return GLFW_KEY_CAPS_LOCK;+        case VK_SCROLL:        return GLFW_KEY_SCROLL_LOCK;+        case VK_PAUSE:         return GLFW_KEY_PAUSE;++        case VK_LWIN:          return GLFW_KEY_LSUPER;+        case VK_RWIN:          return GLFW_KEY_RSUPER;+        case VK_APPS:          return GLFW_KEY_MENU;++        // 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 translateChar( 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;++    GetKeyboardState( keyboard_state );++    // Derive scan code from lParam and action+    scan_code = (lParam & 0x01ff0000) >> 16;+    if( action == GLFW_RELEASE )+    {+        scan_code |= 0x8000000;+    }++    if( _glfwLibrary.Sys.hasUnicode )+    {+        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 windowProc( HWND hWnd, UINT uMsg,+                                    WPARAM wParam, LPARAM lParam )+{+    int wheelDelta, iconified;++    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.window );+                        iconified = GL_TRUE;+                    }++                    // Restore the original desktop resolution+                    ChangeDisplaySettings( NULL, CDS_FULLSCREEN );+                }++                // Unlock mouse if locked+                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.window );+                        iconified = GL_FALSE;++                        // Activate window+                        ShowWindow( hWnd, SW_SHOW );+                        setForegroundWindow( _glfwWin.window );+                        SetFocus( _glfwWin.window );+                    }+                }++                // Lock mouse, if necessary+                if( _glfwWin.oldMouseLockValid && _glfwWin.oldMouseLock )+                {+                    glfwDisable( GLFW_MOUSE_CURSOR );+                }+                _glfwWin.oldMouseLockValid = GL_FALSE;+            }++            _glfwWin.iconified = iconified;+            return 0;+        }++        case WM_SYSCOMMAND:+        {+            switch( wParam & 0xfff0 )+            {+                case SC_SCREENSAVE:+                case SC_MONITORPOWER:+                {+                    if( _glfwWin.fullscreen )+                    {+                        // Disallow screen saver and screen blanking if we are+                        // running in fullscreen mode+                        return 0;+                    }+                    else+                    {+                        break;+                    }+                }++                // User trying to access application menu using ALT?+                case SC_KEYMENU:+                    return 0;+            }+            break;+        }++        case WM_CLOSE:+        {+            // Translate this to WM_QUIT so that we can handle all cases in the+            // same place+            PostQuitMessage( 0 );+            return 0;+        }++        case WM_KEYDOWN:+        case WM_SYSKEYDOWN:+        {+            _glfwInputKey( translateKey( wParam, lParam ), GLFW_PRESS );++            if( _glfwWin.charCallback )+            {+                translateChar( (DWORD) wParam, (DWORD) lParam, GLFW_PRESS );+            }+            return 0;+          }++        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+            {+                _glfwInputKey( translateKey( wParam, lParam ), GLFW_RELEASE );+            }++            if( _glfwWin.charCallback )+            {+                translateChar( (DWORD) wParam, (DWORD) lParam, GLFW_RELEASE );+            }++            return 0;+        }++        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;+        }++        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;+        }++        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;++                if( _glfwWin.mousePosCallback )+                {+                    _glfwWin.mousePosCallback( _glfwInput.MousePosX,+                                               _glfwInput.MousePosY );+                }+            }+            return 0;+        }++        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;+        }++        case WM_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.window, &ClipWindowRect ) )+                {+                    ClipCursor( &ClipWindowRect );+                }+            }++            if( _glfwWin.windowSizeCallback )+            {+                _glfwWin.windowSizeCallback( LOWORD(lParam), HIWORD(lParam) );+            }+            return 0;+        }++        case WM_MOVE:+        {+            // If the mouse is locked, update the clipping rect+            if( _glfwWin.mouseLock )+            {+                RECT ClipWindowRect;+                if( GetWindowRect( _glfwWin.window, &ClipWindowRect ) )+                {+                    ClipCursor( &ClipWindowRect );+                }+            }+            return 0;+        }++        // Was the window contents damaged?+        case WM_PAINT:+        {+            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 getFullWindowSize( int clientWidth, int clientHeight,+                               int *fullWidth, int *fullHeight )+{+    RECT rect;++    // Create a window rectangle+    rect.left   = (long)0;+    rect.right  = (long)clientWidth - 1;+    rect.top    = (long)0;+    rect.bottom = (long)clientHeight - 1;++    // Adjust according to window styles+    AdjustWindowRectEx( &rect, _glfwWin.dwStyle, FALSE, _glfwWin.dwExStyle );++    // Calculate width and height of full window+    *fullWidth = rect.right - rect.left + 1;+    *fullHeight = rect.bottom - rect.top + 1;+}+++//========================================================================+// Initialize WGL-specific extensions+// This function is called once before initial context creation, i.e. before+// any WGL extensions could be present.  This is done in order to have both+// extension variable clearing and loading in the same place, hopefully+// decreasing the possibility of forgetting to add one without the other.+//========================================================================++static void initWGLExtensions( void )+{+    // This needs to include every function pointer loaded below+    _glfwWin.SwapIntervalEXT = NULL;+    _glfwWin.GetPixelFormatAttribivARB = NULL;+    _glfwWin.GetExtensionsStringARB = NULL;+    _glfwWin.GetExtensionsStringEXT = NULL;+    _glfwWin.CreateContextAttribsARB = NULL;++    // This needs to include every extension used below except for+    // WGL_ARB_extensions_string and WGL_EXT_extensions_string+    _glfwWin.has_WGL_EXT_swap_control = GL_FALSE;+    _glfwWin.has_WGL_ARB_pixel_format = GL_FALSE;+    _glfwWin.has_WGL_ARB_multisample = GL_FALSE;+    _glfwWin.has_WGL_ARB_create_context = GL_FALSE;++    _glfwWin.GetExtensionsStringEXT = (WGLGETEXTENSIONSSTRINGEXT_T)+        wglGetProcAddress( "wglGetExtensionsStringEXT" );+    if( !_glfwWin.GetExtensionsStringEXT )+    {+        _glfwWin.GetExtensionsStringARB = (WGLGETEXTENSIONSSTRINGARB_T)+            wglGetProcAddress( "wglGetExtensionsStringARB" );+        if( !_glfwWin.GetExtensionsStringARB )+        {+            return;+        }+    }++    if( _glfwPlatformExtensionSupported( "WGL_ARB_multisample" ) )+    {+        _glfwWin.has_WGL_ARB_multisample = GL_TRUE;+    }++    if( _glfwPlatformExtensionSupported( "WGL_ARB_create_context" ) )+    {+        _glfwWin.has_WGL_ARB_create_context = GL_TRUE;+        _glfwWin.CreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC)+            wglGetProcAddress( "wglCreateContextAttribsARB" );+    }++    if( _glfwPlatformExtensionSupported( "WGL_EXT_swap_control" ) )+    {+        _glfwWin.has_WGL_EXT_swap_control = GL_TRUE;+        _glfwWin.SwapIntervalEXT = (WGLSWAPINTERVALEXT_T)+            wglGetProcAddress( "wglSwapIntervalEXT" );+    }++    if( _glfwPlatformExtensionSupported( "WGL_ARB_pixel_format" ) )+    {+        _glfwWin.has_WGL_ARB_pixel_format = GL_TRUE;+        _glfwWin.GetPixelFormatAttribivARB = (WGLGETPIXELFORMATATTRIBIVARB_T)+            wglGetProcAddress( "wglGetPixelFormatAttribivARB" );+    }+}+++//========================================================================+// Registers the GLFW window class+//========================================================================++static ATOM registerWindowClass( void )+{+    WNDCLASS wc;++    // Set window class parameters+    wc.style         = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; // Redraw on...+    wc.lpfnWndProc   = (WNDPROC)windowProc;           // 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 );+    }++    return RegisterClass( &wc );+}+++//========================================================================+// Returns the closest matching pixel format, or zero on error+//========================================================================++static int choosePixelFormat( const _GLFWfbconfig *fbconfig )+{+    unsigned int fbcount;+    int pixelFormat;+    _GLFWfbconfig *fbconfigs;+    const _GLFWfbconfig *closest;++    fbconfigs = getFBConfigs( &fbcount );+    if( !fbconfigs )+    {+        fprintf( stderr, "Failed to find any usable GLFWFBConfigs\n" );+        return 0;+    }++    closest = _glfwChooseFBConfig( fbconfig, fbconfigs, fbcount );+    if( !closest )+    {+        fprintf( stderr, "Failed to select a GLFWFBConfig from the alternatives\n" );+        free( fbconfigs );+        return 0;+    }++    pixelFormat = (int) closest->platformID;++    free( fbconfigs );+    fbconfigs = NULL;+    closest = NULL;++    return pixelFormat;+}+++//========================================================================+// Creates the GLFW window and rendering context+//========================================================================++static int createWindow( const _GLFWwndconfig *wndconfig,+                         const _GLFWfbconfig *fbconfig )+{+    DWORD dwStyle, dwExStyle;+    int pixelFormat, fullWidth, fullHeight;+    RECT wa;+    POINT pos;++    _glfwWin.DC  = NULL;+    _glfwWin.context = NULL;+    _glfwWin.window = NULL;++    // 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/.NET/+)+        /*+        if( _glfwLibrary.Sys.WinVer != _GLFW_WIN_95 &&+            _glfwLibrary.Sys.WinVer != _GLFW_WIN_NT4 &&+            _glfwLibrary.Sys.WinVer != _GLFW_WIN_XP )+        {+            dwStyle |= WS_MINIMIZE;+        }+        */+    }+    else+    {+        dwStyle |= WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX;++        if( !wndconfig->windowNoResize )+        {+            dwStyle |= ( WS_MAXIMIZEBOX | WS_SIZEBOX );+            dwExStyle |= WS_EX_WINDOWEDGE;+        }+    }++    // Remember window styles (used by getFullWindowSize)+    _glfwWin.dwStyle   = dwStyle;+    _glfwWin.dwExStyle = dwExStyle;++    // Adjust window size for frame and title bar+    getFullWindowSize( _glfwWin.width, _glfwWin.height, &fullWidth, &fullHeight );++    // 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 );+    }++    _glfwWin.window = CreateWindowEx( _glfwWin.dwExStyle,    // Extended style+                                      _GLFW_WNDCLASSNAME,    // Class name+                                      "GLFW Window",         // Window title+                                      _glfwWin.dwStyle,      // Defined window style+                                      wa.left, wa.top,       // Window position+                                      fullWidth,             // Decorated window width+                                      fullHeight,            // Decorated window height+                                      NULL,                  // No parent window+                                      NULL,                  // No menu+                                      _glfwLibrary.instance, // Instance+                                      NULL );                // Nothing to WM_CREATE++    if( !_glfwWin.window )+    {+        fprintf( stderr, "Unable to create Win32 window\n" );+        return GL_FALSE;+    }++    _glfwWin.DC = GetDC( _glfwWin.window );+    if( !_glfwWin.DC )+    {+        fprintf( stderr, "Unable to retrieve GLFW window DC\n" );+        return GL_FALSE;+    }++    pixelFormat = choosePixelFormat( fbconfig );+    if( !pixelFormat )+    {+        fprintf( stderr, "Unable to find a usable pixel format\n" );+        return GL_FALSE;+    }++    _glfwWin.context = createContext( _glfwWin.DC, wndconfig, pixelFormat );+    if( !_glfwWin.context )+    {+        fprintf( stderr, "Unable to create OpenGL context\n" );+        return GL_FALSE;+    }++    if( !wglMakeCurrent( _glfwWin.DC, _glfwWin.context ) )+    {+        fprintf( stderr, "Unable to make OpenGL context current\n" );+        return GL_FALSE;+    }++    initWGLExtensions();++    // Initialize mouse position data+    GetCursorPos( &pos );+    ScreenToClient( _glfwWin.window, &pos );+    _glfwInput.OldMouseX = _glfwInput.MousePosX = pos.x;+    _glfwInput.OldMouseY = _glfwInput.MousePosY = pos.y;++    return GL_TRUE;+}+++//========================================================================+// Destroys the GLFW window and rendering context+//========================================================================++static void destroyWindow( void )+{+    if( _glfwWin.context )+    {+        wglMakeCurrent( NULL, NULL );+        wglDeleteContext( _glfwWin.context );+        _glfwWin.context = NULL;+    }++    if( _glfwWin.DC )+    {+        ReleaseDC( _glfwWin.window, _glfwWin.DC );+        _glfwWin.DC = NULL;+    }++    if( _glfwWin.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.window, SW_HIDE );+        }++        DestroyWindow( _glfwWin.window );+        _glfwWin.window = NULL;+    }+}++++//************************************************************************+//****               Platform implementation functions                ****+//************************************************************************++//========================================================================+// Here is where the window is created, and the OpenGL rendering context is+// created+//========================================================================++int _glfwPlatformOpenWindow( int width, int height,+                             const _GLFWwndconfig *wndconfig,+                             const _GLFWfbconfig *fbconfig )+{+    GLboolean recreateContext = GL_FALSE;++    // Clear platform specific GLFW window state+    _glfwWin.classAtom         = 0;+    _glfwWin.oldMouseLockValid = GL_FALSE;++    _glfwWin.desiredRefreshRate = wndconfig->refreshRate;++    _glfwWin.classAtom = registerWindowClass();+    if( !_glfwWin.classAtom )+    {+        fprintf( stderr, "Failed to register GLFW window class\n" );+        _glfwPlatformCloseWindow();+        return GL_FALSE;+    }++    if( _glfwWin.fullscreen )+    {+        _glfwSetVideoMode( &_glfwWin.width, &_glfwWin.height,+                           fbconfig->redBits, fbconfig->greenBits, fbconfig->blueBits,+                           wndconfig->refreshRate );+    }++    initWGLExtensions();++    if( !createWindow( wndconfig, fbconfig ) )+    {+        fprintf( stderr, "Failed to create GLFW window\n" );+        _glfwPlatformCloseWindow();+        return GL_FALSE;+    }++    if( wndconfig->glMajor > 2 )+    {+        if( !_glfwWin.has_WGL_ARB_create_context )+        {+            fprintf( stderr, "OpenGL 3.0+ is not supported\n" );+            _glfwPlatformCloseWindow();+            return GL_FALSE;+        }++        recreateContext = GL_TRUE;+    }++    if( fbconfig->samples > 0 )+    {+        // We want FSAA, but can we get it?+        // FSAA is not a hard constraint, so otherwise we just don't care++        if( _glfwWin.has_WGL_ARB_multisample && _glfwWin.has_WGL_ARB_pixel_format )+        {+            // We appear to have both the FSAA extension and the means to ask for it+            recreateContext = GL_TRUE;+        }+    }++    if( recreateContext )+    {+        // Some window hints require us to re-create the context using WGL+        // extensions retrieved through the current context, as we cannot check+        // for WGL extensions or retrieve WGL entry points before we have a+        // current context (actually until we have implicitly loaded the ICD)++        // Yes, this is strange, and yes, this is the proper way on Win32++        // As Windows only allows you to set the pixel format once for a+        // window, we need to destroy the current window and create a new one+        // to be able to use the new pixel format++        // Technically, it may be possible to keep the old window around if+        // we're just creating an OpenGL 3.0+ context with the same pixel+        // format, but it's not worth the potential compatibility problems++        destroyWindow();++        if( !createWindow( wndconfig, fbconfig ) )+        {+            fprintf( stderr, "Unable to re-create GLFW window\n" );+            _glfwPlatformCloseWindow();+            return GL_FALSE;+        }+    }++    if( _glfwWin.fullscreen )+    {+        // Place the window above all topmost windows+        SetWindowPos( _glfwWin.window, HWND_TOPMOST, 0,0,0,0,+                      SWP_NOMOVE | SWP_NOSIZE );+    }++    setForegroundWindow( _glfwWin.window );+    SetFocus( _glfwWin.window );++    // 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 )+{+    destroyWindow();++    if( _glfwWin.classAtom )+    {+        UnregisterClass( _GLFW_WNDCLASSNAME, _glfwLibrary.instance );+        _glfwWin.classAtom = 0;+    }++    if( _glfwWin.fullscreen )+    {+        // Restore original desktop resolution+        ChangeDisplaySettings( NULL, CDS_FULLSCREEN );+    }+}+++//========================================================================+// Set the window title+//========================================================================++void _glfwPlatformSetWindowTitle( const char *title )+{+    (void) SetWindowText( _glfwWin.window, 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( _glfwWin.fullscreen )+    {+        // Get some info about the current mode++        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+        getFullWindowSize( width, height, &width, &height );+    }++    // Change window size before changing fullscreen mode?+    if( _glfwWin.fullscreen && (width > _glfwWin.width) )+    {+        SetWindowPos( _glfwWin.window, 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 )+    {+        _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.window, HWND_TOP, 0, 0, width, height,+                      SWP_NOOWNERZORDER | SWP_NOMOVE | SWP_NOZORDER );+    }+}+++//========================================================================+// Set the window position+//========================================================================++void _glfwPlatformSetWindowPos( int x, int y )+{+    (void) SetWindowPos( _glfwWin.window, HWND_TOP, x, y, 0, 0,+                         SWP_NOOWNERZORDER | SWP_NOSIZE | SWP_NOZORDER );+}+++//========================================================================+// Window iconification+//========================================================================++void _glfwPlatformIconifyWindow( void )+{+    // Iconify window+    CloseWindow( _glfwWin.window );+    _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.window );++    // Make sure that our window ends up on top of things+    ShowWindow( _glfwWin.window, SW_SHOW );+    setForegroundWindow( _glfwWin.window );+    SetFocus( _glfwWin.window );++    // 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.has_WGL_EXT_swap_control )+    {+        _glfwWin.SwapIntervalEXT( 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.has_WGL_ARB_pixel_format )+    {+        if( getPixelFormatAttrib( pixelFormat, WGL_ACCELERATION_ARB ) !=+            WGL_NO_ACCELERATION_ARB )+        {+            _glfwWin.accelerated = GL_TRUE;+        }+        else+        {+            _glfwWin.accelerated = GL_FALSE;+        }++        _glfwWin.redBits = getPixelFormatAttrib( pixelFormat, WGL_RED_BITS_ARB );+        _glfwWin.greenBits = getPixelFormatAttrib( pixelFormat, WGL_GREEN_BITS_ARB );+        _glfwWin.blueBits = getPixelFormatAttrib( pixelFormat, WGL_BLUE_BITS_ARB );++        _glfwWin.alphaBits = getPixelFormatAttrib( pixelFormat, WGL_ALPHA_BITS_ARB );+        _glfwWin.depthBits = getPixelFormatAttrib( pixelFormat, WGL_DEPTH_BITS_ARB );+        _glfwWin.stencilBits = getPixelFormatAttrib( pixelFormat, WGL_STENCIL_BITS_ARB );++        _glfwWin.accumRedBits = getPixelFormatAttrib( pixelFormat, WGL_ACCUM_RED_BITS_ARB );+        _glfwWin.accumGreenBits = getPixelFormatAttrib( pixelFormat, WGL_ACCUM_GREEN_BITS_ARB );+        _glfwWin.accumBlueBits = getPixelFormatAttrib( pixelFormat, WGL_ACCUM_BLUE_BITS_ARB );+        _glfwWin.accumAlphaBits = getPixelFormatAttrib( pixelFormat, WGL_ACCUM_ALPHA_BITS_ARB );++        _glfwWin.auxBuffers = getPixelFormatAttrib( pixelFormat, WGL_AUX_BUFFERS_ARB );+        _glfwWin.stereo = getPixelFormatAttrib( pixelFormat, WGL_STEREO_ARB ) ? GL_TRUE : GL_FALSE;++        if( _glfwWin.has_WGL_ARB_multisample )+        {+            _glfwWin.samples = getPixelFormatAttrib( pixelFormat, WGL_SAMPLES_ARB );+            // Should we force 1 to 0 here for consistency, or keep 1 for transparency?+        }+        else+        {+            _glfwWin.samples = 0;+        }+    }+    else+    {+        _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) ? GL_TRUE : GL_FALSE;++        // If we don't have WGL_ARB_pixel_format then we can't have created a+        // multisampling context, so it's safe to hardcode zero here+        _glfwWin.samples = 0;+    }++    // 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 )+{+    WaitMessage();++    _glfwPlatformPollEvents();+}+++//========================================================================+// Hide mouse cursor (lock it)+//========================================================================++void _glfwPlatformHideMouseCursor( void )+{+    RECT ClipWindowRect;++    ShowCursor( FALSE );++    // Clip cursor to the window+    if( GetWindowRect( _glfwWin.window, &ClipWindowRect ) )+    {+        ClipCursor( &ClipWindowRect );+    }++    // Capture cursor to user window+    SetCapture( _glfwWin.window );+}+++//========================================================================+// Show mouse cursor (unlock it)+//========================================================================++void _glfwPlatformShowMouseCursor( void )+{+    // Un-capture cursor+    ReleaseCapture();++    // Release the cursor from the window+    ClipCursor( NULL );++    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.window, &pos );++    SetCursorPos( pos.x, pos.y );+}+
+ glfw/lib/window.c view
@@ -0,0 +1,981 @@+//========================================================================+// GLFW - An OpenGL framework+// File:        window.c+// Platform:    Any+// API version: 2.7+// WWW:         http://glfw.sourceforge.net+//------------------------------------------------------------------------+// Copyright (c) 2002-2006 Camilla Berglund+//+// This software is provided 'as-is', without any express or implied+// warranty. In no event will the authors be held liable for any damages+// arising from the use of this software.+//+// Permission is granted to anyone to use this software for any purpose,+// including commercial applications, and to alter it and redistribute it+// freely, subject to the following restrictions:+//+// 1. The origin of this software must not be misrepresented; you must not+//    claim that you wrote the original software. If you use this software+//    in a product, an acknowledgment in the product documentation would+//    be appreciated but is not required.+//+// 2. Altered source versions must be plainly marked as such, and must not+//    be misrepresented as being the original software.+//+// 3. This notice may not be removed or altered from any source+//    distribution.+//+//========================================================================++#include "internal.h"++#include <limits.h>++++//************************************************************************+//****                  GLFW internal functions                       ****+//************************************************************************++static int Max(int a, int b)+{+    return (a > b) ? a : b;+}++//========================================================================+// Clear all open window hints+//========================================================================++void _glfwClearWindowHints( void )+{+    memset( &_glfwLibrary.hints, 0, sizeof( _glfwLibrary.hints ) );+}+++//========================================================================+// 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 );+    }+}+++//========================================================================+// 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;+    }++    if( action != GLFW_PRESS )+    {+        // This intentionally breaks release notifications for Unicode+        // characters, partly to see if anyone cares but mostly because it's+        // a nonsensical concept to begin with+        //+        // It will remain broken either until its removal in the 3.0 API or+        // until someone explains, in a way that makes sense to people outside+        // the US and Scandinavia, what "Unicode character up" actually means+        //+        // If what you want is "physical key up" then you should be using the+        // key functions and/or the key callback, NOT the Unicode input+        //+        // However, if your particular application uses this misfeature for...+        // something, you can re-enable it by removing this if-statement+        return;+    }++    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 );+        }+    }+}+++//========================================================================+// Return the available framebuffer config closest to the desired values+// This is based on the manual GLX Visual selection from 2.6+//========================================================================++const _GLFWfbconfig *_glfwChooseFBConfig( const _GLFWfbconfig *desired,+                                          const _GLFWfbconfig *alternatives,+                                          unsigned int count )+{+    unsigned int i;+    unsigned int missing, leastMissing = UINT_MAX;+    unsigned int colorDiff, leastColorDiff = UINT_MAX;+    unsigned int extraDiff, leastExtraDiff = UINT_MAX;+    GLboolean desiresColor = GL_FALSE;+    const _GLFWfbconfig *current;+    const _GLFWfbconfig *closest = NULL;++    // Cache some long-winded preferences++    if( desired->redBits || desired->greenBits || desired->blueBits ||+        desired->alphaBits )+    {+        desiresColor = GL_TRUE;+    }++    for( i = 0;  i < count;  i++ )+    {+        current = alternatives + i;++        if( desired->stereo > 0 && current->stereo == 0 )+        {+            // Stereo is a hard constraint+            continue;+        }++        // Count number of missing buffers+        {+            missing = 0;++            if( desired->alphaBits > 0 && current->alphaBits == 0 )+            {+                missing++;+            }++            if( desired->depthBits > 0 && current->depthBits == 0 )+            {+                missing++;+            }++            if( desired->stencilBits > 0 && current->stencilBits == 0 )+            {+                missing++;+            }++            if( desired->auxBuffers > 0 && current->auxBuffers < desired->auxBuffers )+            {+                missing += desired->auxBuffers - current->auxBuffers;+            }++            if( desired->samples > 0 && current->samples == 0 )+            {+                // Technically, several multisampling buffers could be+                // involved, but that's a lower level implementation detail and+                // not important to us here, so we count them as one+                missing++;+            }+        }++        // These polynomials make many small channel size differences matter+        // less than one large channel size difference++        // Calculate color channel size difference value+        {+            colorDiff = 0;++            if ( desired->redBits > 0 )+            {+                colorDiff += ( desired->redBits - current->redBits ) *+                             ( desired->redBits - current->redBits );+            }++            if ( desired->greenBits > 0 )+            {+                colorDiff += ( desired->greenBits - current->greenBits ) *+                             ( desired->greenBits - current->greenBits );+            }++            if ( desired->blueBits > 0 )+            {+                colorDiff += ( desired->blueBits - current->blueBits ) *+                             ( desired->blueBits - current->blueBits );+            }+        }++        // Calculate non-color channel size difference value+        {+            extraDiff = 0;++            if( desired->alphaBits > 0 )+            {+                extraDiff += ( desired->alphaBits - current->alphaBits ) *+                             ( desired->alphaBits - current->alphaBits );+            }++            if( desired->depthBits > 0 )+            {+                extraDiff += ( desired->depthBits - current->depthBits ) *+                             ( desired->depthBits - current->depthBits );+            }++            if( desired->stencilBits > 0 )+            {+                extraDiff += ( desired->stencilBits - current->stencilBits ) *+                             ( desired->stencilBits - current->stencilBits );+            }++            if( desired->accumRedBits > 0 )+            {+                extraDiff += ( desired->accumRedBits - current->accumRedBits ) *+                             ( desired->accumRedBits - current->accumRedBits );+            }++            if( desired->accumGreenBits > 0 )+            {+                extraDiff += ( desired->accumGreenBits - current->accumGreenBits ) *+                             ( desired->accumGreenBits - current->accumGreenBits );+            }++            if( desired->accumBlueBits > 0 )+            {+                extraDiff += ( desired->accumBlueBits - current->accumBlueBits ) *+                             ( desired->accumBlueBits - current->accumBlueBits );+            }++            if( desired->accumAlphaBits > 0 )+            {+                extraDiff += ( desired->accumAlphaBits - current->accumAlphaBits ) *+                             ( desired->accumAlphaBits - current->accumAlphaBits );+            }++            if( desired->samples > 0 )+            {+                extraDiff += ( desired->samples - current->samples ) *+                             ( desired->samples - current->samples );+            }+        }++        // Figure out if the current one is better than the best one found so far++        if( missing < leastMissing )+        {+            closest = current;+        }+        else if( missing == leastMissing )+        {+            if( desiresColor )+            {+                if( ( colorDiff < leastColorDiff ) ||+                    ( colorDiff == leastColorDiff && extraDiff < leastExtraDiff ) )+                {+                    closest = current;+                }+            }+            else+            {+                if( ( extraDiff < leastExtraDiff ) ||+                    ( extraDiff == leastExtraDiff && colorDiff < leastColorDiff ) )+                {+                    closest = current;+                }+            }+        }++        if( current == closest )+        {+            leastMissing = missing;+            leastColorDiff = colorDiff;+            leastExtraDiff = extraDiff;+        }+    }++    return closest;+}+++//************************************************************************+//****                    GLFW user functions                         ****+//************************************************************************++//========================================================================+// Create the GLFW window and its associated context+//========================================================================++GLFWAPI int GLFWAPIENTRY glfwOpenWindow( int width, int height,+    int redbits, int greenbits, int bluebits, int alphabits,+    int depthbits, int stencilbits, int mode )+{+    _GLFWfbconfig fbconfig;+    _GLFWwndconfig wndconfig;++    // Is GLFW initialized?+    if( !_glfwInitialized || _glfwWin.opened )+    {+        return GL_FALSE;+    }++    // Set up desired framebuffer config+    fbconfig.redBits        = redbits;+    fbconfig.greenBits      = greenbits;+    fbconfig.blueBits       = bluebits;+    fbconfig.alphaBits      = alphabits;+    fbconfig.depthBits      = depthbits;+    fbconfig.stencilBits    = stencilbits;+    fbconfig.accumRedBits   = _glfwLibrary.hints.accumRedBits;+    fbconfig.accumGreenBits = _glfwLibrary.hints.accumGreenBits;+    fbconfig.accumBlueBits  = _glfwLibrary.hints.accumBlueBits;+    fbconfig.accumAlphaBits = _glfwLibrary.hints.accumAlphaBits;+    fbconfig.auxBuffers     = _glfwLibrary.hints.auxBuffers;+    fbconfig.stereo         = _glfwLibrary.hints.stereo;+    fbconfig.samples        = _glfwLibrary.hints.samples;++    // Set up desired window config+    wndconfig.mode           = mode;+    wndconfig.refreshRate    = _glfwLibrary.hints.refreshRate;+    wndconfig.windowNoResize = _glfwLibrary.hints.windowNoResize;+    wndconfig.glMajor        = _glfwLibrary.hints.glMajor;+    wndconfig.glMinor        = _glfwLibrary.hints.glMinor;+    wndconfig.glForward      = _glfwLibrary.hints.glForward;+    wndconfig.glDebug        = _glfwLibrary.hints.glDebug;+    wndconfig.glProfile      = _glfwLibrary.hints.glProfile;++    // Clear for next open call+    _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 ? GL_TRUE : GL_FALSE);++    // Platform specific window opening routine+    if( !_glfwPlatformOpenWindow( width, height, &wndconfig, &fbconfig ) )+    {+        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+    _glfwParseGLVersion( &_glfwWin.glMajor, &_glfwWin.glMinor,+                         &_glfwWin.glRevision );++    // Do we have non-power-of-two textures?+    _glfwWin.has_GL_ARB_texture_non_power_of_two =+        ( _glfwWin.glMajor >= 2 ) ||+        glfwExtensionSupported( "GL_ARB_texture_non_power_of_two" );++    // Do we have automatic mipmap generation?+    _glfwWin.has_GL_SGIS_generate_mipmap =+        ( _glfwWin.glMajor >= 2 ) || ( _glfwWin.glMinor >= 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;+}+++//========================================================================+// 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:+            _glfwLibrary.hints.refreshRate = Max(hint, 0);+            break;+        case GLFW_ACCUM_RED_BITS:+            _glfwLibrary.hints.accumRedBits = Max(hint, 0);+            break;+        case GLFW_ACCUM_GREEN_BITS:+            _glfwLibrary.hints.accumGreenBits = Max(hint, 0);+            break;+        case GLFW_ACCUM_BLUE_BITS:+            _glfwLibrary.hints.accumBlueBits = Max(hint, 0);+            break;+        case GLFW_ACCUM_ALPHA_BITS:+            _glfwLibrary.hints.accumAlphaBits = Max(hint, 0);+            break;+        case GLFW_AUX_BUFFERS:+            _glfwLibrary.hints.auxBuffers = Max(hint, 0);+            break;+        case GLFW_STEREO:+            _glfwLibrary.hints.stereo = hint ? GL_TRUE : GL_FALSE;+            break;+        case GLFW_WINDOW_NO_RESIZE:+            _glfwLibrary.hints.windowNoResize = hint ? GL_TRUE : GL_FALSE;+            break;+        case GLFW_FSAA_SAMPLES:+            _glfwLibrary.hints.samples = Max(hint, 0);+            break;+        case GLFW_OPENGL_VERSION_MAJOR:+            _glfwLibrary.hints.glMajor = Max(hint, 0);+            break;+        case GLFW_OPENGL_VERSION_MINOR:+            _glfwLibrary.hints.glMinor = Max(hint, 0);+            break;+        case GLFW_OPENGL_FORWARD_COMPAT:+            _glfwLibrary.hints.glForward = hint ? GL_TRUE : GL_FALSE;+            break;+        case GLFW_OPENGL_DEBUG_CONTEXT:+            _glfwLibrary.hints.glDebug = hint ? GL_TRUE : GL_FALSE;+            break;+        case GLFW_OPENGL_PROFILE:+            if( hint == GLFW_OPENGL_CORE_PROFILE ||+                hint == GLFW_OPENGL_COMPAT_PROFILE )+            {+                _glfwLibrary.hints.glProfile = hint;+            }+            else+            {+                _glfwLibrary.hints.glProfile = 0;+            }+        default:+            break;+    }+}+++//========================================================================+// Properly kill the window / video display+//========================================================================++GLFWAPI void GLFWAPIENTRY glfwCloseWindow( void )+{+    if( !_glfwInitialized )+    {+        return;+    }++    // Show mouse pointer again (if hidden)+    glfwEnable( GLFW_MOUSE_CURSOR );++    _glfwPlatformCloseWindow();++    memset( &_glfwWin, 0, sizeof(_glfwWin) );+    _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;+        case GLFW_OPENGL_VERSION_MAJOR:+            return _glfwWin.glMajor;+        case GLFW_OPENGL_VERSION_MINOR:+            return _glfwWin.glMinor;+        case GLFW_OPENGL_FORWARD_COMPAT:+            return _glfwWin.glForward;+        case GLFW_OPENGL_DEBUG_CONTEXT:+            return _glfwWin.glDebug;+        case GLFW_OPENGL_PROFILE:+            return _glfwWin.glProfile;+        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();+}+
+ glfw/lib/x11/x11_enable.c view
@@ -0,0 +1,55 @@+//========================================================================+// GLFW - An OpenGL framework+// File:        x11_enable.c+// Platform:    X11 (Unix)+// API version: 2.7+// WWW:         http://glfw.sourceforge.net+//------------------------------------------------------------------------+// Copyright (c) 2002-2006 Camilla Berglund+//+// This software is provided 'as-is', without any express or implied+// warranty. In no event will the authors be held liable for any damages+// arising from the use of this software.+//+// Permission is granted to anyone to use this software for any purpose,+// including commercial applications, and to alter it and redistribute it+// freely, subject to the following restrictions:+//+// 1. The origin of this software must not be misrepresented; you must not+//    claim that you wrote the original software. If you use this software+//    in a product, an acknowledgment in the product documentation would+//    be appreciated but is not required.+//+// 2. Altered source versions must be plainly marked as such, and must not+//    be misrepresented as being the original software.+//+// 3. This notice may not be removed or altered from any source+//    distribution.+//+//========================================================================++#include "internal.h"+++//************************************************************************+//****               Platform implementation functions                ****+//************************************************************************++//========================================================================+// Enable system keys+//========================================================================++void _glfwPlatformEnableSystemKeys( void )+{+    // Not supported under X11 (yet)+}++//========================================================================+// Disable system keys+//========================================================================++void _glfwPlatformDisableSystemKeys( void )+{+    // Not supported under X11 (yet)+}+
+ glfw/lib/x11/x11_fullscreen.c view
@@ -0,0 +1,528 @@+//========================================================================+// GLFW - An OpenGL framework+// File:        x11_fullscreen.c+// Platform:    X11 (Unix)+// API version: 2.7+// WWW:         http://glfw.sourceforge.net+//------------------------------------------------------------------------+// Copyright (c) 2002-2006 Camilla Berglund+//+// This software is provided 'as-is', without any express or implied+// warranty. In no event will the authors be held liable for any damages+// arising from the use of this software.+//+// Permission is granted to anyone to use this software for any purpose,+// including commercial applications, and to alter it and redistribute it+// freely, subject to the following restrictions:+//+// 1. The origin of this software must not be misrepresented; you must not+//    claim that you wrote the original software. If you use this software+//    in a product, an acknowledgment in the product documentation would+//    be appreciated but is not required.+//+// 2. Altered source versions must be plainly marked as such, and must not+//    be misrepresented as being the original software.+//+// 3. This notice may not be removed or altered from any source+//    distribution.+//+//========================================================================++#include "internal.h"++#include <limits.h>+++//************************************************************************+//****                  GLFW internal functions                       ****+//************************************************************************++//========================================================================+// Convert BPP to RGB bits (based on "best guess")+//========================================================================++static void BPP2RGB( 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.display,+                               RootWindow( _glfwLibrary.display, screen ) );++        sizelist = XRRConfigSizes( sc, &sizecount );++        // Find the best matching mode+        bestsize  = -1;+        bestmatch = INT_MAX;+        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 = INT_MAX;+                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.display, screen,+                                    &modecount, &modelist );++        // Find the best matching mode+        bestmode  = -1;+        bestmatch = INT_MAX;+        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;+            *height = modelist[ bestmode ]->vdisplay;+        }++        // Free modelist+        XFree( modelist );++        if( bestmode != -1 )+        {+            return bestmode;+        }+    }+#endif++    // Default: Simply use the screen resolution+    *width = DisplayWidth( _glfwLibrary.display, screen );+    *height = DisplayHeight( _glfwLibrary.display, 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.display, screen );+        sc   = XRRGetScreenInfo( _glfwLibrary.display, 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.display, screen );+            _glfwWin.FS.oldHeight = DisplayHeight( _glfwLibrary.display, screen );++            _glfwWin.FS.modeChanged = GL_TRUE;+        }++        if( rate > 0 )+        {+            // Set desired configuration+            XRRSetScreenConfigAndRate( _glfwLibrary.display,+                                       sc,+                                       root,+                                       mode,+                                       RR_Rotate_0,+                                       (short) rate,+                                       CurrentTime );+        }+        else+        {+            // Set desired configuration+            XRRSetScreenConfig( _glfwLibrary.display,+                                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.display, screen,+                                    &modecount, &modelist );++        // Unlock mode switch if necessary+        if( _glfwWin.FS.modeChanged )+        {+            XF86VidModeLockModeSwitch( _glfwLibrary.display, screen, 0 );+        }++        // Change the video mode to the desired mode+        XF86VidModeSwitchToMode(  _glfwLibrary.display, screen,+                                  modelist[ mode ] );++        // Set viewport to upper left corner (where our window will be)+        XF86VidModeSetViewPort( _glfwLibrary.display, screen, 0, 0 );++        // Lock mode switch+        XF86VidModeLockModeSwitch( _glfwLibrary.display, 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.display;+    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+            BPP2RGB( 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.display;+    screen = DefaultScreen( dpy );++    // Get display depth+    bpp = DefaultDepth( dpy, screen );++    // Convert BPP to RGB bits+    BPP2RGB( 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 );+}+
+ glfw/lib/x11/x11_glext.c view
@@ -0,0 +1,90 @@+//========================================================================+// GLFW - An OpenGL framework+// File:        x11_glext.c+// Platform:    X11 (Unix)+// API version: 2.7+// WWW:         http://glfw.sourceforge.net+//------------------------------------------------------------------------+// Copyright (c) 2002-2006 Camilla Berglund+//+// This software is provided 'as-is', without any express or implied+// warranty. In no event will the authors be held liable for any damages+// arising from the use of this software.+//+// Permission is granted to anyone to use this software for any purpose,+// including commercial applications, and to alter it and redistribute it+// freely, subject to the following restrictions:+//+// 1. The origin of this software must not be misrepresented; you must not+//    claim that you wrote the original software. If you use this software+//    in a product, an acknowledgment in the product documentation would+//    be appreciated but is not required.+//+// 2. Altered source versions must be plainly marked as such, and must not+//    be misrepresented as being the original software.+//+// 3. This notice may not be removed or altered from any source+//    distribution.+//+//========================================================================++#include "internal.h"+++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+++//************************************************************************+//****               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.display,+                                                            _glfwWin.screen );+    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 );+}+
+ glfw/lib/x11/x11_init.c view
@@ -0,0 +1,286 @@+//========================================================================+// GLFW - An OpenGL framework+// File:        x11_init.c+// Platform:    X11 (Unix)+// API version: 2.7+// WWW:         http://glfw.sourceforge.net+//------------------------------------------------------------------------+// Copyright (c) 2002-2006 Camilla Berglund+//+// This software is provided 'as-is', without any express or implied+// warranty. In no event will the authors be held liable for any damages+// arising from the use of this software.+//+// Permission is granted to anyone to use this software for any purpose,+// including commercial applications, and to alter it and redistribute it+// freely, subject to the following restrictions:+//+// 1. The origin of this software must not be misrepresented; you must not+//    claim that you wrote the original software. If you use this software+//    in a product, an acknowledgment in the product documentation would+//    be appreciated but is not required.+//+// 2. Altered source versions must be plainly marked as such, and must not+//    be misrepresented as being the original software.+//+// 3. This notice may not be removed or altered from any source+//    distribution.+//+//========================================================================++#include "internal.h"++++//************************************************************************+//****                  GLFW internal functions                       ****+//************************************************************************++//========================================================================+// Initialize GLFW thread package+//========================================================================++static void initThreads( 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 terminateThreads( 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+//========================================================================++static void initLibraries( void )+{+#ifdef _GLFW_DLOPEN_LIBGL+    int i;+    char *libGL_names[ ] =+    {+        "libGL.so",+        "libGL.so.1",+        "/usr/lib/libGL.so",+        "/usr/lib/libGL.so.1",+        NULL+    };++    _glfwLibrary.Libs.libGL = NULL;+    for( i = 0; !libGL_names[ i ] != NULL; i ++ )+    {+        _glfwLibrary.Libs.libGL = dlopen( libGL_names[ i ],+                                          RTLD_LAZY | RTLD_GLOBAL );+        if( _glfwLibrary.Libs.libGL )+            break;+    }+#endif+}+++//========================================================================+// Terminate GLFW when exiting application+//========================================================================++static void glfw_atexit( void )+{+    glfwTerminate();+}+++//========================================================================+// Initialize X11 display+//========================================================================++static int initDisplay( void )+{+    // Open display+    _glfwLibrary.display = XOpenDisplay( 0 );+    if( !_glfwLibrary.display )+    {+        fprintf(stderr, "Failed to open X display\n");+        return GL_FALSE;+    }++    // Check for XF86VidMode extension+#ifdef _GLFW_HAS_XF86VIDMODE+    _glfwLibrary.XF86VidMode.available =+        XF86VidModeQueryExtension( _glfwLibrary.display,+                                   &_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.display,+                           &_glfwLibrary.XRandR.eventBase,+                           &_glfwLibrary.XRandR.errorBase );+#else+    _glfwLibrary.XRandR.available = 0;+#endif++    // Fullscreen & screen saver settings+    // Check if GLX is supported on this display+    if( !glXQueryExtension( _glfwLibrary.display, NULL, NULL ) )+    {+        fprintf(stderr, "GLX not supported\n");+        return GL_FALSE;+    }++    // Retrieve GLX version+    if( !glXQueryVersion( _glfwLibrary.display,+                          &_glfwLibrary.glxMajor,+                          &_glfwLibrary.glxMinor ) )+    {+        fprintf(stderr, "Unable to query GLX version\n");+        return GL_FALSE;+    }++    return GL_TRUE;+}+++//========================================================================+// Terminate X11 display+//========================================================================++static void terminateDisplay( void )+{+    // Open display+    if( _glfwLibrary.display )+    {+        XCloseDisplay( _glfwLibrary.display );+        _glfwLibrary.display = NULL;+    }+}+++//************************************************************************+//****               Platform implementation functions                ****+//************************************************************************++//========================================================================+// Initialize various GLFW state+//========================================================================++int _glfwPlatformInit( void )+{+    // Initialize display+    if( !initDisplay() )+    {+        return GL_FALSE;+    }++    // Initialize thread package+    initThreads();++    // Try to load libGL.so if necessary+    initLibraries();++    // Install atexit() routine+    // atexit( glfw_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+    terminateThreads();++    // Terminate display+    terminateDisplay();++    // 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;+}+
+ glfw/lib/x11/x11_joystick.c view
@@ -0,0 +1,367 @@+//========================================================================+// GLFW - An OpenGL framework+// File:        x11_joystick.c+// Platform:    X11 (Unix)+// API version: 2.7+// WWW:         http://glfw.sourceforge.net+//------------------------------------------------------------------------+// Copyright (c) 2002-2006 Camilla Berglund+//+// This software is provided 'as-is', without any express or implied+// warranty. In no event will the authors be held liable for any damages+// arising from the use of this software.+//+// Permission is granted to anyone to use this software for any purpose,+// including commercial applications, and to alter it and redistribute it+// freely, subject to the following restrictions:+//+// 1. The origin of this software must not be misrepresented; you must not+//    claim that you wrote the original software. If you use this software+//    in a product, an acknowledgment in the product documentation would+//    be appreciated but is not required.+//+// 2. Altered source versions must be plainly marked as such, and must not+//    be misrepresented as being the original software.+//+// 3. This notice may not be removed or altered from any source+//    distribution.+//+//========================================================================++#include "internal.h"+++//========================================================================+// Note: Only Linux joystick input is supported at the moment. Other+// systems will behave as if there are no joysticks connected.+//========================================================================+++//************************************************************************+//****                  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 =+                    (unsigned 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++}+++//========================================================================+// Empty joystick event queue+//========================================================================++static void pollJoystickEvents( 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+    pollJoystickEvents();++    // 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+    pollJoystickEvents();++    // 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;+}+
+ glfw/lib/x11/x11_keysym2unicode.c view
@@ -0,0 +1,901 @@+//========================================================================+// GLFW - An OpenGL framework+// File:        x11_keysym2unicode.c+// Platform:    X11 (Unix)+// API version: 2.7+// WWW:         http://glfw.sourceforge.net+//------------------------------------------------------------------------+// Copyright (c) 2002-2006 Camilla Berglund+//+// This software is provided 'as-is', without any express or implied+// warranty. In no event will the authors be held liable for any damages+// arising from the use of this software.+//+// Permission is granted to anyone to use this software for any purpose,+// including commercial applications, and to alter it and redistribute it+// freely, subject to the following restrictions:+//+// 1. The origin of this software must not be misrepresented; you must not+//    claim that you wrote the original software. If you use this software+//    in a product, an acknowledgment in the product documentation would+//    be appreciated but is not required.+//+// 2. Altered source versions must be plainly marked as such, and must not+//    be misrepresented as being the original software.+//+// 3. This notice may not be removed or altered from any source+//    distribution.+//+//========================================================================++#include "internal.h"+++/*+ * 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;+}
+ glfw/lib/x11/x11_thread.c view
@@ -0,0 +1,508 @@+//========================================================================+// GLFW - An OpenGL framework+// File:        x11_thread.c+// Platform:    X11 (Unix)+// API version: 2.7+// WWW:         http://glfw.sourceforge.net+//------------------------------------------------------------------------+// Copyright (c) 2002-2006 Camilla Berglund+//+// This software is provided 'as-is', without any express or implied+// warranty. In no event will the authors be held liable for any damages+// arising from the use of this software.+//+// Permission is granted to anyone to use this software for any purpose,+// including commercial applications, and to alter it and redistribute it+// freely, subject to the following restrictions:+//+// 1. The origin of this software must not be misrepresented; you must not+//    claim that you wrote the original software. If you use this software+//    in a product, an acknowledgment in the product documentation would+//    be appreciated but is not required.+//+// 2. Altered source versions must be plainly marked as such, and must not+//    be misrepresented as being the original software.+//+// 3. This notice may not be removed or altered from any source+//    distribution.+//+//========================================================================++#include "internal.h"++++//************************************************************************+//****                  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;+}+
+ glfw/lib/x11/x11_time.c view
@@ -0,0 +1,154 @@+//========================================================================+// GLFW - An OpenGL framework+// File:        x11_time.c+// Platform:    X11 (Unix)+// API version: 2.7+// WWW:         http://glfw.sourceforge.net+//------------------------------------------------------------------------+// Copyright (c) 2002-2006 Camilla Berglund+//+// This software is provided 'as-is', without any express or implied+// warranty. In no event will the authors be held liable for any damages+// arising from the use of this software.+//+// Permission is granted to anyone to use this software for any purpose,+// including commercial applications, and to alter it and redistribute it+// freely, subject to the following restrictions:+//+// 1. The origin of this software must not be misrepresented; you must not+//    claim that you wrote the original software. If you use this software+//    in a product, an acknowledgment in the product documentation would+//    be appreciated but is not required.+//+// 2. Altered source versions must be plainly marked as such, and must not+//    be misrepresented as being the original software.+//+// 3. This notice may not be removed or altered from any source+//    distribution.+//+//========================================================================++#include "internal.h"+++//========================================================================+// 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+}+
+ glfw/lib/x11/x11_window.c view
@@ -0,0 +1,1993 @@+//========================================================================+// GLFW - An OpenGL framework+// File:        x11_window.c+// Platform:    X11 (Unix)+// API version: 2.7+// WWW:         http://glfw.sourceforge.net+//------------------------------------------------------------------------+// Copyright (c) 2002-2006 Camilla Berglund+//+// This software is provided 'as-is', without any express or implied+// warranty. In no event will the authors be held liable for any damages+// arising from the use of this software.+//+// Permission is granted to anyone to use this software for any purpose,+// including commercial applications, and to alter it and redistribute it+// freely, subject to the following restrictions:+//+// 1. The origin of this software must not be misrepresented; you must not+//    claim that you wrote the original software. If you use this software+//    in a product, an acknowledgment in the product documentation would+//    be appreciated but is not required.+//+// 2. Altered source versions must be plainly marked as such, and must not+//    be misrepresented as being the original software.+//+// 3. This notice may not be removed or altered from any source+//    distribution.+//+//========================================================================++#include "internal.h"+++/* 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+};+++/* Define GLX 1.4 FSAA tokens if not already defined */+#ifndef GLX_VERSION_1_4++#define GLX_SAMPLE_BUFFERS  100000+#define GLX_SAMPLES         100001++#endif /*GLX_VERSION_1_4*/++++//************************************************************************+//****                  GLFW internal functions                       ****+//************************************************************************++//========================================================================+// Checks whether the event is a MapNotify for the specified window+//========================================================================++static Bool isMapNotify( Display *d, XEvent *e, char *arg )+{+    return (e->type == MapNotify) && (e->xmap.window == (Window)arg);+}+++//========================================================================+// Turn off window decorations+// Based on xawdecode: src/wmhooks.c+//========================================================================++#define MWM_HINTS_DECORATIONS (1L << 1)++static void disableDecorations( void )+{+    GLboolean removedDecorations;+    Atom hintAtom;+    XSetWindowAttributes attributes;++    removedDecorations = GL_FALSE;++    // First try to set MWM hints+    hintAtom = XInternAtom( _glfwLibrary.display, "_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.display, _glfwWin.window, hintAtom, hintAtom,+                         32, PropModeReplace, (unsigned char *)&MWMHints,+                         sizeof(MWMHints) / 4 );+        removedDecorations = GL_TRUE;+    }++    // Now try to set KWM hints+    hintAtom = XInternAtom( _glfwLibrary.display, "KWM_WIN_DECORATION", True );+    if ( hintAtom != None )+    {+        long KWMHints = KDE_tinyDecoration;++        XChangeProperty( _glfwLibrary.display, _glfwWin.window, hintAtom, hintAtom,+                         32, PropModeReplace, (unsigned char *)&KWMHints,+                         sizeof(KWMHints) / 4 );+        removedDecorations = GL_TRUE;+    }++    // Now try to set GNOME hints+    hintAtom = XInternAtom( _glfwLibrary.display, "_WIN_HINTS", True );+    if ( hintAtom != None )+    {+        long GNOMEHints = 0;++        XChangeProperty( _glfwLibrary.display, _glfwWin.window, hintAtom, hintAtom,+                         32, PropModeReplace, (unsigned char *)&GNOMEHints,+                         sizeof(GNOMEHints) / 4 );+        removedDecorations = GL_TRUE;+    }++    // Now try to set KDE NET_WM hints+    hintAtom = XInternAtom( _glfwLibrary.display, "_NET_WM_WINDOW_TYPE", True );+    if ( hintAtom != None )+    {+        Atom NET_WMHints[2];++        NET_WMHints[0] = XInternAtom( _glfwLibrary.display,+                                      "_KDE_NET_WM_WINDOW_TYPE_OVERRIDE",+                                      True );+        /* define a fallback... */+        NET_WMHints[1] = XInternAtom( _glfwLibrary.display,+                                      "_NET_WM_WINDOW_TYPE_NORMAL",+                                      True );++        XChangeProperty( _glfwLibrary.display, _glfwWin.window, hintAtom, XA_ATOM,+                         32, PropModeReplace, (unsigned char *)&NET_WMHints,+                         2 );+        removedDecorations = GL_TRUE;+    }++    // Set ICCCM fullscreen WM hint+    hintAtom = XInternAtom( _glfwLibrary.display, "_NET_WM_STATE", True );+    if ( hintAtom != None )+    {+        Atom NET_WMHints[1];++        NET_WMHints[0] = XInternAtom( _glfwLibrary.display,+                                      "_NET_WM_STATE_FULLSCREEN",+                                      True );++        XChangeProperty( _glfwLibrary.display, _glfwWin.window, 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.display,+                              _glfwWin.window,+                              RootWindow( _glfwLibrary.display, _glfwWin.screen) );+        XUnmapWindow( _glfwLibrary.display, _glfwWin.window );+        XMapWindow( _glfwLibrary.display, _glfwWin.window );+    }+    else+    {+        // The Butcher way of removing window decorations+        attributes.override_redirect = True;+        XChangeWindowAttributes( _glfwLibrary.display,+                                 _glfwWin.window,+                                 CWOverrideRedirect,+                                 &attributes );+        _glfwWin.overrideRedirect = GL_TRUE;+    }+}+++//========================================================================+// Turn on window decorations+//========================================================================++static void enableDecorations( void )+{+    GLboolean 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.display, "_MOTIF_WM_HINTS", True );+    if ( hintAtom != None )+    {+        XDeleteProperty( _glfwLibrary.display, _glfwWin.window, hintAtom );+        activatedDecorations = GL_TRUE;+    }++    // Now try to unset KWM hints+    hintAtom = XInternAtom( _glfwLibrary.display, "KWM_WIN_DECORATION", True );+    if ( hintAtom != None )+    {+        XDeleteProperty( _glfwLibrary.display, _glfwWin.window, hintAtom );+        activatedDecorations = GL_TRUE;+    }++    // Now try to unset GNOME hints+    hintAtom = XInternAtom( _glfwLibrary.display, "_WIN_HINTS", True );+    if ( hintAtom != None )+    {+        XDeleteProperty( _glfwLibrary.display, _glfwWin.window, hintAtom );+        activatedDecorations = GL_TRUE;+    }++    // Now try to unset NET_WM hints+    hintAtom = XInternAtom( _glfwLibrary.display, "_NET_WM_WINDOW_TYPE", True );+    if ( hintAtom != None )+    {+        Atom NET_WMHints = XInternAtom( _glfwLibrary.display,+                                        "_NET_WM_WINDOW_TYPE_NORMAL",+                                        True);+        if( NET_WMHints != None )+        {+            XChangeProperty( _glfwLibrary.display, _glfwWin.window,+                            hintAtom, XA_ATOM, 32, PropModeReplace,+                            (unsigned char *)&NET_WMHints, 1 );+            activatedDecorations = GL_TRUE;+        }+    }++    // Finally unset the transient hints if necessary+    if( activatedDecorations )+    {+        // NOTE: Does this work?+        XSetTransientForHint( _glfwLibrary.display, _glfwWin.window, None );+        XUnmapWindow( _glfwLibrary.display, _glfwWin.window );+        XMapWindow( _glfwLibrary.display, _glfwWin.window );+    }+}+++//========================================================================+// Translates an X Window key to internal coding+//========================================================================++static int translateKey( 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.display, 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.display, 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_ISO_Level3_Shift: // AltGr on at least some machines+        case XK_Alt_R:        return GLFW_KEY_RALT;+        case XK_Super_L:      return GLFW_KEY_LSUPER;+        case XK_Super_R:      return GLFW_KEY_RSUPER;+        case XK_Menu:         return GLFW_KEY_MENU;+        case XK_Num_Lock:     return GLFW_KEY_KP_NUM_LOCK;+        case XK_Caps_Lock:    return GLFW_KEY_CAPS_LOCK;+        case XK_Scroll_Lock:  return GLFW_KEY_SCROLL_LOCK;+        case XK_Pause:        return GLFW_KEY_PAUSE;+        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;+    }+}+++//========================================================================+// Translates an X Window event to Unicode+//========================================================================++static int translateChar( 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 getNextEvent( void )+{+    XEvent event, next_event;++    // Pull next event from event queue+    XNextEvent( _glfwLibrary.display, &event );++    // Handle certain window messages+    switch( event.type )+    {+        // Is a key being pressed?+        case KeyPress:+        {+            // Translate and report key press+            _glfwInputKey( translateKey( event.xkey.keycode ), GLFW_PRESS );++            // Translate and report character input+            if( _glfwWin.charCallback )+            {+                _glfwInputChar( translateChar( &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.display, QueuedAfterReading ) )+            {+                XPeekEvent( _glfwLibrary.display, &next_event );+                if( next_event.type == KeyPress &&+                    next_event.xkey.window == event.xkey.window &&+                    next_event.xkey.keycode == event.xkey.keycode )+                {+                    // This last check is a hack to work around key repeats+                    // leaking through due to some sort of time drift+                    // Toshiyuki Takahashi can press a button 16 times per+                    // second so it's fairly safe to assume that no human is+                    // pressing the key 50 times per second (value is ms)+                    if( ( next_event.xkey.time - event.xkey.time ) < 20 )+                    {+                        // Do not report anything for this event+                        break;+                    }+                }+            }++            // Translate and report key release+            _glfwInputKey( translateKey( event.xkey.keycode ), GLFW_RELEASE );++            // Translate and report character input+            if( _glfwWin.charCallback )+            {+                _glfwInputChar( translateChar( &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.display,+                        RootWindow( _glfwLibrary.display, _glfwWin.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_FALSE;++        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;+}+++//========================================================================+// Create a blank cursor (for locked mouse mode)+//========================================================================++static Cursor createNULLCursor( 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;+}+++//========================================================================+// Returns the specified attribute of the specified GLXFBConfig+// NOTE: Do not call this unless we have found GLX 1.3 or GLX_SGIX_fbconfig+//========================================================================++static int getFBConfigAttrib( GLXFBConfig fbconfig, int attrib )+{+    int value;++    if( _glfwWin.has_GLX_SGIX_fbconfig )+    {+        _glfwWin.GetFBConfigAttribSGIX( _glfwLibrary.display, fbconfig, attrib, &value );+    }+    else+    {+        glXGetFBConfigAttrib( _glfwLibrary.display, fbconfig, attrib, &value );+    }++    return value;+}+++//========================================================================+// Return a list of available and usable framebuffer configs+//========================================================================++static _GLFWfbconfig *getFBConfigs( unsigned int *found )+{+    GLXFBConfig *fbconfigs;+    _GLFWfbconfig *result;+    int i, count = 0;++    *found = 0;++    if( _glfwLibrary.glxMajor == 1 && _glfwLibrary.glxMinor < 3 )+    {+        if( !_glfwWin.has_GLX_SGIX_fbconfig )+        {+            fprintf(stderr, "GLXFBConfigs are not supported by the X server\n");+            return NULL;+        }+    }++    if( _glfwWin.has_GLX_SGIX_fbconfig )+    {+        fbconfigs = _glfwWin.ChooseFBConfigSGIX( _glfwLibrary.display,+                                                 _glfwWin.screen,+                                                 NULL,+                                                 &count );+        if( !count )+        {+            fprintf(stderr, "No GLXFBConfigs returned");+            return NULL;+        }+    }+    else+    {+        fbconfigs = glXGetFBConfigs( _glfwLibrary.display, _glfwWin.screen, &count );+        if( !count )+        {+            fprintf(stderr, "No GLXFBConfigs returned");+            return NULL;+        }+    }++    result = (_GLFWfbconfig*) malloc(sizeof(_GLFWfbconfig) * count);+    if( !result )+    {+        fprintf(stderr, "Out of memory");+        return NULL;+    }++    for( i = 0;  i < count;  i++ )+    {+        if( !getFBConfigAttrib( fbconfigs[i], GLX_DOUBLEBUFFER ) ||+            !getFBConfigAttrib( fbconfigs[i], GLX_VISUAL_ID ) )+        {+            // Only consider doublebuffered GLXFBConfigs with associated visuals+            continue;+        }++        if( !( getFBConfigAttrib( fbconfigs[i], GLX_RENDER_TYPE ) & GLX_RGBA_BIT ) )+        {+            // Only consider RGBA GLXFBConfigs+            continue;+        }++        if( !( getFBConfigAttrib( fbconfigs[i], GLX_DRAWABLE_TYPE ) & GLX_WINDOW_BIT ) )+        {+            // Only consider window GLXFBConfigs+            continue;+        }++        result[*found].redBits = getFBConfigAttrib( fbconfigs[i], GLX_RED_SIZE );+        result[*found].greenBits = getFBConfigAttrib( fbconfigs[i], GLX_GREEN_SIZE );+        result[*found].blueBits = getFBConfigAttrib( fbconfigs[i], GLX_BLUE_SIZE );++        result[*found].alphaBits = getFBConfigAttrib( fbconfigs[i], GLX_ALPHA_SIZE );+        result[*found].depthBits = getFBConfigAttrib( fbconfigs[i], GLX_DEPTH_SIZE );+        result[*found].stencilBits = getFBConfigAttrib( fbconfigs[i], GLX_STENCIL_SIZE );++        result[*found].accumRedBits = getFBConfigAttrib( fbconfigs[i], GLX_ACCUM_RED_SIZE );+        result[*found].accumGreenBits = getFBConfigAttrib( fbconfigs[i], GLX_ACCUM_GREEN_SIZE );+        result[*found].accumBlueBits = getFBConfigAttrib( fbconfigs[i], GLX_ACCUM_BLUE_SIZE );+        result[*found].accumAlphaBits = getFBConfigAttrib( fbconfigs[i], GLX_ACCUM_ALPHA_SIZE );++        result[*found].auxBuffers = getFBConfigAttrib( fbconfigs[i], GLX_AUX_BUFFERS );+        result[*found].stereo = getFBConfigAttrib( fbconfigs[i], GLX_STEREO );++        if( _glfwWin.has_GLX_ARB_multisample )+        {+            result[*found].samples = getFBConfigAttrib( fbconfigs[i], GLX_SAMPLES );+        }+        else+        {+            result[*found].samples = 0;+        }++        result[*found].platformID = (GLFWintptr) getFBConfigAttrib( fbconfigs[i], GLX_FBCONFIG_ID );++        (*found)++;+    }++    XFree( fbconfigs );++    return result;+}+++//========================================================================+// Create the OpenGL context+//========================================================================++#define setGLXattrib( attribs, index, attribName, attribValue ) \+    attribs[index++] = attribName; \+    attribs[index++] = attribValue;++static int createContext( const _GLFWwndconfig *wndconfig, GLXFBConfigID fbconfigID )+{+    int attribs[40];+    int flags, dummy, index;+    GLXFBConfig *fbconfig;++    if( wndconfig->glMajor > 2 )+    {+        if( !_glfwWin.has_GLX_ARB_create_context )+        {+            fprintf(stderr, "GLX_ARB_create_context extension not found\n");+            return GL_FALSE;+        }+    }++    // Retrieve the previously selected GLXFBConfig+    {+        index = 0;++        setGLXattrib( attribs, index, GLX_FBCONFIG_ID, (int) fbconfigID );+        setGLXattrib( attribs, index, None, None );++        if( _glfwWin.has_GLX_SGIX_fbconfig )+        {+            fbconfig = _glfwWin.ChooseFBConfigSGIX( _glfwLibrary.display,+                                                    _glfwWin.screen,+                                                    attribs,+                                                    &dummy );+        }+        else+        {+            fbconfig = glXChooseFBConfig( _glfwLibrary.display,+                                          _glfwWin.screen,+                                          attribs,+                                          &dummy );+        }++        if( fbconfig == NULL )+        {+            fprintf(stderr, "Unable to retrieve the selected GLXFBConfig\n");+            return GL_FALSE;+        }+    }++    // Retrieve the corresponding visual+    if( _glfwWin.has_GLX_SGIX_fbconfig )+    {+        _glfwWin.visual = _glfwWin.GetVisualFromFBConfigSGIX( _glfwLibrary.display,+                                                              *fbconfig );+    }+    else+    {+        _glfwWin.visual = glXGetVisualFromFBConfig( _glfwLibrary.display, *fbconfig );+    }++    if( _glfwWin.visual == NULL )+    {+        XFree( fbconfig );++        fprintf(stderr, "Unable to retrieve visual for GLXFBconfig\n");+        return GL_FALSE;+    }++    if( _glfwWin.has_GLX_ARB_create_context )+    {+        index = 0;++        if( wndconfig->glMajor != 0 || wndconfig->glMinor != 0 )+        {+            // Request an explicitly versioned context++            setGLXattrib( attribs, index, GLX_CONTEXT_MAJOR_VERSION_ARB, wndconfig->glMajor );+            setGLXattrib( attribs, index, GLX_CONTEXT_MINOR_VERSION_ARB, wndconfig->glMinor );+        }++        if( wndconfig->glForward || wndconfig->glDebug )+        {+            flags = 0;++            if( wndconfig->glForward )+            {+                flags |= GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB;+            }++            if( wndconfig->glDebug )+            {+                flags |= GLX_CONTEXT_DEBUG_BIT_ARB;+            }++            setGLXattrib( attribs, index, GLX_CONTEXT_FLAGS_ARB, flags );+        }++        if( wndconfig->glProfile )+        {+            if( !_glfwWin.has_GLX_ARB_create_context_profile )+            {+                fprintf( stderr, "OpenGL profile requested but GLX_ARB_create_context_profile "+                                 "is unavailable\n" );+                return GL_FALSE;+            }++            if( wndconfig->glProfile == GLFW_OPENGL_CORE_PROFILE )+            {+                flags = GLX_CONTEXT_CORE_PROFILE_BIT_ARB;+            }+            else+            {+                flags = GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB;+            }++            setGLXattrib( attribs, index, GLX_CONTEXT_PROFILE_MASK_ARB, flags );+        }++        setGLXattrib( attribs, index, None, None );++        _glfwWin.context = _glfwWin.CreateContextAttribsARB( _glfwLibrary.display,+                                                             *fbconfig,+                                                             NULL,+                                                             True,+                                                             attribs );+    }+    else+    {+        if( _glfwWin.has_GLX_SGIX_fbconfig )+        {+            _glfwWin.context = _glfwWin.CreateContextWithConfigSGIX( _glfwLibrary.display,+                                                                     *fbconfig,+                                                                     GLX_RGBA_TYPE,+                                                                     NULL,+                                                                     True );+        }+        else+        {+            _glfwWin.context = glXCreateNewContext( _glfwLibrary.display,+                                                    *fbconfig,+                                                    GLX_RGBA_TYPE,+                                                    NULL,+                                                    True );+        }+    }++    XFree( fbconfig );++    if( _glfwWin.context == NULL )+    {+        fprintf(stderr, "Unable to create OpenGL context\n");+        return GL_FALSE;+    }++    _glfwWin.fbconfigID = fbconfigID;++    return GL_TRUE;+}+++//========================================================================+// Initialize GLX-specific extensions+//========================================================================++static void initGLXExtensions( void )+{+    // This needs to include every function pointer loaded below+    _glfwWin.SwapIntervalSGI             = NULL;+    _glfwWin.GetFBConfigAttribSGIX       = NULL;+    _glfwWin.ChooseFBConfigSGIX          = NULL;+    _glfwWin.CreateContextWithConfigSGIX = NULL;+    _glfwWin.GetVisualFromFBConfigSGIX   = NULL;+    _glfwWin.CreateContextAttribsARB     = NULL;++    // This needs to include every extension used below+    _glfwWin.has_GLX_SGIX_fbconfig              = GL_FALSE;+    _glfwWin.has_GLX_SGI_swap_control           = GL_FALSE;+    _glfwWin.has_GLX_ARB_multisample            = GL_FALSE;+    _glfwWin.has_GLX_ARB_create_context         = GL_FALSE;+    _glfwWin.has_GLX_ARB_create_context_profile = GL_FALSE;++    if( _glfwPlatformExtensionSupported( "GLX_SGI_swap_control" ) )+    {+        _glfwWin.SwapIntervalSGI = (PFNGLXSWAPINTERVALSGIPROC)+            _glfwPlatformGetProcAddress( "glXSwapIntervalSGI" );++        if( _glfwWin.SwapIntervalSGI )+        {+            _glfwWin.has_GLX_SGI_swap_control = GL_TRUE;+        }+    }++    if( _glfwPlatformExtensionSupported( "GLX_SGIX_fbconfig" ) )+    {+        _glfwWin.GetFBConfigAttribSGIX = (PFNGLXGETFBCONFIGATTRIBSGIXPROC)+            _glfwPlatformGetProcAddress( "glXGetFBConfigAttribSGIX" );+        _glfwWin.ChooseFBConfigSGIX = (PFNGLXCHOOSEFBCONFIGSGIXPROC)+            _glfwPlatformGetProcAddress( "glXChooseFBConfigSGIX" );+        _glfwWin.CreateContextWithConfigSGIX = (PFNGLXCREATECONTEXTWITHCONFIGSGIXPROC)+            _glfwPlatformGetProcAddress( "glXCreateContextWithConfigSGIX" );+        _glfwWin.GetVisualFromFBConfigSGIX = (PFNGLXGETVISUALFROMFBCONFIGSGIXPROC)+            _glfwPlatformGetProcAddress( "glXGetVisualFromFBConfigSGIX" );++        if( _glfwWin.GetFBConfigAttribSGIX &&+            _glfwWin.ChooseFBConfigSGIX &&+            _glfwWin.CreateContextWithConfigSGIX &&+            _glfwWin.GetVisualFromFBConfigSGIX )+        {+            _glfwWin.has_GLX_SGIX_fbconfig = GL_TRUE;+        }+    }++    if( _glfwPlatformExtensionSupported( "GLX_ARB_multisample" ) )+    {+        _glfwWin.has_GLX_ARB_multisample = GL_TRUE;+    }++    if( _glfwPlatformExtensionSupported( "GLX_ARB_create_context" ) )+    {+        _glfwWin.CreateContextAttribsARB = (PFNGLXCREATECONTEXTATTRIBSARBPROC)+            _glfwPlatformGetProcAddress( "glXCreateContextAttribsARB" );++        if( _glfwWin.CreateContextAttribsARB )+        {+            _glfwWin.has_GLX_ARB_create_context = GL_TRUE;+        }+    }++    if( _glfwPlatformExtensionSupported( "GLX_ARB_create_context_profile" ) )+    {+        _glfwWin.has_GLX_ARB_create_context_profile = GL_TRUE;+    }+}+++//========================================================================+// Create the X11 window (and its colormap)+//========================================================================++static GLboolean createWindow( int width, int height,+                               const _GLFWwndconfig *wndconfig )+{+    XEvent event;+    Atom protocols[2];+    XSizeHints *sizehints;+    unsigned long wamask;+    XSetWindowAttributes wa;++    // Every window needs a colormap+    // We create one based on the visual used by the current context++    _glfwWin.colormap = XCreateColormap( _glfwLibrary.display,+                                         RootWindow( _glfwLibrary.display,+                                                     _glfwWin.screen ),+                                         _glfwWin.visual->visual,+                                         AllocNone );++    // Create the actual window+    {+        wamask = CWBorderPixel | CWColormap | CWEventMask;++        wa.colormap = _glfwWin.colormap;+        wa.border_pixel = 0;+        wa.event_mask = StructureNotifyMask | KeyPressMask | KeyReleaseMask |+            PointerMotionMask | ButtonPressMask | ButtonReleaseMask |+            ExposureMask | FocusChangeMask | VisibilityChangeMask;++        if( wndconfig->mode == GLFW_WINDOW )+        {+            // The /only/ reason we are setting the background pixel here is+            // because otherwise our window wont get any decorations on systems+            // using Compiz on Intel hardware+            wa.background_pixel = BlackPixel( _glfwLibrary.display, _glfwWin.screen );+            wamask |= CWBackPixel;+        }++        _glfwWin.window = XCreateWindow(+            _glfwLibrary.display,+            RootWindow( _glfwLibrary.display, _glfwWin.screen ),+            0, 0,                            // Upper left corner of this window on root+            _glfwWin.width, _glfwWin.height,+            0,                               // Border width+            _glfwWin.visual->depth,          // Color depth+            InputOutput,+            _glfwWin.visual->visual,+            wamask,+            &wa+        );+        if( !_glfwWin.window )+        {+            _glfwPlatformCloseWindow();+            return GL_FALSE;+        }+    }++    // Declare which WM protocols we support+    {+        // Basic window close notification protocol+        _glfwWin.WMDeleteWindow = XInternAtom( _glfwLibrary.display,+                                               "WM_DELETE_WINDOW",+                                               False );++        // Tells the WM to ping our window and flag us as unresponsive if we+        // don't reply within a few seconds+        _glfwWin.WMPing = XInternAtom( _glfwLibrary.display, "_NET_WM_PING", False );++        protocols[0] = _glfwWin.WMDeleteWindow;+        protocols[1] = _glfwWin.WMPing;++        XSetWMProtocols( _glfwLibrary.display, _glfwWin.window, protocols,+                         sizeof(protocols) / sizeof(Atom) );+    }++    if( wndconfig->mode == GLFW_FULLSCREEN )+    {+        disableDecorations();+    }++    // Set window position and size WM hints+    {+        sizehints = XAllocSizeHints();+        sizehints->flags = 0;++        if( wndconfig->windowNoResize )+        {+            sizehints->flags |= (PMinSize | PMaxSize);+            sizehints->min_width  = sizehints->max_width  = _glfwWin.width;+            sizehints->min_height = sizehints->max_height = _glfwWin.height;+        }++        if( wndconfig->mode == GLFW_FULLSCREEN )+        {+            sizehints->flags |= PPosition;+            sizehints->x = 0;+            sizehints->y = 0;+        }++        XSetWMNormalHints( _glfwLibrary.display, _glfwWin.window, sizehints );+        XFree( sizehints );+    }++    _glfwPlatformSetWindowTitle( "GLFW Window" );++    XMapWindow( _glfwLibrary.display, _glfwWin.window );++    // Wait for map notification+    XIfEvent( _glfwLibrary.display, &event, isMapNotify,+              (char*)_glfwWin.window );++    // Make sure that our window ends up on top of things+    XRaiseWindow( _glfwLibrary.display, _glfwWin.window );++    return GL_TRUE;+}++++//************************************************************************+//****               Platform implementation functions                ****+//************************************************************************++//========================================================================+// Here is where the window is created, and+// the OpenGL rendering context is created+//========================================================================++int _glfwPlatformOpenWindow( int width, int height,+                             const _GLFWwndconfig* wndconfig,+                             const _GLFWfbconfig* fbconfig )+{+    unsigned int mask, fbcount;+    _GLFWfbconfig *fbconfigs;+    _GLFWfbconfig closest;+    const _GLFWfbconfig *result;+    Window window, root;+    int windowX, windowY, rootX, rootY;++    // Clear platform specific GLFW window state+    _glfwWin.visual           = (XVisualInfo*)NULL;+    _glfwWin.colormap         = (Colormap)0;+    _glfwWin.context          = (GLXContext)NULL;+    _glfwWin.window           = (Window)0;+    _glfwWin.pointerGrabbed   = GL_FALSE;+    _glfwWin.pointerHidden    = GL_FALSE;+    _glfwWin.keyboardGrabbed  = GL_FALSE;+    _glfwWin.overrideRedirect = GL_FALSE;+    _glfwWin.FS.modeChanged   = GL_FALSE;+    _glfwWin.Saver.changed    = GL_FALSE;+    _glfwWin.refreshRate      = wndconfig->refreshRate;+    _glfwWin.windowNoResize   = wndconfig->windowNoResize;++    // As the 2.x API doesn't understand screens, we hardcode this choice and+    // hope for the best+    _glfwWin.screen = DefaultScreen( _glfwLibrary.display );++    initGLXExtensions();++    // Choose the best available fbconfig+    {+        fbconfigs = getFBConfigs( &fbcount );+        if( !fbconfigs )+        {+            _glfwPlatformCloseWindow();+            return GL_FALSE;+        }++        result = _glfwChooseFBConfig( fbconfig, fbconfigs, fbcount );+        if( !result )+        {+            free( fbconfigs );+            _glfwPlatformCloseWindow();+            return GL_FALSE;+        }++        closest = *result;+        free( fbconfigs );+        fbconfigs = NULL;+        result = NULL;+    }++    if( !createContext( wndconfig, (GLXFBConfigID) closest.platformID ) )+    {+        _glfwPlatformCloseWindow();+        return GL_FALSE;+    }++    if( wndconfig->mode == GLFW_FULLSCREEN )+    {+        // Change video mode+        _glfwSetVideoMode( _glfwWin.screen, &_glfwWin.width,+                           &_glfwWin.height, &_glfwWin.refreshRate );++        // Remember old screen saver settings+        XGetScreenSaver( _glfwLibrary.display, &_glfwWin.Saver.timeout,+                         &_glfwWin.Saver.interval, &_glfwWin.Saver.blanking,+                         &_glfwWin.Saver.exposure );++        // Disable screen saver+        XSetScreenSaver( _glfwLibrary.display, 0, 0, DontPreferBlanking,+                         DefaultExposures );+    }++    if( !createWindow( width, height, wndconfig ) )+    {+        _glfwPlatformCloseWindow();+        return GL_FALSE;+    }++    if( wndconfig->mode == GLFW_FULLSCREEN )+    {+        // Fullscreen mode post-window-creation work++#if defined( _GLFW_HAS_XRANDR )+        // Request screen change notifications+        if( _glfwLibrary.XRandR.available )+        {+            XRRSelectInput( _glfwLibrary.display,+                            _glfwWin.window,+                            RRScreenChangeNotifyMask );+        }+#endif++        // Force window position/size (some WMs do their own window+        // geometry, which we want to override)+        XMoveWindow( _glfwLibrary.display, _glfwWin.window, 0, 0 );+        XResizeWindow( _glfwLibrary.display, _glfwWin.window, _glfwWin.width,+                       _glfwWin.height );++        if( XGrabKeyboard( _glfwLibrary.display, _glfwWin.window, True,+                           GrabModeAsync, GrabModeAsync, CurrentTime ) ==+            GrabSuccess )+        {+            _glfwWin.keyboardGrabbed = GL_TRUE;+        }++        if( XGrabPointer( _glfwLibrary.display, _glfwWin.window, True,+                          ButtonPressMask | ButtonReleaseMask |+                          PointerMotionMask, GrabModeAsync, GrabModeAsync,+                          _glfwWin.window, 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.display, None, _glfwWin.window, 0,0,0,0, 0,0 );+        XWarpPointer( _glfwLibrary.display, None, _glfwWin.window, 0,0,0,0,+                      _glfwWin.width/2, _glfwWin.height/2 );+    }++    // Retrieve and set initial cursor position+    {+        XQueryPointer( _glfwLibrary.display,+                       _glfwWin.window,+                       &root,+                       &window,+                       &rootX, &rootY,+                       &windowX, &windowY,+                       &mask );++        // TODO: Probably check for some corner cases here.++        _glfwInput.MousePosX = windowX;+        _glfwInput.MousePosY = windowY;+    }++    // Connect the context to the window+    glXMakeCurrent( _glfwLibrary.display, _glfwWin.window, _glfwWin.context );++    // Start by clearing the front buffer to black (avoid ugly desktop+    // remains in our OpenGL window)+    glClear( GL_COLOR_BUFFER_BIT );+    glXSwapBuffers( _glfwLibrary.display, _glfwWin.window );++    return GL_TRUE;+}+++//========================================================================+// Properly kill the window/video display+//========================================================================++void _glfwPlatformCloseWindow( void )+{+#if defined( _GLFW_HAS_XRANDR )+    XRRScreenConfiguration *sc;+    Window root;+#endif++    // Do we have a rendering context?+    if( _glfwWin.context )+    {+        // Release the context+        glXMakeCurrent( _glfwLibrary.display, None, NULL );++        // Delete the context+        glXDestroyContext( _glfwLibrary.display, _glfwWin.context );+        _glfwWin.context = NULL;+    }++    // Do we have a visual?+    if( _glfwWin.visual )+    {+        XFree( _glfwWin.visual );+        _glfwWin.visual = NULL;+    }++    // Ungrab pointer and/or keyboard?+    if( _glfwWin.keyboardGrabbed )+    {+        XUngrabKeyboard( _glfwLibrary.display, CurrentTime );+        _glfwWin.keyboardGrabbed = GL_FALSE;+    }+    if( _glfwWin.pointerGrabbed )+    {+        XUngrabPointer( _glfwLibrary.display, CurrentTime );+        _glfwWin.pointerGrabbed = GL_FALSE;+    }++    // Do we have a window?+    if( _glfwWin.window )+    {+        // Unmap the window+        XUnmapWindow( _glfwLibrary.display, _glfwWin.window );++        // Destroy the window+        XDestroyWindow( _glfwLibrary.display, _glfwWin.window );+        _glfwWin.window = (Window) 0;+    }++    if( _glfwWin.colormap )+    {+        XFreeColormap( _glfwLibrary.display, _glfwWin.colormap );+        _glfwWin.colormap = (Colormap) 0;+    }++    // Did we change the fullscreen resolution?+    if( _glfwWin.FS.modeChanged )+    {+#if defined( _GLFW_HAS_XRANDR )+        if( _glfwLibrary.XRandR.available )+        {+            root = RootWindow( _glfwLibrary.display, _glfwWin.screen );+            sc = XRRGetScreenInfo( _glfwLibrary.display, root );++            XRRSetScreenConfig( _glfwLibrary.display,+                                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.display,+                                       _glfwWin.screen,+                                       0 );++            // Change the video mode back to the old mode+            XF86VidModeSwitchToMode( _glfwLibrary.display,+                                     _glfwWin.screen,+                                     &_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.display,+                         _glfwWin.Saver.timeout,+                         _glfwWin.Saver.interval,+                         _glfwWin.Saver.blanking,+                         _glfwWin.Saver.exposure );+        _glfwWin.Saver.changed = GL_FALSE;+    }+}+++//========================================================================+// _glfwPlatformSetWindowTitle() - Set the window title.+//========================================================================++void _glfwPlatformSetWindowTitle( const char *title )+{+    // Set window & icon title+    XStoreName( _glfwLibrary.display, _glfwWin.window, title );+    XSetIconName( _glfwLibrary.display, _glfwWin.window, title );+}+++//========================================================================+// _glfwPlatformSetWindowSize() - Set the window size.+//========================================================================++void _glfwPlatformSetWindowSize( int width, int height )+{+    int     mode = 0, rate, sizeChanged = GL_FALSE;+    XSizeHints *sizehints;++    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.screen, &width, &height, &rate );+    }++    if( _glfwWin.windowNoResize )+    {+        sizehints = XAllocSizeHints();+        sizehints->flags = 0;++        sizehints->min_width  = sizehints->max_width  = width;+        sizehints->min_height = sizehints->max_height = height;++        XSetWMNormalHints( _glfwLibrary.display, _glfwWin.window, sizehints );+        XFree( sizehints );+    }++    // Change window size before changing fullscreen mode?+    if( _glfwWin.fullscreen && (width > _glfwWin.width) )+    {+        XResizeWindow( _glfwLibrary.display, _glfwWin.window, width, height );+        sizeChanged = GL_TRUE;+    }++    // Change fullscreen video mode?+    if( _glfwWin.fullscreen )+    {+        // Change video mode (keeping current rate)+        _glfwSetVideoModeMODE( _glfwWin.screen, mode, _glfwWin.refreshRate );+    }++    // Set window size (if not already changed)+    if( !sizeChanged )+    {+        XResizeWindow( _glfwLibrary.display, _glfwWin.window, width, height );+    }+}+++//========================================================================+// _glfwPlatformSetWindowPos() - Set the window position.+//========================================================================++void _glfwPlatformSetWindowPos( int x, int y )+{+    // Set window position+    XMoveWindow( _glfwLibrary.display, _glfwWin.window, 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_XRANDR )+        if( _glfwLibrary.XRandR.available )+        {+            // TODO: The code.+        }+#elif defined( _GLFW_HAS_XF86VIDMODE )+        if( _glfwLibrary.XF86VidMode.available )+        {+            // Unlock mode switch+            XF86VidModeLockModeSwitch( _glfwLibrary.display,+                                       _glfwWin.screen,+                                       0 );++            // Change the video mode back to the old mode+            XF86VidModeSwitchToMode( _glfwLibrary.display,+                _glfwWin.screen, &_glfwWin.FS.oldMode );+        }+#endif+        _glfwWin.FS.modeChanged = GL_FALSE;+    }++    // Show mouse pointer+    if( _glfwWin.pointerHidden )+    {+        XUndefineCursor( _glfwLibrary.display, _glfwWin.window );+        _glfwWin.pointerHidden = GL_FALSE;+    }++    // Un-grab mouse pointer+    if( _glfwWin.pointerGrabbed )+    {+        XUngrabPointer( _glfwLibrary.display, CurrentTime );+        _glfwWin.pointerGrabbed = GL_FALSE;+    }++    // Iconify window+    XIconifyWindow( _glfwLibrary.display, _glfwWin.window,+                    _glfwWin.screen );++    // 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.screen,+                       &_glfwWin.width, &_glfwWin.height, &_glfwWin.refreshRate );+    }++    // Un-iconify window+    XMapWindow( _glfwLibrary.display, _glfwWin.window );++    // In fullscreen mode...+    if( _glfwWin.fullscreen )+    {+        // Make sure window is in upper left corner+        XMoveWindow( _glfwLibrary.display, _glfwWin.window, 0, 0 );++        // Get input focus+        XSetInputFocus( _glfwLibrary.display, _glfwWin.window, RevertToParent,+                        CurrentTime );+    }++    // Lock mouse, if necessary+    if( _glfwWin.mouseLock )+    {+        // Hide cursor+        if( !_glfwWin.pointerHidden )+        {+            XDefineCursor( _glfwLibrary.display, _glfwWin.window,+                           createNULLCursor( _glfwLibrary.display,+                                             _glfwWin.window ) );++            _glfwWin.pointerHidden = GL_TRUE;+        }++        // Grab cursor+        if( !_glfwWin.pointerGrabbed )+        {+            if( XGrabPointer( _glfwLibrary.display, _glfwWin.window, True,+                              ButtonPressMask | ButtonReleaseMask |+                              PointerMotionMask, GrabModeAsync,+                              GrabModeAsync, _glfwWin.window, 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.display, _glfwWin.window );+}+++//========================================================================+// _glfwPlatformSwapInterval() - Set double buffering swap interval+//========================================================================++void _glfwPlatformSwapInterval( int interval )+{+    if( _glfwWin.has_GLX_SGI_swap_control )+    {+        _glfwWin.SwapIntervalSGI( interval );+    }+}+++//========================================================================+// Read back framebuffer parameters from the context+//========================================================================++void _glfwPlatformRefreshWindowParams( void )+{+    int dummy;+    GLXFBConfig *fbconfig;+#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 attribs[] = { GLX_FBCONFIG_ID, _glfwWin.fbconfigID, None };++    if( _glfwWin.has_GLX_SGIX_fbconfig )+    {+        fbconfig = _glfwWin.ChooseFBConfigSGIX( _glfwLibrary.display,+                                                _glfwWin.screen,+                                                attribs,+                                                &dummy );+    }+    else+    {+        fbconfig = glXChooseFBConfig( _glfwLibrary.display,+                                    _glfwWin.screen,+                                    attribs,+                                    &dummy );+    }++    if( fbconfig == NULL )+    {+        // This should never ever happen+        // TODO: Figure out what to do when this happens+        fprintf( stderr, "Cannot find known GLXFBConfig by ID. "+                         "This cannot happen. Have a nice day.\n");+        abort();+    }++    // There is no clear definition of an "accelerated" context on X11/GLX, and+    // true sounds better than false, so we hardcode true here+    _glfwWin.accelerated = GL_TRUE;++    // "Standard" window parameters+    _glfwWin.redBits = getFBConfigAttrib( *fbconfig, GLX_RED_SIZE );+    _glfwWin.greenBits = getFBConfigAttrib( *fbconfig, GLX_GREEN_SIZE );+    _glfwWin.blueBits = getFBConfigAttrib( *fbconfig, GLX_BLUE_SIZE );++    _glfwWin.alphaBits = getFBConfigAttrib( *fbconfig, GLX_ALPHA_SIZE );+    _glfwWin.depthBits = getFBConfigAttrib( *fbconfig, GLX_DEPTH_SIZE );+    _glfwWin.stencilBits = getFBConfigAttrib( *fbconfig, GLX_STENCIL_SIZE );++    _glfwWin.accumRedBits = getFBConfigAttrib( *fbconfig, GLX_ACCUM_RED_SIZE );+    _glfwWin.accumGreenBits = getFBConfigAttrib( *fbconfig, GLX_ACCUM_GREEN_SIZE );+    _glfwWin.accumBlueBits = getFBConfigAttrib( *fbconfig, GLX_ACCUM_BLUE_SIZE );+    _glfwWin.accumAlphaBits = getFBConfigAttrib( *fbconfig, GLX_ACCUM_ALPHA_SIZE );++    _glfwWin.auxBuffers = getFBConfigAttrib( *fbconfig, GLX_AUX_BUFFERS );++    // Get stereo rendering setting+    _glfwWin.stereo = getFBConfigAttrib( *fbconfig, GLX_STEREO ) ? 1 : 0;++    // Get multisample buffer samples+    if( _glfwWin.has_GLX_ARB_multisample )+    {+        _glfwWin.samples = getFBConfigAttrib( *fbconfig, GLX_SAMPLES );+    }+    else+    {+        _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.display,+                               RootWindow( _glfwLibrary.display, _glfwWin.screen ) );+        _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.display, _glfwWin.screen,+                                &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++    XFree( fbconfig );+}+++//========================================================================+// _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;++    // Empty the window event queue+    while( XPending( _glfwLibrary.display ) )+    {+        if( getNextEvent() )+        {+            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 );+        }+    }++    // Was the window (un)iconified?+    if( _glfwWin.mapNotifyCount < 0 && !_glfwWin.iconified )+    {+        // Show mouse pointer+        if( _glfwWin.pointerHidden )+        {+            XUndefineCursor( _glfwLibrary.display, _glfwWin.window );+            _glfwWin.pointerHidden = GL_FALSE;+        }++        // Un-grab mouse pointer+        if( _glfwWin.pointerGrabbed )+        {+            XUngrabPointer( _glfwLibrary.display, 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.screen, &_glfwWin.width,+                               &_glfwWin.height, &_glfwWin.refreshRate );+            // Disable window manager decorations+            enableDecorations();++            // Make sure window is in upper left corner+            XMoveWindow( _glfwLibrary.display, _glfwWin.window, 0, 0 );++            // Get input focus+            XSetInputFocus( _glfwLibrary.display, _glfwWin.window,+                            RevertToParent, CurrentTime );+        }++        // Hide cursor if necessary+        if( _glfwWin.mouseLock && !_glfwWin.pointerHidden )+        {+            if( !_glfwWin.pointerHidden )+            {+                XDefineCursor( _glfwLibrary.display, _glfwWin.window,+                               createNULLCursor( _glfwLibrary.display,+                                                 _glfwWin.window ) );++                _glfwWin.pointerHidden = GL_TRUE;+            }+        }++        // Grab cursor if necessary+        if( (_glfwWin.mouseLock || _glfwWin.fullscreen) &&+            !_glfwWin.pointerGrabbed )+        {+            if( XGrabPointer( _glfwLibrary.display, _glfwWin.window, True,+                    ButtonPressMask | ButtonReleaseMask |+                    PointerMotionMask, GrabModeAsync,+                    GrabModeAsync, _glfwWin.window, 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.display, &event );+    XPutBackEvent( _glfwLibrary.display, &event );++    // Poll events from queue+    _glfwPlatformPollEvents();+}+++//========================================================================+// _glfwPlatformHideMouseCursor() - Hide mouse cursor (lock it)+//========================================================================++void _glfwPlatformHideMouseCursor( void )+{+    // Hide cursor+    if( !_glfwWin.pointerHidden )+    {+        XDefineCursor( _glfwLibrary.display, _glfwWin.window,+                       createNULLCursor( _glfwLibrary.display,+                                         _glfwWin.window ) );++        _glfwWin.pointerHidden = GL_TRUE;+    }++    // Grab cursor to user window+    if( !_glfwWin.pointerGrabbed )+    {+        if( XGrabPointer( _glfwLibrary.display, _glfwWin.window, True,+                          ButtonPressMask | ButtonReleaseMask |+                          PointerMotionMask, GrabModeAsync, GrabModeAsync,+                          _glfwWin.window, 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.display, CurrentTime );+        _glfwWin.pointerGrabbed = GL_FALSE;+    }++    // Show cursor+    if( _glfwWin.pointerHidden )+    {+        XUndefineCursor( _glfwLibrary.display, _glfwWin.window );+        _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.display, None, _glfwWin.window, 0,0,0,0, x, y );+}+
+ src/Graphics/UI/GLFW.hsc view
@@ -0,0 +1,988 @@+{-# LANGUAGE ForeignFunctionInterface #-}+{-# LANGUAGE MultiParamTypeClasses    #-}++module Graphics.UI.GLFW+  ( -- *   Initialization and termination+    initialize+  , terminate++    -- *   Video mode information+  , getVideoMode+  , getVideoModes+    --+  , VideoMode(..)++    -- *   Windows+    -- **  Management+  , openWindow+  , closeWindow+  , setWindowTitle+  , setWindowDimensions+  , setWindowPosition+  , iconifyWindow+  , restoreWindow+  , swapBuffers+  , setWindowBufferSwapInterval+    --+  , DisplayMode(..)+  , DisplayOptions(..)+  , defaultDisplayOptions+    -- **  Information+  , windowIsOpen+  , windowIsActive+  , windowIsIconified+  , windowIsResizable+  , windowIsHardwareAccelerated+  , windowSupportsStereoRendering+  , getWindowRefreshRate+  , getWindowDimensions+  , getWindowValue+  , setWindowCloseCallback+  , setWindowSizeCallback+  , setWindowRefreshCallback+    --+  , WindowValue(..)+  , WindowCloseCallback+  , WindowSizeCallback+  , WindowRefreshCallback++    -- *   Input+  , pollEvents+  , waitEvents+    -- **  Keyboard+  , keyIsPressed+  , setCharCallback+  , setKeyCallback+    --+  , Key(..)+  , CharCallback+  , KeyCallback+    -- **  Mouse+  , mouseButtonIsPressed+  , getMousePosition+  , getMouseWheel+  , setMousePosition+  , setMouseWheel+  , setMouseButtonCallback+  , setMousePositionCallback+  , setMouseWheelCallback+    --+  , MouseButton(..)+  , MouseButtonCallback+  , MousePositionCallback+  , MouseWheelCallback+    -- **  Joystick+  , joystickIsPresent+  , getJoystickPosition+  , getNumJoystickAxes+  , getNumJoystickButtons+  , joystickButtonsArePressed+    --+  , Joystick(..)++    -- *   Time+  , getTime+  , setTime+  , resetTime+  , sleep++    -- *   Version information+  , getGlfwVersion+  , getGlVersion+  ) where++-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --++import Control.Monad         (when)+import Data.Char             (chr, ord)+import Data.IORef            (IORef, atomicModifyIORef, newIORef)+import Data.Maybe            (fromJust, isJust)+import Data.Version          (Version(..))+import Foreign.C.String      (CString, withCString)+import Foreign.C.Types       (CDouble, CFloat, CInt, CUChar)+import Foreign.Marshal.Alloc (alloca)+import Foreign.Marshal.Array (allocaArray, peekArray)+import Foreign.Ptr           (FunPtr, Ptr, freeHaskellFunPtr)+import Foreign.Storable      (Storable(..))+import System.IO.Unsafe      (unsafePerformIO)++-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --++#include <GL/glfw.h>++foreign import ccall unsafe glfwInit                     :: IO CInt+foreign import ccall unsafe glfwTerminate                :: IO ()+foreign import ccall unsafe glfwGetVersion               :: Ptr CInt -> Ptr CInt -> Ptr CInt -> IO ()++foreign import ccall unsafe glfwOpenWindow               :: CInt -> CInt -> CInt -> CInt -> CInt -> CInt -> CInt -> CInt -> CInt -> IO CInt+foreign import ccall unsafe glfwOpenWindowHint           :: CInt -> CInt -> IO ()+foreign import ccall unsafe glfwCloseWindow              :: IO ()+foreign import ccall unsafe glfwSetWindowCloseCallback   :: FunPtr GlfwWindowCloseCallback -> IO ()+foreign import ccall unsafe glfwSetWindowTitle           :: CString -> IO ()+foreign import ccall unsafe glfwSetWindowSize            :: CInt -> CInt -> IO ()+foreign import ccall unsafe glfwSetWindowPos             :: CInt -> CInt -> IO ()+foreign import ccall unsafe glfwGetWindowSize            :: Ptr CInt -> Ptr CInt -> IO ()+foreign import ccall        glfwSetWindowSizeCallback    :: FunPtr GlfwWindowSizeCallback -> IO ()+foreign import ccall unsafe glfwIconifyWindow            :: IO ()+foreign import ccall unsafe glfwRestoreWindow            :: IO ()+foreign import ccall unsafe glfwGetWindowParam           :: CInt -> IO CInt+foreign import ccall        glfwSwapBuffers              :: IO ()+foreign import ccall unsafe glfwSwapInterval             :: CInt -> IO ()+foreign import ccall unsafe glfwSetWindowRefreshCallback :: FunPtr GlfwWindowRefreshCallback -> IO ()++foreign import ccall unsafe glfwGetVideoModes            :: Ptr VideoMode -> CInt -> IO CInt+foreign import ccall unsafe glfwGetDesktopMode           :: Ptr VideoMode -> IO ()++foreign import ccall unsafe glfwPollEvents               :: IO ()+foreign import ccall unsafe glfwWaitEvents               :: IO ()+foreign import ccall unsafe glfwGetKey                   :: CInt -> IO CInt+foreign import ccall unsafe glfwGetMouseButton           :: CInt -> IO CInt+foreign import ccall unsafe glfwGetMousePos              :: Ptr CInt -> Ptr CInt -> IO ()+foreign import ccall unsafe glfwSetMousePos              :: CInt -> CInt -> IO ()+foreign import ccall unsafe glfwGetMouseWheel            :: IO CInt+foreign import ccall unsafe glfwSetMouseWheel            :: CInt -> IO ()+foreign import ccall        glfwSetKeyCallback           :: FunPtr GlfwKeyCallback -> IO ()+foreign import ccall        glfwSetCharCallback          :: FunPtr GlfwCharCallback -> IO ()+foreign import ccall        glfwSetMouseButtonCallback   :: FunPtr GlfwMouseButtonCallback -> IO ()+foreign import ccall        glfwSetMousePosCallback      :: FunPtr GlfwMousePositionCallback -> IO ()+foreign import ccall        glfwSetMouseWheelCallback    :: FunPtr GlfwMouseWheelCallback -> IO ()+foreign import ccall unsafe glfwGetJoystickParam         :: CInt -> CInt -> IO CInt+foreign import ccall unsafe glfwGetJoystickPos           :: CInt -> Ptr CFloat -> CInt -> IO CInt+foreign import ccall unsafe glfwGetJoystickButtons       :: CInt -> Ptr CUChar -> CInt -> IO CInt++foreign import ccall unsafe glfwGetTime                  :: IO CDouble+foreign import ccall unsafe glfwSetTime                  :: CDouble -> IO ()+foreign import ccall unsafe glfwSleep                    :: CDouble -> IO ()++foreign import ccall unsafe glfwGetGLVersion             :: Ptr CInt -> Ptr CInt -> Ptr CInt -> IO ()++type GlfwCharCallback          = CInt -> CInt -> IO ()+type GlfwKeyCallback           = CInt -> CInt -> IO ()+type GlfwMouseButtonCallback   = CInt -> CInt -> IO ()+type GlfwMousePositionCallback = CInt -> CInt -> IO ()+type GlfwMouseWheelCallback    = CInt         -> IO ()+type GlfwWindowCloseCallback   =                 IO CInt+type GlfwWindowRefreshCallback =                 IO ()+type GlfwWindowSizeCallback    = CInt -> CInt -> IO ()++type CharCallback          = Char -> Bool        -> IO ()+type KeyCallback           = Key -> Bool         -> IO ()+type MouseButtonCallback   = MouseButton -> Bool -> IO ()+type MousePositionCallback = Int -> Int          -> IO ()+type MouseWheelCallback    = Int                 -> IO ()+type WindowCloseCallback   =                        IO Bool+type WindowRefreshCallback =                        IO ()+type WindowSizeCallback    = Int -> Int          -> IO ()++foreign import ccall unsafe "wrapper" wrapCharCallback          :: GlfwCharCallback          -> IO (FunPtr GlfwCharCallback)+foreign import ccall unsafe "wrapper" wrapKeyCallback           :: GlfwKeyCallback           -> IO (FunPtr GlfwKeyCallback)+foreign import ccall unsafe "wrapper" wrapMouseButtonCallback   :: GlfwMouseButtonCallback   -> IO (FunPtr GlfwMouseButtonCallback)+foreign import ccall unsafe "wrapper" wrapMousePositionCallback :: GlfwMousePositionCallback -> IO (FunPtr GlfwMousePositionCallback)+foreign import ccall unsafe "wrapper" wrapMouseWheelCallback    :: GlfwMouseWheelCallback    -> IO (FunPtr GlfwMouseWheelCallback)+foreign import ccall unsafe "wrapper" wrapWindowCloseCallback   :: GlfwWindowCloseCallback   -> IO (FunPtr GlfwWindowCloseCallback)+foreign import ccall unsafe "wrapper" wrapWindowRefreshCallback :: GlfwWindowRefreshCallback -> IO (FunPtr GlfwWindowRefreshCallback)+foreign import ccall unsafe "wrapper" wrapWindowSizeCallback    :: GlfwWindowSizeCallback    -> IO (FunPtr GlfwWindowSizeCallback)++-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --+-- Initialization and termination++initialize :: IO Bool+initialize =+    fromC `fmap` glfwInit++terminate :: IO ()+terminate =+    glfwTerminate++-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --+-- Video mode information++getVideoMode :: IO VideoMode+getVideoMode =+    alloca $ \ptr -> do+        glfwGetDesktopMode ptr+        peek ptr++getVideoModes :: IO [VideoMode]+getVideoModes =+    allocaArray m $ \ptr -> do+        n <- glfwGetVideoModes ptr (toC m)+        peekArray (fromC n) ptr+  where+    m = 256++-- -- -- -- -- -- -- -- -- --++data VideoMode = VideoMode+  { videoMode_width        :: Int+  , videoMode_height       :: Int+  , videoMode_numRedBits   :: Int+  , videoMode_numGreenBits :: Int+  , videoMode_numBlueBits  :: Int+  } deriving Show++instance Storable VideoMode where+  sizeOf    _ = (#const sizeof(GLFWvidmode))+  alignment _ = alignment (undefined :: CInt)++  peek ptr = do+      w <- (#peek GLFWvidmode, Width)     ptr :: IO CInt+      h <- (#peek GLFWvidmode, Height)    ptr :: IO CInt+      r <- (#peek GLFWvidmode, RedBits)   ptr :: IO CInt+      g <- (#peek GLFWvidmode, GreenBits) ptr :: IO CInt+      b <- (#peek GLFWvidmode, BlueBits)  ptr :: IO CInt+      return VideoMode+        { videoMode_width        = fromC w+        , videoMode_height       = fromC h+        , videoMode_numRedBits   = fromC r+        , videoMode_numGreenBits = fromC g+        , videoMode_numBlueBits  = fromC b+        }++-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --+-- Window management++openWindow :: DisplayOptions -> IO Bool+openWindow displayOptions = do+    let DisplayOptions+          { displayOptions_width               = _displayOptions_width+          , displayOptions_height              = _displayOptions_height+          , displayOptions_numRedBits          = _displayOptions_numRedBits+          , displayOptions_numGreenBits        = _displayOptions_numGreenBits+          , displayOptions_numBlueBits         = _displayOptions_numBlueBits+          , displayOptions_numAlphaBits        = _displayOptions_numAlphaBits+          , displayOptions_numDepthBits        = _displayOptions_numDepthBits+          , displayOptions_numStencilBits      = _displayOptions_numStencilBits+          , displayOptions_displayMode         = _displayOptions_displayMode+          , displayOptions_refreshRate         = _displayOptions_refreshRate+          , displayOptions_accumNumRedBits     = _displayOptions_accumNumRedBits+          , displayOptions_accumNumGreenBits   = _displayOptions_accumNumGreenBits+          , displayOptions_accumNumBlueBits    = _displayOptions_accumNumBlueBits+          , displayOptions_accumNumAlphaBits   = _displayOptions_accumNumAlphaBits+          , displayOptions_numAuxiliaryBuffers = _displayOptions_numAuxiliaryBuffers+          , displayOptions_numFsaaSamples      = _displayOptions_numFsaaSamples+          , displayOptions_windowIsResizable   = _displayOptions_windowIsResizable+          , displayOptions_stereoRendering     = _displayOptions_stereoRendering+          } = displayOptions++    -- Add hints.+    when (isJust _displayOptions_refreshRate)         $ glfwOpenWindowHint (#const GLFW_REFRESH_RATE)     (toC (fromJust _displayOptions_refreshRate))+    when (isJust _displayOptions_accumNumRedBits)     $ glfwOpenWindowHint (#const GLFW_ACCUM_RED_BITS)   (toC (fromJust _displayOptions_accumNumRedBits))+    when (isJust _displayOptions_accumNumGreenBits)   $ glfwOpenWindowHint (#const GLFW_ACCUM_GREEN_BITS) (toC (fromJust _displayOptions_accumNumGreenBits))+    when (isJust _displayOptions_accumNumBlueBits)    $ glfwOpenWindowHint (#const GLFW_ACCUM_BLUE_BITS)  (toC (fromJust _displayOptions_accumNumBlueBits))+    when (isJust _displayOptions_accumNumAlphaBits)   $ glfwOpenWindowHint (#const GLFW_ACCUM_ALPHA_BITS) (toC (fromJust _displayOptions_accumNumAlphaBits))+    when (isJust _displayOptions_numAuxiliaryBuffers) $ glfwOpenWindowHint (#const GLFW_AUX_BUFFERS)      (toC (fromJust _displayOptions_numAuxiliaryBuffers))+    when (isJust _displayOptions_numFsaaSamples)      $ glfwOpenWindowHint (#const GLFW_FSAA_SAMPLES)     (toC (fromJust _displayOptions_numFsaaSamples))++    glfwOpenWindowHint (#const GLFW_WINDOW_NO_RESIZE) (toC (not _displayOptions_windowIsResizable))+    glfwOpenWindowHint (#const GLFW_STEREO)           (toC      _displayOptions_stereoRendering)++    -- Open the window.+    fromC `fmap` glfwOpenWindow+      (toC _displayOptions_width)+      (toC _displayOptions_height)+      (toC _displayOptions_numRedBits)+      (toC _displayOptions_numGreenBits)+      (toC _displayOptions_numBlueBits)+      (toC _displayOptions_numAlphaBits)+      (toC _displayOptions_numDepthBits)+      (toC _displayOptions_numStencilBits)+      (toC _displayOptions_displayMode)++closeWindow :: IO ()+closeWindow =+    glfwCloseWindow++setWindowTitle :: String -> IO ()+setWindowTitle t =+    withCString t glfwSetWindowTitle++setWindowDimensions :: Int -> Int -> IO ()+setWindowDimensions w h =+    glfwSetWindowSize (toC w) (toC h)++setWindowPosition :: Int -> Int -> IO ()+setWindowPosition w h =+    glfwSetWindowPos (toC w) (toC h)++iconifyWindow :: IO ()+iconifyWindow =+    glfwIconifyWindow++restoreWindow :: IO ()+restoreWindow =+    glfwRestoreWindow++swapBuffers :: IO ()+swapBuffers =+    glfwSwapBuffers++setWindowBufferSwapInterval :: Int -> IO ()+setWindowBufferSwapInterval =+    glfwSwapInterval . toC++-- -- -- -- -- -- -- -- -- --++data DisplayMode+  = Window+  | Fullscreen+  deriving (Show)++instance C DisplayMode CInt where+  toC dm = case dm of+      Window     -> #const GLFW_WINDOW+      Fullscreen -> #const GLFW_FULLSCREEN++  fromC i = case i of+      (#const GLFW_WINDOW    ) -> Window+      (#const GLFW_FULLSCREEN) -> Fullscreen+      _                        -> makeFromCError "DisplayMode" i++-- -- -- -- -- -- -- -- -- --++data DisplayOptions = DisplayOptions+  { displayOptions_width               :: Int+  , displayOptions_height              :: Int+  , displayOptions_numRedBits          :: Int+  , displayOptions_numGreenBits        :: Int+  , displayOptions_numBlueBits         :: Int+  , displayOptions_numAlphaBits        :: Int+  , displayOptions_numDepthBits        :: Int+  , displayOptions_numStencilBits      :: Int+  , displayOptions_displayMode         :: DisplayMode+  , displayOptions_refreshRate         :: Maybe Int+  , displayOptions_accumNumRedBits     :: Maybe Int+  , displayOptions_accumNumGreenBits   :: Maybe Int+  , displayOptions_accumNumBlueBits    :: Maybe Int+  , displayOptions_accumNumAlphaBits   :: Maybe Int+  , displayOptions_numAuxiliaryBuffers :: Maybe Int+  , displayOptions_numFsaaSamples      :: Maybe Int+  , displayOptions_windowIsResizable   :: Bool+  , displayOptions_stereoRendering     :: Bool+  } deriving (Show)++defaultDisplayOptions :: DisplayOptions+defaultDisplayOptions =+    DisplayOptions+      { displayOptions_width               = 0+      , displayOptions_height              = 0+      , displayOptions_numRedBits          = 0+      , displayOptions_numGreenBits        = 0+      , displayOptions_numBlueBits         = 0+      , displayOptions_numAlphaBits        = 0+      , displayOptions_numDepthBits        = 0+      , displayOptions_numStencilBits      = 0+      , displayOptions_displayMode         = Window+      , displayOptions_refreshRate         = Nothing+      , displayOptions_accumNumRedBits     = Nothing+      , displayOptions_accumNumGreenBits   = Nothing+      , displayOptions_accumNumBlueBits    = Nothing+      , displayOptions_accumNumAlphaBits   = Nothing+      , displayOptions_numAuxiliaryBuffers = Nothing+      , displayOptions_numFsaaSamples      = Nothing+      , displayOptions_windowIsResizable   = True+      , displayOptions_stereoRendering     = False+      }++-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --+-- Window information++windowIsOpen :: IO Bool+windowIsOpen =+    fromC `fmap` glfwGetWindowParam (#const GLFW_OPENED)++windowIsActive :: IO Bool+windowIsActive =+    fromC `fmap` glfwGetWindowParam (#const GLFW_ACTIVE)++windowIsIconified :: IO Bool+windowIsIconified =+    fromC `fmap` glfwGetWindowParam (#const GLFW_ICONIFIED)++windowIsResizable :: IO Bool+windowIsResizable =+    (not . fromC) `fmap` glfwGetWindowParam (#const GLFW_WINDOW_NO_RESIZE)++windowIsHardwareAccelerated :: IO Bool+windowIsHardwareAccelerated =+    fromC `fmap` glfwGetWindowParam (#const GLFW_ACCELERATED)++windowSupportsStereoRendering :: IO Bool+windowSupportsStereoRendering =+    fromC `fmap` glfwGetWindowParam (#const GLFW_STEREO)++getWindowRefreshRate :: IO Int+getWindowRefreshRate =+    fromC `fmap` glfwGetWindowParam (#const GLFW_REFRESH_RATE)++getWindowDimensions :: IO (Int, Int)+getWindowDimensions =+    alloca $ \wp ->+    alloca $ \hp -> do+        glfwGetWindowSize wp hp+        w <- peek wp+        h <- peek hp+        return (fromC w, fromC h)++getWindowValue :: WindowValue -> IO Int+getWindowValue wn =+    fromC `fmap` glfwGetWindowParam (toC wn)++setWindowCloseCallback :: WindowCloseCallback -> IO ()+setWindowCloseCallback cb = do+    ccb <- wrapWindowCloseCallback (toC `fmap` cb)+    glfwSetWindowCloseCallback ccb+    storeCallback windowCloseCallback ccb++setWindowSizeCallback :: WindowSizeCallback -> IO ()+setWindowSizeCallback cb = do+    ccb <- wrapWindowSizeCallback (\w h -> cb (fromC w) (fromC h))+    glfwSetWindowSizeCallback ccb+    storeCallback windowSizeCallback ccb++setWindowRefreshCallback :: WindowRefreshCallback -> IO ()+setWindowRefreshCallback cb = do+    ccb <- wrapWindowRefreshCallback cb+    glfwSetWindowRefreshCallback ccb+    storeCallback windowRefreshCallback ccb++-- -- -- -- -- -- -- -- -- --++data WindowValue+  = NumRedBits+  | NumGreenBits+  | NumBlueBits+  | NumAlphaBits+  | NumDepthBits+  | NumStencilBits+  | NumAccumRedBits+  | NumAccumGreenBits+  | NumAccumBlueBits+  | NumAccumAlphaBits+  | NumAuxBuffers+  | NumFsaaSamples+  deriving (Bounded, Enum, Eq, Show)++instance C WindowValue CInt where+  toC wn = case wn of+      NumRedBits        -> #const GLFW_RED_BITS+      NumGreenBits      -> #const GLFW_GREEN_BITS+      NumBlueBits       -> #const GLFW_BLUE_BITS+      NumAlphaBits      -> #const GLFW_ALPHA_BITS+      NumDepthBits      -> #const GLFW_DEPTH_BITS+      NumStencilBits    -> #const GLFW_STENCIL_BITS+      NumAccumRedBits   -> #const GLFW_ACCUM_RED_BITS+      NumAccumGreenBits -> #const GLFW_ACCUM_GREEN_BITS+      NumAccumBlueBits  -> #const GLFW_ACCUM_BLUE_BITS+      NumAccumAlphaBits -> #const GLFW_ACCUM_ALPHA_BITS+      NumAuxBuffers     -> #const GLFW_AUX_BUFFERS+      NumFsaaSamples    -> #const GLFW_FSAA_SAMPLES++-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --+-- Input++pollEvents :: IO ()+pollEvents =+    glfwPollEvents++waitEvents :: IO ()+waitEvents =+    glfwWaitEvents++-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --+-- Keyboard++keyIsPressed :: Key -> IO Bool+keyIsPressed k =+    fromC `fmap` glfwGetKey (toC k)++setCharCallback :: CharCallback -> IO ()+setCharCallback cb = do+    ccb <- wrapCharCallback (\c b -> cb (fromC c) (fromC b))+    glfwSetCharCallback ccb+    storeCallback charCallback ccb++setKeyCallback :: KeyCallback -> IO ()+setKeyCallback cb = do+    ccb <- wrapKeyCallback (\k b -> cb (fromC k) (fromC b))+    glfwSetKeyCallback ccb+    storeCallback keyCallback ccb++-- -- -- -- -- -- -- -- -- --++data Key+  = CharKey Char+  | KeyUnknown+  | KeySpace+  | KeySpecial+  | KeyEsc+  | KeyF1+  | KeyF2+  | KeyF3+  | KeyF4+  | KeyF5+  | KeyF6+  | KeyF7+  | KeyF8+  | KeyF9+  | KeyF10+  | KeyF11+  | KeyF12+  | KeyF13+  | KeyF14+  | KeyF15+  | KeyF16+  | KeyF17+  | KeyF18+  | KeyF19+  | KeyF20+  | KeyF21+  | KeyF22+  | KeyF23+  | KeyF24+  | KeyF25+  | KeyUp+  | KeyDown+  | KeyLeft+  | KeyRight+  | KeyLeftShift+  | KeyRightShift+  | KeyLeftCtrl+  | KeyRightCtrl+  | KeyLeftAlt+  | KeyRightAlt+  | KeyTab+  | KeyEnter+  | KeyBackspace+  | KeyInsert+  | KeyDel+  | KeyPageup+  | KeyPagedown+  | KeyHome+  | KeyEnd+  | KeyPad0+  | KeyPad1+  | KeyPad2+  | KeyPad3+  | KeyPad4+  | KeyPad5+  | KeyPad6+  | KeyPad7+  | KeyPad8+  | KeyPad9+  | KeyPadDivide+  | KeyPadMultiply+  | KeyPadSubtract+  | KeyPadAdd+  | KeyPadDecimal+  | KeyPadEqual+  | KeyPadEnter+  deriving (Eq, Show)++instance C Key CInt where+  toC k = case k of+      CharKey c      -> fromIntegral (ord c)+      KeyUnknown     -> #const GLFW_KEY_UNKNOWN+      KeySpace       -> #const GLFW_KEY_SPACE+      KeySpecial     -> #const GLFW_KEY_SPECIAL+      KeyEsc         -> #const GLFW_KEY_ESC+      KeyF1          -> #const GLFW_KEY_F1+      KeyF2          -> #const GLFW_KEY_F2+      KeyF3          -> #const GLFW_KEY_F3+      KeyF4          -> #const GLFW_KEY_F4+      KeyF5          -> #const GLFW_KEY_F5+      KeyF6          -> #const GLFW_KEY_F6+      KeyF7          -> #const GLFW_KEY_F7+      KeyF8          -> #const GLFW_KEY_F8+      KeyF9          -> #const GLFW_KEY_F9+      KeyF10         -> #const GLFW_KEY_F10+      KeyF11         -> #const GLFW_KEY_F11+      KeyF12         -> #const GLFW_KEY_F12+      KeyF13         -> #const GLFW_KEY_F13+      KeyF14         -> #const GLFW_KEY_F14+      KeyF15         -> #const GLFW_KEY_F15+      KeyF16         -> #const GLFW_KEY_F16+      KeyF17         -> #const GLFW_KEY_F17+      KeyF18         -> #const GLFW_KEY_F18+      KeyF19         -> #const GLFW_KEY_F19+      KeyF20         -> #const GLFW_KEY_F20+      KeyF21         -> #const GLFW_KEY_F21+      KeyF22         -> #const GLFW_KEY_F22+      KeyF23         -> #const GLFW_KEY_F23+      KeyF24         -> #const GLFW_KEY_F24+      KeyF25         -> #const GLFW_KEY_F25+      KeyUp          -> #const GLFW_KEY_UP+      KeyDown        -> #const GLFW_KEY_DOWN+      KeyLeft        -> #const GLFW_KEY_LEFT+      KeyRight       -> #const GLFW_KEY_RIGHT+      KeyLeftShift   -> #const GLFW_KEY_LSHIFT+      KeyRightShift  -> #const GLFW_KEY_RSHIFT+      KeyLeftCtrl    -> #const GLFW_KEY_LCTRL+      KeyRightCtrl   -> #const GLFW_KEY_RCTRL+      KeyLeftAlt     -> #const GLFW_KEY_LALT+      KeyRightAlt    -> #const GLFW_KEY_RALT+      KeyTab         -> #const GLFW_KEY_TAB+      KeyEnter       -> #const GLFW_KEY_ENTER+      KeyBackspace   -> #const GLFW_KEY_BACKSPACE+      KeyInsert      -> #const GLFW_KEY_INSERT+      KeyDel         -> #const GLFW_KEY_DEL+      KeyPageup      -> #const GLFW_KEY_PAGEUP+      KeyPagedown    -> #const GLFW_KEY_PAGEDOWN+      KeyHome        -> #const GLFW_KEY_HOME+      KeyEnd         -> #const GLFW_KEY_END+      KeyPad0        -> #const GLFW_KEY_KP_0+      KeyPad1        -> #const GLFW_KEY_KP_1+      KeyPad2        -> #const GLFW_KEY_KP_2+      KeyPad3        -> #const GLFW_KEY_KP_3+      KeyPad4        -> #const GLFW_KEY_KP_4+      KeyPad5        -> #const GLFW_KEY_KP_5+      KeyPad6        -> #const GLFW_KEY_KP_6+      KeyPad7        -> #const GLFW_KEY_KP_7+      KeyPad8        -> #const GLFW_KEY_KP_8+      KeyPad9        -> #const GLFW_KEY_KP_9+      KeyPadDivide   -> #const GLFW_KEY_KP_DIVIDE+      KeyPadMultiply -> #const GLFW_KEY_KP_MULTIPLY+      KeyPadSubtract -> #const GLFW_KEY_KP_SUBTRACT+      KeyPadAdd      -> #const GLFW_KEY_KP_ADD+      KeyPadDecimal  -> #const GLFW_KEY_KP_DECIMAL+      KeyPadEqual    -> #const GLFW_KEY_KP_EQUAL+      KeyPadEnter    -> #const GLFW_KEY_KP_ENTER++  fromC i =+      if i < #const GLFW_KEY_SPECIAL+        then CharKey (chr (fromIntegral i))+        else case i of+               (#const GLFW_KEY_UNKNOWN    ) -> KeyUnknown+               (#const GLFW_KEY_SPACE      ) -> KeySpace+               (#const GLFW_KEY_SPECIAL    ) -> KeySpecial+               (#const GLFW_KEY_ESC        ) -> KeyEsc+               (#const GLFW_KEY_F1         ) -> KeyF1+               (#const GLFW_KEY_F2         ) -> KeyF2+               (#const GLFW_KEY_F3         ) -> KeyF3+               (#const GLFW_KEY_F4         ) -> KeyF4+               (#const GLFW_KEY_F5         ) -> KeyF5+               (#const GLFW_KEY_F6         ) -> KeyF6+               (#const GLFW_KEY_F7         ) -> KeyF7+               (#const GLFW_KEY_F8         ) -> KeyF8+               (#const GLFW_KEY_F9         ) -> KeyF9+               (#const GLFW_KEY_F10        ) -> KeyF10+               (#const GLFW_KEY_F11        ) -> KeyF11+               (#const GLFW_KEY_F12        ) -> KeyF12+               (#const GLFW_KEY_F13        ) -> KeyF13+               (#const GLFW_KEY_F14        ) -> KeyF14+               (#const GLFW_KEY_F15        ) -> KeyF15+               (#const GLFW_KEY_F16        ) -> KeyF16+               (#const GLFW_KEY_F17        ) -> KeyF17+               (#const GLFW_KEY_F18        ) -> KeyF18+               (#const GLFW_KEY_F19        ) -> KeyF19+               (#const GLFW_KEY_F20        ) -> KeyF20+               (#const GLFW_KEY_F21        ) -> KeyF21+               (#const GLFW_KEY_F22        ) -> KeyF22+               (#const GLFW_KEY_F23        ) -> KeyF23+               (#const GLFW_KEY_F24        ) -> KeyF24+               (#const GLFW_KEY_F25        ) -> KeyF25+               (#const GLFW_KEY_UP         ) -> KeyUp+               (#const GLFW_KEY_DOWN       ) -> KeyDown+               (#const GLFW_KEY_LEFT       ) -> KeyLeft+               (#const GLFW_KEY_RIGHT      ) -> KeyRight+               (#const GLFW_KEY_LSHIFT     ) -> KeyLeftShift+               (#const GLFW_KEY_RSHIFT     ) -> KeyRightShift+               (#const GLFW_KEY_LCTRL      ) -> KeyLeftCtrl+               (#const GLFW_KEY_RCTRL      ) -> KeyRightCtrl+               (#const GLFW_KEY_LALT       ) -> KeyLeftAlt+               (#const GLFW_KEY_RALT       ) -> KeyRightAlt+               (#const GLFW_KEY_TAB        ) -> KeyTab+               (#const GLFW_KEY_ENTER      ) -> KeyEnter+               (#const GLFW_KEY_BACKSPACE  ) -> KeyBackspace+               (#const GLFW_KEY_INSERT     ) -> KeyInsert+               (#const GLFW_KEY_DEL        ) -> KeyDel+               (#const GLFW_KEY_PAGEUP     ) -> KeyPageup+               (#const GLFW_KEY_PAGEDOWN   ) -> KeyPagedown+               (#const GLFW_KEY_HOME       ) -> KeyHome+               (#const GLFW_KEY_END        ) -> KeyEnd+               (#const GLFW_KEY_KP_0       ) -> KeyPad0+               (#const GLFW_KEY_KP_1       ) -> KeyPad1+               (#const GLFW_KEY_KP_2       ) -> KeyPad2+               (#const GLFW_KEY_KP_3       ) -> KeyPad3+               (#const GLFW_KEY_KP_4       ) -> KeyPad4+               (#const GLFW_KEY_KP_5       ) -> KeyPad5+               (#const GLFW_KEY_KP_6       ) -> KeyPad6+               (#const GLFW_KEY_KP_7       ) -> KeyPad7+               (#const GLFW_KEY_KP_8       ) -> KeyPad8+               (#const GLFW_KEY_KP_9       ) -> KeyPad9+               (#const GLFW_KEY_KP_DIVIDE  ) -> KeyPadDivide+               (#const GLFW_KEY_KP_MULTIPLY) -> KeyPadMultiply+               (#const GLFW_KEY_KP_SUBTRACT) -> KeyPadSubtract+               (#const GLFW_KEY_KP_ADD     ) -> KeyPadAdd+               (#const GLFW_KEY_KP_DECIMAL ) -> KeyPadDecimal+               (#const GLFW_KEY_KP_EQUAL   ) -> KeyPadEqual+               (#const GLFW_KEY_KP_ENTER   ) -> KeyPadEnter+               _                             -> KeyUnknown++-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --+-- Mouse++mouseButtonIsPressed :: MouseButton -> IO Bool+mouseButtonIsPressed mb =+    fromC `fmap` glfwGetMouseButton (toC mb)++getMousePosition :: IO (Int, Int)+getMousePosition =+    alloca $ \px ->+    alloca $ \py -> do+        glfwGetMousePos px py+        x <- peek px+        y <- peek py+        return (fromC x, fromC y)++getMouseWheel :: IO Int+getMouseWheel =+    fromC `fmap` glfwGetMouseWheel++setMousePosition :: Int -> Int -> IO ()+setMousePosition x y =+    glfwSetMousePos (toC x) (toC y)++setMouseWheel :: Int -> IO ()+setMouseWheel =+    glfwSetMouseWheel . toC++setMouseButtonCallback :: MouseButtonCallback -> IO ()+setMouseButtonCallback cb = do+    ccb <- wrapMouseButtonCallback (\b p -> cb (fromC b) (fromC p))+    glfwSetMouseButtonCallback ccb+    storeCallback mouseButtonCallback ccb++setMousePositionCallback :: MousePositionCallback -> IO ()+setMousePositionCallback cb = do+    ccb <- wrapMousePositionCallback (\x y -> cb (fromC x) (fromC y))+    glfwSetMousePosCallback ccb+    storeCallback mousePositionCallback ccb++setMouseWheelCallback :: MouseWheelCallback -> IO ()+setMouseWheelCallback cb = do+    ccb <- wrapMouseWheelCallback (cb . fromC)+    glfwSetMouseWheelCallback ccb+    storeCallback mouseWheelCallback ccb++-- -- -- -- -- -- -- -- -- --++data MouseButton+  = MouseButton0 | MouseButton1 | MouseButton2 | MouseButton3+  | MouseButton4 | MouseButton5 | MouseButton6 | MouseButton7+  deriving (Bounded, Enum, Eq, Show)++instance C MouseButton CInt where+  toC mb = case mb of+      MouseButton0 -> #const GLFW_MOUSE_BUTTON_1+      MouseButton1 -> #const GLFW_MOUSE_BUTTON_2+      MouseButton2 -> #const GLFW_MOUSE_BUTTON_3+      MouseButton3 -> #const GLFW_MOUSE_BUTTON_4+      MouseButton4 -> #const GLFW_MOUSE_BUTTON_5+      MouseButton5 -> #const GLFW_MOUSE_BUTTON_6+      MouseButton6 -> #const GLFW_MOUSE_BUTTON_7+      MouseButton7 -> #const GLFW_MOUSE_BUTTON_8++  fromC i = case i of+      (#const GLFW_MOUSE_BUTTON_1) -> MouseButton0+      (#const GLFW_MOUSE_BUTTON_2) -> MouseButton1+      (#const GLFW_MOUSE_BUTTON_3) -> MouseButton2+      (#const GLFW_MOUSE_BUTTON_4) -> MouseButton3+      (#const GLFW_MOUSE_BUTTON_5) -> MouseButton4+      (#const GLFW_MOUSE_BUTTON_6) -> MouseButton5+      (#const GLFW_MOUSE_BUTTON_7) -> MouseButton6+      (#const GLFW_MOUSE_BUTTON_8) -> MouseButton7+      _                            -> makeFromCError "MouseButton" i++-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --+-- Joystick++joystickIsPresent :: Joystick -> IO Bool+joystickIsPresent j =+    fromC `fmap` glfwGetJoystickParam (toC j) (#const GLFW_PRESENT)++getNumJoystickAxes :: Joystick -> IO Int+getNumJoystickAxes j =+    fromC `fmap` glfwGetJoystickParam (toC j) (#const GLFW_AXES)++getNumJoystickButtons :: Joystick -> IO Int+getNumJoystickButtons j =+    fromC `fmap` glfwGetJoystickParam (toC j) (#const GLFW_BUTTONS)++getJoystickPosition :: Joystick -> Int -> IO [Float]+getJoystickPosition j m =+    if m < 1+      then return []+      else allocaArray m $ \ptr -> do+               n <- fromC `fmap` glfwGetJoystickPos (toC j) ptr (toC m)+               a <- peekArray n ptr+               return $ map fromC a++joystickButtonsArePressed :: Joystick -> Int -> IO [Bool]+joystickButtonsArePressed j m =+    if m < 1+      then return []+      else allocaArray m $ \ptr -> do+               n <- fromC `fmap` glfwGetJoystickButtons (toC j) ptr (toC m)+               a <- peekArray n ptr :: IO [CUChar]+               return $ map ((glfwPress ==) . fromIntegral) a++-- -- -- -- -- -- -- -- -- --++data Joystick+  = Joystick0  | Joystick1  | Joystick2  | Joystick3+  | Joystick4  | Joystick5  | Joystick6  | Joystick7+  | Joystick8  | Joystick9  | Joystick10 | Joystick11+  | Joystick12 | Joystick13 | Joystick14 | Joystick15+  deriving (Bounded, Enum, Eq, Show)++instance C Joystick CInt where+  toC j = case j of+      Joystick0  -> #const GLFW_JOYSTICK_1+      Joystick1  -> #const GLFW_JOYSTICK_2+      Joystick2  -> #const GLFW_JOYSTICK_3+      Joystick3  -> #const GLFW_JOYSTICK_4+      Joystick4  -> #const GLFW_JOYSTICK_5+      Joystick5  -> #const GLFW_JOYSTICK_6+      Joystick6  -> #const GLFW_JOYSTICK_7+      Joystick7  -> #const GLFW_JOYSTICK_8+      Joystick8  -> #const GLFW_JOYSTICK_9+      Joystick9  -> #const GLFW_JOYSTICK_10+      Joystick10 -> #const GLFW_JOYSTICK_11+      Joystick11 -> #const GLFW_JOYSTICK_12+      Joystick12 -> #const GLFW_JOYSTICK_13+      Joystick13 -> #const GLFW_JOYSTICK_14+      Joystick14 -> #const GLFW_JOYSTICK_15+      Joystick15 -> #const GLFW_JOYSTICK_16++  fromC i = case i of+      (#const GLFW_JOYSTICK_1 ) -> Joystick0+      (#const GLFW_JOYSTICK_2 ) -> Joystick1+      (#const GLFW_JOYSTICK_3 ) -> Joystick2+      (#const GLFW_JOYSTICK_4 ) -> Joystick3+      (#const GLFW_JOYSTICK_5 ) -> Joystick4+      (#const GLFW_JOYSTICK_6 ) -> Joystick5+      (#const GLFW_JOYSTICK_7 ) -> Joystick6+      (#const GLFW_JOYSTICK_8 ) -> Joystick7+      (#const GLFW_JOYSTICK_9 ) -> Joystick8+      (#const GLFW_JOYSTICK_10) -> Joystick9+      (#const GLFW_JOYSTICK_11) -> Joystick10+      (#const GLFW_JOYSTICK_12) -> Joystick11+      (#const GLFW_JOYSTICK_13) -> Joystick12+      (#const GLFW_JOYSTICK_14) -> Joystick13+      (#const GLFW_JOYSTICK_15) -> Joystick14+      (#const GLFW_JOYSTICK_16) -> Joystick15+      _                         -> makeFromCError "Joystick" i++-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --+-- Time++getTime :: IO Double+getTime =+    realToFrac `fmap` glfwGetTime++setTime :: Double -> IO ()+setTime =+    glfwSetTime . realToFrac++resetTime :: IO ()+resetTime =+    setTime (0 :: Double)++sleep :: Double -> IO ()+sleep =+    glfwSleep . realToFrac++-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --+-- Version information++getGlfwVersion :: IO Version+getGlfwVersion =+    alloca $ \p0 ->+    alloca $ \p1 ->+    alloca $ \p2 -> do+        glfwGetVersion p0 p1 p2+        v0 <- fromC `fmap` peek p0+        v1 <- fromC `fmap` peek p1+        v2 <- fromC `fmap` peek p2+        return $ Version [v0, v1, v2] []++getGlVersion :: IO Version+getGlVersion =+    alloca $ \p0 ->+    alloca $ \p1 ->+    alloca $ \p2 -> do+        glfwGetGLVersion p0 p1 p2+        v0 <- fromC `fmap` peek p0+        v1 <- fromC `fmap` peek p1+        v2 <- fromC `fmap` peek p2+        return $ Version [v0, v1, v2] []++-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --++glfwPress :: CInt+glfwPress = #const GLFW_PRESS++-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --++class C h c where+  toC   :: h -> c+  fromC :: c -> h++  toC   = undefined+  fromC = undefined++makeFromCError :: (Show c) => String -> c -> a+makeFromCError s c = error (s ++ " fromC: no match for " ++ show c)++-- -- -- -- -- -- -- -- -- --++instance C Bool CInt where+  toC False = #const GL_FALSE+  toC True  = #const GL_TRUE++  fromC (#const GL_FALSE) = False+  fromC (#const GL_TRUE)  = True+  fromC i                 = makeFromCError "Bool" i++-- -- -- -- -- -- -- -- -- --++instance C Char CInt where+  toC   = fromIntegral . ord+  fromC = chr . fromIntegral++-- -- -- -- -- -- -- -- -- --++instance C Float CFloat where+  toC   = realToFrac+  fromC = realToFrac++-- -- -- -- -- -- -- -- -- --++instance C Int CInt where+  toC   = fromIntegral+  fromC = fromIntegral++-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --++charCallback          :: IORef (Maybe (FunPtr GlfwCharCallback))+keyCallback           :: IORef (Maybe (FunPtr GlfwKeyCallback))+mouseButtonCallback   :: IORef (Maybe (FunPtr GlfwMouseButtonCallback))+mousePositionCallback :: IORef (Maybe (FunPtr GlfwMousePositionCallback))+mouseWheelCallback    :: IORef (Maybe (FunPtr GlfwMouseWheelCallback))+windowCloseCallback   :: IORef (Maybe (FunPtr GlfwWindowCloseCallback))+windowRefreshCallback :: IORef (Maybe (FunPtr GlfwWindowRefreshCallback))+windowSizeCallback    :: IORef (Maybe (FunPtr GlfwWindowSizeCallback))++charCallback          = unsafePerformIO (newIORef Nothing)+keyCallback           = unsafePerformIO (newIORef Nothing)+mouseButtonCallback   = unsafePerformIO (newIORef Nothing)+mousePositionCallback = unsafePerformIO (newIORef Nothing)+mouseWheelCallback    = unsafePerformIO (newIORef Nothing)+windowCloseCallback   = unsafePerformIO (newIORef Nothing)+windowRefreshCallback = unsafePerformIO (newIORef Nothing)+windowSizeCallback    = unsafePerformIO (newIORef Nothing)++storeCallback :: IORef (Maybe (FunPtr a)) -> FunPtr a -> IO ()+storeCallback ior cb =+    atomicModifyIORef ior (\mcb -> (Just cb, mcb)) >>= maybe (return ()) freeHaskellFunPtr