diff --git a/Changelog.txt b/Changelog.txt
--- a/Changelog.txt
+++ b/Changelog.txt
@@ -1,80 +1,198 @@
-Fri Oct 16 10:18:31 EDT 2009  paul@thev.net
-  * make linux support generic to *nix, and bump version to 0.4.2
+Sat Jan 21 01:08:46 PST 2012  paul@thev.net
+  * update API doc for windowCloseCallback
 
-Wed Sep 16 14:00:09 EDT 2009  paul@thev.net
+Sat Jan 21 01:05:06 PST 2012  paul@thev.net
+  * update SOE url
+
+Fri Jan 20 13:17:21 PST 2012  paul@thev.net
+  * cosmetic changes before new release
+
+Fri Jan 20 09:55:56 PST 2012  paul@thev.net
+  * update README
+
+Fri Jan 20 02:45:53 PST 2012  Marc Sunet <jeannekamikaze@gmail.com>
+  * Minor docs edit. I mentioned that AutoPollEvent is enabled by default.
+
+Fri Jan 20 01:34:45 PST 2012  paul@thev.net
+  * use a record for confState
+
+Fri Jan 20 01:34:19 PST 2012  paul@thev.net
+  * update README
+
+Fri Jan 20 01:06:41 PST 2012  paul@thev.net
+  * re-org haddock comments
+
+Thu Jan 19 22:55:43 PST 2012  paul@thev.net
+  * fix example to match new param API
+
+Thu Jan 19 14:24:38 PST 2012  paul@thev.net
+  * revert back to atexit on x11
+
+Thu Jan 19 12:37:13 PST 2012  Marc Sunet <jeannekamikaze@gmail.com>
+  * Fixed X11 build.
+  X11 build now detects the directory where the X11 files are installed and passes that as an include 
+  directory to gcc.
+  Edited .cabal file so that the X11 section is triggered on FreeBSD, not only on Linux.
+
+Wed Jan 18 01:32:08 PST 2012  Marc Sunet <jeannekamikaze@gmail.com>
+  * Added myself to the maintainer list.
+
+Mon Jan 16 14:10:07 PST 2012  paul@thev.net
+  * clean up Setup.hs, and put back the x-cc-name hack for OS X
+
+Sat Jan 14 03:40:41 PST 2012  Marc Sunet <jeannekamikaze@gmail.com>
+  * Setup.hs now successfully passes the extra libs to the install process.
+  The extra libs were being passed to the build process, but not the install one, so applications would 
+  fail to link properly.
+  I haven't figured out how to pass data between hooks, so as a workaround I made the build hook write 
+  the extra libs to a temporary file which is then read by the install hook. The install hook reads the 
+  extra libs, creates a modified PackageDescription and then delegates the rest of the work to the real 
+  install process.
+
+Sat Jan 14 02:46:18 PST 2012  Marc Sunet <jeannekamikaze@gmail.com>
+  * Setup.hs now passes the extra libraries to the build process.
+
+Sat Jan 14 01:37:47 PST 2012  Marc Sunet <jeannekamikaze@gmail.com>
+  * Added Setup.hs sysctl check.
+
+Sat Jan 14 01:31:30 PST 2012  Marc Sunet <jeannekamikaze@gmail.com>
+  * Setup.hs flags auto detection.
+  I have also edited the .cabal file to add some default flags for Linux.
+
+Wed Jan 11 10:58:17 PST 2012  Marc Sunet <jeannekamikaze@gmail.com>
+  * Hint and Param type families.
+  openWindowHint and getParam substituted by param families.
+
+Mon Jan  9 02:00:58 PST 2012  Marc Sunet <jeannekamikaze@gmail.com>
+  * Added default-language: Haskell98 to cabal file.
+
+Sun Jan  8 21:19:49 PST 2012  paul@thev.net
+  * mark safe foreign calls
+
+Sun Jan  8 21:18:51 PST 2012  paul@thev.net
+  * WindowCloseCallback now returns Bool instead of ()
+
+Sun Jan  8 21:04:46 PST 2012  paul@thev.net
+  * get rid of compilation warning
+
+Thu Jan  5 06:45:05 PST 2012  Marc Sunet <jeannekamikaze@gmail.com>
+  * Documentation + glVersion
+  Documentation has been extended. Added the gettable statevar 'glVersion'.
+
+Thu Jan  5 05:51:37 PST 2012  Marc Sunet <jeannekamikaze@gmail.com>
+  * windowPos statevar added
+
+Thu Jan  5 02:51:59 PST 2012  Marc Sunet <jeannekamikaze@gmail.com>
+  * WindowParam missing constructors added.
+  I have added the missing values to the WindowParam enum. In the original glfw library WindowHint and 
+  WindowParam share enum values, so I prepended a P to WindowParam constructors to avoid name clashes. 
+  The result isn't very clean, but I suppose that since WindowHint is used more frequently it should be 
+  ok.
+
+Thu Jan  5 02:20:40 PST 2012  Marc Sunet <jeannekamikaze@gmail.com>
+  * WindowHint and openWindowHint redesign
+  Redesigned WindwoHint and openWindowHint. Also added the Profile enum.
+
+Wed Jan  4 02:30:25 PST 2012  paul@thev.net
+  * require Cabal >= 1.10, and fix building on 32-bit OS X
+
+Tue Jan  3 10:06:50 PST 2012  Marc Sunet <jeannekamikaze@gmail.com>
+  * WindowHint - OpenGL context info
+  Added the following constructors to WindowHint: OpenGLVersionMajor, OpenGLVersionMinor, 
+  OpenGLForwardCompat, OpenGLContext, OpenGLProfile.
+
+Mon Jan  2 15:01:31 PST 2012  paul@thev.net
+  * add an example (same one I wrote on HaskellWiki)
+
+Mon Jan  2 14:27:45 PST 2012  paul@thev.net
+  * use default hook when x-cc-name is not available
+
+Mon Jan  2 14:20:10 PST 2012  paul@thev.net
+  * replace atexit with on_exit on x11
+
+Mon Sep 26 01:59:21 PDT 2011  paul@thev.net
+  * upgrade to glfw-2.7.2, build darwin through gcc, and bump our version to 0.5.0.0
+
+Mon Sep 26 01:52:52 PDT 2011  paul@thev.net
+  * fix compilation warnings
+
+Mon Sep 26 01:09:24 PDT 2011  paul@thev.net
+  * change texture rendering direction to counter-clockwise in renderChar
+
+Wed Sep 16 11:00:09 PDT 2009  paul@thev.net
   * change CC option to fit Snow Leopard
 
-Wed Aug 12 20:53:18 EDT 2009  paul@thev.net
+Wed Aug 12 17:53:18 PDT 2009  paul@thev.net
   * bugfix for the dynamic flag; bump version to 0.4.1 for release.
 
-Wed Aug 12 15:53:09 EDT 2009  paul@thev.net
+Wed Aug 12 12:53:09 PDT 2009  paul@thev.net
   * update README.txt
 
-Wed Aug 12 15:52:38 EDT 2009  paul@thev.net
+Wed Aug 12 12:52:38 PDT 2009  paul@thev.net
   * addition to Work around GHC FFI bug 2594 only in GHC < 6.10
 
-Sun Aug  2 08:02:16 EDT 2009  paul@thev.net
+Sun Aug  2 05:02:16 PDT 2009  paul@thev.net
   * remove use of Int32 and make it compatible with OpenGL 2.3.0.0
 
-Sun Jun  7 00:10:07 EDT 2009  brian@lorf.org
+Sat Jun  6 21:10:07 PDT 2009  brian@lorf.org
   * Work around GHC FFI bug 2594 only in GHC < 6.10
 
-Sat Jun  6 03:03:14 EDT 2009  brian@lorf.org
+Sat Jun  6 00:03:14 PDT 2009  brian@lorf.org
   * Whitespace-only change to LICENSE.
 
-Sat Jun  6 03:01:48 EDT 2009  brian@lorf.org
+Sat Jun  6 00:01:48 PDT 2009  brian@lorf.org
   * hlint cleanliness, Haddock comment improvements.
 
-Sat Jun  6 01:37:10 EDT 2009  brian@lorf.org
+Fri Jun  5 22:37:10 PDT 2009  brian@lorf.org
   * Made small improvements to GLFW.cabal
 
-Sat Jun  6 01:10:19 EDT 2009  brian@lorf.org
+Fri Jun  5 22:10:19 PDT 2009  brian@lorf.org
   * Made small improvements to Setup.hs
 
-Wed Jun  3 09:41:31 EDT 2009  paul@thev.net
+Wed Jun  3 06:41:31 PDT 2009  paul@thev.net
   * cabal related adjustments
   1. adjust to work properly with latest cabal.
   2. add -mach=apple as a cc-option for OS X in order not to break GHC 6.10.2.
   3. add a "dynamic" flag for Linux to link to GLFW dynamic libs already in system.
 
-Tue Dec  2 22:46:37 EST 2008  brianchina60221@gmail.com
+Tue Dec  2 19:46:37 PST 2008  brianchina60221@gmail.com
   * joystick-related cleanup
 
-Mon Nov  3 18:03:56 EST 2008  shahn@cs.tu-berlin.de
+Mon Nov  3 15:03:56 PST 2008  shahn@cs.tu-berlin.de
   * add derived instance for Ord for Key and SpecialKey
 
-Sat Nov  1 20:50:32 EDT 2008  shahn@cs.tu-berlin.de
+Sat Nov  1 17:50:32 PDT 2008  shahn@cs.tu-berlin.de
   * fix 64-bug for mousePosCallback (with dirty hack)
 
-Mon Oct 27 18:41:18 EDT 2008  brianchina60221@gmail.com
+Mon Oct 27 15:41:18 PDT 2008  brianchina60221@gmail.com
   * openWindow fixes
 
-Thu Oct  2 06:04:13 EDT 2008  brianchina60221@gmail.com
+Thu Oct  2 03:04:13 PDT 2008  brianchina60221@gmail.com
   * marking more foreign imports safe
 
-Thu Oct  2 03:26:39 EDT 2008  brianchina60221@gmail.com
+Thu Oct  2 00:26:39 PDT 2008  brianchina60221@gmail.com
   * 'deteced -> detected'
 
-Thu Oct  2 03:25:35 EDT 2008  brianchina60221@gmail.com
+Thu Oct  2 00:25:35 PDT 2008  brianchina60221@gmail.com
   * some foreign imports cannot be marked unsafe
 
-Tue Sep 30 14:25:57 EDT 2008  brianchina60221@gmail.com
+Tue Sep 30 11:25:57 PDT 2008  brianchina60221@gmail.com
   * miscellaneous simplification
 
-Tue Sep 30 09:26:03 EDT 2008  brianchina60221@gmail.com
+Tue Sep 30 06:26:03 PDT 2008  brianchina60221@gmail.com
   * removed unnecessary stuff from foreign imports, added "unsafe"s
 
-Tue Sep 30 03:57:00 EDT 2008  brianchina60221@gmail.com
+Tue Sep 30 00:57:00 PDT 2008  brianchina60221@gmail.com
   * bump to 0.4, miscellaneous cleanup
 
-Sat Sep 13 19:20:00 EDT 2008  shahn@cs.tu-berlin.de
+Sat Sep 13 16:20:00 PDT 2008  shahn@cs.tu-berlin.de
   * workaround for correct mouse wheel values on 64-bit-machines
 
-Sat Sep  6 15:17:51 EDT 2008  shahn@cs.tu-berlin.de
+Sat Sep  6 12:17:51 PDT 2008  shahn@cs.tu-berlin.de
   * fix mousePosCallback bug on 64-bit machines
 
-Thu Sep  4 21:30:11 EDT 2008  paul@thev.net
+Thu Sep  4 18:30:11 PDT 2008  paul@thev.net
   * fix typo bug in disableSpecial, and improve some error msgs.
 
-Wed Sep  3 22:39:52 EDT 2008  paul@thev.net
+Wed Sep  3 19:39:52 PDT 2008  paul@thev.net
   * GLFW-0.3 init release
diff --git a/GLFW.cabal b/GLFW.cabal
--- a/GLFW.cabal
+++ b/GLFW.cabal
@@ -1,27 +1,28 @@
 name:          GLFW
-version:       0.4.2
+version:       0.5.0.0
 homepage:      http://haskell.org/haskellwiki/GLFW
-maintainer:    Paul H. Liu <paul@thev.net>
-cabal-version: >= 1.6
-build-type:    Simple
+maintainer:    Paul H. Liu <paul@thev.net>, Marc Sunet <jeannekamikaze@gmail.com>
+cabal-version: >= 1.10
+build-type:    Custom
 category:      Graphics
 synopsis:      A Haskell binding for GLFW
 description:   A Haskell binding for GLFW, a window system independent toolkit
                for writing OpenGL programs. For more information about the C
                library on which this binding is based, please see
-               <http://glfw.sourceforge.net>.
+               <http://www.glfw.org>.
 license:       BSD3
 license-file:  LICENSE
 
 extra-source-files:
   Changelog.txt
   README.txt
-  glfw/license.txt
+  example/example.lhs
+  glfw/COPYING.txt
   glfw/include/GL/glfw.h
   glfw/lib/internal.h
   glfw/lib/x11/platform.h
   glfw/lib/win32/platform.h
-  glfw/lib/macosx/platform.h
+  glfw/lib/cocoa/platform.h
 
 flag dynamic
   description: Dynamically link with GLFW C libray if your system provides it.
@@ -31,11 +32,13 @@
   build-depends:
     base   >= 3   && < 5,
     OpenGL >= 2.1 && < 3
+    
+  default-language: Haskell98
 
   exposed-modules:
     Graphics.UI.GLFW
 
-  ghc-options:   -Wall -O2
+  ghc-options:   -Wall -fspec-constr-count=6 
   if impl(ghc >= 6.8)
     ghc-options: -fwarn-tabs
 
@@ -46,6 +49,7 @@
   if flag(dynamic)
     extra-libraries: glfw
   else
+    cc-options: 
     c-sources:
       glfw/lib/enable.c
       glfw/lib/fullscreen.c
@@ -61,18 +65,18 @@
       glfw/lib/window.c
 
     if os(darwin)
-      include-dirs: glfw/lib/macosx
-      frameworks:   AGL Carbon OpenGL
-      cc-options:   -msse2
+      x-cc-name: gcc
+      include-dirs: glfw/lib/cocoa
+      frameworks:   Cocoa OpenGL
       c-sources:
-        glfw/lib/macosx/macosx_enable.c
-        glfw/lib/macosx/macosx_fullscreen.c
-        glfw/lib/macosx/macosx_glext.c
-        glfw/lib/macosx/macosx_init.c
-        glfw/lib/macosx/macosx_joystick.c
-        glfw/lib/macosx/macosx_thread.c
-        glfw/lib/macosx/macosx_time.c
-        glfw/lib/macosx/macosx_window.c
+        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
     else
       if os(mingw32)
         include-dirs:    glfw/lib/win32
@@ -87,8 +91,9 @@
           glfw/lib/win32/win32_time.c
           glfw/lib/win32/win32_window.c
       else
-        include-dirs: glfw/lib/x11
-        extra-libraries: Xrandr X11
+        include-dirs:    glfw/lib/x11
+        extra-libraries: X11 GL
+        cc-options:      -D_GLFW_USE_LINUX_JOYSTICKS
         c-sources:
           glfw/lib/x11/x11_enable.c
           glfw/lib/x11/x11_fullscreen.c
@@ -98,7 +103,7 @@
           glfw/lib/x11/x11_keysym2unicode.c
           glfw/lib/x11/x11_thread.c
           glfw/lib/x11/x11_time.c
-          glfw/lib/x11/x11_window.c
+          glfw/lib/x11/x11_window.c    
 
 source-repository head
   type:     darcs
diff --git a/Graphics/UI/GLFW.hs b/Graphics/UI/GLFW.hs
--- a/Graphics/UI/GLFW.hs
+++ b/Graphics/UI/GLFW.hs
@@ -1,15 +1,16 @@
--- | Haskell Interface to GLFW (<http://glfw.sourceforge.net>).
---   Supports GLFW API version 2.6.
+-- | Haskell Interface to GLFW (<http://www.glfw.org>).
+--   Supports GLFW API version 2.7.2.
+--
+--   GLFW thread functions are not supported by this module; use
+--   Haskell thread instead.
 
-{-# LANGUAGE CPP, ExistentialQuantification, ForeignFunctionInterface #-}
+{-# LANGUAGE CPP, ExistentialQuantification, ForeignFunctionInterface, TypeFamilies #-}
 
 module Graphics.UI.GLFW
   ( -- * Data types
     Version
   , DisplayBits(..)
   , WindowMode(..)
-  , WindowHint(..)
-  , WindowParam(..)
   , VideoMode(..)
   , KeyButtonState(..)
   , Key(..)
@@ -28,30 +29,31 @@
   , MouseButtonCallback
   , MousePosCallback
   , MouseWheelCallback
-    -- * Initialization and window functions
+    -- * Initialization and Termination
   , initialize
   , terminate
-  , videoModes
-  , desktopMode
   , version
+    -- * Window Handling
   , openWindow
-  , openWindowHint
   , closeWindow
   , windowTitle
   , windowSize
+  , windowPos
   , iconifyWindow
   , restoreWindow
   , swapBuffers
   , swapInterval
-  , windowParam
-  , joystickParam
-    -- * Event handling
+    -- * Video Modes
+  , videoModes
+  , desktopMode
+    -- * Input Handling
   , pollEvents
   , waitEvents
   , getKey
   , getMouseButton
   , mousePos
   , mouseWheel
+  , joystickParam
   , joystickPos
   , joystickPos'
   , joystickButtons
@@ -60,34 +62,62 @@
   , windowSizeCallback
   , windowCloseCallback
   , windowRefreshCallback
-    -- ** Event callbacks
+    -- ** Input callbacks
   , keyCallback
   , charCallback
   , mouseButtonCallback
   , mousePosCallback
   , mouseWheelCallback
-    -- * Other
+    -- * Timing
   , time
   , sleep
+    -- * OpenGL Extension Support
   , extensionSupported
-  , enableSpecial
-  , disableSpecial
+  , glVersion
     -- * Texture loading
   , loadTexture2D
   , loadMemoryTexture2D
     -- * Text rendering
   , renderString
-    -- * GLFW thread support functions purposefully omitted
-  ) where
+    -- * Miscellaneous
+  , enableSpecial
+  , disableSpecial
+    -- * Window parameters and hints
+  , ParamVal
+  , Param(..)
+  , Hint(..)
+  , Opened(..)
+  , Active(..)
+  , Iconified(..)
+  , Accelerated(..)
+  , RedBits(..)
+  , GreenBits(..)
+  , BlueBits(..)
+  , AlphaBits(..)
+  , DepthBits(..)
+  , StencilBits(..)
+  , RefreshRate(..)
+  , AccumRedBits(..)
+  , AccumGreenBits(..)
+  , AccumBlueBits(..)
+  , AccumAlphaBits(..)
+  , AuxBuffers(..)
+  , Stereo(..)
+  , NoResize(..)
+  , FSAASamples(..)
+  , OpenGLVersionMajor(..)
+  , OpenGLVersionMinor(..)
+  , OpenGLForwardCompat(..)
+  , OpenGLDebugContext(..)
+  , OpenGLProfile(..)
+  , Profile(..)
+) where
 
 import Control.Monad (liftM, liftM2)
 import Data.IORef    (IORef, atomicModifyIORef, newIORef, readIORef, writeIORef)
 import Foreign
 import Foreign.C
-import Foreign.Marshal
-import Graphics.Rendering.OpenGL (($=))
-import System.IO.Unsafe
-import Graphics.Rendering.OpenGL (GLfloat)
+import Graphics.Rendering.OpenGL (GLfloat, ($=))
 import qualified Graphics.Rendering.OpenGL as GL
 
 -- | Version is represented by (major, minor, revision), used
@@ -114,77 +144,115 @@
   toEnum 0x00010001 = Window
   toEnum 0x00010002 = FullScreen
   toEnum _          = error "GLFW: WindowMode toEnum out of bounds"
+  
+-- | We use type families to organize Window params that
+--   can be retrieved using 'getParam' of the 'Param' class.
+--   The value of a param 'a' is of type 'ParamVal' 'a', 
+--   where 'ParamVal' is a type family defined as follows: 
+--  
+-- > ParamVal Opened      = Bool
+-- > ParamVal Active      = Bool
+-- > ParamVal Iconified   = Bool
+-- > ParamVal Accelerated = Bool
+-- > ParamVal RedBits     = Int
+-- > ParamVal GreenBits   = Int
+-- > ParamVal BlueBits    = Int
+-- > ParamVal AlphaBits   = Int
+-- > ParamVal DepthBits   = Int
+-- > ParamVal StencilBits = Int
+-- 
+--   The following are both params and hints that can be set using 
+--   'openWindowHint' of the 'Hint' class.
+-- 
+-- > ParamVal RefreshRate         = Int
+-- > ParamVal AccumRedBits        = Int
+-- > ParamVal AccumGreenBits      = Int
+-- > ParamVal AccumBlueBits       = Int
+-- > ParamVal AccumAlphaBits      = Int
+-- > ParamVal AuxBuffers          = Int
+-- > ParamVal Stereo              = Bool
+-- > ParamVal NoResize            = Bool
+-- > ParamVal FSAASamples         = Int
+-- > ParamVal OpenGLVersionMajor  = Int
+-- > ParamVal OpenGLVersionMinor  = Int
+-- > ParamVal OpenGLForwardCompat = Bool
+-- > ParamVal OpenGLDebugContext  = Bool
+-- > ParamVal OpenGLProfile       = Profile
+--
 
--- | Window hints, used in settable variable 'openWindowHint'.
-data WindowHint
-  = RefreshRate
-  | AccumRedBits
-  | AccumGreenBits
-  | AccumBlueBits
-  | AccumAlphaButs
-  | AuxBuffers
-  | Stereo
-  | NoResize
-  | FSAASamples
-  deriving (Eq, Show)
+type family ParamVal a
 
-instance Enum WindowHint where
-  fromEnum RefreshRate    = 0x0002000B
-  fromEnum AccumRedBits   = 0x0002000C
-  fromEnum AccumGreenBits = 0x0002000D
-  fromEnum AccumBlueBits  = 0x0002000E
-  fromEnum AccumAlphaButs = 0x0002000F
-  fromEnum AuxBuffers     = 0x00020010
-  fromEnum Stereo         = 0x00020011
-  fromEnum NoResize       = 0x00020012
-  fromEnum FSAASamples    = 0x00020013
-  toEnum 0x0002000B = RefreshRate
-  toEnum 0x0002000C = AccumRedBits
-  toEnum 0x0002000D = AccumGreenBits
-  toEnum 0x0002000E = AccumBlueBits
-  toEnum 0x0002000F = AccumAlphaButs
-  toEnum 0x00020010 = AuxBuffers
-  toEnum 0x00020011 = Stereo
-  toEnum 0x00020012 = NoResize
-  toEnum 0x00020013 = FSAASamples
-  toEnum _          = error "GLFW: WindowHint toEnum out of bounds"
+class Param a where
+    getParam :: a -> IO (ParamVal a)
+    
+class Param a => Hint a where
+    openWindowHint :: a -> ParamVal a -> IO ()
+    
+data Opened = Opened
+data Active = Active
+data Iconified = Iconified
+data Accelerated = Accelerated
+data RedBits = RedBits
+data GreenBits = GreenBits
+data BlueBits = BlueBits
+data AlphaBits = AlphaBits
+data DepthBits = DepthBits
+data StencilBits = StencilBits
+data RefreshRate = RefreshRate
+data AccumRedBits = AccumRedBits
+data AccumGreenBits = AccumGreenBits
+data AccumBlueBits = AccumBlueBits
+data AccumAlphaBits = AccumAlphaBits
+data AuxBuffers = AuxBuffers
+data Stereo = Stereo
+data NoResize = NoResize
+data FSAASamples = FSAASamples
+data OpenGLVersionMajor = OpenGLVersionMajor
+data OpenGLVersionMinor = OpenGLVersionMinor
+data OpenGLForwardCompat = OpenGLForwardCompat
+data OpenGLDebugContext = OpenGLDebugContext
+data OpenGLProfile = OpenGLProfile
 
--- | Window parameters used in gettable variable 'windowParam'.
-data WindowParam
-  = Opened
-  | Active
-  | Iconified
-  | Accelerated
-  | RedBits
-  | GreenBits
-  | BlueBits
-  | AlphaBits
-  | DepthBits
-  | StencilBits
-  deriving (Eq, Show)
+type instance ParamVal Opened = Bool
+type instance ParamVal Active = Bool
+type instance ParamVal Iconified = Bool
+type instance ParamVal Accelerated = Bool
+type instance ParamVal RedBits = Int
+type instance ParamVal GreenBits = Int
+type instance ParamVal BlueBits = Int
+type instance ParamVal AlphaBits = Int
+type instance ParamVal DepthBits = Int
+type instance ParamVal StencilBits = Int
+type instance ParamVal RefreshRate = Int
+type instance ParamVal AccumRedBits = Int
+type instance ParamVal AccumGreenBits = Int
+type instance ParamVal AccumBlueBits = Int
+type instance ParamVal AccumAlphaBits = Int
+type instance ParamVal AuxBuffers = Int
+type instance ParamVal Stereo = Bool
+type instance ParamVal NoResize = Bool
+type instance ParamVal FSAASamples = Int
+type instance ParamVal OpenGLVersionMajor = Int
+type instance ParamVal OpenGLVersionMinor = Int
+type instance ParamVal OpenGLForwardCompat = Bool
+type instance ParamVal OpenGLDebugContext = Bool
+type instance ParamVal OpenGLProfile = Profile
 
-instance Enum WindowParam where
-  fromEnum Opened      = 0x00020001
-  fromEnum Active      = 0x00020002
-  fromEnum Iconified   = 0x00020003
-  fromEnum Accelerated = 0x00020004
-  fromEnum RedBits     = 0x00020005
-  fromEnum GreenBits   = 0x00020006
-  fromEnum BlueBits    = 0x00020007
-  fromEnum AlphaBits   = 0x00020008
-  fromEnum DepthBits   = 0x00020009
-  fromEnum StencilBits = 0x0002000A
-  toEnum 0x00020001 = Opened
-  toEnum 0x00020002 = Active
-  toEnum 0x00020003 = Iconified
-  toEnum 0x00020004 = Accelerated
-  toEnum 0x00020005 = RedBits
-  toEnum 0x00020006 = GreenBits
-  toEnum 0x00020007 = BlueBits
-  toEnum 0x00020008 = AlphaBits
-  toEnum 0x00020009 = DepthBits
-  toEnum 0x0002000A = StencilBits
-  toEnum _          = error "GLFW: WindowParam toEnum out of bounds"
+-- | OpenGL profiles, used in 'openWindowHint' with 'OpenGLProfile'.
+data Profile
+  = DefaultProfile
+  | OpenGLCoreProfile
+  | OpenGLCompatProfile
+  deriving (Eq, Show)
+  
+instance Enum Profile where
+  fromEnum DefaultProfile      = 0
+  fromEnum OpenGLCoreProfile   = 0x00050001
+  fromEnum OpenGLCompatProfile = 0x00050002
+  toEnum 0          = DefaultProfile
+  toEnum 0x00050001 = OpenGLCoreProfile
+  toEnum 0x00050002 = OpenGLCompatProfile
+  toEnum _          = error "GLFW: Profile toEnum out of bounds"
 
 -- | Video modes used in gettable variables 'videoModes' and 'desktopMode'.
 data VideoMode = VideoMode
@@ -447,8 +515,11 @@
 
 -- | Joystick parameters
 data JoystickParam
+  -- | Indicates whether the joystick is present.
   = Present
+  -- | Number of axes supported by the joystick.
   | Axes
+  -- | Number of buttons supported by the joystick.
   | Buttons
   deriving (Eq, Show)
 
@@ -463,11 +534,24 @@
 
 -- | Special features used in 'enableSpecial' and 'disableSpecial'.
 data SpecialFeature
+  -- | When enabled, the mouse cursor is visible and mouse coordinates are relative to the
+  --   upper left corner of the client area of the GLFW window. The coordinates are limited
+  --   to the client area of the window.
   = MouseCursor
+  -- | When enabled, keys which are pressed will not be released until they are physically
+  --   released and checked with 'getKey'.
   | StickyKey
+  -- | When enabled, mouse buttons which are pressed will not be released until they are
+  --   physically released and checked with 'getMouseButton'.
   | StickyMouseButton
+  -- | When enabled, pressing standard system key combinations, such as ALT+TAB under Windows,
+  --   will give the normal behavior.
   | SystemKey
+  -- | When enabled, the key and character callback functions are called repeatedly when a
+  --   key is held down long enough (according to the system key repeat configuration).
   | KeyRepeat
+  -- | When enabled, 'pollEvents' is automatically called each time 'swapBuffers' is called,
+  --   immediately after the buffer swap itself. Enabled by default.
   | AutoPollEvent
   deriving (Eq, Show)
 
@@ -488,9 +572,14 @@
 
 -- | Texture flag used in 'loadTexture2D' and 'loadMemoryTexture2D'.
 data TextureFlag
+  -- | Do not rescale to the closest 2^m x 2^n resolution.
   = NoRescale
+  -- | Specifies that the origin of the loaded image should be in the upper left corner
+  --   (default is the lower left corner).
   | OriginUL
+  -- | Automatically build and upload all mipmap levels.
   | BuildMipMaps
+  -- | Treat single component images as alpha maps rather than luminance maps.
   | AlphaMap
   deriving (Eq, Show)
 
@@ -524,7 +613,7 @@
 
 -- Callback function type
 type GLFWwindowsizefun    = Int -> Int -> IO ()
-type GLFWwindowclosefun   = IO ()
+type GLFWwindowclosefun   = IO Bool
 type GLFWwindowrefreshfun = IO ()
 type GLFWmousebuttonfun   = Int -> Int -> IO ()
 type GLFWmouseposfun      = Int -> Int -> IO ()
@@ -553,15 +642,25 @@
   with 0 $ \y ->
   with 0 $ \z -> do
     glfwGetVersion x y z
-    x' <- peek x
-    y' <- peek y
-    z' <- peek z
-    return (x', y', z')
+    peek3 (x, y, z)
 
 foreign import ccall unsafe glfwGetVersion :: Ptr Int -> Ptr Int -> Ptr Int -> IO ()
 
 -- | Open a window. Returns 'True' if successful, 'False' otherwise. GLFW
 --   applications can only open one window.
+--
+--   If width is zero and height is not, width will be calculated as width = 4/3 height.
+--
+--   If height is zero and width is not, height will be calculated as height = 3/4 width.
+--
+--   If both width and height are zero, width is set to 640 and height to 480.
+--
+--   Display bits default to 0 if no value is specified, meaning that particular buffer is not created.
+--
+--   In fullscreen mode a resolution that best matches the given window dimensions will be chosen.
+--
+--   In fullscreen mode the mouse cursor is hidden by default. To change the visibility of the mouse
+--   cursor, see, 'enableSpecial' and 'disableSpecial'.
 openWindow :: GL.Size -> [DisplayBits] -> WindowMode -> IO Bool
 openWindow (GL.Size w h) bits mode = do
   writeIORef fontTextures []
@@ -582,12 +681,67 @@
 -- | Close the open window and destroy the associated OpenGL context.
 foreign import ccall unsafe "glfwCloseWindow" closeWindow :: IO ()
 
--- | Set the window hints, i.e., additional window properties, before
---   openWindow.
-openWindowHint :: GL.SettableStateVar (WindowHint, Int)
-openWindowHint = GL.makeSettableStateVar setter
-  where setter (hint, val) = glfwOpenWindowHint (fromEnum hint) val
+-- | Vertical monitor refresh rate in Hz (only used for fullscreen windows).
+--   Zero means system default. Use with caution: specifying a refresh rate can override the system's settings,
+--   in which case the display may be suboptimal, fail or even damage the monitor.
+instance Hint RefreshRate where
+    openWindowHint RefreshRate = glfwOpenWindowHint 0x0002000B 
+    
+-- | Specify the number of bits for the red channel of the accumulation buffer.
+instance Hint AccumRedBits where
+    openWindowHint AccumRedBits = glfwOpenWindowHint 0x0002000C 
+    
+-- | Specify the number of bits for the green channel of the accumulation buffer.
+instance Hint AccumGreenBits where
+    openWindowHint AccumGreenBits = glfwOpenWindowHint 0x0002000D 
+    
+-- | Specify the number of bits for the blue channel of the accumulation buffer.
+instance Hint AccumBlueBits where
+    openWindowHint AccumBlueBits = glfwOpenWindowHint 0x0002000E 
+    
+-- | Specify the number of bits for the alpha channel of the accumulation buffer.
+instance Hint AccumAlphaBits where
+    openWindowHint AccumAlphaBits = glfwOpenWindowHint 0x0002000F 
 
+-- | Specify the number of auxiliary buffers.
+instance Hint AuxBuffers where
+    openWindowHint AuxBuffers = glfwOpenWindowHint 0x00020010 
+    
+-- | Specify if stereo rendering should be supported.
+--   If Stereo is requested on a call to 'openWindowHint', but no stereo rendering pixel formats / framebuffer
+--   configs are available, 'openWindow' will fail.
+instance Hint Stereo where
+    openWindowHint Stereo = glfwOpenWindowHint 0x00020011 . fromEnum 
+
+-- | Specify whether the window can be resized by the user.
+instance Hint NoResize where
+    openWindowHint NoResize = glfwOpenWindowHint 0x00020012 . fromEnum 
+    
+-- | Specify the number of samples to use for the multisampling buffer.
+instance Hint FSAASamples where
+    openWindowHint FSAASamples = glfwOpenWindowHint 0x00020013
+    
+-- | Specify the major number of the desired minimum OpenGL version.
+instance Hint OpenGLVersionMajor where
+    openWindowHint OpenGLVersionMajor = glfwOpenWindowHint 0x00020014 
+    
+-- | Specify the minor number of the desired minimum OpenGL version.
+instance Hint OpenGLVersionMinor where
+    openWindowHint OpenGLVersionMinor = glfwOpenWindowHint 0x00020015 
+
+-- | Specify whether the OpenGL context should be forward-compatible (i.e. disallow legacy functionality).
+--   This should only be used when requesting OpenGL version 3.0 or above.
+instance Hint OpenGLForwardCompat where
+    openWindowHint OpenGLForwardCompat = glfwOpenWindowHint 0x00020016 . fromEnum 
+   
+-- | Specify whether a debug context should be created.
+instance Hint OpenGLDebugContext where
+    openWindowHint OpenGLDebugContext = glfwOpenWindowHint 0x00020017 . fromEnum 
+    
+-- | Specify the OpenGL profile the context should implement. For available profiles see 'Profile'.
+instance Hint OpenGLProfile where
+    openWindowHint OpenGLProfile = glfwOpenWindowHint 0x00020018 . fromEnum 
+
 foreign import ccall unsafe glfwOpenWindowHint :: Int -> Int -> IO ()
 
 -- | Set the title of the opened window.
@@ -598,6 +752,16 @@
 foreign import ccall unsafe glfwSetWindowTitle :: CString -> IO ()
 
 -- | Get or set the size of the opened window.
+--
+--   The dimensions denote the size of the client area of the window (i.e. excluding any
+--   window borders and decorations).
+--
+--   If the window is in fullscreen mode when setting new dimensions, the video mode will
+--   be changed to a resolution that closest matches the given dimensions.
+--
+--   The setter has no effect if the window is iconified.
+--
+--   The OpenGL context is guaranteed to be preserved when the window is resized.
 windowSize :: GL.StateVar GL.Size
 windowSize = GL.makeStateVar getter setter
   where getter =
@@ -610,6 +774,16 @@
 foreign import ccall unsafe glfwGetWindowSize :: Ptr Int -> Ptr Int -> IO ()
 foreign import ccall unsafe glfwSetWindowSize :: Int -> Int -> IO ()
 
+-- | Set the position of the opened window.
+--
+--   The setter has no effect in fullscreen mode or if the window is iconified.
+--
+--   On multi-monitor systems, the behavior of the setter is ill-defined.
+windowPos :: GL.SettableStateVar GL.Position
+windowPos = GL.makeSettableStateVar $ \(GL.Position x y) -> glfwSetWindowPos x y
+
+foreign import ccall unsafe glfwSetWindowPos :: GL.GLint -> GL.GLint -> IO ()
+
 -- | Iconify the window.
 foreign import ccall unsafe "glfwIconifyWindow" iconifyWindow :: IO ()
 
@@ -619,7 +793,7 @@
 -- | Swap the back and front color buffers of the window. If 'AutoPollEvent' is
 --   enabled by 'enableSpecial' (which is the default), it also polls for new
 --   events before the swapping.
-foreign import ccall "glfwSwapBuffers" swapBuffers :: IO ()
+foreign import ccall safe "glfwSwapBuffers" swapBuffers :: IO ()
 
 -- | Set the minimum number of monitor retraces between each each buffer swap
 --   performed by 'swapBuffers'. If set to zero, buffer swaps will not be
@@ -629,10 +803,102 @@
 
 foreign import ccall unsafe glfwSwapInterval :: Int -> IO ()
 
--- | Get the value of window parameters.
-windowParam :: WindowParam -> GL.GettableStateVar Int
-windowParam = GL.makeGettableStateVar . glfwGetWindowParam . fromEnum
+-- | Query the window opened status.
+instance Param Opened where
+    getParam Opened = fmap toEnum $ glfwGetWindowParam 0x00020001
 
+-- | Query the window active status.
+instance Param Active where
+    getParam Active = fmap toEnum $ glfwGetWindowParam 0x00020002
+    
+-- | Query the window iconified status.
+instance Param Iconified where
+    getParam Iconified = fmap toEnum $ glfwGetWindowParam 0x00020003
+    
+-- | Query the window hardware accelerated status.
+instance Param Accelerated where
+    getParam Accelerated = fmap toEnum $ glfwGetWindowParam 0x00020004
+    
+-- | Query the number of bits for the red color component.
+instance Param RedBits where
+    getParam RedBits = glfwGetWindowParam 0x00020005
+    
+-- | Query the number of bits for the green color component.
+instance Param GreenBits where
+    getParam GreenBits = glfwGetWindowParam 0x00020006
+    
+-- | Query the number of bits for the blue color component.
+instance Param BlueBits where
+    getParam BlueBits = glfwGetWindowParam 0x00020007
+    
+-- | Query the number of bits for the alpha buffer.
+instance Param AlphaBits where
+    getParam AlphaBits = glfwGetWindowParam 0x00020008
+    
+-- | Query the number of bits for the depth buffer.
+instance Param DepthBits where
+    getParam DepthBits = glfwGetWindowParam 0x00020009
+    
+-- | Query the number of bits for the stencil buffer.
+instance Param StencilBits where
+    getParam StencilBits = glfwGetWindowParam 0x0002000A
+    
+-- | Query the vertical monitor refresh rate in Hz (only used for fullscreen windows).
+instance Param RefreshRate where
+    getParam RefreshRate = glfwGetWindowParam 0x0002000B
+    
+-- | Query the number of bits for the red channel of the accumulation buffer.
+instance Param AccumRedBits where
+    getParam AccumRedBits = glfwGetWindowParam 0x0002000C
+    
+-- | Query the number of bits for the green channel of the accumulation buffer.
+instance Param AccumGreenBits where
+    getParam AccumGreenBits = glfwGetWindowParam 0x0002000D
+    
+-- | Query the number of bits for the blue channel of the accumulation buffer.
+instance Param AccumBlueBits where
+    getParam AccumBlueBits = glfwGetWindowParam 0x0002000E
+    
+-- | Query the number of bits for the alpha channel of the accumulation buffer.
+instance Param AccumAlphaBits where
+    getParam AccumAlphaBits = glfwGetWindowParam 0x0002000F
+    
+-- | Query the number of auxiliary buffers.
+instance Param AuxBuffers where
+    getParam AuxBuffers = glfwGetWindowParam 0x00020010
+    
+-- | Query whether the window supports stereo rendering.
+instance Param Stereo where
+    getParam Stereo = fmap toEnum $ glfwGetWindowParam 0x00020011
+    
+-- | Query whether the window can be resized by the user.
+instance Param NoResize where
+    getParam NoResize = fmap toEnum $ glfwGetWindowParam 0x00020012
+    
+-- | Query the number used for the multisampling buffer.
+instance Param FSAASamples where
+    getParam FSAASamples = glfwGetWindowParam 0x00020013
+    
+-- | Query the OpenGL major version.
+instance Param OpenGLVersionMajor where
+    getParam OpenGLVersionMajor = glfwGetWindowParam 0x00020014
+    
+-- | Query the OpenGL minor version.
+instance Param OpenGLVersionMinor where
+    getParam OpenGLVersionMinor = glfwGetWindowParam 0x00020015
+    
+-- | Query whether the current OpenGL context is forward-compatible.
+instance Param OpenGLForwardCompat where
+    getParam OpenGLForwardCompat = fmap toEnum $ glfwGetWindowParam 0x000200016
+    
+-- | Query whether the current OpenGL context is a debug context.
+instance Param OpenGLDebugContext where
+    getParam OpenGLDebugContext = fmap toEnum $ glfwGetWindowParam 0x00020017
+    
+-- | Query the OpenGL 'Profile' implemented by the current context.
+instance Param OpenGLProfile where
+    getParam OpenGLProfile = fmap toEnum $ glfwGetWindowParam 0x00020018
+
 foreign import ccall unsafe glfwGetWindowParam :: Int -> IO Int
 
 -- | Callback type for 'windowSizeCallback'.
@@ -647,19 +913,19 @@
   glfwSetWindowSizeCallback ptr)
 
 -- glfwSetWindowSizeCallback executes the callback (see window.c), ccall cannot be marked unsafe
-foreign import ccall glfwSetWindowSizeCallback :: FunPtr GLFWwindowsizefun -> IO ()
+foreign import ccall safe glfwSetWindowSizeCallback :: FunPtr GLFWwindowsizefun -> IO ()
 
--- | Callback type for 'windowCloseCallback'.
-type WindowCloseCallback = IO ()
+-- | Callback type for 'windowCloseCallback'. The callback should return 'True' to close the window, and 'False' otherwise.
+type WindowCloseCallback = IO Bool
 
 -- | Set the function that will be called when the window is closed.
 windowCloseCallback :: GL.SettableStateVar WindowCloseCallback
 windowCloseCallback = GL.makeSettableStateVar (\f -> do
-  ptr <- glfwWrapFun0 f
+  ptr <- glfwWrapFunB f
   glfwSetCallbackIORef glfwWindowclosefun ptr
   glfwSetWindowCloseCallback ptr)
 
-foreign import ccall unsafe glfwSetWindowCloseCallback :: FunPtr GLFWwindowclosefun -> IO ()
+foreign import ccall safe glfwSetWindowCloseCallback :: FunPtr GLFWwindowclosefun -> IO ()
 
 -- | Callback type for 'windowRefreshCallback'.
 type WindowRefreshCallback = IO ()
@@ -715,16 +981,23 @@
 --   function, all window states, keyboard states and mouse states are updated.
 --   If any related callback functions are registered, these are called during
 --   the call of 'pollEvents'.
-foreign import ccall "glfwPollEvents" pollEvents :: IO ()
+--
+--   'pollEvents' is called implicitly from 'swapBuffers' if 'AutoPollEvent' is
+--   enabled (as it is by default).
+foreign import ccall safe "glfwPollEvents" pollEvents :: IO ()
 
 -- | Wait for events, such as user input and window events. The calling thread
 --   will be put to sleep until any event appears in the event queue.
 --   When events are ready, the events will be processed just as they are
 --   processed by 'pollEvents'.
-foreign import ccall "glfwWaitEvents" waitEvents :: IO ()
+foreign import ccall safe "glfwWaitEvents" waitEvents :: IO ()
 
 -- | Return a 'KeyButtonState', either 'Release' or 'Press', of the indicated
 --   key.
+--
+--   A window must be opened for the function to have any effect, and 'pollEvents',
+--   'waitEvents' or 'swapBuffers' (with 'AutoPollEvent' enabled) must be called
+--   before any keyboard events are recorded and reported by 'getKey'.
 getKey :: Enum a => a -> IO KeyButtonState
 getKey = fmap toEnum . glfwGetKey . fromEnum
 
@@ -732,12 +1005,26 @@
 
 -- | Return a 'KeyButtonState', either 'Release' or 'Press', of the indicated
 --   mouse button.
+--
+--   A window must be opened for the function to have any effect, and 'pollEvents',
+--   'waitEvents' or 'swapBuffers' (with 'AutoPollEvent' enabled) must be called
+--   before any mouse events are recorded and reported by 'getMouseButton'.
 getMouseButton :: MouseButton -> IO KeyButtonState
 getMouseButton = fmap toEnum . glfwGetMouseButton . fromEnum
 
 foreign import ccall unsafe glfwGetMouseButton :: Int -> IO Int
 
 -- | Set or get the mouse position.
+--
+--   A window must be opened for the getter to have any effect, and 'pollEvents',
+--   'waitEvents' or 'swapBuffers' (with 'AutoPollEvent' enabled) must be called
+--   before any mouse movements are recorded and reported by 'mousePos'.
+--
+--   When setting the mouse position, if the cursor is visible (not disabled), the
+--   cursor will be moved to the specified position, relative to the upper left
+--   corner of the window client area and with the Y-axis down. If the cursor is
+--   hidden (disabled), only the mouse position that is reported by the getter is
+--   changed.
 mousePos :: GL.StateVar GL.Position
 mousePos = GL.makeStateVar getter setter
   where
@@ -752,6 +1039,10 @@
 foreign import ccall unsafe glfwSetMousePos :: Int -> Int -> IO ()
 
 -- | Set or get the mouse wheel position.
+--
+--   A window must be opened for the getter to have any effect, and 'pollEvents',
+--   'waitEvents' or 'swapBuffers' (with 'AutoPollEvent' enabled) must be called
+--   before any wheel movements are recorded and reported by 'mouseWheel'.
 mouseWheel :: GL.StateVar Int
 mouseWheel = GL.makeStateVar glfwGetMouseWheel glfwSetMouseWheel
 
@@ -759,6 +1050,10 @@
 foreign import ccall unsafe glfwSetMouseWheel :: Int -> IO ()
 
 -- | Get joystick parameters.
+--
+--   The joystick information is updated every time the getter is queried.
+--
+--   No window has to be opened for joystick information to be available.
 joystickParam :: Joystick -> JoystickParam -> GL.GettableStateVar Int
 joystickParam j param = GL.makeGettableStateVar (glfwGetJoystickParam (fromEnum j) (fromEnum param))
 
@@ -767,14 +1062,22 @@
 -- | Get a certain number of axis positions for the given joystick. If the
 --   number of positions requested is is greater than the number available, the
 --   unavailable positions will be 0.
+--
+--   The joystick state is updated every time the getter is queried.
+--
+--   No window has to be opened for joystick input to be available.
 joystickPos :: Joystick -> Int -> GL.GettableStateVar [Float]
 joystickPos j n = GL.makeGettableStateVar $
   withArray (replicate n 0) $ \a -> do
-    glfwGetJoystickPos (fromEnum j) a n
+    _ <- glfwGetJoystickPos (fromEnum j) a n
     peekArray n a
 
 -- | Get joystick positions. The returned list contains the positions
 --   for all available axes for the given joystick.
+--
+--   The joystick state is updated every time the getter is queried.
+--
+--   No window has to be opened for joystick input to be available.
 joystickPos' :: Joystick -> GL.GettableStateVar [Float]
 joystickPos' j = GL.makeGettableStateVar $ do
   n <- glfwGetJoystickParam (fromEnum j) (fromEnum Axes)
@@ -786,6 +1089,10 @@
 
 -- | Get joystick button states. The returned list contains the states
 --   for all available buttons for the given joystick.
+--
+--   The joystick state is updated every time the getter is queried.
+--
+--   No window has to be opened for joystick input to be available.
 joystickButtons :: Joystick -> GL.GettableStateVar [KeyButtonState]
 joystickButtons j = GL.makeGettableStateVar $ do
   n <- glfwGetJoystickParam (fromEnum j) (fromEnum Buttons)
@@ -862,20 +1169,19 @@
 #else
       -- Work around bug in GHC FFI
       -- See http://hackage.haskell.org/trac/ghc/ticket/2594
-            ptr <- malloc
-            poke ptr x
-            x32 <- (peek (castPtr ptr)) :: IO Int32
-            poke ptr y
-            y32 <- (peek (castPtr ptr)) :: IO Int32
-            free ptr
-            return $ GL.Position (fromIntegral x32) (fromIntegral y32)
+            with 0 $ \ptr -> do
+              poke ptr x
+              x32 <- peek (castPtr ptr) :: IO Int32
+              poke ptr y
+              y32 <- peek (castPtr ptr) :: IO Int32
+              return $ GL.Position (fromIntegral x32) (fromIntegral y32)
 #endif
       ptr <- glfwWrapFun2 g
       glfwSetCallbackIORef glfwMouseposfun ptr
       glfwSetMousePosCallback ptr
 
 -- glfwSetMousePosCallback executes the callback (see input.c), ccall cannot be marked unsafe
-foreign import ccall glfwSetMousePosCallback :: FunPtr GLFWmouseposfun -> IO ()
+foreign import ccall safe glfwSetMousePosCallback :: FunPtr GLFWmouseposfun -> IO ()
 
 -- | Callback type for 'mouseWheelCallback'.
 type MouseWheelCallback = Int -> IO ()
@@ -891,25 +1197,25 @@
 #else
       -- Work around bug in GHC FFI
       -- See http://hackage.haskell.org/trac/ghc/ticket/2594
-      let g x = do
-            ptr <- malloc
-            poke ptr x
-            x32 <- (peek (castPtr ptr)) :: IO Int32
-            free ptr
-            f (fromIntegral x32)
+      let g x = with 0 \ptr -> do
+                    poke ptr x
+                    x32 <- peek (castPtr ptr) :: IO Int32
+                    f (fromIntegral x32)
       ptr <- glfwWrapFun1 g
 #endif
       glfwSetCallbackIORef glfwMousewheelfun ptr
       glfwSetMouseWheelCallback ptr
 
 -- glfwSetMouseWheelCallback executes the callback (see input.c), ccall cannot be marked unsafe
-foreign import ccall glfwSetMouseWheelCallback :: FunPtr GLFWmousewheelfun -> IO ()
+foreign import ccall safe glfwSetMouseWheelCallback :: FunPtr GLFWmousewheelfun -> IO ()
 
 -- | Get or set the value of the high precision timer. The time is measured in
 --   seconds as a double precision floating point number.
 --
 --   Unless the timer has been set by the programmer, the time is measured as
 --   the number of seconds that have passed since 'initialize' was called.
+--
+--   The resolution of the timer depends on which system the program is running on.
 time :: GL.StateVar Double
 time = GL.makeStateVar glfwGetTime glfwSetTime
 
@@ -929,6 +1235,17 @@
 
 foreign import ccall unsafe glfwExtensionSupported :: CString -> IO Int
 
+-- | Returns the version numbers for the currently used OpenGL implementation.
+glVersion :: GL.GettableStateVar Version
+glVersion = GL.makeGettableStateVar $
+  with 0 $ \x ->
+  with 0 $ \y ->
+  with 0 $ \z -> do
+    glfwGetGLVersion x y z
+    peek3 (x, y, z)
+    
+foreign import ccall unsafe glfwGetGLVersion :: Ptr Int -> Ptr Int -> Ptr Int -> IO ()
+
 -- TODO:
 -- foreign import ccall unsafe glfwGetProcAddress :: Ptr CChar -> FunPtr ?
 -- foreign import ccall unsafe glfwGetGLVersion :: Ptr Int -> Ptr Int -> Ptr Int -> IO ()
@@ -973,7 +1290,7 @@
 --   resolution using bilinear interpolation if necessary.
 loadTexture2D :: String -> [TextureFlag] -> IO Bool
 loadTexture2D fname flag = do
-  r <- flip withCString (flip glfwLoadTexture2D (readFlag flag)) fname
+  r <- withCString fname (`glfwLoadTexture2D` readFlag flag) 
   return $ toEnum r
 
 foreign import ccall unsafe glfwLoadTexture2D :: CString -> Int -> IO Int
@@ -1010,6 +1327,7 @@
 
 foreign import ccall unsafe "wrapper" glfwWrapFun2 :: (Int -> Int -> IO ()) -> IO (FunPtr (Int -> Int -> IO ()))
 foreign import ccall unsafe "wrapper" glfwWrapFun1 :: (Int -> IO ()) -> IO (FunPtr (Int -> IO ()))
+foreign import ccall unsafe "wrapper" glfwWrapFunB :: IO Bool -> IO (FunPtr (IO Bool))
 foreign import ccall unsafe "wrapper" glfwWrapFun0 :: IO () -> IO (FunPtr (IO ()))
 
 glfwSetCallbackIORef :: forall a. IORef (Maybe (FunPtr a)) -> FunPtr a -> IO ()
@@ -1028,13 +1346,14 @@
   cleanup glfwKeyfun
   cleanup glfwCharfun
   where
+    cleanup :: IORef (Maybe (FunPtr a)) -> IO ()
     cleanup ref =
       atomicModifyIORef ref (\g -> (Nothing, g)) >>=
         maybe (return ()) freeHaskellFunPtr
 
 -- text rendering
 
-fontTextures :: IORef ([(BitmapFont, GL.TextureObject)])
+fontTextures :: IORef [(BitmapFont, GL.TextureObject)]
 fontTextures = unsafePerformIO (newIORef [])
 
 loadFont :: BitmapFont -> IO GL.TextureObject
@@ -1057,7 +1376,7 @@
           GL.textureBinding GL.Texture2D $= Just font
           -- this next line is important, otherwise it won't render the texture!
           GL.textureFilter GL.Texture2D $= ((GL.Linear', Nothing), GL.Linear')
-          loadMemoryTexture2D bitmap [OriginUL, NoRescale]
+          _ <- loadMemoryTexture2D bitmap [OriginUL, NoRescale]
           writeIORef fontTextures ((name, font):l)
           return font
         _ -> error "GLFW: loadFont Unable to load texture"
@@ -1073,12 +1392,12 @@
   GL.preservingMatrix $ GL.renderPrimitive GL.Quads (do
     GL.texCoord (texCoord2 x y)
     GL.vertex (vertex3 0 h 0)
-    GL.texCoord (texCoord2 (x + dx) y)
-    GL.vertex (vertex3 w h 0)
+    GL.texCoord (texCoord2 x (y + dy))
+    GL.vertex (vertex3 0 0 0)
     GL.texCoord (texCoord2 (x + dx) (y + dy))
     GL.vertex (vertex3 w 0 0)
-    GL.texCoord (texCoord2 x (y + dy))
-    GL.vertex (vertex3 0 0 0))
+    GL.texCoord (texCoord2 (x + dx) y)
+    GL.vertex (vertex3 w h 0))
   GL.translate (vector3 w 0 0)
 
 -- | Render a text string using the given 'BitmapFont'. Text is rendered
@@ -1090,6 +1409,13 @@
   GL.textureBinding GL.Texture2D $= Just font
   GL.preservingMatrix $ mapM_ (renderChar font) s
   GL.texture GL.Texture2D $= GL.Disabled
+
+peek3 :: (Storable t1, Storable t2, Storable t) => (Ptr t, Ptr t1, Ptr t2) -> IO (t, t1, t2)
+peek3 (x, y, z) = do
+  x' <- peek x
+  y' <- peek y
+  z' <- peek z
+  return (x', y', z')
 
 vector3 :: GLfloat -> GLfloat -> GLfloat -> GL.Vector3 GLfloat
 vector3 = GL.Vector3
diff --git a/README.txt b/README.txt
--- a/README.txt
+++ b/README.txt
@@ -1,8 +1,9 @@
 This is a Haskell module for GLFW OpenGL framework
-(http://glfw.sourceforge.net). It provides an alternative
+(http://www.glfw.org). It provides an alternative
 to GLUT for OpenGL based Haskell programs.
 
-SOE (http://www.haskell.org/soe) now depends on this package.
+SOE (http://www.cs.yale.edu/homes/hudak/SOE/) now 
+depends on this package.
 
 The website for this Haskell module is at Haskell Wiki site:
 http://haskell.org/haskellwiki/GLFW
@@ -18,7 +19,7 @@
 ============
 
 The package comes together with a (partial) source distribution 
-of GLFW v2.6, which is compiled and installed together with
+of GLFW v2.7.2, which is compiled and installed together with
 the Haskell package.
 
 If you already have the Haskell package cabal-install, you can
@@ -70,11 +71,16 @@
 done by providing "--flags=dynamic" as an option to cabal configure
 command. 
 
+For Mac users, unfortunately interactively running GLFW programs
+from GHCi would result in a crash. The only sensible way is to 
+compile and run the program. On the other hand, it no longer 
+requires the enableGUI trick.
+
 =============
 Package Usage
 =============
 
-The package is tested with GHC 6.8.3 as well GHC 6.10.3 on all
+The package is tested with GHC 6.10.2 and GHC 7.0.2 on all
 three platforms (Linux, Win32/MinGW, and Mac OS X). Though it may
 work with older versions of GHC or even Hugs, they are not tested.
 
@@ -121,4 +127,4 @@
   http://projects.haskell.org/cgi-bin/mailman/listinfo/glfw
 
 --
-Last Updated: Wed Aug 12 EDT 2009
+Last Updated: Fri Jan 20 PST 2012
diff --git a/Setup.hs b/Setup.hs
--- a/Setup.hs
+++ b/Setup.hs
@@ -1,6 +1,229 @@
+{- source partly taken from http://wewantarock.wordpress.com/tag/cabal/ -}
 module Main (main) where
 
-import Distribution.Simple (defaultMain)
+import Distribution.Simple
+import Distribution.Simple.Setup
+import Distribution.Simple.Utils (rawSystemStdInOut, withTempFile)
+import Distribution.Simple.LocalBuildInfo
+import Distribution.Simple.Program
+import Distribution.Verbosity
+import Distribution.PackageDescription
+import Distribution.System
+import System.FilePath
+import System.Directory
+import Control.Monad.State
+import Control.Monad.Trans.Class (lift)
+import System.IO (hClose, hPutStr)
+import System.Cmd (rawSystem)
+import Data.Maybe (fromJust)
+import Foreign (bitSize)
+import System.Exit 
 
 main :: IO ()
-main = defaultMain
+main = defaultMainWithHooks $ simpleUserHooks 
+    { confHook = myConfHook 
+    , buildHook = myBuildHook
+    }
+    
+myConfHook pkg_descr flags = do
+    let verbosity = fromFlag (configVerbosity flags)
+    lbi <- confHook simpleUserHooks pkg_descr flags
+    cfg <- (case buildOS of
+                        Windows -> configureWindows 
+                        OSX     -> configureOSX
+                        _       -> configureUnix) verbosity
+    let info  = emptyBuildInfo
+              { ccOptions = confFlags cfg
+              , extraLibs = confLibs cfg
+              }
+        descr = updatePackageDescription (Just info, []) (localPkgDescr lbi)
+    return $ lbi { localPkgDescr = descr } 
+
+myBuildHook pkg_descr local_bld_info user_hooks bld_flags =
+    do
+    let lib       = fromJust (library pkg_descr)
+        lib_bi    = libBuildInfo lib
+        custom_bi = customFieldsBI lib_bi
+    case lookup "x-cc-name" custom_bi of
+      Nothing -> buildHook simpleUserHooks pkg_descr local_bld_info user_hooks bld_flags
+      Just cpp_name -> do
+        let cpp_name  = fromJust (lookup "x-cc-name" custom_bi)
+            c_srcs    = cSources lib_bi
+            mbits     = bitSize (undefined :: Int)
+            cc_opts   = ("-m" ++ show mbits) : "-S" : ccOptions lib_bi
+            inc_dirs  = includeDirs lib_bi
+            lib_dirs  = extraLibDirs lib_bi
+            bld_dir   = buildDir local_bld_info
+            prog      = ConfiguredProgram { programId = cpp_name, programVersion = Nothing,
+                                            programDefaultArgs = [], programOverrideArgs = [],
+                                            programLocation = FoundOnSystem { locationPath = cpp_name } }
+        -- Compile C/C++ sources
+        putStrLn $ "invoking my compile phase " ++ cpp_name
+        objs <- mapM (compileCxx prog cc_opts inc_dirs bld_dir) c_srcs
+        -- Remove C/C++ source code from the hooked build (don't change libs)
+        let 
+            lib_bi'    = lib_bi { cSources = map replaceWithAsm c_srcs }
+            lib'       = lib    { libBuildInfo = lib_bi' }
+            pkg_descr' = pkg_descr { library = Just lib' }
+        -- The following line invokes the standard build behaviour
+        putStrLn "Invoke default build hook"
+        buildHook simpleUserHooks pkg_descr' local_bld_info user_hooks bld_flags
+
+compileCxx :: ConfiguredProgram  -- ^ C/C++ compiler (gcc)
+           -> [String]           -- ^ Compile options from Cabal and wxConfig
+           -> [String]           -- ^ Include paths from Cabal and wxConfig
+           -> FilePath           -- ^ Base output directory
+           -> FilePath           -- ^ Path to source file
+           -> IO FilePath        -- ^ Path to generated object code
+compileCxx gcc opts incls out_path cxx_src = do
+    let includes  = map ("-I" ++) incls
+        -- out_path' = normalisePath out_path
+        -- cxx_src'  = normalisePath cxx_src
+        -- out_file  = out_path </> dropFileName cxx_src </>
+        --                replaceExtension (takeFileName cxx_src) ".o"
+        out_file = replaceWithAsm cxx_src
+        out       = ["-c", cxx_src, "-o", out_file]
+        -- opts     = opts ++ osCompileOpts
+        do_it     = True -- needsCompiling cxx_src out_file
+    when do_it $ createDirectoryIfMissing True (dropFileName out_file) >> 
+                 runProgram verbose gcc (includes ++ opts ++ out)
+    return out_file
+
+replaceWithAsm p = replaceExtension p ".s"
+
+type Flags = [String]
+type Libs  = [String]
+
+data ConfState = ConfState { confFlags :: Flags, confLibs :: Libs }
+
+emptyCfg = ConfState [] []
+
+addFlag :: String -> StateT ConfState IO ()
+addFlag flag = modify $ \(ConfState fs ls) -> ConfState (flag:fs) ls
+
+addLib :: String -> StateT ConfState IO ()
+addLib lib = modify $ \(ConfState fs ls) -> ConfState fs (lib:ls)
+   
+configureWindows :: Verbosity -> IO ConfState
+configureWindows verbosity = return emptyCfg
+
+configureOSX :: Verbosity -> IO ConfState
+configureOSX verbosity = return emptyCfg
+
+configureUnix :: Verbosity -> IO ConfState
+configureUnix verbosity = do
+    cfg <- execStateT configureUnix' $ ConfState [] []
+    when (verbosity > normal) $ putStrLn $ unlines $ 
+        map unwords [ "Flags:" : confFlags cfg, "Libs:" : confLibs cfg ]
+    return cfg
+    where 
+      check' test = check verbosity (performTest verbosity test)
+      configureUnix' :: StateT ConfState IO ()
+      configureUnix' = do
+          checkLibDir "/usr/X11" `orelse`
+            checkLibDir "/usr/X11R7" `orelse`
+            checkLibDir "/usr/X11R6" `orelse`
+            checkLibDir "/usr/X11R5" `orelse`
+            checkLibDir "/opt/X11R6" `orelse`
+            checkLibDir "/usr/X"
+          check' progXrandr  "Xrandr"  ["-D_GLFW_HAS_XRANDR"]      ["Xrandr"] `orelse`
+            check' progVidMode "VidMode" ["-D_GLFW_HAS_XF86VIDMODE"] ["Xxf86vm", "Xext"]
+          check' progGlXGetProcAddress    "glXGetProcAddress"    ["-D_GLFW_HAS_GLXGETPROCADDRESS"]    [] `orelse`
+            check' progGlXGetProcAddressARB "glXGetProcAddressARB" ["-D_GLFW_HAS_GLXGETPROCADDRESSARB"] [] `orelse`
+            check' progGlXGetProcAddressEXT "glXGetProcAddressEXT" ["-D_GLFW_HAS_GLXGETPROCADDRESSEXT"] [] `orelse`
+            check' progDlOpen               "dlopen"               ["-D_GLFW_HAS_DLOPEN"]               []
+          check' progSysConf "sysconf" ["-D_GLFW_HAS_SYSCONF"] []
+          check' progSysCtl  "sysctl"  ["-D_GLFW_HAS_SYSCTL"]  []
+          return ()
+
+f `orelse` g = f >>= \b -> if b then return b else g
+
+
+
+checkLibDir :: String -> StateT ConfState IO Bool
+checkLibDir dir = do
+	result <- lift $ doesDirectoryExist (dir ++ "/lib")
+	when (result) $ addFlag ("-I" ++ dir ++ "/include")
+	return result
+
+check :: Verbosity -> (Flags -> IO Bool) -> String -> Flags -> Libs -> StateT ConfState IO Bool
+check verbosity performCheck name flags libs = do
+    when (verbosity >= normal) $ lift . putStr $ "Checking for " ++ name ++ " support..."
+    success <- get >>= lift . performCheck . confFlags
+    when (verbosity >= normal) $ lift . putStrLn $ if success then "yes" else "no"
+    when success $ mapM_ addFlag flags >> mapM_ addLib libs
+    return success
+    
+performTest :: Verbosity -> String -> Flags -> IO Bool
+performTest verbosity contents flags = do
+    tmpDir  <- getTemporaryDirectory
+    withTempFile tmpDir "glfw-test.c" $ \path inHandle -> 
+      withTempFile tmpDir "glfw-test.o" $ \objPath outHandle -> do
+        hClose outHandle
+        hPutStr inHandle contents
+        hClose inHandle
+        (out, err, exitCode) <- rawSystemStdInOut verbosity "cc" (["-c", path, "-o", objPath] ++ flags) Nothing False
+        return (exitCode == ExitSuccess)     
+
+progXrandr = unlines
+            ["#include <X11/Xlib.h>"
+            ,"#include <X11/extensions/Xrandr.h>"
+            ,"int main() {return 0;}"
+            ]
+    
+progVidMode = unlines
+            ["#include <X11/Xlib.h>"
+            ,"#include <X11/extensions/xf86vmode.h>"
+            ,"#if defined(__APPLE_CC__)"
+            ,"#error Not supported under Mac OS X"
+            ,"#endif"
+            ,"int main() {return 0;}"
+            ]
+          
+progGlXGetProcAddress = unlines
+            ["#include <X11/Xlib.h>"
+            ,"#include <GL/glx.h>"
+            ,"#include <GL/gl.h>"
+            ,"int main() {void *ptr=(void*)glXGetProcAddress(\"glFun\"); return 0;}"
+            ]
+          
+progGlXGetProcAddressARB = unlines
+            ["#include <X11/Xlib.h>"
+            ,"#include <GL/glx.h>"
+            ,"#include <GL/gl.h>"
+            ,"int main() {void *ptr=(void*)glXGetProcAddressARB(\"glFun\"); return 0;}"
+            ]
+          
+progGlXGetProcAddressEXT = unlines
+            ["#include <X11/Xlib.h>"
+            ,"#include <GL/glx.h>"
+            ,"#include <GL/gl.h>"
+            ,"int main() {void *ptr=(void*)glXGetProcAddressEXT(\"glFun\"); return 0;}"
+            ]
+    
+progDlOpen = unlines
+            ["#include <dlfcn.h>"
+            ,"int main() {void *l=dlopen(\"libGL.so\",RTLD_LAZY|RTLD_GLOBAL); return 0;}"
+            ]
+    
+progSysConf = unlines
+            ["#include <unistd.h>"
+            ,"#ifndef _SC_NPROCESSORS_ONLN"
+            ,"#ifndef _SC_NPROC_ONLN"
+            ,"#error Neither _SC_NPROCESSORS_ONLN nor _SC_NPROC_ONLN available"
+            ,"#endif"
+            ,"#endif"
+            ,"int main() {long x=sysconf(_SC_ARG_MAX); return 0; }"
+            ]
+    
+progSysCtl = unlines
+            ["#include <sys/types.h>"
+            ,"#include <sys/sysctl.h>"
+            ,"#ifdef CTL_HW"
+            ,"#ifndef HW_NCPU"
+            ,"  error;"
+            ,"#endif"
+            ,"#endif"
+            ,"int main() { return 0; }"
+            ]
+
diff --git a/example/example.lhs b/example/example.lhs
new file mode 100644
--- /dev/null
+++ b/example/example.lhs
@@ -0,0 +1,257 @@
+[[Category:Libraries]]
+[[Category:Graphics]]
+
+== About ==
+
+This is a Haskell module for [http://www.glfw.org/ GLFW OpenGL framework]. It provides an alternative to GLUT for OpenGL based Haskell programs.
+
+== Status ==
+
+The library is being used by the [http://www.cs.yale.edu/homes/hudak/SOE/ Haskell School of Expression (SOE)] code to render Graphics in a cross-platform manner. It currently interfaces with GLFW version 2.7.2, works on Windows, Linux (i386) and Mac OS X.
+
+GLFW itself is well documented (see [http://www.glfw.org/  GLFW website]), and the Haskell module API is documented via Haddock.
+
+Not all functions are fully tested, and there are still a
+few GLFW C functions missing from the Haskell module, namely
+the image loading functions. They are excluded because image
+handling is a separate issue, and low level buffer manipulation
+would obscure their use further. Texture loading from TGA
+format is supported both from file and from memory (via a
+string buffer)..
+
+The Haskell module also provides basic text rendering while
+GLFW doesn't. It comes from a free 8x16 font which is made
+into a TGA texture, stored as a Haskell string in the file
+GLFW.hs. Text rendering
+is only possible with Alpha enabled. Again, see SOE.hs from
+the SOE package for sample usage.
+
+GLFW may not work well with GHC threads, forkIO or threadDelay.
+So avoid them if you can.
+
+
+== Download ==
+
+Current version is [http://hackage.haskell.org/cgi-bin/hackage-scripts/package/GLFW GLFW-0.5.0.0]. It works with Cabal 1.10 or later. It compiles GLFW C source code as part of the building process, please report to the package maintainer if you have build problems.
+
+
+== More information ==
+* [http://hackage.haskell.org/packages/archive/GLFW/0.5.0.0/doc/html/Graphics-UI-GLFW.html The Haddock documentation]
+* [http://www.glfw.org/ The GLFW site]
+
+
+== Sample Program ==
+
+To demonstrate the usage of GLFW for OpenGL based Haskell applications, here is a sample program that allows user to draw lines by holding the left mouse button and move the mouse.
+
+\begin{code}
+import Graphics.Rendering.OpenGL as GL
+import Graphics.UI.GLFW as GLFW
+import Graphics.Rendering.OpenGL (($=))
+import Data.IORef
+import Control.Monad
+import System.Environment (getArgs, getProgName)
+\end{code}
+
+Because the program needs to process user input, i.e., mouse button and movements, we'll use a continuation like structure for this purpose. The <hask>Action</hask> type represents an IO operation that returns the next <hask>Action</hask> to continue execution.
+
+\begin{code}
+data Action = Action (IO Action)
+\end{code}
+
+The main program is mostly book-keeping such as initializing OpenGL and GLFW, creating window, setting up viewport, etc.
+
+\begin{code}
+main = do
+  -- invoke either active or passive drawing loop depending on command line argument
+  args <- getArgs
+  prog <- getProgName
+  case args of
+    ["active"]  -> putStrLn "Running in active mode" >> main' active 
+    ["passive"] -> putStrLn "Running in passive mode" >> main' passive
+    _ -> putStrLn $ "USAGE: " ++ prog ++ " [active|passive]"
+
+main' run = do
+  GLFW.initialize
+  -- open window
+  GLFW.openWindow (GL.Size 400 400) [GLFW.DisplayAlphaBits 8] GLFW.Window
+  GLFW.windowTitle $= "GLFW Demo"
+  GL.shadeModel    $= GL.Smooth
+  -- enable antialiasing
+  GL.lineSmooth $= GL.Enabled
+  GL.blend      $= GL.Enabled
+  GL.blendFunc  $= (GL.SrcAlpha, GL.OneMinusSrcAlpha)
+  GL.lineWidth  $= 1.5
+  -- set the color to clear background
+  GL.clearColor $= Color4 0 0 0 0
+
+  -- set 2D orthogonal view inside windowSizeCallback because
+  -- any change to the Window size should result in different
+  -- OpenGL Viewport.
+  GLFW.windowSizeCallback $= \ size@(GL.Size w h) ->
+    do
+      GL.viewport   $= (GL.Position 0 0, size)
+      GL.matrixMode $= GL.Projection
+      GL.loadIdentity
+      GL.ortho2D 0 (realToFrac w) (realToFrac h) 0
+
+  -- keep all line strokes as a list of points in an IORef
+  lines <- newIORef []
+  -- run the main loop
+  run lines
+  -- finish up
+  GLFW.closeWindow
+  GLFW.terminate
+\end{code}
+
+There are usually two ways to structure the main loop of GLFW programs. One is by actively polling events before processing them. The screen buffer is usually redrawn every time before <hask>swapBuffers</hask> is called. This is the simplest main loop often seen in game applications, and may waste CPU cycles even when there is no visual update. Note that <hask>swapBuffers</hask> by default calls <hask>pollEvents</hask> implicitly, so there is no need to do a separate poll.
+
+\begin{code}
+-- we start with waitForPress action
+active lines = loop waitForPress
+  where 
+ 
+    loop action = do
+      -- draw the entire screen
+      render lines
+      -- swap buffer
+      GLFW.swapBuffers
+      -- check whether ESC is pressed for termination
+      p <- GLFW.getKey GLFW.ESC
+      unless (p == GLFW.Press) $
+        do
+            -- perform action
+            Action action' <- action
+            -- sleep for 1ms to yield CPU to other applications
+            GLFW.sleep 0.001
+
+            -- only continue when the window is not closed
+            windowOpen <- getParam Opened
+            unless (not windowOpen) $
+              loop action' -- loop with next action
+
+    waitForPress = do
+      b <- GLFW.getMouseButton GLFW.ButtonLeft
+      case b of
+        GLFW.Release -> return (Action waitForPress)
+        GLFW.Press   -> do
+          -- when left mouse button is pressed, add the point
+          -- to lines and switch to waitForRelease action.
+          (GL.Position x y) <- GL.get GLFW.mousePos 
+          modifyIORef lines (((x,y):) . ((x,y):))
+          return (Action waitForRelease)
+ 
+    waitForRelease = do
+        -- keep track of mouse movement while waiting for button 
+        -- release
+        (GL.Position x y) <- GL.get GLFW.mousePos
+        -- update the line with new ending position
+        modifyIORef lines (((x,y):) . tail)
+        b <- GLFW.getMouseButton GLFW.ButtonLeft
+        case b of
+          -- when button is released, switch back back to 
+          -- waitForPress action
+          GLFW.Release -> return (Action waitForPress)
+          GLFW.Press   -> return (Action waitForRelease)
+\end{code}
+
+Another way to structure the main loop is to register event callbacks and use <hask>waitEvents</hask>. This way we don't have to put the program to sleep every 1ms because it'll not be using any CPU cycle when there is no event to handle.
+
+One reminder in this approach is that <hask>swapBuffers</hask> must be handled with care, because it by default invokes <hask>pollEvents</hask>, which in turn invokes all callback functions. So if <hask>swapBuffers</hask> is used inside a callback, it'll create infinite loop and hang the program. To avoid it, we should disable the <hask>AutoPollEvent</hask> behavior using <hask>disableSpecial</hask>.
+
+Another optimization we can do is to use a dirty marker to remember whether the screen really needs to be redrawn. This'll not only save CPU cycles but also speed up event processing to avoid piling up events in the event queue. Similar tricks can be done to optimize the active polling approach.
+
+\begin{code}
+passive lines = do
+  -- disable auto polling in swapBuffers
+  GLFW.disableSpecial GLFW.AutoPollEvent
+
+  -- keep track of whether ESC has been pressed
+  quit <- newIORef False
+
+  -- keep track of whether screen needs to be redrawn
+  dirty <- newIORef True
+
+  -- mark screen dirty in refresh callback which is often called
+  -- when screen or part of screen comes into visibility.
+  GLFW.windowRefreshCallback $= writeIORef dirty True
+
+  -- use key callback to track whether ESC is pressed
+  GLFW.keyCallback $= \k s -> 
+     when (fromEnum k == fromEnum GLFW.ESC && s == GLFW.Press) $ 
+        writeIORef quit True
+     
+  -- Terminate the program if the window is closed
+  GLFW.windowCloseCallback $= (writeIORef quit True >> return True)
+
+  -- by default start with waitForPress
+  waitForPress dirty
+  loop dirty quit
+  where
+ 
+    loop dirty quit = do
+        GLFW.waitEvents
+        -- redraw screen if dirty
+        d <- readIORef dirty
+
+        when d $ 
+          render lines >> GLFW.swapBuffers
+
+        writeIORef dirty False
+        -- check if we need to quit the loop
+        q <- readIORef quit
+        unless q $
+          loop dirty quit
+ 
+    waitForPress dirty =
+      do
+        GLFW.mousePosCallback    $= \_ -> return ()
+
+        GLFW.mouseButtonCallback $= \b s -> 
+            when (b == GLFW.ButtonLeft && s == GLFW.Press) $
+              do
+                -- when left mouse button is pressed, add the point
+                -- to lines and switch to waitForRelease action.
+                (GL.Position x y) <- GL.get GLFW.mousePos
+                modifyIORef lines (((x,y):) . ((x,y):))
+                waitForRelease dirty
+ 
+    waitForRelease dirty = 
+      do 
+        GLFW.mousePosCallback $= \(Position x y) ->
+          do
+            -- update the line with new ending position
+            modifyIORef lines (((x,y):) . tail)
+            -- mark screen dirty
+            writeIORef dirty True
+
+        GLFW.mouseButtonCallback $= \b s ->
+            -- when left mouse button is released, switch back to
+            -- waitForPress action.
+            when (b == GLFW.ButtonLeft && s == GLFW.Release) $
+              waitForPress dirty
+\end{code}
+
+The rest of the program goes below.
+
+\begin{code}
+render lines = do
+  l <- readIORef lines
+  GL.clear [GL.ColorBuffer]
+  GL.color $ color3 1 0 0
+  GL.renderPrimitive GL.Lines $ mapM_
+      (\ (x, y) -> GL.vertex (vertex3 (fromIntegral x) (fromIntegral y) 0)) l
+ 
+
+vertex3 :: GLfloat -> GLfloat -> GLfloat -> GL.Vertex3 GLfloat
+vertex3 = GL.Vertex3
+ 
+
+color3 :: GLfloat -> GLfloat -> GLfloat -> GL.Color3 GLfloat
+color3 = GL.Color3
+\end{code}
+
+
+== More examples and external links ==
+
+A number of famous [http://nehe.gamedev.net/ NeHe OpenGL tutorials] have been translated into Haskell using GLFW and made available in the [http://hackage.haskell.org/package/nehe-tuts nehe-tuts package] by Jason Dagit. Code as well as executables are available via the package page.
diff --git a/glfw/COPYING.txt b/glfw/COPYING.txt
new file mode 100644
--- /dev/null
+++ b/glfw/COPYING.txt
@@ -0,0 +1,22 @@
+Copyright (c) 2002-2006 Marcus Geelnard
+Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org>
+
+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.
+
diff --git a/glfw/include/GL/glfw.h b/glfw/include/GL/glfw.h
--- a/glfw/include/GL/glfw.h
+++ b/glfw/include/GL/glfw.h
@@ -1,31 +1,31 @@
-//========================================================================
-// GLFW - An OpenGL framework
-// File:        glfw.h
-// API version: 2.6
-// WWW:         http://glfw.sourceforge.net
-//------------------------------------------------------------------------
-// Copyright (c) 2002-2006 Camilla Berglund
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-//    claim that you wrote the original software. If you use this software
-//    in a product, an acknowledgment in the product documentation would
-//    be appreciated but is not required.
-//
-// 2. Altered source versions must be plainly marked as such, and must not
-//    be misrepresented as being the original software.
-//
-// 3. This notice may not be removed or altered from any source
-//    distribution.
-//
-//========================================================================
+/************************************************************************
+ * GLFW - An OpenGL framework
+ * API version: 2.7
+ * WWW:         http://www.glfw.org/
+ *------------------------------------------------------------------------
+ * Copyright (c) 2002-2006 Marcus Geelnard
+ * Copyright (c) 2006-2010 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_
@@ -35,38 +35,40 @@
 #endif
 
 
-//========================================================================
-// Global definitions
-//========================================================================
+/*************************************************************************
+ * Global definitions
+ *************************************************************************/
 
-// We need a NULL pointer from time to time
+/* We need a NULL pointer from time to time */
 #ifndef NULL
  #ifdef __cplusplus
   #define NULL 0
  #else
   #define NULL ((void *)0)
  #endif
-#endif // NULL
+#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.
+/* ------------------- BEGIN SYSTEM/COMPILER SPECIFIC -------------------- */
 
-// 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)
+/* 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
+#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>)
+/* 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
@@ -74,63 +76,64 @@
   #define APIENTRY
  #endif
  #define GL_APIENTRY_DEFINED
-#endif // APIENTRY
+#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.
+/* 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
+/* 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
+  /* Microsoft Visual C++, Borland C++ Builder and Pelles C */
   #define WINGDIAPI __declspec(dllimport)
  #elif defined(__LCC__)
-  // LCC-Win32
+  /* LCC-Win32 */
   #define WINGDIAPI __stdcall
  #else
-  // Others (e.g. MinGW, Cygwin)
+  /* Others (e.g. MinGW, Cygwin) */
   #define WINGDIAPI extern
  #endif
  #define GL_WINGDIAPI_DEFINED
-#endif // WINGDIAPI
+#endif /* WINGDIAPI */
 
-// Some <GL/glu.h> files also need CALLBACK defined
+/* Some <GL/glu.h> files also need CALLBACK defined */
 #if !defined(CALLBACK) && defined(_WIN32)
  #if defined(_MSC_VER)
-  // Microsoft Visual C++
+  /* 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
+  /* Other Windows compilers */
   #define CALLBACK __stdcall
  #endif
  #define GLU_CALLBACK_DEFINED
-#endif // CALLBACK
+#endif /* CALLBACK */
 
-// Microsoft Visual C++, Borland C++ and Pelles C <GL/glu.h> needs wchar_t
+/* 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
+#endif /* _WCHAR_T_DEFINED */
 
 
-// ---------------- GLFW related system specific defines -----------------
+/* ---------------- GLFW related system specific defines ----------------- */
 
 #if defined(_WIN32) && defined(GLFW_BUILD_DLL)
 
- // We are building a Win32 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
+ /* We are calling a Win32 DLL */
  #if defined(__LCC__)
   #define GLFWAPI      extern
  #else
@@ -141,49 +144,55 @@
 
 #else
 
- // We are either building/calling a static lib or we are non-win32
+ /* We are either building/calling a static lib or we are non-win32 */
  #define GLFWAPIENTRY
  #define GLFWAPI
  #define GLFWCALL
 
 #endif
 
-// -------------------- END SYSTEM/COMPILER SPECIFIC ---------------------
+/* -------------------- 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).
+/* 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>
- #include <OpenGL/glu.h>
+ #ifndef GLFW_NO_GLU
+  #include <OpenGL/glu.h>
+ #endif
 #else
  #include <GL/gl.h>
- #include <GL/glu.h>
+ #ifndef GLFW_NO_GLU
+  #include <GL/glu.h>
+ #endif
 #endif
 
 
-//========================================================================
-// GLFW version
-//========================================================================
+/*************************************************************************
+ * GLFW version
+ *************************************************************************/
 
 #define GLFW_VERSION_MAJOR    2
-#define GLFW_VERSION_MINOR    6
-#define GLFW_VERSION_REVISION 0
+#define GLFW_VERSION_MINOR    7
+#define GLFW_VERSION_REVISION 2
 
 
-//========================================================================
-// Input handling definitions
-//========================================================================
+/*************************************************************************
+ * Input handling definitions
+ *************************************************************************/
 
-// Key and button state/action 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).
+/* 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
@@ -249,9 +258,16 @@
 #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_LAST         GLFW_KEY_KP_ENTER
+#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
+/* Mouse button definitions */
 #define GLFW_MOUSE_BUTTON_1      0
 #define GLFW_MOUSE_BUTTON_2      1
 #define GLFW_MOUSE_BUTTON_3      2
@@ -262,13 +278,13 @@
 #define GLFW_MOUSE_BUTTON_8      7
 #define GLFW_MOUSE_BUTTON_LAST   GLFW_MOUSE_BUTTON_8
 
-// Mouse button aliases
+/* 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
+/* Joystick identifiers */
 #define GLFW_JOYSTICK_1          0
 #define GLFW_JOYSTICK_2          1
 #define GLFW_JOYSTICK_3          2
@@ -288,15 +304,15 @@
 #define GLFW_JOYSTICK_LAST       GLFW_JOYSTICK_16
 
 
-//========================================================================
-// Other definitions
-//========================================================================
+/*************************************************************************
+ * Other definitions
+ *************************************************************************/
 
-// glfwOpenWindow modes
+/* glfwOpenWindow modes */
 #define GLFW_WINDOW               0x00010001
 #define GLFW_FULLSCREEN           0x00010002
 
-// glfwGetWindowParam tokens
+/* glfwGetWindowParam tokens */
 #define GLFW_OPENED               0x00020001
 #define GLFW_ACTIVE               0x00020002
 #define GLFW_ICONIFIED            0x00020003
@@ -308,8 +324,9 @@
 #define GLFW_DEPTH_BITS           0x00020009
 #define GLFW_STENCIL_BITS         0x0002000A
 
-// The following constants are used for both glfwGetWindowParam
-// and glfwOpenWindowHint
+/* 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
@@ -319,8 +336,17 @@
 #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
 
-// glfwEnable/glfwDisable tokens
+/* 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
@@ -328,36 +354,36 @@
 #define GLFW_KEY_REPEAT           0x00030005
 #define GLFW_AUTO_POLL_EVENTS     0x00030006
 
-// glfwWaitThread wait modes
+/* glfwWaitThread wait modes */
 #define GLFW_WAIT                 0x00040001
 #define GLFW_NOWAIT               0x00040002
 
-// glfwGetJoystickParam tokens
+/* 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
+/* 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_BUILD_MIPMAPS_BIT    0x00000004 /* Only for glfwLoadTexture2D */
 #define GLFW_ALPHA_MAP_BIT        0x00000008
 
-// Time spans longer than this (seconds) are considered to be infinity
+/* Time spans longer than this (seconds) are considered to be infinity */
 #define GLFW_INFINITY 100000.0
 
 
-//========================================================================
-// Typedefs
-//========================================================================
+/*************************************************************************
+ * Typedefs
+ *************************************************************************/
 
-// The video mode structure used by glfwGetVideoModes()
+/* The video mode structure used by glfwGetVideoModes() */
 typedef struct {
     int Width, Height;
     int RedBits, BlueBits, GreenBits;
 } GLFWvidmode;
 
-// Image/texture information
+/* Image/texture information */
 typedef struct {
     int Width, Height;
     int Format;
@@ -365,16 +391,16 @@
     unsigned char *Data;
 } GLFWimage;
 
-// Thread ID
+/* Thread ID */
 typedef int GLFWthread;
 
-// Mutex object
+/* Mutex object */
 typedef void * GLFWmutex;
 
-// Condition variable object
+/* Condition variable object */
 typedef void * GLFWcond;
 
-// Function pointer types
+/* Function pointer types */
 typedef void (GLFWCALL * GLFWwindowsizefun)(int,int);
 typedef int  (GLFWCALL * GLFWwindowclosefun)(void);
 typedef void (GLFWCALL * GLFWwindowrefreshfun)(void);
@@ -386,20 +412,16 @@
 typedef void (GLFWCALL * GLFWthreadfun)(void *);
 
 
-//========================================================================
-// Prototypes
-//========================================================================
+/*************************************************************************
+ * Prototypes
+ *************************************************************************/
 
-/*! @file glfw.h
- */
-// GLFW initialization, termination and version querying
-/*! @fn glfwInit
- */
+/* 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
+/* 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 );
@@ -416,11 +438,11 @@
 GLFWAPI void GLFWAPIENTRY glfwSetWindowCloseCallback( GLFWwindowclosefun cbfun );
 GLFWAPI void GLFWAPIENTRY glfwSetWindowRefreshCallback( GLFWwindowrefreshfun cbfun );
 
-// Video mode functions
+/* Video mode functions */
 GLFWAPI int  GLFWAPIENTRY glfwGetVideoModes( GLFWvidmode *list, int maxcount );
 GLFWAPI void GLFWAPIENTRY glfwGetDesktopMode( GLFWvidmode *mode );
 
-// Input handling
+/* Input handling */
 GLFWAPI void GLFWAPIENTRY glfwPollEvents( void );
 GLFWAPI void GLFWAPIENTRY glfwWaitEvents( void );
 GLFWAPI int  GLFWAPIENTRY glfwGetKey( int key );
@@ -435,22 +457,22 @@
 GLFWAPI void GLFWAPIENTRY glfwSetMousePosCallback( GLFWmouseposfun cbfun );
 GLFWAPI void GLFWAPIENTRY glfwSetMouseWheelCallback( GLFWmousewheelfun cbfun );
 
-// Joystick input
+/* 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
+/* Time */
 GLFWAPI double GLFWAPIENTRY glfwGetTime( void );
 GLFWAPI void   GLFWAPIENTRY glfwSetTime( double time );
 GLFWAPI void   GLFWAPIENTRY glfwSleep( double time );
 
-// Extension support
+/* 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
+/* Threading support */
 GLFWAPI GLFWthread GLFWAPIENTRY glfwCreateThread( GLFWthreadfun fun, void *arg );
 GLFWAPI void GLFWAPIENTRY glfwDestroyThread( GLFWthread ID );
 GLFWAPI int  GLFWAPIENTRY glfwWaitThread( GLFWthread ID, int waitmode );
@@ -466,11 +488,11 @@
 GLFWAPI void GLFWAPIENTRY glfwBroadcastCond( GLFWcond cond );
 GLFWAPI int  GLFWAPIENTRY glfwGetNumberOfProcessors( void );
 
-// Enable/disable functions
+/* Enable/disable functions */
 GLFWAPI void GLFWAPIENTRY glfwEnable( int token );
 GLFWAPI void GLFWAPIENTRY glfwDisable( int token );
 
-// Image/texture I/O support
+/* 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 );
@@ -483,4 +505,5 @@
 }
 #endif
 
-#endif // __glfw_h_
+#endif /* __glfw_h_ */
+
diff --git a/glfw/lib/cocoa/cocoa_enable.m b/glfw/lib/cocoa/cocoa_enable.m
new file mode 100644
--- /dev/null
+++ b/glfw/lib/cocoa/cocoa_enable.m
@@ -0,0 +1,51 @@
+//========================================================================
+// GLFW - An OpenGL framework
+// Platform:    Cocoa/NSOpenGL
+// API Version: 2.7
+// WWW:         http://www.glfw.org/
+//------------------------------------------------------------------------
+// Copyright (c) 2009-2010 Camilla Berglund <elmindreda@elmindreda.org>
+//
+// 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.
+}
+
diff --git a/glfw/lib/cocoa/cocoa_fullscreen.m b/glfw/lib/cocoa/cocoa_fullscreen.m
new file mode 100644
--- /dev/null
+++ b/glfw/lib/cocoa/cocoa_fullscreen.m
@@ -0,0 +1,102 @@
+//========================================================================
+// GLFW - An OpenGL framework
+// Platform:    Cocoa/NSOpenGL
+// API Version: 2.7
+// WWW:         http://www.glfw.org/
+//------------------------------------------------------------------------
+// Copyright (c) 2009-2010 Camilla Berglund <elmindreda@elmindreda.org>
+//
+// 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 && j < (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 );
+}
+
diff --git a/glfw/lib/cocoa/cocoa_glext.m b/glfw/lib/cocoa/cocoa_glext.m
new file mode 100644
--- /dev/null
+++ b/glfw/lib/cocoa/cocoa_glext.m
@@ -0,0 +1,63 @@
+//========================================================================
+// GLFW - An OpenGL framework
+// Platform:    Cocoa/NSOpenGL
+// API Version: 2.7
+// WWW:         http://www.glfw.org/
+//------------------------------------------------------------------------
+// Copyright (c) 2009-2010 Camilla Berglund <elmindreda@elmindreda.org>
+//
+// 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;
+}
+
diff --git a/glfw/lib/cocoa/cocoa_init.m b/glfw/lib/cocoa/cocoa_init.m
new file mode 100644
--- /dev/null
+++ b/glfw/lib/cocoa/cocoa_init.m
@@ -0,0 +1,297 @@
+//========================================================================
+// GLFW - An OpenGL framework
+// Platform:    Cocoa/NSOpenGL
+// API Version: 2.7
+// WWW:         http://www.glfw.org/
+//------------------------------------------------------------------------
+// Copyright (c) 2009-2010 Camilla Berglund <elmindreda@elmindreda.org>
+//
+// 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"
+
+@interface GLFWThread : NSThread
+@end
+
+@implementation GLFWThread
+
+- (void)main
+{
+}
+
+@end
+
+@interface GLFWApplication : NSApplication
+@end
+
+@implementation GLFWApplication
+
+// From http://cocoadev.com/index.pl?GameKeyboardHandlingAlmost
+// This works around an AppKit bug, where key up events while holding
+// down the command key don't get sent to the key window.
+- (void)sendEvent:(NSEvent *)event
+{
+    if( [event type] == NSKeyUp && ( [event modifierFlags] & NSCommandKeyMask ) )
+    {
+        [[self keyWindow] sendEvent:event];
+    }
+    else
+    {
+        [super sendEvent:event];
+    }
+}
+
+@end
+
+// 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];
+    }
+}
+
+//========================================================================
+// Terminate GLFW when exiting application
+//========================================================================
+
+static void glfw_atexit( void )
+{
+    glfwTerminate();
+}
+
+
+//========================================================================
+// 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
+    [GLFWApplication sharedApplication];
+
+    _glfwLibrary.OpenGLFramework =
+        CFBundleGetBundleWithIdentifier( CFSTR( "com.apple.opengl" ) );
+    if( _glfwLibrary.OpenGLFramework == NULL )
+    {
+        return GL_FALSE;
+    }
+
+    GLFWThread* thread = [[GLFWThread alloc] init];
+    [thread start];
+    [thread release];
+
+    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];
+
+    // Install atexit routine
+    atexit( glfw_atexit );
+
+    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;
+}
+
diff --git a/glfw/lib/cocoa/cocoa_joystick.m b/glfw/lib/cocoa/cocoa_joystick.m
new file mode 100644
--- /dev/null
+++ b/glfw/lib/cocoa/cocoa_joystick.m
@@ -0,0 +1,65 @@
+//========================================================================
+// GLFW - An OpenGL framework
+// Platform:    Cocoa/NSOpenGL
+// API Version: 2.7
+// WWW:         http://www.glfw.org/
+//------------------------------------------------------------------------
+// Copyright (c) 2009-2010 Camilla Berglund <elmindreda@elmindreda.org>
+//
+// 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;
+}
+
diff --git a/glfw/lib/cocoa/cocoa_thread.c b/glfw/lib/cocoa/cocoa_thread.c
new file mode 100644
--- /dev/null
+++ b/glfw/lib/cocoa/cocoa_thread.c
@@ -0,0 +1,415 @@
+//========================================================================
+// GLFW - An OpenGL framework
+// Platform:    Cocoa/NSOpenGL
+// API Version: 2.7
+// WWW:         http://www.glfw.org/
+//------------------------------------------------------------------------
+// Copyright (c) 2009-2010 Camilla Berglund <elmindreda@elmindreda.org>
+//
+// 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;
+}
+
diff --git a/glfw/lib/cocoa/cocoa_time.m b/glfw/lib/cocoa/cocoa_time.m
new file mode 100644
--- /dev/null
+++ b/glfw/lib/cocoa/cocoa_time.m
@@ -0,0 +1,105 @@
+//========================================================================
+// GLFW - An OpenGL framework
+// Platform:    Cocoa/NSOpenGL
+// API Version: 2.7
+// WWW:         http://www.glfw.org/
+//------------------------------------------------------------------------
+// Copyright (c) 2009-2010 Camilla Berglund <elmindreda@elmindreda.org>
+//
+// 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 );
+}
+
diff --git a/glfw/lib/cocoa/cocoa_window.m b/glfw/lib/cocoa/cocoa_window.m
new file mode 100644
--- /dev/null
+++ b/glfw/lib/cocoa/cocoa_window.m
@@ -0,0 +1,924 @@
+//========================================================================
+// GLFW - An OpenGL framework
+// Platform:    Cocoa/NSOpenGL
+// API Version: 2.7
+// WWW:         http://www.glfw.org/
+//------------------------------------------------------------------------
+// Copyright (c) 2009-2010 Camilla Berglund <elmindreda@elmindreda.org>
+//
+// 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 <AvailabilityMacros.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 );
+    }
+}
+
+- (void)windowDidMiniaturize:(NSNotification *)notification
+{
+    _glfwWin.iconified = GL_TRUE;
+}
+
+- (void)windowDidDeminiaturize:(NSNotification *)notification
+{
+    _glfwWin.iconified = GL_FALSE;
+}
+
+- (void)windowDidBecomeKey:(NSNotification *)notification
+{
+    _glfwWin.active = GL_TRUE;
+}
+
+- (void)windowDidResignKey:(NSNotification *)notification
+{
+    _glfwWin.active = GL_FALSE;
+    _glfwInputDeactivation();
+}
+
+- (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 */ '=',
+    /* 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, /*Function*/
+    /* 40 */ GLFW_KEY_F17,
+    /* 41 */ GLFW_KEY_KP_DECIMAL,
+    /* 42 */ -1,
+    /* 43 */ GLFW_KEY_KP_MULTIPLY,
+    /* 44 */ -1,
+    /* 45 */ GLFW_KEY_KP_ADD,
+    /* 46 */ -1,
+    /* 47 */ -1, /*KeypadClear*/
+    /* 48 */ -1, /*VolumeUp*/
+    /* 49 */ -1, /*VolumeDown*/
+    /* 4a */ -1, /*Mute*/
+    /* 4b */ GLFW_KEY_KP_DIVIDE,
+    /* 4c */ GLFW_KEY_KP_ENTER,
+    /* 4d */ -1,
+    /* 4e */ GLFW_KEY_KP_SUBTRACT,
+    /* 4f */ GLFW_KEY_F18,
+    /* 50 */ GLFW_KEY_F19,
+    /* 51 */ GLFW_KEY_KP_EQUAL,
+    /* 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 */ GLFW_KEY_F20,
+    /* 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 */ GLFW_KEY_F9,
+    /* 66 */ -1,
+    /* 67 */ GLFW_KEY_F11,
+    /* 68 */ -1,
+    /* 69 */ GLFW_KEY_F13,
+    /* 6a */ GLFW_KEY_F16,
+    /* 6b */ GLFW_KEY_F14,
+    /* 6c */ -1,
+    /* 6d */ GLFW_KEY_F10,
+    /* 6e */ -1,
+    /* 6f */ GLFW_KEY_F12,
+    /* 70 */ -1,
+    /* 71 */ GLFW_KEY_F15,
+    /* 72 */ GLFW_KEY_INSERT, /*Help*/
+    /* 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] | NSDeviceIndependentModifierFlagsMask;
+    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;
+
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
+    // Fail if OpenGL 3.3 or above was requested
+    if( wndconfig->glMajor > 3 || wndconfig->glMajor == 3 && wndconfig->glMinor > 2 )
+    {
+        return GL_FALSE;
+    }
+
+    if( wndconfig->glProfile )
+    {
+        // Fail if a profile other than core was explicitly selected
+        if( wndconfig->glProfile != GLFW_OPENGL_CORE_PROFILE )
+        {
+            return GL_FALSE;
+        }
+    }
+#else
+    // Fail if OpenGL 3.0 or above was requested
+    if( wndconfig->glMajor > 2 )
+    {
+        return GL_FALSE;
+    }
+#endif /*MAC_OS_X_VERSION_MAX_ALLOWED*/
+
+    _glfwWin.delegate = [[GLFWWindowDelegate alloc] init];
+    if( _glfwWin.delegate == nil )
+    {
+        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:
+    // 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 64 // urrgh
+    NSOpenGLPixelFormatAttribute attributes[MAX_ATTRS];
+
+    ADD_ATTR( NSOpenGLPFADoubleBuffer );
+
+    if( wndconfig->mode == GLFW_FULLSCREEN )
+    {
+        ADD_ATTR( NSOpenGLPFAFullScreen );
+        ADD_ATTR( NSOpenGLPFANoRecovery );
+        ADD_ATTR2( NSOpenGLPFAScreenMask,
+                   CGDisplayIDToOpenGLDisplayMask( CGMainDisplayID() ) );
+    }
+
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
+    if( wndconfig->glMajor > 2 )
+    {
+        ADD_ATTR2( NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core );
+    }
+#endif /*MAC_OS_X_VERSION_MAX_ALLOWED*/
+
+    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 )
+    {
+        return GL_FALSE;
+    }
+
+    _glfwWin.context = [[NSOpenGLContext alloc] initWithFormat:_glfwWin.pixelFormat
+                                                  shareContext:nil];
+    if( _glfwWin.context == nil )
+    {
+        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;
+
+    _glfwWin.glDebug = GL_FALSE;
+}
+
+//========================================================================
+// 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 );
+}
+
diff --git a/glfw/lib/cocoa/platform.h b/glfw/lib/cocoa/platform.h
new file mode 100644
--- /dev/null
+++ b/glfw/lib/cocoa/platform.h
@@ -0,0 +1,252 @@
+//========================================================================
+// GLFW - An OpenGL framework
+// Platform:    Cocoa/NSOpenGL
+// API Version: 2.7
+// WWW:         http://www.glfw.org/
+//------------------------------------------------------------------------
+// Copyright (c) 2009-2010 Camilla Berglund <elmindreda@elmindreda.org>
+//
+// This software is provided 'as-is', without any express or implied
+// warranty. In no event will the authors be held liable for any damages
+// arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it
+// freely, subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented; you must not
+//    claim that you wrote the original software. If you use this software
+//    in a product, an acknowledgment in the product documentation would
+//    be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such, and must not
+//    be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source
+//    distribution.
+//
+//========================================================================
+
+#ifndef _platform_h_
+#define _platform_h_
+
+
+// This is the Mac OS X version of GLFW
+#define _GLFW_MAC_OS_X
+
+#if defined(__OBJC__)
+#import <Cocoa/Cocoa.h>
+#else
+typedef void *id;
+#endif
+
+#include <pthread.h>
+
+#include "../../include/GL/glfw.h"
+
+
+#ifndef GL_VERSION_3_0
+
+typedef const GLubyte * (APIENTRY *PFNGLGETSTRINGIPROC) (GLenum, GLuint);
+
+#endif /*GL_VERSION_3_0*/
+
+
+//========================================================================
+// GLFW platform specific types
+//========================================================================
+
+//------------------------------------------------------------------------
+// Pointer length integer
+//------------------------------------------------------------------------
+typedef intptr_t GLFWintptr;
+
+//------------------------------------------------------------------------
+// Window structure
+//------------------------------------------------------------------------
+typedef struct _GLFWwin_struct _GLFWwin;
+
+struct _GLFWwin_struct {
+
+// ========= PLATFORM INDEPENDENT MANDATORY PART =========================
+
+    // User callback functions
+    GLFWwindowsizefun    windowSizeCallback;
+    GLFWwindowclosefun   windowCloseCallback;
+    GLFWwindowrefreshfun windowRefreshCallback;
+    GLFWmousebuttonfun   mouseButtonCallback;
+    GLFWmouseposfun      mousePosCallback;
+    GLFWmousewheelfun    mouseWheelCallback;
+    GLFWkeyfun           keyCallback;
+    GLFWcharfun          charCallback;
+
+    // User selected window settings
+    int       fullscreen;      // Fullscreen flag
+    int       mouseLock;       // Mouse-lock flag
+    int       autoPollEvents;  // Auto polling flag
+    int       sysKeysDisabled; // System keys disabled flag
+    int       windowNoResize;  // Resize- and maximize gadgets disabled flag
+    int       refreshRate;     // Vertical monitor refresh rate
+
+    // Window status & parameters
+    int       opened;          // Flag telling if window is opened or not
+    int       active;          // Application active flag
+    int       iconified;       // Window iconified flag
+    int       width, height;   // Window width and heigth
+    int       accelerated;     // GL_TRUE if window is HW accelerated
+
+    // Framebuffer attributes
+    int       redBits;
+    int       greenBits;
+    int       blueBits;
+    int       alphaBits;
+    int       depthBits;
+    int       stencilBits;
+    int       accumRedBits;
+    int       accumGreenBits;
+    int       accumBlueBits;
+    int       accumAlphaBits;
+    int       auxBuffers;
+    int       stereo;
+    int       samples;
+
+    // OpenGL extensions and context attributes
+    int       has_GL_SGIS_generate_mipmap;
+    int       has_GL_ARB_texture_non_power_of_two;
+    int       glMajor, glMinor, glRevision;
+    int       glForward, glDebug, glProfile;
+
+    PFNGLGETSTRINGIPROC GetStringi;
+
+// ========= PLATFORM SPECIFIC PART ======================================
+
+    id        window;
+    id        pixelFormat;
+    id	      context;
+    id	      delegate;
+    unsigned int modifierFlags;
+};
+
+GLFWGLOBAL _GLFWwin _glfwWin;
+
+
+//------------------------------------------------------------------------
+// Library global data
+//------------------------------------------------------------------------
+GLFWGLOBAL struct {
+
+// ========= PLATFORM INDEPENDENT MANDATORY PART =========================
+
+    // Window opening hints
+    _GLFWhints      hints;
+
+// ========= PLATFORM SPECIFIC PART ======================================
+
+    // Timer data
+    struct {
+        double t0;
+    } Timer;
+
+    // dlopen handle for dynamically-loading extension function pointers
+    void *OpenGLFramework;
+
+    int Unbundled;
+
+    id DesktopMode;
+
+    id AutoreleasePool;
+
+} _glfwLibrary;
+
+
+//------------------------------------------------------------------------
+// User input status (some of this should go in _GLFWwin)
+//------------------------------------------------------------------------
+GLFWGLOBAL struct {
+
+// ========= PLATFORM INDEPENDENT MANDATORY PART =========================
+
+    // Mouse status
+    int  MousePosX, MousePosY;
+    int  WheelPos;
+    char MouseButton[ GLFW_MOUSE_BUTTON_LAST+1 ];
+
+    // Keyboard status
+    char Key[ GLFW_KEY_LAST+1 ];
+    int  LastChar;
+
+    // User selected settings
+    int  StickyKeys;
+    int  StickyMouseButtons;
+    int  KeyRepeat;
+
+
+// ========= PLATFORM SPECIFIC PART ======================================
+
+    double WheelPosFloating;
+
+} _glfwInput;
+
+//------------------------------------------------------------------------
+// Thread information
+//------------------------------------------------------------------------
+typedef struct _GLFWthread_struct _GLFWthread;
+
+// Thread record (one for each thread)
+struct _GLFWthread_struct {
+
+    // Pointer to previous and next threads in linked list
+    _GLFWthread   *Previous, *Next;
+
+    // GLFW user side thread information
+    GLFWthread    ID;
+    GLFWthreadfun Function;
+
+    // System side thread information
+    pthread_t     PosixID;
+};
+
+// General thread information
+GLFWGLOBAL struct {
+
+    // Critical section lock
+    pthread_mutex_t  CriticalSection;
+
+    // Next thread ID to use (increments for every created thread)
+    GLFWthread       NextID;
+
+    // First thread in linked list (always the main thread)
+    _GLFWthread      First;
+
+} _glfwThrd;
+
+
+//========================================================================
+// Macros for encapsulating critical code sections (i.e. making parts
+// of GLFW thread safe)
+//========================================================================
+
+// Define so we can use the same thread code as X11
+#define _glfw_numprocessors(n) { \
+    int mib[2], ncpu; \
+    size_t len = 1; \
+    mib[0] = CTL_HW; \
+    mib[1] = HW_NCPU; \
+    n      = 1; \
+    if( sysctl( mib, 2, &ncpu, &len, NULL, 0 ) != -1 ) \
+    { \
+        if( len > 0 ) \
+        { \
+            n = ncpu; \
+        } \
+    } \
+}
+
+// Thread list management
+#define ENTER_THREAD_CRITICAL_SECTION \
+pthread_mutex_lock( &_glfwThrd.CriticalSection );
+#define LEAVE_THREAD_CRITICAL_SECTION \
+pthread_mutex_unlock( &_glfwThrd.CriticalSection );
+
+
+#endif // _platform_h_
diff --git a/glfw/lib/enable.c b/glfw/lib/enable.c
--- a/glfw/lib/enable.c
+++ b/glfw/lib/enable.c
@@ -1,11 +1,11 @@
 //========================================================================
 // GLFW - An OpenGL framework
-// File:        enable.c
 // Platform:    Any
-// API version: 2.6
-// WWW:         http://glfw.sourceforge.net
+// API version: 2.7
+// WWW:         http://www.glfw.org/
 //------------------------------------------------------------------------
-// Copyright (c) 2002-2006 Camilla Berglund
+// Copyright (c) 2002-2006 Marcus Geelnard
+// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org>
 //
 // This software is provided 'as-is', without any express or implied
 // warranty. In no event will the authors be held liable for any damages
@@ -39,11 +39,11 @@
 // Enable (show) mouse cursor
 //========================================================================
 
-static void _glfwEnableMouseCursor( void )
+static void enableMouseCursor( void )
 {
-    int CenterPosX, CenterPosY;
+    int centerPosX, centerPosY;
 
-    if( !_glfwWin.Opened || !_glfwWin.MouseLock )
+    if( !_glfwWin.opened || !_glfwWin.mouseLock )
     {
         return;
     }
@@ -51,34 +51,34 @@
     // Show mouse cursor
     _glfwPlatformShowMouseCursor();
 
-    CenterPosX = _glfwWin.Width / 2;
-    CenterPosY = _glfwWin.Height / 2;
+    centerPosX = _glfwWin.width / 2;
+    centerPosY = _glfwWin.height / 2;
 
-    if( CenterPosX != _glfwInput.MousePosX || CenterPosY != _glfwInput.MousePosY )
+    if( centerPosX != _glfwInput.MousePosX || centerPosY != _glfwInput.MousePosY )
     {
-	_glfwPlatformSetMouseCursorPos( CenterPosX, CenterPosY );
+        _glfwPlatformSetMouseCursorPos( centerPosX, centerPosY );
 
-	_glfwInput.MousePosX = CenterPosX;
-	_glfwInput.MousePosY = CenterPosY;
+        _glfwInput.MousePosX = centerPosX;
+        _glfwInput.MousePosY = centerPosY;
 
-	if( _glfwWin.MousePosCallback )
-	{
-	    _glfwWin.MousePosCallback( _glfwInput.MousePosX, 
-				       _glfwInput.MousePosY );
-	}
+        if( _glfwWin.mousePosCallback )
+        {
+            _glfwWin.mousePosCallback( _glfwInput.MousePosX,
+                                       _glfwInput.MousePosY );
+        }
     }
 
     // From now on the mouse is unlocked
-    _glfwWin.MouseLock = GL_FALSE;
+    _glfwWin.mouseLock = GL_FALSE;
 }
 
 //========================================================================
 // Disable (hide) mouse cursor
 //========================================================================
 
-static void _glfwDisableMouseCursor( void )
+static void disableMouseCursor( void )
 {
-    if( !_glfwWin.Opened || _glfwWin.MouseLock )
+    if( !_glfwWin.opened || _glfwWin.mouseLock )
     {
         return;
     }
@@ -87,32 +87,35 @@
     _glfwPlatformHideMouseCursor();
 
     // Move cursor to the middle of the window
-    _glfwPlatformSetMouseCursorPos( _glfwWin.Width>>1,
-                                    _glfwWin.Height>>1 );
+    _glfwPlatformSetMouseCursorPos( _glfwWin.width >> 1,
+                                    _glfwWin.height >> 1 );
 
     // From now on the mouse is locked
-    _glfwWin.MouseLock = GL_TRUE;
+    _glfwWin.mouseLock = GL_TRUE;
 }
 
 
 //========================================================================
-// _glfwEnableStickyKeys() - Enable sticky keys
-// _glfwDisableStickyKeys() - Disable sticky keys
+// Enable sticky keys
 //========================================================================
 
-static void _glfwEnableStickyKeys( void )
+static void enableStickyKeys( void )
 {
     _glfwInput.StickyKeys = 1;
 }
 
-static void _glfwDisableStickyKeys( void )
+//========================================================================
+// Disable sticky keys
+//========================================================================
+
+static void disableStickyKeys( void )
 {
     int i;
 
     _glfwInput.StickyKeys = 0;
 
     // Release all sticky keys
-    for( i = 0; i <= GLFW_KEY_LAST; i ++ )
+    for( i = 0; i <= GLFW_KEY_LAST; i++ )
     {
         if( _glfwInput.Key[ i ] == 2 )
         {
@@ -123,23 +126,26 @@
 
 
 //========================================================================
-// _glfwEnableStickyMouseButtons() - Enable sticky mouse buttons
-// _glfwDisableStickyMouseButtons() - Disable sticky mouse buttons
+// Enable sticky mouse buttons
 //========================================================================
 
-static void _glfwEnableStickyMouseButtons( void )
+static void enableStickyMouseButtons( void )
 {
     _glfwInput.StickyMouseButtons = 1;
 }
 
-static void _glfwDisableStickyMouseButtons( void )
+//========================================================================
+// 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 ++ )
+    for( i = 0; i <= GLFW_MOUSE_BUTTON_LAST; i++ )
     {
         if( _glfwInput.MouseButton[ i ] == 2 )
         {
@@ -150,13 +156,12 @@
 
 
 //========================================================================
-// _glfwEnableSystemKeys() - Enable system keys
-// _glfwDisableSystemKeys() - Disable system keys
+// Enable system keys
 //========================================================================
 
-static void _glfwEnableSystemKeys( void )
+static void enableSystemKeys( void )
 {
-    if( !_glfwWin.SysKeysDisabled )
+    if( !_glfwWin.sysKeysDisabled )
     {
         return;
     }
@@ -164,12 +169,16 @@
     _glfwPlatformEnableSystemKeys();
 
     // Indicate that system keys are no longer disabled
-    _glfwWin.SysKeysDisabled = GL_FALSE;
+    _glfwWin.sysKeysDisabled = GL_FALSE;
 }
 
-static void _glfwDisableSystemKeys( void )
+//========================================================================
+// Disable system keys
+//========================================================================
+
+static void disableSystemKeys( void )
 {
-    if( _glfwWin.SysKeysDisabled )
+    if( _glfwWin.sysKeysDisabled )
     {
         return;
     }
@@ -177,39 +186,45 @@
     _glfwPlatformDisableSystemKeys();
 
     // Indicate that system keys are now disabled
-    _glfwWin.SysKeysDisabled = GL_TRUE;
+    _glfwWin.sysKeysDisabled = GL_TRUE;
 }
 
 
 //========================================================================
-// _glfwEnableKeyRepeat() - Enable key repeat
-// _glfwDisableKeyRepeat() - Disable key repeat
+// Enable key repeat
 //========================================================================
 
-static void _glfwEnableKeyRepeat( void )
+static void enableKeyRepeat( void )
 {
     _glfwInput.KeyRepeat = 1;
 }
 
-static void _glfwDisableKeyRepeat( void )
+//========================================================================
+// Disable key repeat
+//========================================================================
+
+static void disableKeyRepeat( void )
 {
     _glfwInput.KeyRepeat = 0;
 }
 
 
 //========================================================================
-// _glfwEnableAutoPollEvents() - Enable automatic event polling
-// _glfwDisableAutoPollEvents() - Disable automatic event polling
+// Enable automatic event polling
 //========================================================================
 
-static void _glfwEnableAutoPollEvents( void )
+static void enableAutoPollEvents( void )
 {
-    _glfwWin.AutoPollEvents = 1;
+    _glfwWin.autoPollEvents = 1;
 }
 
-static void _glfwDisableAutoPollEvents( void )
+//========================================================================
+// Disable automatic event polling
+//========================================================================
+
+static void disableAutoPollEvents( void )
 {
-    _glfwWin.AutoPollEvents = 0;
+    _glfwWin.autoPollEvents = 0;
 }
 
 
@@ -219,7 +234,7 @@
 //************************************************************************
 
 //========================================================================
-// glfwEnable() - Enable certain GLFW/window/system functions.
+// Enable certain GLFW/window/system functions.
 //========================================================================
 
 GLFWAPI void GLFWAPIENTRY glfwEnable( int token )
@@ -232,32 +247,32 @@
 
     switch( token )
     {
-    case GLFW_MOUSE_CURSOR:
-        _glfwEnableMouseCursor();
-        break;
-    case GLFW_STICKY_KEYS:
-        _glfwEnableStickyKeys();
-        break;
-    case GLFW_STICKY_MOUSE_BUTTONS:
-        _glfwEnableStickyMouseButtons();
-        break;
-    case GLFW_SYSTEM_KEYS:
-        _glfwEnableSystemKeys();
-        break;
-    case GLFW_KEY_REPEAT:
-        _glfwEnableKeyRepeat();
-        break;
-    case GLFW_AUTO_POLL_EVENTS:
-        _glfwEnableAutoPollEvents();
-        break;
-    default:
-        break;
+        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;
     }
 }
 
 
 //========================================================================
-// glfwDisable() - Disable certain GLFW/window/system functions.
+// Disable certain GLFW/window/system functions.
 //========================================================================
 
 GLFWAPI void GLFWAPIENTRY glfwDisable( int token )
@@ -270,26 +285,26 @@
 
     switch( token )
     {
-    case GLFW_MOUSE_CURSOR:
-        _glfwDisableMouseCursor();
-        break;
-    case GLFW_STICKY_KEYS:
-        _glfwDisableStickyKeys();
-        break;
-    case GLFW_STICKY_MOUSE_BUTTONS:
-        _glfwDisableStickyMouseButtons();
-        break;
-    case GLFW_SYSTEM_KEYS:
-        _glfwDisableSystemKeys();
-        break;
-    case GLFW_KEY_REPEAT:
-        _glfwDisableKeyRepeat();
-        break;
-    case GLFW_AUTO_POLL_EVENTS:
-        _glfwDisableAutoPollEvents();
-        break;
-    default:
-        break;
+        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;
     }
 }
 
diff --git a/glfw/lib/fullscreen.c b/glfw/lib/fullscreen.c
--- a/glfw/lib/fullscreen.c
+++ b/glfw/lib/fullscreen.c
@@ -1,11 +1,11 @@
 //========================================================================
 // GLFW - An OpenGL framework
-// File:        fullscreen.c
 // Platform:    Any
-// API version: 2.6
-// WWW:         http://glfw.sourceforge.net
+// API version: 2.7
+// WWW:         http://www.glfw.org/
 //------------------------------------------------------------------------
-// Copyright (c) 2002-2006 Camilla Berglund
+// Copyright (c) 2002-2006 Marcus Geelnard
+// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org>
 //
 // This software is provided 'as-is', without any express or implied
 // warranty. In no event will the authors be held liable for any damages
@@ -36,11 +36,10 @@
 //************************************************************************
 
 //========================================================================
-// glfwGetVideoModes() - Get a list of available video modes
+// Get a list of available video modes
 //========================================================================
 
-GLFWAPI int GLFWAPIENTRY glfwGetVideoModes( GLFWvidmode *list,
-    int maxcount )
+GLFWAPI int GLFWAPIENTRY glfwGetVideoModes( GLFWvidmode *list, int maxcount )
 {
     int         count, i, swap, res1, res2, depth1, depth2;
     GLFWvidmode vm;
@@ -80,7 +79,7 @@
 
 
 //========================================================================
-// glfwGetDesktopMode() - Get the desktop video mode
+// Get the desktop video mode
 //========================================================================
 
 GLFWAPI void GLFWAPIENTRY glfwGetDesktopMode( GLFWvidmode *mode )
diff --git a/glfw/lib/glext.c b/glfw/lib/glext.c
--- a/glfw/lib/glext.c
+++ b/glfw/lib/glext.c
@@ -1,11 +1,11 @@
 //========================================================================
 // GLFW - An OpenGL framework
-// File:        glext.c
 // Platform:    Any
-// API version: 2.6
-// WWW:         http://glfw.sourceforge.net
+// API version: 2.7
+// WWW:         http://www.glfw.org/
 //------------------------------------------------------------------------
-// Copyright (c) 2002-2006 Camilla Berglund
+// Copyright (c) 2002-2006 Marcus Geelnard
+// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org>
 //
 // This software is provided 'as-is', without any express or implied
 // warranty. In no event will the authors be held liable for any damages
@@ -35,13 +35,70 @@
 //****                  GLFW internal functions                       ****
 //************************************************************************
 
+#ifndef GL_VERSION_3_0
+#define GL_NUM_EXTENSIONS                 0x821D
+#define GL_CONTEXT_FLAGS                  0x821E
+#define GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT 0x0001
+#endif
+
+#ifndef GL_VERSION_3_2
+#define GL_CONTEXT_CORE_PROFILE_BIT       0x00000001
+#define GL_CONTEXT_COMPATIBILITY_PROFILE_BIT 0x00000002
+#define GL_CONTEXT_PROFILE_MASK           0x9126
+#endif
+
 //========================================================================
-// _glfwStringInExtensionString() - Check if a string can be found in an
-// OpenGL extension string
+// 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;
+}
+
+//========================================================================
+// Check if a string can be found in an OpenGL extension string
+//========================================================================
+
 int _glfwStringInExtensionString( const char *string,
-    const GLubyte *extensions )
+                                  const GLubyte *extensions )
 {
     const GLubyte *start;
     GLubyte *where, *terminator;
@@ -72,23 +129,65 @@
 }
 
 
+//========================================================================
+// Reads back OpenGL context properties from the current context
+//========================================================================
 
+void _glfwRefreshContextParams( void )
+{
+    _glfwParseGLVersion( &_glfwWin.glMajor, &_glfwWin.glMinor,
+                         &_glfwWin.glRevision );
+
+    _glfwWin.glProfile = 0;
+    _glfwWin.glForward = GL_FALSE;
+
+    // Read back the context profile, if applicable
+    if( _glfwWin.glMajor >= 3 )
+    {
+        GLint flags;
+        glGetIntegerv( GL_CONTEXT_FLAGS, &flags );
+
+        if( flags & GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT )
+        {
+            _glfwWin.glForward = GL_TRUE;
+        }
+    }
+
+    if( _glfwWin.glMajor > 3 ||
+        ( _glfwWin.glMajor == 3 && _glfwWin.glMinor >= 2 ) )
+    {
+        GLint mask;
+        glGetIntegerv( GL_CONTEXT_PROFILE_MASK, &mask );
+
+        if( mask & GL_CONTEXT_COMPATIBILITY_PROFILE_BIT )
+        {
+            _glfwWin.glProfile = GLFW_OPENGL_COMPAT_PROFILE;
+        }
+        else if( mask & GL_CONTEXT_CORE_PROFILE_BIT )
+        {
+            _glfwWin.glProfile = GLFW_OPENGL_CORE_PROFILE;
+        }
+    }
+}
+
+
 //************************************************************************
 //****                    GLFW user functions                         ****
 //************************************************************************
 
 //========================================================================
-// glfwExtensionSupported() - Check if an OpenGL extension is available
-// at runtime
+// Check if an OpenGL extension is available at runtime
 //========================================================================
 
 GLFWAPI int GLFWAPIENTRY glfwExtensionSupported( const char *extension )
 {
     const GLubyte *extensions;
-    GLubyte       *where;
+    GLubyte *where;
+    GLint count;
+    int i;
 
     // Is GLFW initialized?
-    if( !_glfwInitialized || !_glfwWin.Opened )
+    if( !_glfwInitialized || !_glfwWin.opened )
     {
         return GL_FALSE;
     }
@@ -100,16 +199,35 @@
         return GL_FALSE;
     }
 
-    // Check if extension is in the standard OpenGL extensions string
-    extensions = (GLubyte *) glGetString( GL_EXTENSIONS );
-    if( extensions != NULL )
+    if( _glfwWin.glMajor < 3 )
     {
-        if( _glfwStringInExtensionString( extension, extensions ) )
+        // Check if extension is in the old style OpenGL extensions string
+
+        extensions = glGetString( GL_EXTENSIONS );
+        if( extensions != NULL )
         {
-            return GL_TRUE;
+            if( _glfwStringInExtensionString( extension, extensions ) )
+            {
+                return GL_TRUE;
+            }
         }
     }
+    else
+    {
+        // Check if extension is in the modern OpenGL extensions string list
 
+        glGetIntegerv( GL_NUM_EXTENSIONS, &count );
+
+        for( i = 0;  i < count;  i++ )
+        {
+             if( strcmp( (const char*) _glfwWin.GetStringi( GL_EXTENSIONS, i ),
+                         extension ) == 0 )
+             {
+                 return GL_TRUE;
+             }
+        }
+    }
+
     // Additional platform specific extension checking (e.g. WGL)
     if( _glfwPlatformExtensionSupported( extension ) )
     {
@@ -121,14 +239,14 @@
 
 
 //========================================================================
-// glfwGetProcAddress() - Get the function pointer to an OpenGL function.
-// This function can be used to get access to extended OpenGL functions.
+// 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 )
+    if( !_glfwInitialized || !_glfwWin.opened )
     {
         return NULL;
     }
@@ -138,64 +256,28 @@
 
 
 //========================================================================
-// glfwGetGLVersion() - Get OpenGL version
+// Returns the OpenGL version
 //========================================================================
 
-GLFWAPI void GLFWAPIENTRY glfwGetGLVersion( int *major, int *minor,
-    int *rev )
+GLFWAPI void GLFWAPIENTRY glfwGetGLVersion( int *major, int *minor, int *rev )
 {
-    GLuint _major, _minor = 0, _rev = 0;
-    const GLubyte *version;
-    GLubyte *ptr;
-
     // Is GLFW initialized?
-    if( !_glfwInitialized || !_glfwWin.Opened )
-    {
-        return;
-    }
-
-    // Get OpenGL version string
-    version = glGetString( GL_VERSION );
-    if( !version )
+    if( !_glfwInitialized || !_glfwWin.opened )
     {
         return;
     }
 
-    // Parse string
-    ptr = (GLubyte*) version;
-    for( _major = 0; *ptr >= '0' && *ptr <= '9'; ptr ++ )
-    {
-        _major = 10*_major + (*ptr - '0');
-    }
-    if( *ptr == '.' )
-    {
-        ptr ++;
-        for( _minor = 0; *ptr >= '0' && *ptr <= '9'; ptr ++ )
-        {
-            _minor = 10*_minor + (*ptr - '0');
-        }
-        if( *ptr == '.' )
-        {
-            ptr ++;
-            for( _rev = 0; *ptr >= '0' && *ptr <= '9'; ptr ++ )
-            {
-                _rev = 10*_rev + (*ptr - '0');
-            }
-        }
-    }
-
-    // Return parsed values
     if( major != NULL )
     {
-        *major = _major;
+        *major = _glfwWin.glMajor;
     }
     if( minor != NULL )
     {
-        *minor = _minor;
+        *minor = _glfwWin.glMinor;
     }
     if( rev != NULL )
     {
-        *rev = _rev;
+        *rev = _glfwWin.glRevision;
     }
 }
 
diff --git a/glfw/lib/image.c b/glfw/lib/image.c
--- a/glfw/lib/image.c
+++ b/glfw/lib/image.c
@@ -1,11 +1,11 @@
 //========================================================================
 // GLFW - An OpenGL framework
-// File:        image.c
 // Platform:    Any
-// API version: 2.6
-// WWW:         http://glfw.sourceforge.net
+// API version: 2.7
+// WWW:         http://www.glfw.org/
 //------------------------------------------------------------------------
-// Copyright (c) 2002-2006 Camilla Berglund
+// Copyright (c) 2002-2006 Marcus Geelnard
+// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org>
 //
 // This software is provided 'as-is', without any express or implied
 // warranty. In no event will the authors be held liable for any damages
@@ -69,10 +69,10 @@
 //************************************************************************
 
 //========================================================================
-// _glfwUpsampleImage() - Upsample image, from size w1 x h1 to w2 x h2
+// Upsample image, from size w1 x h1 to w2 x h2
 //========================================================================
 
-static void _glfwUpsampleImage( unsigned char *src, unsigned char *dst,
+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;
@@ -141,10 +141,10 @@
 
 
 //========================================================================
-// _glfwHalveImage() - Build the next mip-map level
+// Build the next mip-map level
 //========================================================================
 
-static int _glfwHalveImage( GLubyte *src, int *width, int *height,
+static int HalveImage( GLubyte *src, int *width, int *height,
     int components )
 {
     int     halfwidth, halfheight, m, n, k, idx1, idx2;
@@ -208,10 +208,10 @@
 
 
 //========================================================================
-// _glfwRescaleImage() - Rescales an image into power-of-two dimensions
+// Rescales an image into power-of-two dimensions
 //========================================================================
 
-static int _glfwRescaleImage( GLFWimage* image )
+static int RescaleImage( GLFWimage* image )
 {
     int     width, height, log2, newsize;
     unsigned char *data;
@@ -219,19 +219,21 @@
     // 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;
+        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;
+        height <<= 1;
     }
 
     // Do we really need to rescale?
@@ -247,8 +249,8 @@
         }
 
         // Copy old image data to new image data with interpolation
-        _glfwUpsampleImage( image->Data, data, image->Width, image->Height,
-                            width, height, image->BytesPerPixel );
+        UpsampleImage( image->Data, data, image->Width, image->Height,
+                       width, height, image->BytesPerPixel );
 
         // Free memory for old image data (not needed anymore)
         free( image->Data );
@@ -268,7 +270,7 @@
 //************************************************************************
 
 //========================================================================
-// glfwReadImage() - Read an image from a named file
+// Read an image from a named file
 //========================================================================
 
 GLFWAPI int GLFWAPIENTRY glfwReadImage( const char *name, GLFWimage *img,
@@ -297,7 +299,7 @@
     // We only support TGA files at the moment
     if( !_glfwReadTGA( &stream, img, flags ) )
     {
-	_glfwCloseStream( &stream );
+        _glfwCloseStream( &stream );
         return GL_FALSE;
     }
 
@@ -307,10 +309,10 @@
     // Should we rescale the image to closest 2^N x 2^M resolution?
     if( !(flags & GLFW_NO_RESCALE_BIT) )
     {
-	if( !_glfwRescaleImage( img ) )
-	{
-	    return GL_FALSE;
-	}
+        if( !RescaleImage( img ) )
+        {
+            return GL_FALSE;
+        }
     }
 
     // Interpret BytesPerPixel as an OpenGL format
@@ -340,10 +342,10 @@
 
 
 //========================================================================
-// glfwReadMemoryImage() - Read an image file from a memory buffer
+// Read an image file from a memory buffer
 //========================================================================
 
-GLFWAPI int  GLFWAPIENTRY glfwReadMemoryImage( const void *data, long size, GLFWimage *img, int flags )
+GLFWAPI int GLFWAPIENTRY glfwReadMemoryImage( const void *data, long size, GLFWimage *img, int flags )
 {
     _GLFWstream stream;
 
@@ -368,7 +370,7 @@
     // We only support TGA files at the moment
     if( !_glfwReadTGA( &stream, img, flags ) )
     {
-	_glfwCloseStream( &stream );
+        _glfwCloseStream( &stream );
         return GL_FALSE;
     }
 
@@ -378,10 +380,10 @@
     // Should we rescale the image to closest 2^N x 2^M resolution?
     if( !(flags & GLFW_NO_RESCALE_BIT) )
     {
-	if( !_glfwRescaleImage( img ) )
-	{
-	    return GL_FALSE;
-	}
+        if( !RescaleImage( img ) )
+        {
+            return GL_FALSE;
+        }
     }
 
     // Interpret BytesPerPixel as an OpenGL format
@@ -411,7 +413,7 @@
 
 
 //========================================================================
-// glfwFreeImage() - Free allocated memory for an image
+// Free allocated memory for an image
 //========================================================================
 
 GLFWAPI void GLFWAPIENTRY glfwFreeImage( GLFWimage *img )
@@ -438,8 +440,7 @@
 
 
 //========================================================================
-// glfwLoadTexture2D() - Read an image from a file, and upload it to
-// texture memory
+// Read an image from a file, and upload it to texture memory
 //========================================================================
 
 GLFWAPI int GLFWAPIENTRY glfwLoadTexture2D( const char *name, int flags )
@@ -447,15 +448,15 @@
     GLFWimage img;
 
     // Is GLFW initialized?
-    if( !_glfwInitialized || !_glfwWin.Opened )
+    if( !_glfwInitialized || !_glfwWin.opened )
     {
         return GL_FALSE;
     }
 
     // Force rescaling if necessary
-    if( !_glfwWin.Has_GL_ARB_texture_non_power_of_two )
+    if( !_glfwWin.has_GL_ARB_texture_non_power_of_two )
     {
-      flags &= (~GLFW_NO_RESCALE_BIT);
+        flags &= (~GLFW_NO_RESCALE_BIT);
     }
 
     // Read image from file
@@ -466,7 +467,7 @@
 
     if( !glfwLoadTextureImage2D( &img, flags ) )
     {
-	return GL_FALSE;
+        return GL_FALSE;
     }
 
     // Data buffer is not needed anymore
@@ -477,8 +478,7 @@
 
 
 //========================================================================
-// glfwLoadMemoryTexture2D() - Read an image from a buffer, and upload it to
-// texture memory
+// Read an image from a buffer, and upload it to texture memory
 //========================================================================
 
 GLFWAPI int  GLFWAPIENTRY glfwLoadMemoryTexture2D( const void *data, long size, int flags )
@@ -486,15 +486,15 @@
     GLFWimage img;
 
     // Is GLFW initialized?
-    if( !_glfwInitialized || !_glfwWin.Opened )
+    if( !_glfwInitialized || !_glfwWin.opened )
     {
         return GL_FALSE;
     }
 
     // Force rescaling if necessary
-    if( !_glfwWin.Has_GL_ARB_texture_non_power_of_two )
+    if( !_glfwWin.has_GL_ARB_texture_non_power_of_two )
     {
-      flags &= (~GLFW_NO_RESCALE_BIT);
+        flags &= (~GLFW_NO_RESCALE_BIT);
     }
 
     // Read image from file
@@ -505,7 +505,7 @@
 
     if( !glfwLoadTextureImage2D( &img, flags ) )
     {
-	return GL_FALSE;
+        return GL_FALSE;
     }
 
     // Data buffer is not needed anymore
@@ -516,7 +516,7 @@
 
 
 //========================================================================
-// glfwLoadTextureImage2D() - Upload an image object to texture memory
+// Upload an image object to texture memory
 //========================================================================
 
 GLFWAPI int  GLFWAPIENTRY glfwLoadTextureImage2D( GLFWimage *img, int flags )
@@ -526,7 +526,7 @@
     unsigned char *data, *dataptr;
 
     // Is GLFW initialized?
-    if( !_glfwInitialized || !_glfwWin.Opened )
+    if( !_glfwInitialized || !_glfwWin.opened )
     {
         return GL_FALSE;
     }
@@ -536,7 +536,7 @@
     // NOTE: May require box filter downsampling routine.
 
     // Do we need to convert the alpha map to RGBA format (OpenGL 1.0)?
-    if( (_glfwWin.GLVerMajor == 1) && (_glfwWin.GLVerMinor == 0) &&
+    if( (_glfwWin.glMajor == 1) && (_glfwWin.glMinor == 0) &&
         (img->Format == GL_ALPHA) )
     {
         // We go to RGBA representation instead
@@ -574,7 +574,7 @@
 
     // Should we use automatic mipmap generation?
     AutoGen = ( flags & GLFW_BUILD_MIPMAPS_BIT ) &&
-              _glfwWin.Has_GL_SGIS_generate_mipmap;
+              _glfwWin.has_GL_SGIS_generate_mipmap;
 
     // Enable automatic mipmap generation
     if( AutoGen )
@@ -586,7 +586,7 @@
     }
 
     // Format specification is different for OpenGL 1.0
-    if( _glfwWin.GLVerMajor == 1 && _glfwWin.GLVerMinor == 0 )
+    if( _glfwWin.glMajor == 1 && _glfwWin.glMinor == 0 )
     {
         format = img->BytesPerPixel;
     }
@@ -607,7 +607,7 @@
         // Build next mipmap level manually, if required
         if( ( flags & GLFW_BUILD_MIPMAPS_BIT ) && !AutoGen )
         {
-            level = _glfwHalveImage( img->Data, &img->Width,
+            level = HalveImage( img->Data, &img->Width,
                         &img->Height, img->BytesPerPixel ) ?
                     level + 1 : 0;
         }
diff --git a/glfw/lib/init.c b/glfw/lib/init.c
--- a/glfw/lib/init.c
+++ b/glfw/lib/init.c
@@ -1,11 +1,11 @@
 //========================================================================
 // GLFW - An OpenGL framework
-// File:        init.c
 // Platform:    Any
-// API version: 2.6
-// WWW:         http://glfw.sourceforge.net
+// API version: 2.7
+// WWW:         http://www.glfw.org/
 //------------------------------------------------------------------------
-// Copyright (c) 2002-2006 Camilla Berglund
+// Copyright (c) 2002-2006 Marcus Geelnard
+// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org>
 //
 // This software is provided 'as-is', without any express or implied
 // warranty. In no event will the authors be held liable for any damages
@@ -37,7 +37,7 @@
 //************************************************************************
 
 //========================================================================
-// glfwInit() - Initialize various GLFW state
+// Initialize various GLFW state
 //========================================================================
 
 GLFWAPI int GLFWAPIENTRY glfwInit( void )
@@ -48,11 +48,14 @@
         return GL_TRUE;
     }
 
+    memset( &_glfwLibrary, 0, sizeof( _glfwLibrary ) );
+    memset( &_glfwWin, 0, sizeof( _glfwWin ) );
+
     // Window is not yet opened
-    _glfwWin.Opened = GL_FALSE;
+    _glfwWin.opened = GL_FALSE;
 
     // Default enable/disable settings
-    _glfwWin.SysKeysDisabled = GL_FALSE;
+    _glfwWin.sysKeysDisabled = GL_FALSE;
 
     // Clear window hints
     _glfwClearWindowHints();
@@ -72,7 +75,7 @@
 
 
 //========================================================================
-// glfwTerminate() - Close window and kill all threads.
+// Close window and kill all threads.
 //========================================================================
 
 GLFWAPI void GLFWAPIENTRY glfwTerminate( void )
@@ -95,11 +98,10 @@
 
 
 //========================================================================
-// glfwGetVersion() - Get GLFW version
+// Get GLFW version
 //========================================================================
 
-GLFWAPI void GLFWAPIENTRY glfwGetVersion( int *major, int *minor,
-    int *rev )
+GLFWAPI void GLFWAPIENTRY glfwGetVersion( int *major, int *minor, int *rev )
 {
     if( major != NULL ) *major = GLFW_VERSION_MAJOR;
     if( minor != NULL ) *minor = GLFW_VERSION_MINOR;
diff --git a/glfw/lib/input.c b/glfw/lib/input.c
--- a/glfw/lib/input.c
+++ b/glfw/lib/input.c
@@ -1,11 +1,11 @@
 //========================================================================
 // GLFW - An OpenGL framework
-// File:        input.c
 // Platform:    Any
-// API version: 2.6
-// WWW:         http://glfw.sourceforge.net
+// API version: 2.7
+// WWW:         http://www.glfw.org/
 //------------------------------------------------------------------------
-// Copyright (c) 2002-2006 Camilla Berglund
+// Copyright (c) 2002-2006 Marcus Geelnard
+// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org>
 //
 // This software is provided 'as-is', without any express or implied
 // warranty. In no event will the authors be held liable for any damages
@@ -32,13 +32,12 @@
 
 
 //========================================================================
-// glfwGetKey()
+// Return key state
 //========================================================================
 
 GLFWAPI int GLFWAPIENTRY glfwGetKey( int key )
 {
-    // Is GLFW initialized?
-    if( !_glfwInitialized || !_glfwWin.Opened )
+    if( !_glfwInitialized || !_glfwWin.opened )
     {
         return GLFW_RELEASE;
     }
@@ -61,13 +60,12 @@
 
 
 //========================================================================
-// glfwGetMouseButton()
+// Return mouse button state
 //========================================================================
 
 GLFWAPI int GLFWAPIENTRY glfwGetMouseButton( int button )
 {
-    // Is GLFW initialized?
-    if( !_glfwInitialized || !_glfwWin.Opened )
+    if( !_glfwInitialized || !_glfwWin.opened )
     {
         return GLFW_RELEASE;
     }
@@ -90,13 +88,12 @@
 
 
 //========================================================================
-// glfwGetMousePos()
+// Return mouse cursor position
 //========================================================================
 
 GLFWAPI void GLFWAPIENTRY glfwGetMousePos( int *xpos, int *ypos )
 {
-    // Is GLFW initialized?
-    if( !_glfwInitialized || !_glfwWin.Opened )
+    if( !_glfwInitialized || !_glfwWin.opened )
     {
         return;
     }
@@ -114,13 +111,12 @@
 
 
 //========================================================================
-// glfwSetMousePos()
+// Sets the mouse cursor position
 //========================================================================
 
 GLFWAPI void GLFWAPIENTRY glfwSetMousePos( int xpos, int ypos )
 {
-    // Is GLFW initialized?
-    if( !_glfwInitialized || !_glfwWin.Opened )
+    if( !_glfwInitialized || !_glfwWin.opened )
     {
         return;
     }
@@ -136,7 +132,7 @@
     _glfwInput.MousePosY = ypos;
 
     // If we have a locked mouse, do not change cursor position
-    if( _glfwWin.MouseLock )
+    if( _glfwWin.mouseLock )
     {
         return;
     }
@@ -147,13 +143,12 @@
 
 
 //========================================================================
-// glfwGetMouseWheel()
+// Return mouse wheel position
 //========================================================================
 
 GLFWAPI int GLFWAPIENTRY glfwGetMouseWheel( void )
 {
-    // Is GLFW initialized?
-    if( !_glfwInitialized || !_glfwWin.Opened )
+    if( !_glfwInitialized || !_glfwWin.opened )
     {
         return 0;
     }
@@ -164,13 +159,12 @@
 
 
 //========================================================================
-// glfwSetMouseWheel()
+// Set mouse wheel position
 //========================================================================
 
 GLFWAPI void GLFWAPIENTRY glfwSetMouseWheel( int pos )
 {
-    // Is GLFW initialized?
-    if( !_glfwInitialized || !_glfwWin.Opened )
+    if( !_glfwInitialized || !_glfwWin.opened )
     {
         return;
     }
@@ -181,70 +175,66 @@
 
 
 //========================================================================
-// glfwSetKeyCallback() - Set callback function for keyboard input
+// Set callback function for keyboard input
 //========================================================================
 
 GLFWAPI void GLFWAPIENTRY glfwSetKeyCallback( GLFWkeyfun cbfun )
 {
-    // Is GLFW initialized?
-    if( !_glfwInitialized || !_glfwWin.Opened )
+    if( !_glfwInitialized || !_glfwWin.opened )
     {
         return;
     }
 
     // Set callback function
-    _glfwWin.KeyCallback = cbfun;
+    _glfwWin.keyCallback = cbfun;
 }
 
 
 //========================================================================
-// glfwSetCharCallback() - Set callback function for character input
+// Set callback function for character input
 //========================================================================
 
 GLFWAPI void GLFWAPIENTRY glfwSetCharCallback( GLFWcharfun cbfun )
 {
-    // Is GLFW initialized?
-    if( !_glfwInitialized || !_glfwWin.Opened )
+    if( !_glfwInitialized || !_glfwWin.opened )
     {
         return;
     }
 
     // Set callback function
-    _glfwWin.CharCallback = cbfun;
+    _glfwWin.charCallback = cbfun;
 }
 
 
 //========================================================================
-// glfwSetMouseButtonCallback() - Set callback function for mouse clicks
+// Set callback function for mouse clicks
 //========================================================================
 
 GLFWAPI void GLFWAPIENTRY glfwSetMouseButtonCallback( GLFWmousebuttonfun cbfun )
 {
-    // Is GLFW initialized?
-    if( !_glfwInitialized || !_glfwWin.Opened )
+    if( !_glfwInitialized || !_glfwWin.opened )
     {
         return;
     }
 
     // Set callback function
-    _glfwWin.MouseButtonCallback = cbfun;
+    _glfwWin.mouseButtonCallback = cbfun;
 }
 
 
 //========================================================================
-// glfwSetMousePosCallback() - Set callback function for mouse moves
+// Set callback function for mouse moves
 //========================================================================
 
 GLFWAPI void GLFWAPIENTRY glfwSetMousePosCallback( GLFWmouseposfun cbfun )
 {
-    // Is GLFW initialized?
-    if( !_glfwInitialized || !_glfwWin.Opened )
+    if( !_glfwInitialized || !_glfwWin.opened )
     {
         return;
     }
 
     // Set callback function
-    _glfwWin.MousePosCallback = cbfun;
+    _glfwWin.mousePosCallback = cbfun;
 
     // Call the callback function to let the application know the current
     // mouse position
@@ -256,19 +246,18 @@
 
 
 //========================================================================
-// glfwSetMouseWheelCallback() - Set callback function for mouse wheel
+// Set callback function for mouse wheel
 //========================================================================
 
 GLFWAPI void GLFWAPIENTRY glfwSetMouseWheelCallback( GLFWmousewheelfun cbfun )
 {
-    // Is GLFW initialized?
-    if( !_glfwInitialized || !_glfwWin.Opened )
+    if( !_glfwInitialized || !_glfwWin.opened )
     {
         return;
     }
 
     // Set callback function
-    _glfwWin.MouseWheelCallback = cbfun;
+    _glfwWin.mouseWheelCallback = cbfun;
 
     // Call the callback function to let the application know the current
     // mouse wheel position
diff --git a/glfw/lib/internal.h b/glfw/lib/internal.h
--- a/glfw/lib/internal.h
+++ b/glfw/lib/internal.h
@@ -1,11 +1,11 @@
 //========================================================================
 // GLFW - An OpenGL framework
-// File:        internal.h
 // Platform:    Any
-// API version: 2.6
-// WWW:         http://glfw.sourceforge.net
+// API version: 2.7
+// WWW:         http://www.glfw.org/
 //------------------------------------------------------------------------
-// Copyright (c) 2002-2006 Camilla Berglund
+// Copyright (c) 2002-2006 Marcus Geelnard
+// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org>
 //
 // This software is provided 'as-is', without any express or implied
 // warranty. In no event will the authors be held liable for any damages
@@ -48,7 +48,7 @@
 //========================================================================
 
 // Internal key and button state/action definitions
-#define GLFW_STICK              2
+#define GLFW_STICK 2
 
 
 //========================================================================
@@ -61,6 +61,30 @@
 
 
 //------------------------------------------------------------------------
+// Window opening hints (set by glfwOpenWindowHint)
+// A bucket of semi-random stuff bunched together for historical reasons
+// This is used only by the platform independent code and only to store
+// parameters passed to us by glfwOpenWindowHint
+//------------------------------------------------------------------------
+typedef struct {
+    int         refreshRate;
+    int         accumRedBits;
+    int         accumGreenBits;
+    int         accumBlueBits;
+    int         accumAlphaBits;
+    int         auxBuffers;
+    int         stereo;
+    int         windowNoResize;
+    int         samples;
+    int         glMajor;
+    int         glMinor;
+    int         glForward;
+    int         glDebug;
+    int         glProfile;
+} _GLFWhints;
+
+
+//------------------------------------------------------------------------
 // Platform specific definitions goes in platform.h (which also includes
 // glfw.h)
 //------------------------------------------------------------------------
@@ -68,6 +92,49 @@
 #include "platform.h"
 
 
+//------------------------------------------------------------------------
+// Parameters relating to the creation of the context and window but not
+// directly related to the properties of the framebuffer
+// This is used to pass window and context creation parameters from the
+// platform independent code to the platform specific code
+//------------------------------------------------------------------------
+typedef struct {
+    int         mode;
+    int         refreshRate;
+    int         windowNoResize;
+    int         glMajor;
+    int         glMinor;
+    int         glForward;
+    int         glDebug;
+    int         glProfile;
+} _GLFWwndconfig;
+
+
+//------------------------------------------------------------------------
+// Framebuffer configuration descriptor, i.e. buffers and their sizes
+// Also a platform specific ID used to map back to the actual backend APIs
+// This is used to pass framebuffer parameters from the platform independent
+// code to the platform specific code, and also to enumerate and select
+// available framebuffer configurations
+//------------------------------------------------------------------------
+typedef struct {
+    int         redBits;
+    int         greenBits;
+    int         blueBits;
+    int         alphaBits;
+    int         depthBits;
+    int         stencilBits;
+    int         accumRedBits;
+    int         accumGreenBits;
+    int         accumBlueBits;
+    int         accumAlphaBits;
+    int         auxBuffers;
+    int         stereo;
+    int         samples;
+    GLFWintptr  platformID;
+} _GLFWfbconfig;
+
+
 //========================================================================
 // System independent global variables (GLFW internals)
 //========================================================================
@@ -81,31 +148,13 @@
 
 
 //------------------------------------------------------------------------
-// Window hints (set by glfwOpenWindowHint - will go into _GLFWthread)
-//------------------------------------------------------------------------
-typedef struct {
-    int          RefreshRate;
-    int          AccumRedBits;
-    int          AccumGreenBits;
-    int          AccumBlueBits;
-    int          AccumAlphaBits;
-    int          AuxBuffers;
-    int          Stereo;
-    int          WindowNoResize;
-    int		 Samples;
-} _GLFWhints;
-
-GLFWGLOBAL _GLFWhints _glfwWinHints;
-
-
-//------------------------------------------------------------------------
-// Abstracted data stream (for image I/O)
+// Abstract data stream (for image I/O)
 //------------------------------------------------------------------------
 typedef struct {
-    FILE*     File;
-    void*     Data;
-    long      Position;
-    long      Size;
+    FILE*   file;
+    void*   data;
+    long    position;
+    long    size;
 } _GLFWstream;
 
 
@@ -126,7 +175,7 @@
 void _glfwPlatformGetDesktopMode( GLFWvidmode *mode );
 
 // OpenGL extensions
-int    _glfwPlatformExtensionSupported( const char *extension );
+int _glfwPlatformExtensionSupported( const char *extension );
 void * _glfwPlatformGetProcAddress( const char *procname );
 
 // Joystick
@@ -136,27 +185,27 @@
 
 // Threads
 GLFWthread _glfwPlatformCreateThread( GLFWthreadfun fun, void *arg );
-void       _glfwPlatformDestroyThread( GLFWthread ID );
-int        _glfwPlatformWaitThread( GLFWthread ID, int waitmode );
+void _glfwPlatformDestroyThread( GLFWthread ID );
+int _glfwPlatformWaitThread( GLFWthread ID, int waitmode );
 GLFWthread _glfwPlatformGetThreadID( void );
-GLFWmutex  _glfwPlatformCreateMutex( void );
-void       _glfwPlatformDestroyMutex( GLFWmutex mutex );
-void       _glfwPlatformLockMutex( GLFWmutex mutex );
-void       _glfwPlatformUnlockMutex( GLFWmutex mutex );
-GLFWcond   _glfwPlatformCreateCond( void );
-void       _glfwPlatformDestroyCond( GLFWcond cond );
-void       _glfwPlatformWaitCond( GLFWcond cond, GLFWmutex mutex, double timeout );
-void       _glfwPlatformSignalCond( GLFWcond cond );
-void       _glfwPlatformBroadcastCond( GLFWcond cond );
-int        _glfwPlatformGetNumberOfProcessors( void );
+GLFWmutex _glfwPlatformCreateMutex( void );
+void _glfwPlatformDestroyMutex( GLFWmutex mutex );
+void _glfwPlatformLockMutex( GLFWmutex mutex );
+void _glfwPlatformUnlockMutex( GLFWmutex mutex );
+GLFWcond _glfwPlatformCreateCond( void );
+void _glfwPlatformDestroyCond( GLFWcond cond );
+void _glfwPlatformWaitCond( GLFWcond cond, GLFWmutex mutex, double timeout );
+void _glfwPlatformSignalCond( GLFWcond cond );
+void _glfwPlatformBroadcastCond( GLFWcond cond );
+int _glfwPlatformGetNumberOfProcessors( void );
 
 // Time
 double _glfwPlatformGetTime( void );
-void   _glfwPlatformSetTime( double time );
-void   _glfwPlatformSleep( double time );
+void _glfwPlatformSetTime( double time );
+void _glfwPlatformSleep( double time );
 
 // Window management
-int  _glfwPlatformOpenWindow( int width, int height, int redbits, int greenbits, int bluebits, int alphabits, int depthbits, int stencilbits, int mode, _GLFWhints* hints );
+int  _glfwPlatformOpenWindow( int width, int height, const _GLFWwndconfig *wndconfig, const _GLFWfbconfig *fbconfig );
 void _glfwPlatformCloseWindow( void );
 void _glfwPlatformSetWindowTitle( const char *title );
 void _glfwPlatformSetWindowSize( int width, int height );
@@ -193,18 +242,25 @@
 void _glfwRemoveThread( _GLFWthread * t );
 
 // OpenGL extensions (glext.c)
+void _glfwParseGLVersion( int *major, int *minor, int *rev );
 int _glfwStringInExtensionString( const char *string, const GLubyte *extensions );
+void _glfwRefreshContextParams( void );
 
 // Abstracted data streams (stream.c)
-int  _glfwOpenFileStream( _GLFWstream *stream, const char *name, const char *mode );
-int  _glfwOpenBufferStream( _GLFWstream *stream, void *data, long size );
+int _glfwOpenFileStream( _GLFWstream *stream, const char *name, const char *mode );
+int _glfwOpenBufferStream( _GLFWstream *stream, void *data, long size );
 long _glfwReadStream( _GLFWstream *stream, void *data, long size );
 long _glfwTellStream( _GLFWstream *stream );
-int  _glfwSeekStream( _GLFWstream *stream, long offset, int whence );
+int _glfwSeekStream( _GLFWstream *stream, long offset, int whence );
 void _glfwCloseStream( _GLFWstream *stream );
 
 // Targa image I/O (tga.c)
-int  _glfwReadTGA( _GLFWstream *s, GLFWimage *img, int flags );
+int _glfwReadTGA( _GLFWstream *s, GLFWimage *img, int flags );
+
+// Framebuffer configs
+const _GLFWfbconfig *_glfwChooseFBConfig( const _GLFWfbconfig *desired,
+                                          const _GLFWfbconfig *alternatives,
+                                          unsigned int count );
 
 
 #endif // _internal_h_
diff --git a/glfw/lib/joystick.c b/glfw/lib/joystick.c
--- a/glfw/lib/joystick.c
+++ b/glfw/lib/joystick.c
@@ -1,11 +1,11 @@
 //========================================================================
 // GLFW - An OpenGL framework
-// File:        joystick.c
 // Platform:    Any
-// API version: 2.6
-// WWW:         http://glfw.sourceforge.net
+// API version: 2.7
+// WWW:         http://www.glfw.org/
 //------------------------------------------------------------------------
-// Copyright (c) 2002-2006 Camilla Berglund
+// Copyright (c) 2002-2006 Marcus Geelnard
+// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org>
 //
 // This software is provided 'as-is', without any express or implied
 // warranty. In no event will the authors be held liable for any damages
@@ -36,12 +36,11 @@
 //************************************************************************
 
 //========================================================================
-// glfwGetJoystickParam() - Determine joystick capabilities
+// Determine joystick capabilities
 //========================================================================
 
 GLFWAPI int GLFWAPIENTRY glfwGetJoystickParam( int joy, int param )
 {
-    // Is GLFW initialized?
     if( !_glfwInitialized )
     {
         return 0;
@@ -52,15 +51,13 @@
 
 
 //========================================================================
-// glfwGetJoystickPos() - Get joystick axis positions
+// Get joystick axis positions
 //========================================================================
 
-GLFWAPI int GLFWAPIENTRY glfwGetJoystickPos( int joy, float *pos,
-    int numaxes )
+GLFWAPI int GLFWAPIENTRY glfwGetJoystickPos( int joy, float *pos, int numaxes )
 {
-    int       i;
+    int i;
 
-    // Is GLFW initialized?
     if( !_glfwInitialized )
     {
         return 0;
@@ -77,15 +74,15 @@
 
 
 //========================================================================
-// glfwGetJoystickButtons() - Get joystick button states
+// Get joystick button states
 //========================================================================
 
 GLFWAPI int GLFWAPIENTRY glfwGetJoystickButtons( int joy,
-    unsigned char *buttons, int numbuttons )
+                                                 unsigned char *buttons,
+                                                 int numbuttons )
 {
-    int       i;
+    int i;
 
-    // Is GLFW initialized?
     if( !_glfwInitialized )
     {
         return 0;
@@ -99,3 +96,4 @@
 
     return _glfwPlatformGetJoystickButtons( joy, buttons, numbuttons );
 }
+
diff --git a/glfw/lib/macosx/macosx_enable.c b/glfw/lib/macosx/macosx_enable.c
deleted file mode 100644
--- a/glfw/lib/macosx/macosx_enable.c
+++ /dev/null
@@ -1,42 +0,0 @@
-//========================================================================
-// GLFW - An OpenGL framework
-// File:        macosx_enable.c
-// Platform:    Mac OS X
-// API Version: 2.6
-// WWW:         http://glfw.sourceforge.net
-//------------------------------------------------------------------------
-// Copyright (c) 2002-2006 Camilla Berglund
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-//    claim that you wrote the original software. If you use this software
-//    in a product, an acknowledgment in the product documentation would
-//    be appreciated but is not required.
-//
-// 2. Altered source versions must be plainly marked as such, and must not
-//    be misrepresented as being the original software.
-//
-// 3. This notice may not be removed or altered from any source
-//    distribution.
-//
-//========================================================================
-
-void _glfwPlatformEnableSystemKeys( void )
-{
-    // Nothing to do; event handling code checks the status of
-    // _glfwWin.SysKeysDisabled to ensure this behavior.
-}
-
-void _glfwPlatformDisableSystemKeys( void )
-{
-    // Nothing to do; event handling code checks the status of
-    // _glfwWin.SysKeysDisabled to ensure this behavior.
-}
-
diff --git a/glfw/lib/macosx/macosx_fullscreen.c b/glfw/lib/macosx/macosx_fullscreen.c
deleted file mode 100644
--- a/glfw/lib/macosx/macosx_fullscreen.c
+++ /dev/null
@@ -1,126 +0,0 @@
-//========================================================================
-// GLFW - An OpenGL framework
-// File:        macosx_fullscreen.c
-// Platform:    Mac OS X
-// API Version: 2.6
-// WWW:         http://glfw.sourceforge.net
-//------------------------------------------------------------------------
-// Copyright (c) 2002-2006 Camilla Berglund
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-//    claim that you wrote the original software. If you use this software
-//    in a product, an acknowledgment in the product documentation would
-//    be appreciated but is not required.
-//
-// 2. Altered source versions must be plainly marked as such, and must not
-//    be misrepresented as being the original software.
-//
-// 3. This notice may not be removed or altered from any source
-//    distribution.
-//
-//========================================================================
-
-#include "internal.h"
-
-//========================================================================
-// _glfwVideoModesEqual() - Compares two video modes
-//========================================================================
-
-static int _glfwVideoModesEqual( GLFWvidmode* first,
-                                 GLFWvidmode* second )
-{
-    if( first->Width != second->Width )
-	return 0;
-		
-    if( first->Height != second->Height )
-	return 0;
-		
-    if( first->RedBits + first->GreenBits + first->BlueBits !=
-      second->RedBits + second->GreenBits + second->BlueBits )
-	return 0;
-	
-    return 1;
-}
-                            
-//========================================================================
-// _glfwCGToGLFWVideoMode() - Converts a CG mode to a GLFW mode
-//========================================================================
-
-static void _glfwCGToGLFWVideoMode( CFDictionaryRef cgMode,
-                                    GLFWvidmode* glfwMode )
-{
-    int bitsPerSample;
-
-    CFNumberGetValue( CFDictionaryGetValue( cgMode, kCGDisplayWidth ),
-                     kCFNumberIntType,
-                     &(glfwMode->Width) );
-    CFNumberGetValue( CFDictionaryGetValue( cgMode, kCGDisplayHeight ),
-                     kCFNumberIntType,
-                     &(glfwMode->Height) );
-
-    CFNumberGetValue( CFDictionaryGetValue( cgMode, kCGDisplayBitsPerSample ),
-                     kCFNumberIntType,
-                     &bitsPerSample );
-
-    glfwMode->RedBits = bitsPerSample;
-    glfwMode->GreenBits = bitsPerSample;
-    glfwMode->BlueBits = bitsPerSample;
-}
-
-//========================================================================
-// _glfwPlatformGetVideoModes() - Get a list of available video modes
-//========================================================================
-
-int _glfwPlatformGetVideoModes( GLFWvidmode *list, int maxcount )
-{
-    int i, j, maxModes, numModes;
-    GLFWvidmode mode;
-    CFArrayRef availableModes = CGDisplayAvailableModes( kCGDirectMainDisplay );
-    CFIndex numberOfAvailableModes = CFArrayGetCount( availableModes );
-
-    numModes = 0;
-    maxModes = ( numberOfAvailableModes < maxcount ?
-                 numberOfAvailableModes :
-                 maxcount );
-
-    for( i = 0; i < maxModes; ++i )
-    {
-        _glfwCGToGLFWVideoMode( CFArrayGetValueAtIndex( availableModes, i ),
-                                &mode );
-
-        // Is it a valid mode? (only list depths >= 15 bpp)
-	if( mode.RedBits + mode.GreenBits + mode.BlueBits < 15 )
-	    continue;
-			
-        // Check for duplicate of current mode in target list
-      	for( j = 0; j < numModes; ++j )
-      	{
-      	    if( _glfwVideoModesEqual( &mode, &(list[j]) ) )
-      		break;
-      	}
-      	
-      	// If empty list or no match found
-      	if( numModes == 0 || j == numModes )
-      	    list[numModes++] = mode;
-    }
-
-    return numModes;
-}
-
-//========================================================================
-// glfwGetDesktopMode() - Get the desktop video mode
-//========================================================================
-
-void _glfwPlatformGetDesktopMode( GLFWvidmode *mode )
-{
-    _glfwCGToGLFWVideoMode( _glfwDesktopVideoMode, mode );
-}
-
diff --git a/glfw/lib/macosx/macosx_glext.c b/glfw/lib/macosx/macosx_glext.c
deleted file mode 100644
--- a/glfw/lib/macosx/macosx_glext.c
+++ /dev/null
@@ -1,52 +0,0 @@
-//========================================================================
-// GLFW - An OpenGL framework
-// File:        macosx_glext.c
-// Platform:    Mac OS X
-// API Version: 2.6
-// WWW:         http://glfw.sourceforge.net
-//------------------------------------------------------------------------
-// Copyright (c) 2002-2006 Camilla Berglund
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-//    claim that you wrote the original software. If you use this software
-//    in a product, an acknowledgment in the product documentation would
-//    be appreciated but is not required.
-//
-// 2. Altered source versions must be plainly marked as such, and must not
-//    be misrepresented as being the original software.
-//
-// 3. This notice may not be removed or altered from any source
-//    distribution.
-//
-//========================================================================
-
-#include "internal.h"
-
-int _glfwPlatformExtensionSupported( const char *extension )
-{
-    // There are no AGL, CGL or NSGL extensions.
-    return GL_FALSE;
-}
-
-void * _glfwPlatformGetProcAddress( const char *procname )
-{
-    CFStringRef symbolName = CFStringCreateWithCString( kCFAllocatorDefault,
-                                                        procname,
-                                                        kCFStringEncodingASCII );
-
-    void *symbol = CFBundleGetFunctionPointerForName( _glfwLibrary.Libs.OpenGLFramework,
-                                                      symbolName );
-
-    CFRelease( symbolName );
-
-    return symbol;
-}
-
diff --git a/glfw/lib/macosx/macosx_init.c b/glfw/lib/macosx/macosx_init.c
deleted file mode 100644
--- a/glfw/lib/macosx/macosx_init.c
+++ /dev/null
@@ -1,194 +0,0 @@
-//========================================================================
-// GLFW - An OpenGL framework
-// File:        macosx_init.c
-// Platform:    Mac OS X
-// API Version: 2.6
-// WWW:         http://glfw.sourceforge.net
-//------------------------------------------------------------------------
-// Copyright (c) 2002-2006 Camilla Berglund
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-//    claim that you wrote the original software. If you use this software
-//    in a product, an acknowledgment in the product documentation would
-//    be appreciated but is not required.
-//
-// 2. Altered source versions must be plainly marked as such, and must not
-//    be misrepresented as being the original software.
-//
-// 3. This notice may not be removed or altered from any source
-//    distribution.
-//
-//========================================================================
-
-#include "internal.h"
-
-#include <unistd.h>
-
-//========================================================================
-// Global variables
-//========================================================================
-
-// KCHR resource pointer for keycode translation
-void *KCHRPtr;
-
-
-//========================================================================
-// _glfwInitThreads() - Initialize GLFW thread package
-//========================================================================
-
-static void _glfwInitThreads( void )
-{
-    // Initialize critical section handle
-    (void) pthread_mutex_init( &_glfwThrd.CriticalSection, NULL );
-
-    // The first thread (the main thread) has ID 0
-    _glfwThrd.NextID = 0;
-
-    // Fill out information about the main thread (this thread)
-    _glfwThrd.First.ID       = _glfwThrd.NextID ++;
-    _glfwThrd.First.Function = NULL;
-    _glfwThrd.First.PosixID  = pthread_self();
-    _glfwThrd.First.Previous = NULL;
-    _glfwThrd.First.Next     = NULL;
-}
-
-#define NO_BUNDLE_MESSAGE \
-    "Working in unbundled mode.  " \
-    "You should build a .app wrapper for your Mac OS X applications.\n"
-
-#define UNBUNDLED \
-    fprintf(stderr, NO_BUNDLE_MESSAGE); \
-    _glfwLibrary.Unbundled = 1; \
-    return
-
-void _glfwChangeToResourcesDirectory( void )
-{
-    CFBundleRef mainBundle = CFBundleGetMainBundle();
-    CFURLRef resourcesURL = CFBundleCopyResourcesDirectoryURL( mainBundle );
-    char resourcesPath[ _GLFW_MAX_PATH_LENGTH ];
-    
-    CFStringRef lastComponent = CFURLCopyLastPathComponent( resourcesURL );
-    if ( kCFCompareEqualTo != CFStringCompare(
-            CFSTR( "Resources" ),
-            lastComponent,
-            0 ) )
-    {
-        UNBUNDLED;
-    }
-    
-    CFRelease( lastComponent );
-
-    if( !CFURLGetFileSystemRepresentation( resourcesURL,
-                                           TRUE,
-                                           (UInt8*)resourcesPath,
-                                           _GLFW_MAX_PATH_LENGTH ) )
-    {
-        CFRelease( resourcesURL );
-        UNBUNDLED;
-    }
-
-    CFRelease( resourcesURL );
-
-    if( chdir( resourcesPath ) != 0 )
-    {
-        UNBUNDLED;
-    }
-}
-
-int _glfwPlatformInit( void )
-{
-    struct timeval tv;
-    UInt32 nullDummy = 0;
-
-    _glfwWin.MacWindow = NULL;
-    _glfwWin.AGLContext = NULL;
-    _glfwWin.CGLContext = NULL;
-    _glfwWin.WindowFunctions = NULL;
-    _glfwWin.MouseUPP = NULL;
-    _glfwWin.CommandUPP = NULL;
-    _glfwWin.KeyboardUPP = NULL;
-    _glfwWin.WindowUPP = NULL;
-    
-    _glfwInput.Modifiers = 0;
-    
-    _glfwLibrary.Unbundled = 0;
-    
-    _glfwLibrary.Libs.OpenGLFramework
-        = CFBundleGetBundleWithIdentifier( CFSTR( "com.apple.opengl" ) );
-    if( _glfwLibrary.Libs.OpenGLFramework == NULL )
-    {
-        fprintf(
-            stderr,
-            "glfwInit failing because you aren't linked to OpenGL\n" );
-        return GL_FALSE;
-    }
-
-    _glfwDesktopVideoMode = CGDisplayCurrentMode( kCGDirectMainDisplay );
-    if( _glfwDesktopVideoMode == NULL )
-    {
-        fprintf(
-            stderr,
-            "glfwInit failing because it kind find the desktop display mode\n" );
-        return GL_FALSE;
-    }
-
-    _glfwInitThreads();
-
-    _glfwChangeToResourcesDirectory();
-
-    if( !_glfwInstallEventHandlers() )
-    {
-    	fprintf(
-            stderr,
-            "glfwInit failing because it can't install event handlers\n" );
-        _glfwPlatformTerminate();
-        return GL_FALSE;
-    }
-
-    // Ugly hack to reduce the nasty jump that occurs at the first non-
-    // sys keypress, caused by OS X loading certain meta scripts used
-    // for lexical- and raw keycode translation - instead of letting
-    // this happen while our application is running, we do some blunt
-    // function calls in advance just to get the script caching out of
-    // the way BEFORE our window/screen is opened. These calls might
-    // generate err return codes, but we don't care in this case.
-    // NOTE: KCHRPtr is declared globally, because we need it later on.
-    KCHRPtr = (void *)GetScriptVariable( smCurrentScript, smKCHRCache );
-    KeyTranslate( KCHRPtr, 0, &nullDummy );
-    UppercaseText( (char *)&nullDummy, 0, smSystemScript );
-
-    gettimeofday( &tv, NULL );
-    _glfwLibrary.Timer.t0 = tv.tv_sec + (double) tv.tv_usec / 1000000.0;
-
-    return GL_TRUE;
-}
-
-int _glfwPlatformTerminate( void )
-{
-    if( _glfwWin.MouseUPP != NULL )
-    {
-        DisposeEventHandlerUPP( _glfwWin.MouseUPP );
-        _glfwWin.MouseUPP = NULL;
-    }
-    if( _glfwWin.CommandUPP != NULL )
-    {
-        DisposeEventHandlerUPP( _glfwWin.CommandUPP );
-        _glfwWin.CommandUPP = NULL;
-    }
-    if( _glfwWin.KeyboardUPP != NULL )
-    {
-        DisposeEventHandlerUPP( _glfwWin.KeyboardUPP );
-        _glfwWin.KeyboardUPP = NULL;
-    }
-    
-    return GL_TRUE;
-}
-
diff --git a/glfw/lib/macosx/macosx_joystick.c b/glfw/lib/macosx/macosx_joystick.c
deleted file mode 100644
--- a/glfw/lib/macosx/macosx_joystick.c
+++ /dev/null
@@ -1,50 +0,0 @@
-//========================================================================
-// GLFW - An OpenGL framework
-// File:        macosx_joystick.c
-// Platform:    Mac OS X
-// API Version: 2.6
-// WWW:         http://glfw.sourceforge.net
-//------------------------------------------------------------------------
-// Copyright (c) 2002-2006 Camilla Berglund
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-//    claim that you wrote the original software. If you use this software
-//    in a product, an acknowledgment in the product documentation would
-//    be appreciated but is not required.
-//
-// 2. Altered source versions must be plainly marked as such, and must not
-//    be misrepresented as being the original software.
-//
-// 3. This notice may not be removed or altered from any source
-//    distribution.
-//
-//========================================================================
-
-#include "internal.h"
-
-// TO DO: use HID manager to implement joystick support.
-
-int _glfwPlatformGetJoystickParam( int joy, int param )
-{
-    // GL_FALSE == 0
-    return 0;
-}
-
-int _glfwPlatformGetJoystickPos( int joy, float *pos, int numaxes )
-{
-    return 0;
-}
-
-int _glfwPlatformGetJoystickButtons( int joy, unsigned char *buttons, int numbuttons )
-{
-    return 0;
-}
-
diff --git a/glfw/lib/macosx/macosx_thread.c b/glfw/lib/macosx/macosx_thread.c
deleted file mode 100644
--- a/glfw/lib/macosx/macosx_thread.c
+++ /dev/null
@@ -1,414 +0,0 @@
-//========================================================================
-// GLFW - An OpenGL framework
-// File:        macosx_thread.c
-// Platform:    Mac OS X
-// API Version: 2.6
-// WWW:         http://glfw.sourceforge.net
-//------------------------------------------------------------------------
-// Copyright (c) 2002-2006 Camilla Berglund
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-//    claim that you wrote the original software. If you use this software
-//    in a product, an acknowledgment in the product documentation would
-//    be appreciated but is not required.
-//
-// 2. Altered source versions must be plainly marked as such, and must not
-//    be misrepresented as being the original software.
-//
-// 3. This notice may not be removed or altered from any source
-//    distribution.
-//
-//========================================================================
-
-#include "internal.h"
-
-
-
-//************************************************************************
-//****                  GLFW internal functions                       ****
-//************************************************************************
-
-//========================================================================
-// _glfwNewThread() - This is simply a "wrapper" for calling the user
-// thread function.
-//========================================================================
-
-void * _glfwNewThread( void * arg )
-{
-    GLFWthreadfun threadfun;
-    _GLFWthread   *t;
-
-    // Get pointer to thread information for current thread
-    t = _glfwGetThreadPointer( glfwGetThreadID() );
-    if( t == NULL )
-    {
-        return 0;
-    }
-
-    // Get user thread function pointer
-    threadfun = t->Function;
-
-    // Call the user thread function
-    threadfun( arg );
-
-    // Remove thread from thread list
-    ENTER_THREAD_CRITICAL_SECTION
-        _glfwRemoveThread( t );
-    LEAVE_THREAD_CRITICAL_SECTION
-
-    // When the thread function returns, the thread will die...
-    return NULL;
-}
-
-
-
-//************************************************************************
-//****               Platform implementation functions                ****
-//************************************************************************
-
-//========================================================================
-// _glfwPlatformCreateThread() - Create a new thread
-//========================================================================
-
-GLFWthread _glfwPlatformCreateThread( GLFWthreadfun fun, void *arg )
-{
-    GLFWthread  ID;
-    _GLFWthread *t;
-    int         result;
-
-    // Enter critical section
-    ENTER_THREAD_CRITICAL_SECTION
-
-    // Create a new thread information memory area
-    t = (_GLFWthread *) malloc( sizeof(_GLFWthread) );
-    if( t == NULL )
-    {
-        // Leave critical section
-        LEAVE_THREAD_CRITICAL_SECTION
-        return -1;
-    }
-
-    // Get a new unique thread id
-    ID = _glfwThrd.NextID ++;
-
-    // Store thread information in the thread list
-    t->Function = fun;
-    t->ID       = ID;
-
-    // Create thread
-    result = pthread_create(
-                            &t->PosixID,      // Thread handle
-                            NULL,             // Default thread attributes
-                            _glfwNewThread,   // Thread function (a wrapper function)
-                            (void *)arg       // Argument to thread is user argument
-                            );
-
-    // Did the thread creation fail?
-    if( result != 0 )
-    {
-        free( (void *) t );
-        LEAVE_THREAD_CRITICAL_SECTION
-        return -1;
-    }
-
-    // Append thread to thread list
-    _glfwAppendThread( t );
-
-    // Leave critical section
-    LEAVE_THREAD_CRITICAL_SECTION
-
-    // Return the GLFW thread ID
-    return ID;
-}
-
-
-//========================================================================
-// _glfwPlatformDestroyThread() - Kill a thread. NOTE: THIS IS A VERY
-// DANGEROUS OPERATION, AND SHOULD NOT BE USED EXCEPT IN EXTREME
-// SITUATIONS!
-//========================================================================
-
-void _glfwPlatformDestroyThread( GLFWthread ID )
-{
-    _GLFWthread *t;
-
-    // Enter critical section
-    ENTER_THREAD_CRITICAL_SECTION
-
-    // Get thread information pointer
-    t = _glfwGetThreadPointer( ID );
-    if( t == NULL )
-    {
-        LEAVE_THREAD_CRITICAL_SECTION
-        return;
-    }
-
-    // Simply murder the process, no mercy!
-    pthread_kill( t->PosixID, SIGKILL );
-
-    // Remove thread from thread list
-    _glfwRemoveThread( t );
-
-    // Leave critical section
-    LEAVE_THREAD_CRITICAL_SECTION
-}
-
-
-//========================================================================
-// _glfwPlatformWaitThread() - Wait for a thread to die
-//========================================================================
-
-int _glfwPlatformWaitThread( GLFWthread ID, int waitmode )
-{
-    pthread_t   thread;
-    _GLFWthread *t;
-
-    // Enter critical section
-    ENTER_THREAD_CRITICAL_SECTION
-
-    // Get thread information pointer
-    t = _glfwGetThreadPointer( ID );
-
-    // Is the thread already dead?
-    if( t == NULL )
-    {
-        LEAVE_THREAD_CRITICAL_SECTION
-        return GL_TRUE;
-    }
-
-    // If got this far, the thread is alive => polling returns FALSE
-    if( waitmode == GLFW_NOWAIT )
-    {
-        LEAVE_THREAD_CRITICAL_SECTION
-        return GL_FALSE;
-    }
-
-    // Get thread handle
-    thread = t->PosixID;
-
-    // Leave critical section
-    LEAVE_THREAD_CRITICAL_SECTION
-
-    // Wait for thread to die
-    (void) pthread_join( thread, NULL );
-
-    return GL_TRUE;
-}
-
-
-//========================================================================
-// _glfwPlatformGetThreadID() - Return the thread ID for the current
-// thread
-//========================================================================
-
-GLFWthread _glfwPlatformGetThreadID( void )
-{
-    _GLFWthread *t;
-    GLFWthread  ID = -1;
-    pthread_t   posixID;
-
-    // Get current thread ID
-    posixID = pthread_self();
-
-    // Enter critical section
-    ENTER_THREAD_CRITICAL_SECTION
-
-    // Loop through entire list of threads to find the matching POSIX
-    // thread ID
-    for( t = &_glfwThrd.First; t != NULL; t = t->Next )
-    {
-        if( t->PosixID == posixID )
-        {
-            ID = t->ID;
-            break;
-        }
-    }
-
-    // Leave critical section
-    LEAVE_THREAD_CRITICAL_SECTION
-
-    // Return the found GLFW thread identifier
-    return ID;
-}
-
-
-//========================================================================
-// _glfwPlatformCreateMutex() - Create a mutual exclusion object
-//========================================================================
-
-GLFWmutex _glfwPlatformCreateMutex( void )
-{
-    pthread_mutex_t *mutex;
-
-    // Allocate memory for mutex
-    mutex = (pthread_mutex_t *) malloc( sizeof( pthread_mutex_t ) );
-    if( !mutex )
-    {
-        return NULL;
-    }
-
-    // Initialise a mutex object
-    (void) pthread_mutex_init( mutex, NULL );
-
-    // Cast to GLFWmutex and return
-    return (GLFWmutex) mutex;
-}
-
-
-//========================================================================
-// _glfwPlatformDestroyMutex() - Destroy a mutual exclusion object
-//========================================================================
-
-void _glfwPlatformDestroyMutex( GLFWmutex mutex )
-{
-    // Destroy the mutex object
-    pthread_mutex_destroy( (pthread_mutex_t *) mutex );
-
-    // Free memory for mutex object
-    free( (void *) mutex );
-}
-
-
-//========================================================================
-// _glfwPlatformLockMutex() - Request access to a mutex
-//========================================================================
-
-void _glfwPlatformLockMutex( GLFWmutex mutex )
-{
-    // Wait for mutex to be released
-    (void) pthread_mutex_lock( (pthread_mutex_t *) mutex );
-}
-
-
-//========================================================================
-// _glfwPlatformUnlockMutex() - Release a mutex
-//========================================================================
-
-void _glfwPlatformUnlockMutex( GLFWmutex mutex )
-{
-    // Release mutex
-    pthread_mutex_unlock( (pthread_mutex_t *) mutex );
-}
-
-
-//========================================================================
-// _glfwPlatformCreateCond() - Create a new condition variable object
-//========================================================================
-
-GLFWcond _glfwPlatformCreateCond( void )
-{
-    pthread_cond_t *cond;
-
-    // Allocate memory for condition variable
-    cond = (pthread_cond_t *) malloc( sizeof(pthread_cond_t) );
-    if( !cond )
-    {
-        return NULL;
-    }
-
-    // Initialise condition variable
-    (void) pthread_cond_init( cond, NULL );
-
-    // Cast to GLFWcond and return
-    return (GLFWcond) cond;
-}
-
-
-//========================================================================
-// _glfwPlatformDestroyCond() - Destroy a condition variable object
-//========================================================================
-
-void _glfwPlatformDestroyCond( GLFWcond cond )
-{
-    // Destroy the condition variable object
-    (void) pthread_cond_destroy( (pthread_cond_t *) cond );
-
-    // Free memory for condition variable object
-    free( (void *) cond );
-}
-
-
-//========================================================================
-// _glfwPlatformWaitCond() - Wait for a condition to be raised
-//========================================================================
-
-void _glfwPlatformWaitCond( GLFWcond cond, GLFWmutex mutex,
-                            double timeout )
-{
-    struct timeval  currenttime;
-    struct timespec wait;
-    long dt_sec, dt_usec;
-
-    // Select infinite or timed wait
-    if( timeout >= GLFW_INFINITY )
-    {
-        // Wait for condition (infinite wait)
-        (void) pthread_cond_wait( (pthread_cond_t *) cond,
-                                  (pthread_mutex_t *) mutex );
-    }
-    else
-    {
-        // Set timeout time, relatvie to current time
-        gettimeofday( &currenttime, NULL );
-        dt_sec  = (long) timeout;
-        dt_usec = (long) ((timeout - (double)dt_sec) * 1000000.0);
-        wait.tv_nsec = (currenttime.tv_usec + dt_usec) * 1000L;
-        if( wait.tv_nsec > 1000000000L )
-        {
-            wait.tv_nsec -= 1000000000L;
-            dt_sec ++;
-        }
-        wait.tv_sec  = currenttime.tv_sec + dt_sec;
-
-        // Wait for condition (timed wait)
-        (void) pthread_cond_timedwait( (pthread_cond_t *) cond,
-                                       (pthread_mutex_t *) mutex, &wait );
-    }
-}
-
-
-//========================================================================
-// _glfwPlatformSignalCond() - Signal a condition to one waiting thread
-//========================================================================
-
-void _glfwPlatformSignalCond( GLFWcond cond )
-{
-    // Signal condition
-    (void) pthread_cond_signal( (pthread_cond_t *) cond );
-}
-
-
-//========================================================================
-// _glfwPlatformBroadcastCond() - Broadcast a condition to all waiting
-// threads
-//========================================================================
-
-void _glfwPlatformBroadcastCond( GLFWcond cond )
-{
-    // Broadcast condition
-    (void) pthread_cond_broadcast( (pthread_cond_t *) cond );
-}
-
-
-//========================================================================
-// _glfwPlatformGetNumberOfProcessors() - Return the number of processors
-// in the system.
-//========================================================================
-
-int _glfwPlatformGetNumberOfProcessors( void )
-{
-    int n;
-
-    // Get number of processors online
-    _glfw_numprocessors( n );
-    return n;
-}
-
diff --git a/glfw/lib/macosx/macosx_time.c b/glfw/lib/macosx/macosx_time.c
deleted file mode 100644
--- a/glfw/lib/macosx/macosx_time.c
+++ /dev/null
@@ -1,112 +0,0 @@
-//========================================================================
-// GLFW - An OpenGL framework
-// File:        macosx_time.c
-// Platform:    Mac OS X
-// API Version: 2.6
-// WWW:         http://glfw.sourceforge.net
-//------------------------------------------------------------------------
-// Copyright (c) 2002-2006 Camilla Berglund
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-//    claim that you wrote the original software. If you use this software
-//    in a product, an acknowledgment in the product documentation would
-//    be appreciated but is not required.
-//
-// 2. Altered source versions must be plainly marked as such, and must not
-//    be misrepresented as being the original software.
-//
-// 3. This notice may not be removed or altered from any source
-//    distribution.
-//
-//========================================================================
-
-#include "internal.h"
-
-//************************************************************************
-//****               Platform implementation functions                ****
-//************************************************************************
-
-//========================================================================
-// Return timer value in seconds
-//========================================================================
-
-double _glfwPlatformGetTime( void )
-{
-    struct timeval  tv;
-
-    gettimeofday( &tv, NULL );
-    return tv.tv_sec + (double) tv.tv_usec / 1000000.0 - _glfwLibrary.Timer.t0;
-}
-
-
-//========================================================================
-// Set timer value in seconds
-//========================================================================
-
-void _glfwPlatformSetTime( double time )
-{
-    struct timeval  tv;
-
-    gettimeofday( &tv, NULL );
-    _glfwLibrary.Timer.t0 = tv.tv_sec + (double) tv.tv_usec / 1000000.0 - time;
-}
-
-
-//========================================================================
-// Put a thread to sleep for a specified amount of time
-//========================================================================
-
-void _glfwPlatformSleep( double time )
-{
-    if( time == 0.0 )
-    {
-	sched_yield();
-	return;
-    }
-
-    struct timeval  currenttime;
-    struct timespec wait;
-    pthread_mutex_t mutex;
-    pthread_cond_t  cond;
-    long dt_sec, dt_usec;
-
-    // Not all pthread implementations have a pthread_sleep() function. We
-    // do it the portable way, using a timed wait for a condition that we
-    // will never signal. NOTE: The unistd functions sleep/usleep suspends
-    // the entire PROCESS, not a signle thread, which is why we can not
-    // use them to implement glfwSleep.
-
-    // Set timeout time, relatvie to current time
-    gettimeofday( &currenttime, NULL );
-    dt_sec  = (long) time;
-    dt_usec = (long) ((time - (double)dt_sec) * 1000000.0);
-    wait.tv_nsec = (currenttime.tv_usec + dt_usec) * 1000L;
-    if( wait.tv_nsec > 1000000000L )
-    {
-        wait.tv_nsec -= 1000000000L;
-        dt_sec ++;
-    }
-    wait.tv_sec  = currenttime.tv_sec + dt_sec;
-
-    // Initialize condition and mutex objects
-    pthread_mutex_init( &mutex, NULL );
-    pthread_cond_init( &cond, NULL );
-
-    // Do a timed wait
-    pthread_mutex_lock( &mutex );
-    pthread_cond_timedwait( &cond, &mutex, &wait );
-    pthread_mutex_unlock( &mutex );
-
-    // Destroy condition and mutex objects
-    pthread_mutex_destroy( &mutex );
-    pthread_cond_destroy( &cond );
-}
-
diff --git a/glfw/lib/macosx/macosx_window.c b/glfw/lib/macosx/macosx_window.c
deleted file mode 100644
--- a/glfw/lib/macosx/macosx_window.c
+++ /dev/null
@@ -1,1281 +0,0 @@
-//========================================================================
-// GLFW - An OpenGL framework
-// File:        macosx_window.c
-// Platform:    Mac OS X
-// API Version: 2.6
-// WWW:         http://glfw.sourceforge.net
-//------------------------------------------------------------------------
-// Copyright (c) 2002-2006 Camilla Berglund
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-//    claim that you wrote the original software. If you use this software
-//    in a product, an acknowledgment in the product documentation would
-//    be appreciated but is not required.
-//
-// 2. Altered source versions must be plainly marked as such, and must not
-//    be misrepresented as being the original software.
-//
-// 3. This notice may not be removed or altered from any source
-//    distribution.
-//
-//========================================================================
-
-#include "internal.h"
-
-static _GLFWmacwindowfunctions _glfwMacFSWindowFunctions =
-{
-    _glfwMacFSOpenWindow,
-    _glfwMacFSCloseWindow,
-    _glfwMacFSSetWindowTitle,
-    _glfwMacFSSetWindowSize,
-    _glfwMacFSSetWindowPos,
-    _glfwMacFSIconifyWindow,
-    _glfwMacFSRestoreWindow,
-    _glfwMacFSRefreshWindowParams,
-    _glfwMacFSSetMouseCursorPos
-};
-
-static _GLFWmacwindowfunctions _glfwMacDWWindowFunctions =
-{
-    _glfwMacDWOpenWindow,
-    _glfwMacDWCloseWindow,
-    _glfwMacDWSetWindowTitle,
-    _glfwMacDWSetWindowSize,
-    _glfwMacDWSetWindowPos,
-    _glfwMacDWIconifyWindow,
-    _glfwMacDWRestoreWindow,
-    _glfwMacDWRefreshWindowParams,
-    _glfwMacDWSetMouseCursorPos
-};
-
-#define _glfwTestModifier( modifierMask, glfwKey ) \
-if ( changed & modifierMask ) \
-{ \
-    _glfwInputKey( glfwKey, (modifiers & modifierMask ? GLFW_PRESS : GLFW_RELEASE) ); \
-}
-
-void _glfwHandleMacModifierChange( UInt32 modifiers )
-{
-    UInt32 changed = modifiers ^ _glfwInput.Modifiers;
-
-    _glfwTestModifier( shiftKey,        GLFW_KEY_LSHIFT );
-    _glfwTestModifier( rightShiftKey,   GLFW_KEY_RSHIFT );
-    _glfwTestModifier( controlKey,      GLFW_KEY_LCTRL );
-    _glfwTestModifier( rightControlKey, GLFW_KEY_RCTRL );
-    _glfwTestModifier( optionKey,       GLFW_KEY_LALT );
-    _glfwTestModifier( rightOptionKey,  GLFW_KEY_RALT );
-
-    _glfwInput.Modifiers = modifiers;
-}
-
-void _glfwHandleMacKeyChange( UInt32 keyCode, int action )
-{
-    switch ( keyCode )
-    {
-        case MAC_KEY_ENTER:       _glfwInputKey( GLFW_KEY_ENTER,       action); break;
-        case MAC_KEY_RETURN:      _glfwInputKey( GLFW_KEY_KP_ENTER,    action); break;
-        case MAC_KEY_ESC:         _glfwInputKey( GLFW_KEY_ESC,         action); break;
-        case MAC_KEY_F1:          _glfwInputKey( GLFW_KEY_F1,          action); break;
-        case MAC_KEY_F2:          _glfwInputKey( GLFW_KEY_F2,          action); break;
-        case MAC_KEY_F3:          _glfwInputKey( GLFW_KEY_F3,          action); break;
-        case MAC_KEY_F4:          _glfwInputKey( GLFW_KEY_F4,          action); break;
-        case MAC_KEY_F5:          _glfwInputKey( GLFW_KEY_F5,          action); break;
-        case MAC_KEY_F6:          _glfwInputKey( GLFW_KEY_F6,          action); break;
-        case MAC_KEY_F7:          _glfwInputKey( GLFW_KEY_F7,          action); break;
-        case MAC_KEY_F8:          _glfwInputKey( GLFW_KEY_F8,          action); break;
-        case MAC_KEY_F9:          _glfwInputKey( GLFW_KEY_F9,          action); break;
-        case MAC_KEY_F10:         _glfwInputKey( GLFW_KEY_F10,         action); break;
-        case MAC_KEY_F11:         _glfwInputKey( GLFW_KEY_F11,         action); break;
-        case MAC_KEY_F12:         _glfwInputKey( GLFW_KEY_F12,         action); break;
-        case MAC_KEY_F13:         _glfwInputKey( GLFW_KEY_F13,         action); break;
-        case MAC_KEY_F14:         _glfwInputKey( GLFW_KEY_F14,         action); break;
-        case MAC_KEY_F15:         _glfwInputKey( GLFW_KEY_F15,         action); break;
-        case MAC_KEY_UP:          _glfwInputKey( GLFW_KEY_UP,          action); break;
-        case MAC_KEY_DOWN:        _glfwInputKey( GLFW_KEY_DOWN,        action); break;
-        case MAC_KEY_LEFT:        _glfwInputKey( GLFW_KEY_LEFT,        action); break;
-        case MAC_KEY_RIGHT:       _glfwInputKey( GLFW_KEY_RIGHT,       action); break;
-        case MAC_KEY_TAB:         _glfwInputKey( GLFW_KEY_TAB,         action); break;
-        case MAC_KEY_BACKSPACE:   _glfwInputKey( GLFW_KEY_BACKSPACE,   action); break;
-        case MAC_KEY_HELP:        _glfwInputKey( GLFW_KEY_INSERT,      action); break;
-        case MAC_KEY_DEL:         _glfwInputKey( GLFW_KEY_DEL,         action); break;
-        case MAC_KEY_PAGEUP:      _glfwInputKey( GLFW_KEY_PAGEUP,      action); break;
-        case MAC_KEY_PAGEDOWN:    _glfwInputKey( GLFW_KEY_PAGEDOWN,    action); break;
-        case MAC_KEY_HOME:        _glfwInputKey( GLFW_KEY_HOME,        action); break;
-        case MAC_KEY_END:         _glfwInputKey( GLFW_KEY_END,         action); break;
-        case MAC_KEY_KP_0:        _glfwInputKey( GLFW_KEY_KP_0,        action); break;
-        case MAC_KEY_KP_1:        _glfwInputKey( GLFW_KEY_KP_1,        action); break;
-        case MAC_KEY_KP_2:        _glfwInputKey( GLFW_KEY_KP_2,        action); break;
-        case MAC_KEY_KP_3:        _glfwInputKey( GLFW_KEY_KP_3,        action); break;
-        case MAC_KEY_KP_4:        _glfwInputKey( GLFW_KEY_KP_4,        action); break;
-        case MAC_KEY_KP_5:        _glfwInputKey( GLFW_KEY_KP_5,        action); break;
-        case MAC_KEY_KP_6:        _glfwInputKey( GLFW_KEY_KP_6,        action); break;
-        case MAC_KEY_KP_7:        _glfwInputKey( GLFW_KEY_KP_7,        action); break;
-        case MAC_KEY_KP_8:        _glfwInputKey( GLFW_KEY_KP_8,        action); break;
-        case MAC_KEY_KP_9:        _glfwInputKey( GLFW_KEY_KP_9,        action); break;
-        case MAC_KEY_KP_DIVIDE:   _glfwInputKey( GLFW_KEY_KP_DIVIDE,   action); break;
-        case MAC_KEY_KP_MULTIPLY: _glfwInputKey( GLFW_KEY_KP_MULTIPLY, action); break;
-        case MAC_KEY_KP_SUBTRACT: _glfwInputKey( GLFW_KEY_KP_SUBTRACT, action); break;
-        case MAC_KEY_KP_ADD:      _glfwInputKey( GLFW_KEY_KP_ADD,      action); break;
-        case MAC_KEY_KP_DECIMAL:  _glfwInputKey( GLFW_KEY_KP_DECIMAL,  action); break;
-        case MAC_KEY_KP_EQUAL:    _glfwInputKey( GLFW_KEY_KP_EQUAL,    action); break;
-        case MAC_KEY_KP_ENTER:    _glfwInputKey( GLFW_KEY_KP_ENTER,    action); break;
-        default:
-        {
-            extern void *KCHRPtr;
-            UInt32 state = 0;
-            char charCode = (char)KeyTranslate( KCHRPtr, keyCode, &state );
-            UppercaseText( &charCode, 1, smSystemScript );
-            _glfwInputKey( (unsigned char)charCode, action );
-        }
-        break;
-    }
-}
-
-EventTypeSpec GLFW_KEY_EVENT_TYPES[] =
-{
-    { kEventClassKeyboard, kEventRawKeyDown },
-    { kEventClassKeyboard, kEventRawKeyUp },
-    { kEventClassKeyboard, kEventRawKeyModifiersChanged }
-};
-
-OSStatus _glfwKeyEventHandler( EventHandlerCallRef handlerCallRef,
-                               EventRef event,
-                               void *userData )
-{
-    UInt32 keyCode;
-    short int keyChar;
-    UInt32 modifiers;
-
-    switch( GetEventKind( event ) )
-    {
-        case kEventRawKeyDown:
-        {
-            if( GetEventParameter( event,
-                                   kEventParamKeyCode,
-                                   typeUInt32,
-                                   NULL,
-                                   sizeof( UInt32 ),
-                                   NULL,
-                                   &keyCode ) == noErr )
-            {
-                _glfwHandleMacKeyChange( keyCode, GLFW_PRESS );
-            }
-            if( GetEventParameter( event,
-                                   kEventParamKeyUnicodes,
-                                   typeUnicodeText,
-                                   NULL,
-                                   sizeof(keyChar),
-                                   NULL,
-                                   &keyChar) == noErr )
-            {
-                _glfwInputChar( keyChar, GLFW_PRESS );
-            }
-            return noErr;
-        }
-
-        case kEventRawKeyUp:
-        {
-            if( GetEventParameter( event,
-                                   kEventParamKeyCode,
-                                   typeUInt32,
-                                   NULL,
-                                   sizeof( UInt32 ),
-                                   NULL,
-                                   &keyCode ) == noErr )
-            {
-                _glfwHandleMacKeyChange( keyCode, GLFW_RELEASE );
-            }
-            if( GetEventParameter( event,
-                                   kEventParamKeyUnicodes,
-                                   typeUnicodeText,
-                                   NULL,
-                                   sizeof(keyChar),
-                                   NULL,
-                                   &keyChar) == noErr )
-            {
-                _glfwInputChar( keyChar, GLFW_RELEASE );
-            }
-            return noErr;
-        }
-
-        case kEventRawKeyModifiersChanged:
-        {
-            if( GetEventParameter( event,
-                                   kEventParamKeyModifiers,
-                                   typeUInt32,
-                                   NULL,
-                                   sizeof( UInt32 ),
-                                   NULL,
-                                   &modifiers ) == noErr )
-            {
-                _glfwHandleMacModifierChange( modifiers );
-                return noErr;
-            }
-        }
-        break;
-    }
-
-    return eventNotHandledErr;
-}
-
-EventTypeSpec GLFW_MOUSE_EVENT_TYPES[] =
-{
-    { kEventClassMouse, kEventMouseDown },
-    { kEventClassMouse, kEventMouseUp },
-    { kEventClassMouse, kEventMouseMoved },
-    { kEventClassMouse, kEventMouseDragged },
-    { kEventClassMouse, kEventMouseWheelMoved },
-};
-
-OSStatus _glfwMouseEventHandler( EventHandlerCallRef handlerCallRef,
-                                 EventRef event,
-                                 void *userData )
-{
-    switch( GetEventKind( event ) )
-    {
-        case kEventMouseDown:
-        {
-            WindowRef window;
-            EventRecord oldStyleMacEvent;
-            ConvertEventRefToEventRecord( event, &oldStyleMacEvent );
-            if( FindWindow ( oldStyleMacEvent.where, &window ) == inMenuBar )
-            {
-                MenuSelect( oldStyleMacEvent.where );
-                HiliteMenu(0);
-                return noErr;
-            }
-            else
-            {
-                EventMouseButton button;
-                if( GetEventParameter( event,
-                                       kEventParamMouseButton,
-                                       typeMouseButton,
-                                       NULL,
-                                       sizeof( EventMouseButton ),
-                                       NULL,
-                                       &button ) == noErr )
-                {
-                    button -= kEventMouseButtonPrimary;
-                    if( button <= GLFW_MOUSE_BUTTON_LAST )
-                    {
-                        _glfwInputMouseClick( button
-                                              + GLFW_MOUSE_BUTTON_LEFT,
-                                              GLFW_PRESS );
-                    }
-                    return noErr;
-                }
-            }
-            break;
-        }
-
-        case kEventMouseUp:
-        {
-            EventMouseButton button;
-            if( GetEventParameter( event,
-                                   kEventParamMouseButton,
-                                   typeMouseButton,
-                                   NULL,
-                                   sizeof( EventMouseButton ),
-                                   NULL,
-                                   &button ) == noErr )
-            {
-                button -= kEventMouseButtonPrimary;
-                if( button <= GLFW_MOUSE_BUTTON_LAST )
-                {
-                    _glfwInputMouseClick( button
-                                          + GLFW_MOUSE_BUTTON_LEFT,
-                                          GLFW_RELEASE );
-                }
-                return noErr;
-            }
-            break;
-        }
-
-        case kEventMouseMoved:
-        case kEventMouseDragged:
-        {
-            HIPoint mouseLocation;
-	    if( _glfwWin.MouseLock )
-	    {
-		if( GetEventParameter( event,
-				       kEventParamMouseDelta,
-				       typeHIPoint,
-				       NULL,
-				       sizeof( HIPoint ),
-				       NULL,
-				       &mouseLocation ) != noErr )
-		{
-		    break;
-		}
-
-		_glfwInput.MousePosX += mouseLocation.x;
-		_glfwInput.MousePosY += mouseLocation.y;
-	    }
-	    else
-	    {
-		if( GetEventParameter( event,
-				       kEventParamMouseLocation,
-				       typeHIPoint,
-				       NULL,
-				       sizeof( HIPoint ),
-				       NULL,
-				       &mouseLocation ) != noErr )
-		{
-		    break;
-		}
-
-		_glfwInput.MousePosX = mouseLocation.x;
-		_glfwInput.MousePosY = mouseLocation.y;
-
-		if( !_glfwWin.Fullscreen )
-		{
-		    Rect content;
-		    GetWindowBounds( _glfwWin.MacWindow,
-		                     kWindowContentRgn,
-				     &content );
-
-		    _glfwInput.MousePosX -= content.left;
-		    _glfwInput.MousePosY -= content.top;
-		}
-	    }
-
-	    if( _glfwWin.MousePosCallback )
-	    {
-		_glfwWin.MousePosCallback( _glfwInput.MousePosX,
-					   _glfwInput.MousePosY );
-	    }
-
-            break;
-        }
-
-        case kEventMouseWheelMoved:
-        {
-            EventMouseWheelAxis axis;
-            if( GetEventParameter( event,
-                                   kEventParamMouseWheelAxis,
-                                   typeMouseWheelAxis,
-                                   NULL,
-                                   sizeof( EventMouseWheelAxis ),
-                                   NULL,
-                                   &axis) == noErr )
-            {
-                long wheelDelta;
-                if( axis == kEventMouseWheelAxisY &&
-                    GetEventParameter( event,
-                                       kEventParamMouseWheelDelta,
-                                       typeLongInteger,
-                                       NULL,
-                                       sizeof( long ),
-                                       NULL,
-                                       &wheelDelta ) == noErr )
-                {
-                    _glfwInput.WheelPos += wheelDelta;
-                    if( _glfwWin.MouseWheelCallback )
-                    {
-                        _glfwWin.MouseWheelCallback( _glfwInput.WheelPos );
-                    }
-                    return noErr;
-                }
-            }
-            break;
-        }
-    }
-
-    return eventNotHandledErr;
-}
-
-EventTypeSpec GLFW_COMMAND_EVENT_TYPES[] =
-{
-    { kEventClassCommand, kEventCommandProcess }
-};
-
-OSStatus _glfwCommandHandler( EventHandlerCallRef handlerCallRef,
-                                 EventRef event,
-                                 void *userData )
-{
-    if( _glfwWin.SysKeysDisabled )
-    {
-        // TO DO: give adequate UI feedback that this is the case
-        return eventNotHandledErr;
-    }
-
-    HICommand command;
-    if( GetEventParameter( event,
-                           kEventParamDirectObject,
-                           typeHICommand,
-                           NULL,
-                           sizeof( HICommand ),
-                           NULL,
-                           &command ) == noErr )
-    {
-        switch( command.commandID )
-        {
-            case kHICommandClose:
-            case kHICommandQuit:
-            {
-                // Check if the program wants us to close the window
-                if( _glfwWin.WindowCloseCallback )
-                {
-                    if( _glfwWin.WindowCloseCallback() )
-                    {
-                        glfwCloseWindow();
-                    }
-                }
-                else
-                {
-                    glfwCloseWindow();
-                }
-                return noErr;
-            }
-        }
-    }
-
-    return eventNotHandledErr;
-}
-
-EventTypeSpec GLFW_WINDOW_EVENT_TYPES[] =
-{
-  { kEventClassWindow, kEventWindowBoundsChanged },
-  { kEventClassWindow, kEventWindowClose },
-  { kEventClassWindow, kEventWindowDrawContent },
-  { kEventClassWindow, kEventWindowActivated },
-  { kEventClassWindow, kEventWindowDeactivated },
-};
-
-OSStatus _glfwWindowEventHandler( EventHandlerCallRef handlerCallRef,
-                              EventRef event,
-                              void *userData )
-{
-    switch( GetEventKind(event) )
-    {
-    	case kEventWindowBoundsChanged:
-    	{
-      	    WindowRef window;
-      	    GetEventParameter( event, kEventParamDirectObject, typeWindowRef, NULL,
-			       sizeof(WindowRef), NULL, &window );
-
-      	    Rect rect;
-      	    GetWindowPortBounds( window, &rect );
-
-      	    if( _glfwWin.Width != rect.right ||
-           	_glfwWin.Height != rect.bottom )
-      	    {
-        	aglUpdateContext(_glfwWin.AGLContext);
-
-        	_glfwWin.Width  = rect.right;
-        	_glfwWin.Height = rect.bottom;
-        	if( _glfwWin.WindowSizeCallback )
-        	{
-          	    _glfwWin.WindowSizeCallback( _glfwWin.Width,
-                                                _glfwWin.Height );
-        	}
-        	// Emulate (force) content invalidation
-        	if( _glfwWin.WindowRefreshCallback )
-        	{
-                    _glfwWin.WindowRefreshCallback();
-        	}
-      	    }
-      	    break;
-    	}
-
-    	case kEventWindowClose:
-    	{
-      	    // Check if the program wants us to close the window
-      	    if( _glfwWin.WindowCloseCallback )
-      	    {
-          	if( _glfwWin.WindowCloseCallback() )
-          	{
-              	    glfwCloseWindow();
-          	}
-     	    }
-      	    else
-      	    {
-          	glfwCloseWindow();
-      	    }
-      	    return noErr;
-    	}
-
-    	case kEventWindowDrawContent:
-    	{
-	    // Call user callback function
-            if( _glfwWin.WindowRefreshCallback )
-	    {
-		_glfwWin.WindowRefreshCallback();
-	    }
-	    break;
-        }
-
-	case kEventWindowActivated:
-	{
-	    _glfwWin.Active = GL_TRUE;
-	    break;
-	}
-
-	case kEventWindowDeactivated:
-	{
-	    _glfwWin.Active = GL_FALSE;
-	    _glfwInputDeactivation();
-	    break;
-	}
-    }
-
-    return eventNotHandledErr;
-}
-
-int _glfwInstallEventHandlers( void )
-{
-    OSStatus error;
-
-    _glfwWin.MouseUPP = NewEventHandlerUPP( _glfwMouseEventHandler );
-
-    error = InstallEventHandler( GetApplicationEventTarget(),
-                                 _glfwWin.MouseUPP,
-                                 GetEventTypeCount( GLFW_MOUSE_EVENT_TYPES ),
-                                 GLFW_MOUSE_EVENT_TYPES,
-                                 NULL,
-                                 NULL );
-    if( error != noErr )
-    {
-        fprintf( stderr, "glfwOpenWindow failing because it can't install mouse event handler\n" );
-        return GL_FALSE;
-    }
-
-    _glfwWin.CommandUPP = NewEventHandlerUPP( _glfwCommandHandler );
-
-    error = InstallEventHandler( GetApplicationEventTarget(),
-                                 _glfwWin.CommandUPP,
-                                 GetEventTypeCount( GLFW_COMMAND_EVENT_TYPES ),
-                                 GLFW_COMMAND_EVENT_TYPES,
-                                 NULL,
-                                 NULL );
-    if( error != noErr )
-    {
-        fprintf( stderr, "glfwOpenWindow failing because it can't install command event handler\n" );
-        return GL_FALSE;
-    }
-
-    _glfwWin.KeyboardUPP = NewEventHandlerUPP( _glfwKeyEventHandler );
-
-    error = InstallEventHandler( GetApplicationEventTarget(),
-                                 _glfwWin.KeyboardUPP,
-                                 GetEventTypeCount( GLFW_KEY_EVENT_TYPES ),
-                                 GLFW_KEY_EVENT_TYPES,
-                                 NULL,
-                                 NULL );
-    if( error != noErr )
-    {
-        fprintf( stderr, "glfwOpenWindow failing because it can't install key event handler\n" );
-        return GL_FALSE;
-    }
-
-    return GL_TRUE;
-}
-
-#define _setAGLAttribute( aglAttributeName, AGLparameter ) \
-if ( AGLparameter != 0 ) \
-{ \
-    AGLpixelFormatAttributes[numAGLAttrs++] = aglAttributeName; \
-    AGLpixelFormatAttributes[numAGLAttrs++] = AGLparameter; \
-}
-
-#define _getAGLAttribute( aglAttributeName, variableName ) \
-{ \
-    GLint aglValue; \
-    (void)aglDescribePixelFormat( pixelFormat, aglAttributeName, &aglValue ); \
-    variableName = aglValue; \
-}
-
-#define _setCGLAttribute( cglAttributeName, CGLparameter ) \
-if ( CGLparameter != 0 ) \
-{ \
-    CGLpixelFormatAttributes[ numCGLAttrs++ ] = cglAttributeName; \
-    CGLpixelFormatAttributes[ numCGLAttrs++ ] = CGLparameter; \
-}
-
-#define _getCGLAttribute( cglAttributeName, variableName ) \
-{ \
-    long cglValue; \
-    (void)CGLDescribePixelFormat( CGLpfObj, 0, cglAttributeName, &cglValue ); \
-    variableName = cglValue; \
-}
-
-int  _glfwPlatformOpenWindow( int width,
-                              int height,
-                              int redbits,
-                              int greenbits,
-                              int bluebits,
-                              int alphabits,
-                              int depthbits,
-                              int stencilbits,
-                              int mode,
-                              _GLFWhints* hints )
-{
-    OSStatus error;
-    ProcessSerialNumber psn;
-
-    unsigned int windowAttributes;
-
-    // TO DO: Refactor this function!
-    _glfwWin.WindowFunctions = ( _glfwWin.Fullscreen ?
-                               &_glfwMacFSWindowFunctions :
-                               &_glfwMacDWWindowFunctions );
-
-    // Windowed or fullscreen; AGL or CGL? Quite the mess...
-    // AGL appears to be the only choice for attaching OpenGL contexts to
-    // Carbon windows, but it leaves the user no control over fullscreen
-    // mode stretching. Solution: AGL for windowed, CGL for fullscreen.
-    if( !_glfwWin.Fullscreen )
-    {
-        // create AGL pixel format attribute list
-        GLint AGLpixelFormatAttributes[256];
-        int numAGLAttrs = 0;
-
-        AGLpixelFormatAttributes[numAGLAttrs++] = AGL_RGBA;
-        AGLpixelFormatAttributes[numAGLAttrs++] = AGL_DOUBLEBUFFER;
-
-        if( hints->Stereo )
-        {
-            AGLpixelFormatAttributes[numAGLAttrs++] = AGL_STEREO;
-        }
-
-        _setAGLAttribute( AGL_AUX_BUFFERS,      hints->AuxBuffers);
-        _setAGLAttribute( AGL_RED_SIZE,         redbits );
-        _setAGLAttribute( AGL_GREEN_SIZE,       greenbits );
-        _setAGLAttribute( AGL_BLUE_SIZE,        bluebits );
-        _setAGLAttribute( AGL_ALPHA_SIZE,       alphabits );
-        _setAGLAttribute( AGL_DEPTH_SIZE,       depthbits );
-        _setAGLAttribute( AGL_STENCIL_SIZE,     stencilbits );
-        _setAGLAttribute( AGL_ACCUM_RED_SIZE,   hints->AccumRedBits );
-        _setAGLAttribute( AGL_ACCUM_GREEN_SIZE, hints->AccumGreenBits );
-        _setAGLAttribute( AGL_ACCUM_BLUE_SIZE,  hints->AccumBlueBits );
-        _setAGLAttribute( AGL_ACCUM_ALPHA_SIZE, hints->AccumAlphaBits );
-
-	if( hints->Samples > 1 )
-	{
-	    _setAGLAttribute( AGL_SAMPLE_BUFFERS_ARB, 1 );
-	    _setAGLAttribute( AGL_SAMPLES_ARB, hints->Samples );
-	    AGLpixelFormatAttributes[numAGLAttrs++] = AGL_NO_RECOVERY;
-	}
-
-        AGLpixelFormatAttributes[numAGLAttrs++] = AGL_NONE;
-
-        // create pixel format descriptor
-        AGLDevice mainMonitor = GetMainDevice();
-        AGLPixelFormat pixelFormat = aglChoosePixelFormat( &mainMonitor,
-                                                           1,
-                                                           AGLpixelFormatAttributes );
-        if( pixelFormat == NULL )
-        {
-            fprintf( stderr, "glfwOpenWindow failing because it can't create a pixel format\n" );
-            return GL_FALSE;
-        }
-
-        // store pixel format's values for _glfwPlatformGetWindowParam's use
-        _getAGLAttribute( AGL_ACCELERATED,      _glfwWin.Accelerated );
-        _getAGLAttribute( AGL_RED_SIZE,         _glfwWin.RedBits );
-        _getAGLAttribute( AGL_GREEN_SIZE,       _glfwWin.GreenBits );
-        _getAGLAttribute( AGL_BLUE_SIZE,        _glfwWin.BlueBits );
-        _getAGLAttribute( AGL_ALPHA_SIZE,       _glfwWin.AlphaBits );
-        _getAGLAttribute( AGL_DEPTH_SIZE,       _glfwWin.DepthBits );
-        _getAGLAttribute( AGL_STENCIL_SIZE,     _glfwWin.StencilBits );
-        _getAGLAttribute( AGL_ACCUM_RED_SIZE,   _glfwWin.AccumRedBits );
-        _getAGLAttribute( AGL_ACCUM_GREEN_SIZE, _glfwWin.AccumGreenBits );
-        _getAGLAttribute( AGL_ACCUM_BLUE_SIZE,  _glfwWin.AccumBlueBits );
-        _getAGLAttribute( AGL_ACCUM_ALPHA_SIZE, _glfwWin.AccumAlphaBits );
-        _getAGLAttribute( AGL_AUX_BUFFERS,      _glfwWin.AuxBuffers );
-        _getAGLAttribute( AGL_STEREO,           _glfwWin.Stereo );
-        _getAGLAttribute( AGL_SAMPLES_ARB,      _glfwWin.Samples );
-        _glfwWin.RefreshRate = hints->RefreshRate;
-
-        // create AGL context
-        _glfwWin.AGLContext = aglCreateContext( pixelFormat, NULL );
-
-        aglDestroyPixelFormat( pixelFormat );
-
-        if( _glfwWin.AGLContext == NULL )
-        {
-            fprintf( stderr, "glfwOpenWindow failing because it can't create an OpenGL context\n" );
-            _glfwPlatformCloseWindow();
-            return GL_FALSE;
-        }
-
-        if (_glfwLibrary.Unbundled)
-        {
-            if( GetCurrentProcess( &psn ) != noErr )
-            {
-                fprintf( stderr, "glfwOpenWindow failing because it can't get its PSN\n" );
-                _glfwPlatformCloseWindow();
-                return GL_FALSE;
-            }
-
-            /* Paul Liu 2007-12-20 - This causes problem in GHCi 
-    	    if( TransformProcessType( &psn, kProcessTransformToForegroundApplication ) != noErr )
-            {
-                fprintf( stderr, "glfwOpenWindow failing because it can't become a foreground application\n" );
-                _glfwPlatformCloseWindow();
-                return GL_FALSE;
-            }
-            */
-            
-            /* Keith Bauer 2007-07-12 - I don't believe this is desirable
-    	    if( SetFrontProcess( &psn ) != noErr )
-            {
-                fprintf( stderr, "glfwOpenWindow failing because it can't become the front process\n" );
-                _glfwPlatformCloseWindow();
-                return GL_FALSE;
-            }
-            */
-        }
-	    
-        // create window
-        Rect windowContentBounds;
-        windowContentBounds.left = 0;
-        windowContentBounds.top = 0;
-        windowContentBounds.right = width;
-        windowContentBounds.bottom = height;
-
-        windowAttributes = ( kWindowCloseBoxAttribute        \
-                           | kWindowCollapseBoxAttribute     \
-                           | kWindowStandardHandlerAttribute );
-
-        if( hints->WindowNoResize )
-        {
-            windowAttributes |= kWindowLiveResizeAttribute;
-        }
-        else
-        {
-            windowAttributes |= ( kWindowFullZoomAttribute | kWindowResizableAttribute );
-        }
-
-        error = CreateNewWindow( kDocumentWindowClass,
-                                 windowAttributes,
-                                 &windowContentBounds,
-                                 &( _glfwWin.MacWindow ) );
-        if( ( error != noErr ) || ( _glfwWin.MacWindow == NULL ) )
-        {
-            fprintf( stderr, "glfwOpenWindow failing because it can't create a window\n" );
-            _glfwPlatformCloseWindow();
-            return GL_FALSE;
-        }
-
-        _glfwWin.WindowUPP = NewEventHandlerUPP( _glfwWindowEventHandler );
-
-        error = InstallWindowEventHandler( _glfwWin.MacWindow,
-                                           _glfwWin.WindowUPP,
-                                           GetEventTypeCount( GLFW_WINDOW_EVENT_TYPES ),
-                                           GLFW_WINDOW_EVENT_TYPES,
-                                           NULL,
-                                           NULL );
-        if( error != noErr )
-        {
-            fprintf( stderr, "glfwOpenWindow failing because it can't install window event handlers\n" );
-            _glfwPlatformCloseWindow();
-            return GL_FALSE;
-        }
-
-        // Don't care if we fail here
-        (void)SetWindowTitleWithCFString( _glfwWin.MacWindow, CFSTR( "GLFW Window" ) );
-        (void)RepositionWindow( _glfwWin.MacWindow,
-                                NULL,
-                                kWindowCenterOnMainScreen );
-
-        if( !aglSetDrawable( _glfwWin.AGLContext,
-                             GetWindowPort( _glfwWin.MacWindow ) ) )
-        {
-            fprintf( stderr, "glfwOpenWindow failing because it can't draw to the window\n" );
-            _glfwPlatformCloseWindow();
-            return GL_FALSE;
-        }
-
-        // Make OpenGL context current
-        if( !aglSetCurrentContext( _glfwWin.AGLContext ) )
-        {
-            fprintf( stderr, "glfwOpenWindow failing because it can't make the OpenGL context current\n" );
-            _glfwPlatformCloseWindow();
-            return GL_FALSE;
-        }
-
-        // show window
-        ShowWindow( _glfwWin.MacWindow );
-
-        return GL_TRUE;
-    }
-    else
-    {
-        CGDisplayErr cgErr;
-        CGLError cglErr;
-
-        CFDictionaryRef optimalMode;
-
-        CGLPixelFormatObj CGLpfObj;
-        long numCGLvs = 0;
-
-        CGLPixelFormatAttribute CGLpixelFormatAttributes[64];
-        int numCGLAttrs = 0;
-
-        // variables for enumerating color depths
-        long rgbColorDepth;
-        long rgbaAccumDepth = 0;
-        int rgbChannelDepth = 0;
-
-        // CGL pixel format attributes
-        _setCGLAttribute( kCGLPFADisplayMask,
-                          CGDisplayIDToOpenGLDisplayMask( kCGDirectMainDisplay ) );
-
-        if( hints->Stereo )
-        {
-            CGLpixelFormatAttributes[ numCGLAttrs++ ] = kCGLPFAStereo;
-        }
-
-	if( hints->Samples > 1 )
-	{
-	    _setCGLAttribute( kCGLPFASamples,       (CGLPixelFormatAttribute)hints->Samples );
-	    _setCGLAttribute( kCGLPFASampleBuffers, (CGLPixelFormatAttribute)1 );
-	    CGLpixelFormatAttributes[ numCGLAttrs++ ] = kCGLPFANoRecovery;
-	}
-
-        CGLpixelFormatAttributes[ numCGLAttrs++ ]     = kCGLPFAFullScreen;
-        CGLpixelFormatAttributes[ numCGLAttrs++ ]     = kCGLPFADoubleBuffer;
-        CGLpixelFormatAttributes[ numCGLAttrs++ ]     = kCGLPFAAccelerated;
-        CGLpixelFormatAttributes[ numCGLAttrs++ ]     = kCGLPFANoRecovery;
-        CGLpixelFormatAttributes[ numCGLAttrs++ ]     = kCGLPFAMinimumPolicy;
-
-        _setCGLAttribute( kCGLPFAAccumSize,
-                          (CGLPixelFormatAttribute)( hints->AccumRedBits \
-                                                   + hints->AccumGreenBits \
-                                                   + hints->AccumBlueBits \
-                                                   + hints->AccumAlphaBits ) );
-
-        _setCGLAttribute( kCGLPFAAlphaSize,   (CGLPixelFormatAttribute)alphabits );
-        _setCGLAttribute( kCGLPFADepthSize,   (CGLPixelFormatAttribute)depthbits );
-        _setCGLAttribute( kCGLPFAStencilSize, (CGLPixelFormatAttribute)stencilbits );
-        _setCGLAttribute( kCGLPFAAuxBuffers,  (CGLPixelFormatAttribute)hints->AuxBuffers );
-
-        CGLpixelFormatAttributes[ numCGLAttrs++ ]     = (CGLPixelFormatAttribute)NULL;
-
-        // create a suitable pixel format with above attributes..
-        cglErr = CGLChoosePixelFormat( CGLpixelFormatAttributes,
-                                       &CGLpfObj,
-                                       &numCGLvs );
-        if( cglErr != kCGLNoError )
-	{
-	    return GL_FALSE;
-	}
-
-        // ..and create a rendering context using that pixel format
-        cglErr = CGLCreateContext( CGLpfObj, NULL, &_glfwWin.CGLContext );
-        if( cglErr != kCGLNoError )
-	{
-	    return GL_FALSE;
-	}
-
-        // enumerate depth of RGB channels - unlike AGL, CGL works with
-        // a single parameter reflecting the full depth of the frame buffer
-        (void)CGLDescribePixelFormat( CGLpfObj, 0, kCGLPFAColorSize, &rgbColorDepth );
-        if( rgbColorDepth == 24 || rgbColorDepth == 32 )
-	{
-	    rgbChannelDepth = 8;
-	}
-        if( rgbColorDepth == 16 )
-	{
-	    rgbChannelDepth = 5;
-	}
-
-        // get pixel depth of accumulator - I haven't got the slightest idea
-        // how this number conforms to any other channel depth than 8 bits,
-        // so this might end up giving completely knackered results...
-        (void)CGLDescribePixelFormat( CGLpfObj, 0, kCGLPFAAccumSize, &rgbaAccumDepth );
-        if( rgbaAccumDepth == 32 )
-	{
-	    rgbaAccumDepth = 8;
-	}
-
-        // store values of pixel format for _glfwPlatformGetWindowParam's use
-        _getCGLAttribute( kCGLPFAAccelerated, _glfwWin.Accelerated );
-        _getCGLAttribute( rgbChannelDepth,    _glfwWin.RedBits );
-        _getCGLAttribute( rgbChannelDepth,    _glfwWin.GreenBits );
-        _getCGLAttribute( rgbChannelDepth,    _glfwWin.BlueBits );
-        _getCGLAttribute( kCGLPFAAlphaSize,   _glfwWin.AlphaBits );
-        _getCGLAttribute( kCGLPFADepthSize,   _glfwWin.DepthBits );
-        _getCGLAttribute( kCGLPFAStencilSize, _glfwWin.StencilBits );
-        _getCGLAttribute( rgbaAccumDepth,     _glfwWin.AccumRedBits );
-        _getCGLAttribute( rgbaAccumDepth,     _glfwWin.AccumGreenBits );
-        _getCGLAttribute( rgbaAccumDepth,     _glfwWin.AccumBlueBits );
-        _getCGLAttribute( rgbaAccumDepth,     _glfwWin.AccumAlphaBits );
-        _getCGLAttribute( kCGLPFAAuxBuffers,  _glfwWin.AuxBuffers );
-        _getCGLAttribute( kCGLPFAStereo,      _glfwWin.Stereo );
-        _glfwWin.RefreshRate = hints->RefreshRate;
-
-        // destroy our pixel format
-        (void)CGLDestroyPixelFormat( CGLpfObj );
-
-        // capture the display for our application
-        cgErr = CGCaptureAllDisplays();
-        if( cgErr != kCGErrorSuccess )
-	{
-	    return GL_FALSE;
-	}
-
-        // find closest matching NON-STRETCHED display mode..
-        optimalMode = CGDisplayBestModeForParametersAndRefreshRateWithProperty( kCGDirectMainDisplay,
-	                                                                            rgbColorDepth,
-	                                                                            width,
-	/* Check further to the right -> */                                         height,
-	                                                                            hints->RefreshRate,
-	                                                                            NULL,
-	                                                                            NULL );
-        if( optimalMode == NULL )
-	{
-	    return GL_FALSE;
-	}
-
-        // ..and switch to that mode
-        cgErr = CGDisplaySwitchToMode( kCGDirectMainDisplay, optimalMode );
-        if( cgErr != kCGErrorSuccess )
-	{
-	    return GL_FALSE;
-	}
-
-        // switch to our OpenGL context, and bring it up fullscreen
-        cglErr = CGLSetCurrentContext( _glfwWin.CGLContext );
-        if( cglErr != kCGLNoError )
-	{
-	    return GL_FALSE;
-	}
-
-        cglErr = CGLSetFullScreen( _glfwWin.CGLContext );
-        if( cglErr != kCGLNoError )
-	{
-	    return GL_FALSE;
-	}
-
-        return GL_TRUE;
-    }
-}
-
-void _glfwPlatformCloseWindow( void )
-{
-    if( _glfwWin.WindowFunctions != NULL )
-    {
-        if( _glfwWin.WindowUPP != NULL )
-        {
-            DisposeEventHandlerUPP( _glfwWin.WindowUPP );
-            _glfwWin.WindowUPP = NULL;
-        }
-
-        _glfwWin.WindowFunctions->CloseWindow();
-
-        if( !_glfwWin.Fullscreen && _glfwWin.AGLContext != NULL )
-        {
-            aglSetCurrentContext( NULL );
-            aglSetDrawable( _glfwWin.AGLContext, NULL );
-            aglDestroyContext( _glfwWin.AGLContext );
-            _glfwWin.AGLContext = NULL;
-        }
-
-        if( _glfwWin.Fullscreen && _glfwWin.CGLContext != NULL )
-        {
-            CGLSetCurrentContext( NULL );
-            CGLClearDrawable( _glfwWin.CGLContext );
-            CGLDestroyContext( _glfwWin.CGLContext );
-            CGReleaseAllDisplays();
-            _glfwWin.CGLContext = NULL;
-        }
-
-        if( _glfwWin.MacWindow != NULL )
-        {
-            ReleaseWindow( _glfwWin.MacWindow );
-            _glfwWin.MacWindow = NULL;
-        }
-
-        _glfwWin.WindowFunctions = NULL;
-    }
-}
-
-void _glfwPlatformSetWindowTitle( const char *title )
-{
-    _glfwWin.WindowFunctions->SetWindowTitle( title );
-}
-
-void _glfwPlatformSetWindowSize( int width, int height )
-{
-    _glfwWin.WindowFunctions->SetWindowSize( width, height );
-}
-
-void _glfwPlatformSetWindowPos( int x, int y )
-{
-    _glfwWin.WindowFunctions->SetWindowPos( x, y );
-}
-
-void _glfwPlatformIconifyWindow( void )
-{
-    _glfwWin.WindowFunctions->IconifyWindow();
-}
-
-void _glfwPlatformRestoreWindow( void )
-{
-    _glfwWin.WindowFunctions->RestoreWindow();
-}
-
-void _glfwPlatformSwapBuffers( void )
-{
-    if( !_glfwWin.Fullscreen )
-    {
-        aglSwapBuffers( _glfwWin.AGLContext );
-    }
-    else
-    {
-        CGLFlushDrawable( _glfwWin.CGLContext );
-    }
-}
-
-void _glfwPlatformSwapInterval( int interval )
-{
-    GLint AGLparameter = interval;
-
-    // CGL doesn't seem to like intervals other than 0 (vsync off) or 1 (vsync on)
-    long CGLparameter = ( interval == 0 ? 0 : 1 );
-
-    if( !_glfwWin.Fullscreen )
-    {
-        // Don't care if we fail here..
-        (void)aglSetInteger( _glfwWin.AGLContext,
-                             AGL_SWAP_INTERVAL,
-                             &AGLparameter );
-    }
-    else
-    {
-        // ..or here
-        (void)CGLSetParameter( _glfwWin.CGLContext,
-                               kCGLCPSwapInterval,
-                               &CGLparameter );
-    }
-}
-
-void _glfwPlatformRefreshWindowParams( void )
-{
-    _glfwWin.WindowFunctions->RefreshWindowParams();
-}
-
-int _glfwPlatformGetWindowParam( int param )
-{
-    switch ( param )
-    {
-        case GLFW_ACCELERATED:      return _glfwWin.Accelerated;    break;
-        case GLFW_RED_BITS:         return _glfwWin.RedBits;        break;
-        case GLFW_GREEN_BITS:       return _glfwWin.GreenBits;      break;
-        case GLFW_BLUE_BITS:        return _glfwWin.BlueBits;       break;
-        case GLFW_ALPHA_BITS:       return _glfwWin.AlphaBits;      break;
-        case GLFW_DEPTH_BITS:       return _glfwWin.DepthBits;      break;
-        case GLFW_STENCIL_BITS:     return _glfwWin.StencilBits;    break;
-        case GLFW_ACCUM_RED_BITS:   return _glfwWin.AccumRedBits;   break;
-        case GLFW_ACCUM_GREEN_BITS: return _glfwWin.AccumGreenBits; break;
-        case GLFW_ACCUM_BLUE_BITS:  return _glfwWin.AccumBlueBits;  break;
-        case GLFW_ACCUM_ALPHA_BITS: return _glfwWin.AccumAlphaBits; break;
-        case GLFW_AUX_BUFFERS:      return _glfwWin.AuxBuffers;     break;
-        case GLFW_STEREO:           return _glfwWin.Stereo;         break;
-        case GLFW_REFRESH_RATE:     return _glfwWin.RefreshRate;    break;
-        default:                    return GL_FALSE;
-    }
-}
-
-void _glfwPlatformPollEvents( void )
-{
-    EventRef event;
-    EventTargetRef eventDispatcher = GetEventDispatcherTarget();
-
-    while ( ReceiveNextEvent( 0, NULL, 0.0, TRUE, &event ) == noErr )
-    {
-        SendEventToEventTarget( event, eventDispatcher );
-        ReleaseEvent( event );
-    }
-}
-
-void _glfwPlatformWaitEvents( void )
-{
-    EventRef event;
-
-    // Wait for new events
-    ReceiveNextEvent( 0, NULL, kEventDurationForever, FALSE, &event );
-
-    // Poll new events
-    _glfwPlatformPollEvents();
-}
-
-void _glfwPlatformHideMouseCursor( void )
-{
-    // TO DO: What if we fail here?
-    CGDisplayHideCursor( kCGDirectMainDisplay );
-    CGAssociateMouseAndMouseCursorPosition( false );
-}
-
-void _glfwPlatformShowMouseCursor( void )
-{
-    // TO DO: What if we fail here?
-    CGDisplayShowCursor( kCGDirectMainDisplay );
-    CGAssociateMouseAndMouseCursorPosition( true );
-}
-
-void _glfwPlatformSetMouseCursorPos( int x, int y )
-{
-    _glfwWin.WindowFunctions->SetMouseCursorPos( x, y );
-}
-
-int _glfwMacFSOpenWindow( int width,
-                          int height,
-                          int redbits,
-                          int greenbits,
-                          int bluebits,
-                          int alphabits,
-                          int depthbits,
-                          int stencilbits,
-                          int accumredbits,
-                          int accumgreenbits,
-                          int accumbluebits,
-                          int accumalphabits,
-                          int auxbuffers,
-                          int stereo,
-                          int refreshrate )
-{
-    return GL_FALSE;
-}
-
-void _glfwMacFSCloseWindow( void )
-{
-    // TO DO: un-capture displays, &c.
-}
-
-void _glfwMacFSSetWindowTitle( const char *title )
-{
-    // no-op really, change "fake" mini-window title
-    _glfwMacDWSetWindowTitle( title );
-}
-
-void _glfwMacFSSetWindowSize( int width, int height )
-{
-    // TO DO: something funky for full-screen
-    _glfwMacDWSetWindowSize( width, height );
-}
-
-void _glfwMacFSSetWindowPos( int x, int y )
-{
-    // no-op really, change "fake" mini-window position
-    _glfwMacDWSetWindowPos( x, y );
-}
-
-void _glfwMacFSIconifyWindow( void )
-{
-    // TO DO: Something funky for full-screen
-    _glfwMacDWIconifyWindow();
-}
-
-void _glfwMacFSRestoreWindow( void )
-{
-    _glfwMacDWRestoreWindow();
-    // TO DO: Something funky for full-screen
-}
-
-void _glfwMacFSRefreshWindowParams( void )
-{
-    // TO DO: implement this!
-}
-
-void _glfwMacFSSetMouseCursorPos( int x, int y )
-{
-    // TO DO: what if we fail here?
-    CGDisplayMoveCursorToPoint( kCGDirectMainDisplay,
-                                CGPointMake( x, y ) );
-}
-
-int  _glfwMacDWOpenWindow( int width,
-                           int height,
-                           int redbits,
-                           int greenbits,
-                           int bluebits,
-                           int alphabits,
-                           int depthbits,
-                           int stencilbits,
-                           int accumredbits,
-                           int accumgreenbits,
-                           int accumbluebits,
-                           int accumalphabits,
-                           int auxbuffers,
-                           int stereo,
-                           int refreshrate )
-{
-    return GL_FALSE;
-}
-
-void _glfwMacDWCloseWindow( void )
-{
-}
-
-void _glfwMacDWSetWindowTitle( const char *title )
-{
-    CFStringRef windowTitle = CFStringCreateWithCString( kCFAllocatorDefault,
-                                                         title,
-                                                         kCFStringEncodingISOLatin1 );
-
-    // Don't care if we fail
-    (void)SetWindowTitleWithCFString( _glfwWin.MacWindow, windowTitle );
-
-    CFRelease( windowTitle );
-}
-
-void _glfwMacDWSetWindowSize( int width, int height )
-{
-    SizeWindow( _glfwWin.MacWindow,
-                width,
-                height,
-                TRUE );
-}
-
-void _glfwMacDWSetWindowPos( int x, int y )
-{
-    // TO DO: take main monitor bounds into account
-    MoveWindow( _glfwWin.MacWindow,
-                x,
-                y,
-                FALSE );
-}
-
-void _glfwMacDWIconifyWindow( void )
-{
-    // TO DO: What if we fail here?
-    (void)CollapseWindow( _glfwWin.MacWindow,
-                          TRUE );
-}
-
-void _glfwMacDWRestoreWindow( void )
-{
-    // TO DO: What if we fail here?
-    (void)CollapseWindow( _glfwWin.MacWindow,
-                          FALSE );
-}
-
-void _glfwMacDWRefreshWindowParams( void )
-{
-    // TO DO: implement this!
-}
-
-void _glfwMacDWSetMouseCursorPos( int x, int y )
-{
-    Rect content;
-    GetWindowBounds(_glfwWin.MacWindow, kWindowContentRgn, &content);
-
-    _glfwInput.MousePosX = x + content.left;
-    _glfwInput.MousePosY = y + content.top;
-
-    CGDisplayMoveCursorToPoint( kCGDirectMainDisplay,
-			        CGPointMake( _glfwInput.MousePosX,
-					     _glfwInput.MousePosY ) );
-}
-
diff --git a/glfw/lib/macosx/platform.h b/glfw/lib/macosx/platform.h
deleted file mode 100644
--- a/glfw/lib/macosx/platform.h
+++ /dev/null
@@ -1,349 +0,0 @@
-//========================================================================
-// GLFW - An OpenGL framework
-// File:        platform.h
-// Platform:    Mac OS X
-// API Version: 2.6
-// WWW:         http://glfw.sourceforge.net
-//------------------------------------------------------------------------
-// Copyright (c) 2002-2006 Camilla Berglund
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-//    claim that you wrote the original software. If you use this software
-//    in a product, an acknowledgment in the product documentation would
-//    be appreciated but is not required.
-//
-// 2. Altered source versions must be plainly marked as such, and must not
-//    be misrepresented as being the original software.
-//
-// 3. This notice may not be removed or altered from any source
-//    distribution.
-//
-//========================================================================
-
-#ifndef _platform_h_
-#define _platform_h_
-
-
-// This is the Mac OS X version of GLFW
-#define _GLFW_MAC_OS_X
-
-
-// Include files
-#include <Carbon/Carbon.h>
-#include <OpenGL/OpenGL.h>
-#include <AGL/agl.h>
-#include <sched.h>
-#include <pthread.h>
-#include <sys/sysctl.h>
-#include "../../include/GL/glfw.h"
-
-
-//========================================================================
-// Defines
-//========================================================================
-
-#define _GLFW_MAX_PATH_LENGTH (8192)
-
-#define MAC_KEY_ENTER       0x24
-#define MAC_KEY_RETURN      0x34
-#define MAC_KEY_ESC         0x35
-#define MAC_KEY_F1          0x7A
-#define MAC_KEY_F2          0x78
-#define MAC_KEY_F3          0x63
-#define MAC_KEY_F4          0x76
-#define MAC_KEY_F5          0x60
-#define MAC_KEY_F6          0x61
-#define MAC_KEY_F7          0x62
-#define MAC_KEY_F8          0x64
-#define MAC_KEY_F9          0x65
-#define MAC_KEY_F10         0x6D
-#define MAC_KEY_F11         0x67
-#define MAC_KEY_F12         0x6F
-#define MAC_KEY_F13         0x69
-#define MAC_KEY_F14         0x6B
-#define MAC_KEY_F15         0x71
-#define MAC_KEY_UP          0x7E
-#define MAC_KEY_DOWN        0x7D
-#define MAC_KEY_LEFT        0x7B
-#define MAC_KEY_RIGHT       0x7C
-#define MAC_KEY_TAB         0x30
-#define MAC_KEY_BACKSPACE   0x33
-#define MAC_KEY_HELP        0x72
-#define MAC_KEY_DEL         0x75
-#define MAC_KEY_PAGEUP      0x74
-#define MAC_KEY_PAGEDOWN    0x79
-#define MAC_KEY_HOME        0x73
-#define MAC_KEY_END         0x77
-#define MAC_KEY_KP_0        0x52
-#define MAC_KEY_KP_1        0x53
-#define MAC_KEY_KP_2        0x54
-#define MAC_KEY_KP_3        0x55
-#define MAC_KEY_KP_4        0x56
-#define MAC_KEY_KP_5        0x57
-#define MAC_KEY_KP_6        0x58
-#define MAC_KEY_KP_7        0x59
-#define MAC_KEY_KP_8        0x5B
-#define MAC_KEY_KP_9        0x5C
-#define MAC_KEY_KP_DIVIDE   0x4B
-#define MAC_KEY_KP_MULTIPLY 0x43
-#define MAC_KEY_KP_SUBTRACT 0x4E
-#define MAC_KEY_KP_ADD      0x45
-#define MAC_KEY_KP_DECIMAL  0x41
-#define MAC_KEY_KP_EQUAL    0x51
-#define MAC_KEY_KP_ENTER    0x4C
-
-//========================================================================
-// full-screen/desktop-window "virtual" function table
-//========================================================================
-
-typedef int  ( * GLFWmacopenwindowfun )( int, int, int, int, int, int, int, int, int, int, int, int, int, int, int );
-typedef void ( * GLFWmacclosewindowfun )( void );
-typedef void ( * GLFWmacsetwindowtitlefun )( const char * );
-typedef void ( * GLFWmacsetwindowsizefun )( int, int );
-typedef void ( * GLFWmacsetwindowposfun )( int, int );
-typedef void ( * GLFWmaciconifywindowfun )( void );
-typedef void ( * GLFWmacrestorewindowfun )( void );
-typedef void ( * GLFWmacrefreshwindowparamsfun )( void );
-typedef void ( * GLFWmacsetmousecursorposfun )( int, int );
-
-typedef struct
-{
-    GLFWmacopenwindowfun          OpenWindow;
-    GLFWmacclosewindowfun         CloseWindow;
-    GLFWmacsetwindowtitlefun      SetWindowTitle;
-    GLFWmacsetwindowsizefun       SetWindowSize;
-    GLFWmacsetwindowposfun        SetWindowPos;
-    GLFWmaciconifywindowfun       IconifyWindow;
-    GLFWmacrestorewindowfun       RestoreWindow;
-    GLFWmacrefreshwindowparamsfun RefreshWindowParams;
-    GLFWmacsetmousecursorposfun   SetMouseCursorPos;
-}
-_GLFWmacwindowfunctions;
-
-
-//========================================================================
-// Global variables (GLFW internals)
-//========================================================================
-
-GLFWGLOBAL CFDictionaryRef _glfwDesktopVideoMode;
-
-//------------------------------------------------------------------------
-// Window structure
-//------------------------------------------------------------------------
-typedef struct _GLFWwin_struct _GLFWwin;
-
-struct _GLFWwin_struct {
-
-    // ========= PLATFORM INDEPENDENT MANDATORY PART =========================
-
-    // Window states
-    int       Opened;          // Flag telling if window is opened or not
-    int       Active;          // Application active flag
-    int       Iconified;       // Window iconified flag
-
-    // User callback functions
-    GLFWwindowsizefun    WindowSizeCallback;
-    GLFWwindowclosefun   WindowCloseCallback;
-    GLFWwindowrefreshfun WindowRefreshCallback;
-    GLFWmousebuttonfun   MouseButtonCallback;
-    GLFWmouseposfun      MousePosCallback;
-    GLFWmousewheelfun    MouseWheelCallback;
-    GLFWkeyfun           KeyCallback;
-    GLFWcharfun          CharCallback;
-
-    // User selected window settings
-    int       Fullscreen;      // Fullscreen flag
-    int       MouseLock;       // Mouse-lock flag
-    int       AutoPollEvents;  // Auto polling flag
-    int       SysKeysDisabled; // System keys disabled flag
-    int       RefreshRate;     // Refresh rate (for fullscreen mode)
-    int       WindowNoResize;  // Resize- and maximize gadgets disabled flag
-    int	      Samples;
-
-    // Window status
-    int       Width, Height;   // Window width and heigth
-
-    // Extensions & OpenGL version
-    int       Has_GL_SGIS_generate_mipmap;
-    int       Has_GL_ARB_texture_non_power_of_two;
-    int       GLVerMajor,GLVerMinor;
-
-
-    // ========= PLATFORM SPECIFIC PART ======================================
-
-    WindowRef               MacWindow;
-    AGLContext              AGLContext;
-    CGLContextObj           CGLContext;
-
-    EventHandlerUPP         MouseUPP;
-    EventHandlerUPP         CommandUPP;
-    EventHandlerUPP         KeyboardUPP;
-    EventHandlerUPP         WindowUPP;
-
-    _GLFWmacwindowfunctions* WindowFunctions;
-
-    // for easy access by _glfwPlatformGetWindowParam
-    int Accelerated;
-    int RedBits, GreenBits, BlueBits, AlphaBits;
-    int DepthBits;
-    int StencilBits;
-    int AccumRedBits, AccumGreenBits, AccumBlueBits, AccumAlphaBits;
-    int AuxBuffers;
-    int Stereo;
-};
-
-GLFWGLOBAL _GLFWwin _glfwWin;
-
-
-//------------------------------------------------------------------------
-// User input status (some of this should go in _GLFWwin)
-//------------------------------------------------------------------------
-GLFWGLOBAL struct {
-
-    // ========= PLATFORM INDEPENDENT MANDATORY PART =========================
-
-    // Mouse status
-    int  MousePosX, MousePosY;
-    int  WheelPos;
-    char MouseButton[ GLFW_MOUSE_BUTTON_LAST+1 ];
-
-    // Keyboard status
-    char Key[ GLFW_KEY_LAST+1 ];
-    int  LastChar;
-
-    // User selected settings
-    int  StickyKeys;
-    int  StickyMouseButtons;
-    int  KeyRepeat;
-
-
-    // ========= PLATFORM SPECIFIC PART ======================================
-
-    UInt32 Modifiers;
-
-} _glfwInput;
-
-
-
-
-//------------------------------------------------------------------------
-// Thread information
-//------------------------------------------------------------------------
-typedef struct _GLFWthread_struct _GLFWthread;
-
-// Thread record (one for each thread)
-struct _GLFWthread_struct {
-    // Pointer to previous and next threads in linked list
-    _GLFWthread   *Previous, *Next;
-
-    // GLFW user side thread information
-    GLFWthread    ID;
-    GLFWthreadfun Function;
-
-    // System side thread information
-    pthread_t     PosixID;
-};
-
-// General thread information
-GLFWGLOBAL struct {
-    // Critical section lock
-    pthread_mutex_t  CriticalSection;
-
-    // Next thread ID to use (increments for every created thread)
-    GLFWthread       NextID;
-
-    // First thread in linked list (always the main thread)
-    _GLFWthread      First;
-} _glfwThrd;
-
-
-//------------------------------------------------------------------------
-// Library global data
-//------------------------------------------------------------------------
-GLFWGLOBAL struct {
-
-    // Timer data
-    struct {
-	double       t0;
-    } Timer;
-
-    struct {
-	    // Bundle for dynamically-loading extension function pointers
-    	CFBundleRef OpenGLFramework;
-    } Libs;
-    
-    int Unbundled;
-    
-} _glfwLibrary;
-
-
-
-//========================================================================
-// Macros for encapsulating critical code sections (i.e. making parts
-// of GLFW thread safe)
-//========================================================================
-
-// Define so we can use the same thread code as X11
-#define _glfw_numprocessors(n) { \
-    int mib[2], ncpu; \
-    size_t len = 1; \
-    mib[0] = CTL_HW; \
-    mib[1] = HW_NCPU; \
-    n      = 1; \
-    if( sysctl( mib, 2, &ncpu, &len, NULL, 0 ) != -1 ) \
-    { \
-        if( len > 0 ) \
-        { \
-            n = ncpu; \
-        } \
-    } \
-}
-
-// Thread list management
-#define ENTER_THREAD_CRITICAL_SECTION \
-pthread_mutex_lock( &_glfwThrd.CriticalSection );
-#define LEAVE_THREAD_CRITICAL_SECTION \
-pthread_mutex_unlock( &_glfwThrd.CriticalSection );
-
-
-//========================================================================
-// Prototypes for platform specific internal functions
-//========================================================================
-
-void  _glfwChangeToResourcesDirectory( void );
-
-int  _glfwInstallEventHandlers( void );
-
-//========================================================================
-// Prototypes for full-screen/desktop-window "virtual" functions
-//========================================================================
-
-int  _glfwMacFSOpenWindow( int width, int height, int redbits, int greenbits, int bluebits, int alphabits, int depthbits, int stencilbits, int accumredbits, int accumgreenbits, int accumbluebits, int accumalphabits, int auxbuffers, int stereo, int refreshrate );
-void _glfwMacFSCloseWindow( void );
-void _glfwMacFSSetWindowTitle( const char *title );
-void _glfwMacFSSetWindowSize( int width, int height );
-void _glfwMacFSSetWindowPos( int x, int y );
-void _glfwMacFSIconifyWindow( void );
-void _glfwMacFSRestoreWindow( void );
-void _glfwMacFSRefreshWindowParams( void );
-void _glfwMacFSSetMouseCursorPos( int x, int y );
-
-int  _glfwMacDWOpenWindow( int width, int height, int redbits, int greenbits, int bluebits, int alphabits, int depthbits, int stencilbits, int accumredbits, int accumgreenbits, int accumbluebits, int accumalphabits, int auxbuffers, int stereo, int refreshrate );
-void _glfwMacDWCloseWindow( void );
-void _glfwMacDWSetWindowTitle( const char *title );
-void _glfwMacDWSetWindowSize( int width, int height );
-void _glfwMacDWSetWindowPos( int x, int y );
-void _glfwMacDWIconifyWindow( void );
-void _glfwMacDWRestoreWindow( void );
-void _glfwMacDWRefreshWindowParams( void );
-void _glfwMacDWSetMouseCursorPos( int x, int y );
-
-#endif // _platform_h_
diff --git a/glfw/lib/stream.c b/glfw/lib/stream.c
--- a/glfw/lib/stream.c
+++ b/glfw/lib/stream.c
@@ -1,11 +1,11 @@
 //========================================================================
 // GLFW - An OpenGL framework
-// File:        stream.c
 // Platform:    Any
-// API version: 2.6
-// WWW:         http://glfw.sourceforge.net
+// API version: 2.7
+// WWW:         http://www.glfw.org/
 //------------------------------------------------------------------------
-// Copyright (c) 2002-2006 Camilla Berglund
+// Copyright (c) 2002-2006 Marcus Geelnard
+// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org>
 //
 // This software is provided 'as-is', without any express or implied
 // warranty. In no event will the authors be held liable for any damages
@@ -28,6 +28,7 @@
 //
 //========================================================================
 
+#define _CRT_SECURE_NO_WARNINGS
 
 #include "internal.h"
 
@@ -40,10 +41,10 @@
 {
     memset( stream, 0, sizeof(_GLFWstream) );
 
-    stream->File = fopen( name, mode );
-    if( stream->File == NULL )
+    stream->file = fopen( name, mode );
+    if( stream->file == NULL )
     {
-	return GL_FALSE;
+        return GL_FALSE;
     }
 
     return GL_TRUE;
@@ -58,8 +59,8 @@
 {
     memset( stream, 0, sizeof(_GLFWstream) );
 
-    stream->Data = data;
-    stream->Size = size;
+    stream->data = data;
+    stream->size = size;
     return GL_TRUE;
 }
 
@@ -70,29 +71,29 @@
 
 long _glfwReadStream( _GLFWstream *stream, void *data, long size )
 {
-    if( stream->File != NULL )
+    if( stream->file != NULL )
     {
-	return fread( data, 1, size, stream->File );
+        return (long) fread( data, 1, size, stream->file );
     }
 
-    if( stream->Data != NULL )
+    if( stream->data != NULL )
     {
-	// Check for EOF
-	if( stream->Position == stream->Size )
-	{
-	    return 0;
-	}
+        // 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;
+        // 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;
@@ -105,14 +106,14 @@
 
 long _glfwTellStream( _GLFWstream *stream )
 {
-    if( stream->File != NULL )
+    if( stream->file != NULL )
     {
-	return ftell( stream->File );
+        return ftell( stream->file );
     }
 
-    if( stream->Data != NULL )
+    if( stream->data != NULL )
     {
-	return stream->Position;
+        return stream->position;
     }
 
     return 0;
@@ -127,49 +128,49 @@
 {
     long position;
 
-    if( stream->File != NULL )
+    if( stream->file != NULL )
     {
-	if( fseek( stream->File, offset, whence ) != 0 )
-	{
-	    return GL_FALSE;
-	}
+        if( fseek( stream->file, offset, whence ) != 0 )
+        {
+            return GL_FALSE;
+        }
 
-	return GL_TRUE;
+        return GL_TRUE;
     }
 
-    if( stream->Data != NULL )
+    if( stream->data != NULL )
     {
-	position = offset;
+        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;
-	}
+        // 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;
+        // 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;
@@ -182,9 +183,9 @@
 
 void _glfwCloseStream( _GLFWstream *stream )
 {
-    if( stream->File != NULL )
+    if( stream->file != NULL )
     {
-	fclose( stream->File );
+        fclose( stream->file );
     }
 
     // Nothing to be done about (user allocated) memory blocks
diff --git a/glfw/lib/tga.c b/glfw/lib/tga.c
--- a/glfw/lib/tga.c
+++ b/glfw/lib/tga.c
@@ -1,11 +1,11 @@
 //========================================================================
 // GLFW - An OpenGL framework
-// File:        tga.c
 // Platform:    Any
-// API version: 2.6
-// WWW:         http://glfw.sourceforge.net
+// API version: 2.7
+// WWW:         http://www.glfw.org/
 //------------------------------------------------------------------------
-// Copyright (c) 2002-2006 Camilla Berglund
+// Copyright (c) 2002-2006 Marcus Geelnard
+// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org>
 //
 // This software is provided 'as-is', without any express or implied
 // warranty. In no event will the authors be held liable for any damages
@@ -90,11 +90,10 @@
 
 
 //========================================================================
-// _glfwReadTGAHeader() - Read TGA file header (and check that it is
-// valid)
+// Read TGA file header (and check that it is valid)
 //========================================================================
 
-static int _glfwReadTGAHeader( _GLFWstream *s, _tga_header_t *h )
+static int ReadTGAHeader( _GLFWstream *s, _tga_header_t *h )
 {
     unsigned char buf[ 18 ];
     int pos;
@@ -147,11 +146,11 @@
 }
 
 //========================================================================
-// _glfwReadTGA_RLE() - Read Run-Length Encoded data
+// Read Run-Length Encoded data
 //========================================================================
 
-static void _glfwReadTGA_RLE( unsigned char *buf, int size, int bpp,
-    _GLFWstream *s )
+static void ReadTGA_RLE( unsigned char *buf, int size, int bpp,
+                         _GLFWstream *s )
 {
     int repcount, bytes, k, n;
     unsigned char pixel[ 4 ];
@@ -199,7 +198,7 @@
 
 
 //========================================================================
-// _glfwReadTGA() - Read a TGA image from a file
+// Read a TGA image from a file
 //========================================================================
 
 int _glfwReadTGA( _GLFWstream *s, GLFWimage *img, int flags )
@@ -210,7 +209,7 @@
     int bpp, bpp2, k, m, n, swapx, swapy;
 
     // Read TGA header
-    if( !_glfwReadTGAHeader( s, &h ) )
+    if( !ReadTGAHeader( s, &h ) )
     {
         return 0;
     }
@@ -276,7 +275,7 @@
     // Read pixel data from file
     if( h.imagetype >= _TGA_IMAGETYPE_CMAP_RLE )
     {
-        _glfwReadTGA_RLE( pix, pixsize, bpp, s );
+        ReadTGA_RLE( pix, pixsize, bpp, s );
     }
     else
     {
diff --git a/glfw/lib/thread.c b/glfw/lib/thread.c
--- a/glfw/lib/thread.c
+++ b/glfw/lib/thread.c
@@ -1,11 +1,11 @@
 //========================================================================
 // GLFW - An OpenGL framework
-// File:        thread.c
 // Platform:    Any
-// API version: 2.6
-// WWW:         http://glfw.sourceforge.net
+// API version: 2.7
+// WWW:         http://www.glfw.org/
 //------------------------------------------------------------------------
-// Copyright (c) 2002-2006 Camilla Berglund
+// Copyright (c) 2002-2006 Marcus Geelnard
+// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org>
 //
 // This software is provided 'as-is', without any express or implied
 // warranty. In no event will the authors be held liable for any damages
@@ -37,7 +37,7 @@
 //************************************************************************
 
 //========================================================================
-// _glfwGetThreadPointer() - Find pointer to thread with a matching ID
+// Find pointer to thread with a matching ID
 //========================================================================
 
 _GLFWthread * _glfwGetThreadPointer( int ID )
@@ -57,7 +57,7 @@
 
 
 //========================================================================
-// _glfwAppendThread() - Append thread to thread list
+// Append thread to thread list
 //========================================================================
 
 void _glfwAppendThread( _GLFWthread * t )
@@ -76,7 +76,7 @@
 
 
 //========================================================================
-// _glfwRemoveThread() - Remove thread from thread list
+// Remove thread from thread list
 //========================================================================
 
 void _glfwRemoveThread( _GLFWthread * t )
@@ -99,11 +99,11 @@
 //************************************************************************
 
 //========================================================================
-// glfwCreateThread() - Create a new thread
+// Create a new thread
 //========================================================================
 
 GLFWAPI GLFWthread GLFWAPIENTRY glfwCreateThread( GLFWthreadfun fun,
-    void *arg )
+                                                  void *arg )
 {
     // Is GLFW initialized?
     if( !_glfwInitialized )
@@ -117,8 +117,8 @@
 
 
 //========================================================================
-// glfwDestroyThread() - Kill a thread. NOTE: THIS IS A VERY DANGEROUS
-// OPERATION, AND SHOULD NOT BE USED EXCEPT IN EXTREME SITUATIONS!
+// 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 )
@@ -140,7 +140,7 @@
 
 
 //========================================================================
-// glfwWaitThread() - Wait for a thread to die
+// Wait for a thread to die
 //========================================================================
 
 GLFWAPI int GLFWAPIENTRY glfwWaitThread( GLFWthread ID, int waitmode )
@@ -162,7 +162,7 @@
 
 
 //========================================================================
-// glfwGetThreadID() - Return the thread ID for the current thread
+// Return the thread ID for the current thread
 //========================================================================
 
 GLFWAPI GLFWthread GLFWAPIENTRY glfwGetThreadID( void )
@@ -178,7 +178,7 @@
 
 
 //========================================================================
-// glfwCreateMutex() - Create a mutual exclusion object
+// Create a mutual exclusion object
 //========================================================================
 
 GLFWAPI GLFWmutex GLFWAPIENTRY glfwCreateMutex( void )
@@ -194,7 +194,7 @@
 
 
 //========================================================================
-// glfwDestroyMutex() - Destroy a mutual exclusion object
+// Destroy a mutual exclusion object
 //========================================================================
 
 GLFWAPI void GLFWAPIENTRY glfwDestroyMutex( GLFWmutex mutex )
@@ -210,7 +210,7 @@
 
 
 //========================================================================
-// glfwLockMutex() - Request access to a mutex
+// Request access to a mutex
 //========================================================================
 
 GLFWAPI void GLFWAPIENTRY glfwLockMutex( GLFWmutex mutex )
@@ -226,7 +226,7 @@
 
 
 //========================================================================
-// glfwUnlockMutex() - Release a mutex
+// Release a mutex
 //========================================================================
 
 GLFWAPI void GLFWAPIENTRY glfwUnlockMutex( GLFWmutex mutex )
@@ -242,7 +242,7 @@
 
 
 //========================================================================
-// glfwCreateCond() - Create a new condition variable object
+// Create a new condition variable object
 //========================================================================
 
 GLFWAPI GLFWcond GLFWAPIENTRY glfwCreateCond( void )
@@ -258,7 +258,7 @@
 
 
 //========================================================================
-// glfwDestroyCond() - Destroy a condition variable object
+// Destroy a condition variable object
 //========================================================================
 
 GLFWAPI void GLFWAPIENTRY glfwDestroyCond( GLFWcond cond )
@@ -274,11 +274,11 @@
 
 
 //========================================================================
-// glfwWaitCond() - Wait for a condition to be raised
+// Wait for a condition to be raised
 //========================================================================
 
 GLFWAPI void GLFWAPIENTRY glfwWaitCond( GLFWcond cond, GLFWmutex mutex,
-    double timeout )
+                                        double timeout )
 {
     // Initialized & valid condition variable and mutex?
     if( !_glfwInitialized || !cond || !mutex )
@@ -291,7 +291,7 @@
 
 
 //========================================================================
-// glfwSignalCond() - Signal a condition to one waiting thread
+// Signal a condition to one waiting thread
 //========================================================================
 
 GLFWAPI void GLFWAPIENTRY glfwSignalCond( GLFWcond cond )
@@ -307,7 +307,7 @@
 
 
 //========================================================================
-// glfwBroadcastCond() - Broadcast a condition to all waiting threads
+// Broadcast a condition to all waiting threads
 //========================================================================
 
 GLFWAPI void GLFWAPIENTRY glfwBroadcastCond( GLFWcond cond )
@@ -323,9 +323,9 @@
 
 
 //========================================================================
-// 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.
+// 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 )
@@ -338,3 +338,4 @@
 
     return _glfwPlatformGetNumberOfProcessors();
 }
+
diff --git a/glfw/lib/time.c b/glfw/lib/time.c
--- a/glfw/lib/time.c
+++ b/glfw/lib/time.c
@@ -1,11 +1,11 @@
 //========================================================================
 // GLFW - An OpenGL framework
-// File:        time.c
 // Platform:    Any
-// API version: 2.6
-// WWW:         http://glfw.sourceforge.net
+// API version: 2.7
+// WWW:         http://www.glfw.org/
 //------------------------------------------------------------------------
-// Copyright (c) 2002-2006 Camilla Berglund
+// Copyright (c) 2002-2006 Marcus Geelnard
+// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org>
 //
 // This software is provided 'as-is', without any express or implied
 // warranty. In no event will the authors be held liable for any damages
@@ -36,7 +36,7 @@
 //************************************************************************
 
 //========================================================================
-// glfwGetTime() - Return timer value in seconds
+// Return timer value in seconds
 //========================================================================
 
 GLFWAPI double GLFWAPIENTRY glfwGetTime( void )
@@ -52,7 +52,7 @@
 
 
 //========================================================================
-// glfwSetTime() - Set timer value in seconds
+// Set timer value in seconds
 //========================================================================
 
 GLFWAPI void GLFWAPIENTRY glfwSetTime( double time )
@@ -68,7 +68,7 @@
 
 
 //========================================================================
-// glfwSleep() - Put a thread to sleep for a specified amount of time
+// Put a thread to sleep for a specified amount of time
 //========================================================================
 
 GLFWAPI void GLFWAPIENTRY glfwSleep( double time )
@@ -81,3 +81,4 @@
 
     _glfwPlatformSleep( time );
 }
+
diff --git a/glfw/lib/win32/platform.h b/glfw/lib/win32/platform.h
--- a/glfw/lib/win32/platform.h
+++ b/glfw/lib/win32/platform.h
@@ -1,11 +1,11 @@
 //========================================================================
 // GLFW - An OpenGL framework
-// File:        platform.h
-// Platform:    Windows
-// API version: 2.6
-// WWW:         http://glfw.sourceforge.net
+// Platform:    Win32/WGL
+// API version: 2.7
+// WWW:         http://www.glfw.org/
 //------------------------------------------------------------------------
-// Copyright (c) 2002-2006 Camilla Berglund
+// Copyright (c) 2002-2006 Marcus Geelnard
+// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org>
 //
 // This software is provided 'as-is', without any express or implied
 // warranty. In no event will the authors be held liable for any damages
@@ -35,6 +35,10 @@
 // This is the Windows version of GLFW
 #define _GLFW_WIN32
 
+// We don't need all the fancy stuff
+#define NOMINMAX
+#define WIN32_LEAN_AND_MEAN
+#define VC_EXTRALEAN
 
 // Include files
 #include <windows.h>
@@ -129,40 +133,98 @@
 #define XBUTTON2 2
 #endif
 
-// wglSwapIntervalEXT typedef (Win32 buffer-swap interval control)
-typedef int (APIENTRY * WGLSWAPINTERVALEXT_T) (int);
-// wglChoosePixelFormatARB typedef
-typedef BOOL (WINAPI * WGLCHOOSEPIXELFORMATARB_T) (HDC, const int *, const FLOAT *, UINT, int *, UINT *);
-// wglGetPixelFormatAttribivARB typedef
-typedef BOOL (WINAPI * WGLGETPIXELFORMATATTRIBIVARB_T) (HDC, int, int, UINT, const int *, int *);
-// wglGetExtensionStringEXT typedef
-typedef const char *(APIENTRY * WGLGETEXTENSIONSSTRINGEXT_T)( void );
-// wglGetExtensionStringARB typedef
-typedef const char *(APIENTRY * WGLGETEXTENSIONSSTRINGARB_T)( HDC );
+#ifndef WGL_EXT_swap_control
 
-#define WGL_DRAW_TO_WINDOW_ARB    0x2001
-#define WGL_SUPPORT_OPENGL_ARB    0x2010
-#define WGL_ACCELERATION_ARB      0x2003
-#define WGL_FULL_ACCELERATION_ARB 0x2027
-#define WGL_DOUBLE_BUFFER_ARB     0x2011
-#define WGL_STEREO_ARB            0x2012
-#define WGL_COLOR_BITS_ARB        0x2014
-#define WGL_RED_BITS_ARB          0x2015
-#define WGL_GREEN_BITS_ARB        0x2017
-#define WGL_BLUE_BITS_ARB         0x2019
-#define WGL_ALPHA_BITS_ARB        0x201B
-#define WGL_ACCUM_BITS_ARB        0x201D 
-#define WGL_ACCUM_RED_BITS_ARB    0x201E 
-#define WGL_ACCUM_GREEN_BITS_ARB  0x201F 
-#define WGL_ACCUM_BLUE_BITS_ARB   0x2020 
-#define WGL_ACCUM_ALPHA_BITS_ARB  0x2021 
-#define WGL_DEPTH_BITS_ARB        0x2022
-#define WGL_STENCIL_BITS_ARB      0x2023
-#define WGL_AUX_BUFFERS_ARB       0x2024 
-#define WGL_SAMPLE_BUFFERS_ARB    0x2041
-#define WGL_SAMPLES_ARB           0x2042
+/* Entry points */
+typedef int (APIENTRY * PFNWGLSWAPINTERVALEXTPROC) (int);
 
+#endif /*WGL_EXT_swap_control*/
 
+#ifndef WGL_ARB_extensions_string
+
+/* Entry points */
+typedef const char *(APIENTRY * PFNWGLGETEXTENSIONSSTRINGARBPROC)( HDC );
+
+#endif /*WGL_ARB_extensions_string*/
+
+#ifndef WGL_EXT_extension_string
+
+/* Entry points */
+typedef const char *(APIENTRY * PFNWGLGETEXTENSIONSSTRINGEXTPROC)( void );
+
+#endif /*WGL_EXT_extension_string*/
+
+#ifndef WGL_ARB_pixel_format
+
+/* Entry points */
+typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBIVARBPROC) (HDC, int, int, UINT, const int *, int *);
+
+/* Constants for wglGetPixelFormatAttribivARB */
+#define WGL_NUMBER_PIXEL_FORMATS_ARB    0x2000
+#define WGL_DRAW_TO_WINDOW_ARB          0x2001
+#define WGL_SUPPORT_OPENGL_ARB          0x2010
+#define WGL_ACCELERATION_ARB            0x2003
+#define WGL_DOUBLE_BUFFER_ARB           0x2011
+#define WGL_STEREO_ARB                  0x2012
+#define WGL_PIXEL_TYPE_ARB              0x2013
+#define WGL_COLOR_BITS_ARB              0x2014
+#define WGL_RED_BITS_ARB                0x2015
+#define WGL_GREEN_BITS_ARB              0x2017
+#define WGL_BLUE_BITS_ARB               0x2019
+#define WGL_ALPHA_BITS_ARB              0x201B
+#define WGL_ACCUM_BITS_ARB              0x201D
+#define WGL_ACCUM_RED_BITS_ARB          0x201E
+#define WGL_ACCUM_GREEN_BITS_ARB        0x201F
+#define WGL_ACCUM_BLUE_BITS_ARB         0x2020
+#define WGL_ACCUM_ALPHA_BITS_ARB        0x2021
+#define WGL_DEPTH_BITS_ARB              0x2022
+#define WGL_STENCIL_BITS_ARB            0x2023
+#define WGL_AUX_BUFFERS_ARB             0x2024
+#define WGL_SAMPLE_BUFFERS_ARB          0x2041
+#define WGL_SAMPLES_ARB                 0x2042
+
+/* Constants for WGL_ACCELERATION_ARB */
+#define WGL_NO_ACCELERATION_ARB         0x2025
+#define WGL_GENERIC_ACCELERATION_ARB    0x2026
+#define WGL_FULL_ACCELERATION_ARB       0x2027
+
+/* Constants for WGL_PIXEL_TYPE_ARB */
+#define WGL_TYPE_RGBA_ARB               0x202B
+#define WGL_TYPE_COLORINDEX_ARB         0x202C
+
+#endif /*WGL_ARB_pixel_format*/
+
+
+#ifndef WGL_ARB_create_context
+
+/* Entry points */
+typedef HGLRC (WINAPI * PFNWGLCREATECONTEXTATTRIBSARBPROC) (HDC, HGLRC, const int *);
+
+/* Tokens for wglCreateContextAttribsARB attributes */
+#define WGL_CONTEXT_MAJOR_VERSION_ARB          0x2091
+#define WGL_CONTEXT_MINOR_VERSION_ARB          0x2092
+#define WGL_CONTEXT_LAYER_PLANE_ARB            0x2093
+#define WGL_CONTEXT_FLAGS_ARB                  0x2094
+#define WGL_CONTEXT_PROFILE_MASK_ARB           0x9126
+
+/* Bits for WGL_CONTEXT_FLAGS_ARB */
+#define WGL_CONTEXT_DEBUG_BIT_ARB              0x0001
+#define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x0002
+
+/* Bits for WGL_CONTEXT_PROFILE_MASK_ARB */
+#define WGL_CONTEXT_CORE_PROFILE_BIT_ARB          0x00000001
+#define WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002
+
+#endif /*WGL_ARB_create_context*/
+
+
+#ifndef GL_VERSION_3_0
+
+typedef const GLubyte * (APIENTRY *PFNGLGETSTRINGIPROC) (GLenum, GLuint);
+
+#endif /*GL_VERSION_3_0*/
+
+
 //========================================================================
 // DLLs that are loaded at glfwInit()
 //========================================================================
@@ -215,10 +277,16 @@
 
 
 //========================================================================
-// Global variables (GLFW internals)
+// GLFW platform specific types
 //========================================================================
 
 //------------------------------------------------------------------------
+// Pointer length integer
+//------------------------------------------------------------------------
+typedef INT_PTR GLFWintptr;
+
+
+//------------------------------------------------------------------------
 // Window structure
 //------------------------------------------------------------------------
 typedef struct _GLFWwin_struct _GLFWwin;
@@ -228,73 +296,83 @@
 // ========= PLATFORM INDEPENDENT MANDATORY PART =========================
 
     // User callback functions
-    GLFWwindowsizefun    WindowSizeCallback;
-    GLFWwindowclosefun   WindowCloseCallback;
-    GLFWwindowrefreshfun WindowRefreshCallback;
-    GLFWmousebuttonfun   MouseButtonCallback;
-    GLFWmouseposfun      MousePosCallback;
-    GLFWmousewheelfun    MouseWheelCallback;
-    GLFWkeyfun           KeyCallback;
-    GLFWcharfun          CharCallback;
+    GLFWwindowsizefun    windowSizeCallback;
+    GLFWwindowclosefun   windowCloseCallback;
+    GLFWwindowrefreshfun windowRefreshCallback;
+    GLFWmousebuttonfun   mouseButtonCallback;
+    GLFWmouseposfun      mousePosCallback;
+    GLFWmousewheelfun    mouseWheelCallback;
+    GLFWkeyfun           keyCallback;
+    GLFWcharfun          charCallback;
 
     // User selected window settings
-    int       Fullscreen;      // Fullscreen flag
-    int       MouseLock;       // Mouse-lock flag
-    int       AutoPollEvents;  // Auto polling flag
-    int       SysKeysDisabled; // System keys disabled flag
-    int       WindowNoResize;  // Resize- and maximize gadgets disabled flag
+    int       fullscreen;      // Fullscreen flag
+    int       mouseLock;       // Mouse-lock flag
+    int       autoPollEvents;  // Auto polling flag
+    int       sysKeysDisabled; // System keys disabled flag
+    int       windowNoResize;  // Resize- and maximize gadgets disabled flag
+    int       refreshRate;     // Vertical monitor refresh rate
 
     // Window status & parameters
-    int       Opened;          // Flag telling if window is opened or not
-    int       Active;          // Application active flag
-    int       Iconified;       // Window iconified flag
-    int       Width, Height;   // Window width and heigth
-    int       Accelerated;     // GL_TRUE if window is HW accelerated
-    int       RedBits;
-    int       GreenBits;
-    int       BlueBits;
-    int       AlphaBits;
-    int       DepthBits;
-    int       StencilBits;
-    int       AccumRedBits;
-    int       AccumGreenBits;
-    int       AccumBlueBits;
-    int       AccumAlphaBits;
-    int       AuxBuffers;
-    int       Stereo;
-    int       RefreshRate;     // Vertical monitor refresh rate
-    int       Samples;
+    int       opened;          // Flag telling if window is opened or not
+    int       active;          // Application active flag
+    int       iconified;       // Window iconified flag
+    int       width, height;   // Window width and heigth
+    int       accelerated;     // GL_TRUE if window is HW accelerated
 
-    // Extensions & OpenGL version
-    int       Has_GL_SGIS_generate_mipmap;
-    int       Has_GL_ARB_texture_non_power_of_two;
-    int       GLVerMajor,GLVerMinor;
+    // Framebuffer attributes
+    int       redBits;
+    int       greenBits;
+    int       blueBits;
+    int       alphaBits;
+    int       depthBits;
+    int       stencilBits;
+    int       accumRedBits;
+    int       accumGreenBits;
+    int       accumBlueBits;
+    int       accumAlphaBits;
+    int       auxBuffers;
+    int       stereo;
+    int       samples;
 
+    // OpenGL extensions and context attributes
+    int       has_GL_SGIS_generate_mipmap;
+    int       has_GL_ARB_texture_non_power_of_two;
+    int       glMajor, glMinor, glRevision;
+    int       glForward, glDebug, glProfile;
 
+    PFNGLGETSTRINGIPROC GetStringi;
+
+
 // ========= PLATFORM SPECIFIC PART ======================================
 
     // Platform specific window resources
     HDC       DC;              // Private GDI device context
-    HGLRC     RC;              // Permanent rendering context
-    HWND      Wnd;             // Window handle
-    ATOM      ClassAtom;       // Window class atom
-    int       ModeID;          // Mode ID for fullscreen mode
-    HHOOK     KeyboardHook;    // Keyboard hook handle
+    HGLRC     context;         // Permanent rendering context
+    HWND      window;          // Window handle
+    ATOM      classAtom;       // Window class atom
+    int       modeID;          // Mode ID for fullscreen mode
+    HHOOK     keyboardHook;    // Keyboard hook handle
     DWORD     dwStyle;         // Window styles used for window creation
     DWORD     dwExStyle;       // --"--
 
     // Platform specific extensions (context specific)
-    WGLSWAPINTERVALEXT_T           SwapInterval;
-    WGLCHOOSEPIXELFORMATARB_T      ChoosePixelFormat;
-    WGLGETPIXELFORMATATTRIBIVARB_T GetPixelFormatAttribiv;
-    WGLGETEXTENSIONSSTRINGEXT_T    GetExtensionsStringEXT;
-    WGLGETEXTENSIONSSTRINGARB_T    GetExtensionsStringARB;
+    PFNWGLSWAPINTERVALEXTPROC      SwapIntervalEXT;
+    PFNWGLGETPIXELFORMATATTRIBIVARBPROC GetPixelFormatAttribivARB;
+    PFNWGLGETEXTENSIONSSTRINGEXTPROC GetExtensionsStringEXT;
+    PFNWGLGETEXTENSIONSSTRINGARBPROC GetExtensionsStringARB;
+    PFNWGLCREATECONTEXTATTRIBSARBPROC CreateContextAttribsARB;
+    GLboolean                      has_WGL_EXT_swap_control;
+    GLboolean                      has_WGL_ARB_multisample;
+    GLboolean                      has_WGL_ARB_pixel_format;
+    GLboolean                      has_WGL_ARB_create_context;
+    GLboolean                      has_WGL_ARB_create_context_profile;
 
     // Various platform specific internal variables
-    int       OldMouseLock;    // Old mouse-lock flag (used for remembering
+    int       oldMouseLock;    // Old mouse-lock flag (used for remembering
                                // mouse-lock state when iconifying)
-    int       OldMouseLockValid;
-    int       DesiredRefreshRate; // Desired vertical monitor refresh rate
+    int       oldMouseLockValid;
+    int       desiredRefreshRate; // Desired vertical monitor refresh rate
 
 };
 
@@ -336,9 +414,12 @@
 //------------------------------------------------------------------------
 GLFWGLOBAL struct {
 
+    // Window opening hints
+    _GLFWhints      hints;
+
 // ========= PLATFORM SPECIFIC PART ======================================
 
-  HINSTANCE Instance;        // Instance of the application
+  HINSTANCE instance;        // Instance of the application
 
   // Timer data
   struct {
@@ -350,9 +431,9 @@
 
   // System information
   struct {
-      int     WinVer;
-      int     HasUnicode;
-      DWORD   ForegroundLockTimeout;
+      int     winVer;
+      int     hasUnicode;
+      DWORD   foregroundLockTimeout;
   } Sys;
 
 #if !defined(_GLFW_NO_DLOAD_WINMM) || !defined(_GLFW_NO_DLOAD_GDI32)
diff --git a/glfw/lib/win32/win32_enable.c b/glfw/lib/win32/win32_enable.c
--- a/glfw/lib/win32/win32_enable.c
+++ b/glfw/lib/win32/win32_enable.c
@@ -1,11 +1,11 @@
 //========================================================================
 // GLFW - An OpenGL framework
-// File:        win32_enable.c
-// Platform:    Windows
-// API version: 2.6
-// WWW:         http://glfw.sourceforge.net
+// Platform:    Win32/WGL
+// API version: 2.7
+// WWW:         http://www.glfw.org/
 //------------------------------------------------------------------------
-// Copyright (c) 2002-2006 Camilla Berglund
+// Copyright (c) 2002-2006 Marcus Geelnard
+// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org>
 //
 // This software is provided 'as-is', without any express or implied
 // warranty. In no event will the authors be held liable for any damages
@@ -36,23 +36,23 @@
 //************************************************************************
 
 //========================================================================
-// _glfwLLKeyboardProc() - Low level keyboard callback function (used to
-// disable system keys under Windows NT).
+// Low level keyboard hook (system callback) function
+// Used to disable system keys under Windows NT
 //========================================================================
 
-LRESULT CALLBACK _glfwLLKeyboardProc( int nCode, WPARAM wParam,
-    LPARAM lParam )
+static LRESULT CALLBACK keyboardHook( int nCode, WPARAM wParam, LPARAM lParam )
 {
-    BOOL syskeys = 0;
+    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, then we have a keyboard event
     if( nCode == HC_ACTION )
     {
+        // We have a keyboard event
+
         switch( wParam )
         {
             case WM_KEYDOWN:
@@ -83,9 +83,9 @@
     if( syskeys )
     {
         // Pass the key event to our window message loop
-        if( _glfwWin.Opened )
+        if( _glfwWin.opened )
         {
-            PostMessage( _glfwWin.Wnd, (UINT) wParam, p->vkCode, 0 );
+            PostMessage( _glfwWin.window, (UINT) wParam, p->vkCode, 0 );
         }
 
         // We've taken care of it - don't let the system know about this
@@ -95,8 +95,7 @@
     else
     {
         // It's a harmless key press, let the system deal with it
-        return CallNextHookEx( _glfwWin.KeyboardHook, nCode, wParam,
-                               lParam );
+        return CallNextHookEx( _glfwWin.keyboardHook, nCode, wParam, lParam );
     }
 }
 
@@ -107,49 +106,50 @@
 //************************************************************************
 
 //========================================================================
-// _glfwPlatformEnableSystemKeys() - Enable system keys
-// _glfwPlatformDisableSystemKeys() - Disable system keys
+// Enable system keys
 //========================================================================
 
 void _glfwPlatformEnableSystemKeys( void )
 {
-    BOOL bOld;
+    BOOL dummy;
 
     // Use different methods depending on operating system version
-    if( _glfwLibrary.Sys.WinVer >= _GLFW_WIN_NT4 )
+    if( _glfwLibrary.Sys.winVer >= _GLFW_WIN_NT4 )
     {
-        if( _glfwWin.KeyboardHook != NULL )
+        if( _glfwWin.keyboardHook != NULL )
         {
-            UnhookWindowsHookEx( _glfwWin.KeyboardHook );
-            _glfwWin.KeyboardHook = NULL;
+            UnhookWindowsHookEx( _glfwWin.keyboardHook );
+            _glfwWin.keyboardHook = NULL;
         }
     }
     else
     {
-        (void) SystemParametersInfo( SPI_SETSCREENSAVERRUNNING, FALSE,
-                                     &bOld, 0 );
+        (void) SystemParametersInfo( SPI_SETSCREENSAVERRUNNING, FALSE, &dummy, 0 );
     }
 }
 
+//========================================================================
+// Disable system keys
+//========================================================================
+
 void _glfwPlatformDisableSystemKeys( void )
 {
-    BOOL bOld;
+    BOOL dummy;
 
     // Use different methods depending on operating system version
-    if( _glfwLibrary.Sys.WinVer >= _GLFW_WIN_NT4 )
+    if( _glfwLibrary.Sys.winVer >= _GLFW_WIN_NT4 )
     {
         // Under Windows NT, install a low level keyboard hook
-        _glfwWin.KeyboardHook = SetWindowsHookEx( WH_KEYBOARD_LL,
-                                    _glfwLLKeyboardProc,
-                                    _glfwLibrary.Instance,
-                                    0 );
+        _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,
-                                     &bOld, 0 );
+        (void) SystemParametersInfo( SPI_SETSCREENSAVERRUNNING, TRUE, &dummy, 0 );
     }
 }
 
diff --git a/glfw/lib/win32/win32_fullscreen.c b/glfw/lib/win32/win32_fullscreen.c
--- a/glfw/lib/win32/win32_fullscreen.c
+++ b/glfw/lib/win32/win32_fullscreen.c
@@ -1,11 +1,11 @@
 //========================================================================
 // GLFW - An OpenGL framework
-// File:        win32_fullscreen.c
-// Platform:    Windows
-// API version: 2.6
-// WWW:         http://glfw.sourceforge.net
+// Platform:    Win32/WGL
+// API version: 2.7
+// WWW:         http://www.glfw.org/
 //------------------------------------------------------------------------
-// Copyright (c) 2002-2006 Camilla Berglund
+// Copyright (c) 2002-2006 Marcus Geelnard
+// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org>
 //
 // This software is provided 'as-is', without any express or implied
 // warranty. In no event will the authors be held liable for any damages
@@ -36,17 +36,21 @@
 //************************************************************************
 
 //========================================================================
-// _glfwBPP2RGB() - Convert BPP to RGB bits (based on "best guess")
+// Convert BPP to RGB bits based on "best guess"
 //========================================================================
 
-static void _glfwBPP2RGB( int bpp, int *r, int *g, int *b )
+static void bpp2rgb( int bpp, int *r, int *g, int *b )
 {
     int delta;
 
-    // Special case: BPP = 32
-    if( bpp == 32 ) bpp = 24;
+    // 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 )
@@ -61,7 +65,7 @@
 
 
 //========================================================================
-// _glfwGetClosestVideoModeBPP()
+// Return closest video mode by dimensions, refresh rate and bits per pixel
 //========================================================================
 
 int _glfwGetClosestVideoModeBPP( int *w, int *h, int *bpp, int *refresh )
@@ -128,13 +132,14 @@
 
 
 //========================================================================
-// _glfwGetClosestVideoMode()
+// Return closest video mode by dimensions, refresh rate and channel sizes
 //========================================================================
 
-int _glfwGetClosestVideoMode( int *w, int *h, int *r, int *g, int *b,
-    int *refresh )
+static int getClosestVideoMode( int *w, int *h,
+                                int *r, int *g, int *b,
+                                int *refresh )
 {
-    int     bpp, bestmode;
+    int bpp, bestmode;
 
     // Colorbits = sum of red/green/blue bits
     bpp = *r + *g + *b;
@@ -149,7 +154,7 @@
     bestmode = _glfwGetClosestVideoModeBPP( w, h, &bpp, refresh );
 
     // Convert "bits per pixel" to red, green & blue sizes
-    _glfwBPP2RGB( bpp, r, g, b );
+    bpp2rgb( bpp, r, g, b );
 
     return bestmode;
 }
@@ -162,7 +167,7 @@
 void _glfwSetVideoModeMODE( int mode )
 {
     DEVMODE dm;
-    int     success;
+    int success;
 
     // Get the parameters for the best matching display mode
     dm.dmSize = sizeof( DEVMODE );
@@ -172,10 +177,10 @@
     dm.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL;
 
     // Do we have a prefered refresh rate?
-    if( _glfwWin.DesiredRefreshRate > 0 )
+    if( _glfwWin.desiredRefreshRate > 0 )
     {
         dm.dmFields = dm.dmFields | DM_DISPLAYFREQUENCY;
-	dm.dmDisplayFrequency = _glfwWin.DesiredRefreshRate;
+        dm.dmDisplayFrequency = _glfwWin.desiredRefreshRate;
     }
 
     // Change display setting
@@ -186,22 +191,22 @@
     // settings (we'll use the desktop resolution for fullscreen mode)
     if( success == DISP_CHANGE_SUCCESSFUL )
     {
-        _glfwWin.ModeID = mode;
+        _glfwWin.modeID = mode;
     }
     else
     {
-        _glfwWin.ModeID = ENUM_REGISTRY_SETTINGS;
+        _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;
+    _glfwWin.width  = dm.dmPelsWidth;
+    _glfwWin.height = dm.dmPelsHeight;
 }
 
 
 //========================================================================
-// _glfwSetVideoMode() - Change the current video mode
+// Change the current video mode
 //========================================================================
 
 void _glfwSetVideoMode( int *w, int *h, int r, int g, int b, int refresh )
@@ -209,7 +214,7 @@
     int     bestmode;
 
     // Find a best match mode
-    bestmode = _glfwGetClosestVideoMode( w, h, &r, &g, &b, &refresh );
+    bestmode = getClosestVideoMode( w, h, &r, &g, &b, &refresh );
 
     // Change mode
     _glfwSetVideoModeMODE( bestmode );
@@ -221,7 +226,7 @@
 //************************************************************************
 
 //========================================================================
-// _glfwPlatformGetVideoModes() - Get a list of available video modes
+// Get a list of available video modes
 //========================================================================
 
 int _glfwPlatformGetVideoModes( GLFWvidmode *list, int maxcount )
@@ -243,7 +248,7 @@
         if( success && dm.dmBitsPerPel >= 15 )
         {
             // Convert to RGB, and back to bpp ("mask out" alpha bits etc)
-            _glfwBPP2RGB( dm.dmBitsPerPel, &r, &g, &b );
+            bpp2rgb( dm.dmBitsPerPel, &r, &g, &b );
             bpp = r + g + b;
 
             // Mode "code" for this mode
@@ -296,7 +301,7 @@
 
 
 //========================================================================
-// _glfwPlatformGetDesktopMode() - Get the desktop video mode
+// Get the desktop video mode
 //========================================================================
 
 void _glfwPlatformGetDesktopMode( GLFWvidmode *mode )
@@ -310,8 +315,6 @@
     // Return desktop mode parameters
     mode->Width  = dm.dmPelsWidth;
     mode->Height = dm.dmPelsHeight;
-    _glfwBPP2RGB( dm.dmBitsPerPel, &mode->RedBits, &mode->GreenBits,
-                  &mode->BlueBits );
+    bpp2rgb( dm.dmBitsPerPel, &mode->RedBits, &mode->GreenBits, &mode->BlueBits );
 }
-
 
diff --git a/glfw/lib/win32/win32_glext.c b/glfw/lib/win32/win32_glext.c
--- a/glfw/lib/win32/win32_glext.c
+++ b/glfw/lib/win32/win32_glext.c
@@ -1,11 +1,11 @@
 //========================================================================
 // GLFW - An OpenGL framework
-// File:        win32_glext.c
-// Platform:    Windows
-// API version: 2.6
-// WWW:         http://glfw.sourceforge.net
+// Platform:    Win32/WGL
+// API version: 2.7
+// WWW:         http://www.glfw.org/
 //------------------------------------------------------------------------
-// Copyright (c) 2002-2006 Camilla Berglund
+// Copyright (c) 2002-2006 Marcus Geelnard
+// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org>
 //
 // This software is provided 'as-is', without any express or implied
 // warranty. In no event will the authors be held liable for any damages
@@ -36,15 +36,13 @@
 //************************************************************************
 
 //========================================================================
-// Check if an OpenGL extension is available at runtime (Windows version checks
-// for WGL extensions)
+// Check if the current context supports the specified WGL extension
 //========================================================================
 
 int _glfwPlatformExtensionSupported( const char *extension )
 {
     const GLubyte *extensions;
 
-    // Try wglGetExtensionsStringEXT
     if( _glfwWin.GetExtensionsStringEXT != NULL )
     {
         extensions = (GLubyte *) _glfwWin.GetExtensionsStringEXT();
@@ -57,7 +55,6 @@
         }
     }
 
-    // Try wglGetExtensionsStringARB
     if( _glfwWin.GetExtensionsStringARB != NULL )
     {
         extensions = (GLubyte *) _glfwWin.GetExtensionsStringARB( _glfwWin.DC );
@@ -78,7 +75,7 @@
 // Get the function pointer to an OpenGL function
 //========================================================================
 
-void * _glfwPlatformGetProcAddress( const char *procname )
+void *_glfwPlatformGetProcAddress( const char *procname )
 {
     return (void *) wglGetProcAddress( procname );
 }
diff --git a/glfw/lib/win32/win32_init.c b/glfw/lib/win32/win32_init.c
--- a/glfw/lib/win32/win32_init.c
+++ b/glfw/lib/win32/win32_init.c
@@ -1,11 +1,11 @@
 //========================================================================
 // GLFW - An OpenGL framework
-// File:        win32_init.c
-// Platform:    Windows
-// API version: 2.6
-// WWW:         http://glfw.sourceforge.net
+// Platform:    Win32/WGL
+// API version: 2.7
+// WWW:         http://www.glfw.org/
 //------------------------------------------------------------------------
-// Copyright (c) 2002-2006 Camilla Berglund
+// Copyright (c) 2002-2006 Marcus Geelnard
+// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org>
 //
 // This software is provided 'as-is', without any express or implied
 // warranty. In no event will the authors be held liable for any damages
@@ -42,7 +42,7 @@
 //************************************************************************
 
 //========================================================================
-// _glfwInitLibraries() - Load necessary libraries (DLLs)
+// Load necessary libraries (DLLs)
 //========================================================================
 
 static int _glfwInitLibraries( void )
@@ -113,7 +113,7 @@
 
 
 //========================================================================
-// _glfwFreeLibraries() - Unload used libraries (DLLs)
+// Unload used libraries (DLLs)
 //========================================================================
 
 static void _glfwFreeLibraries( void )
@@ -139,7 +139,7 @@
 
 
 //========================================================================
-// _glfwInitThreads() - Initialize GLFW thread package
+// Initialize GLFW thread package
 //========================================================================
 
 static void _glfwInitThreads( void )
@@ -161,7 +161,7 @@
 
 
 //========================================================================
-// _glfwTerminateThreads() - Terminate GLFW thread package
+// Terminate GLFW thread package
 //========================================================================
 
 static void _glfwTerminateThreads( void )
@@ -202,7 +202,7 @@
 
 
 //========================================================================
-// _glfwTerminate_atexit() - Terminate GLFW when exiting application
+// Terminate GLFW when exiting application
 //========================================================================
 
 void _glfwTerminate_atexit( void )
@@ -217,7 +217,7 @@
 //************************************************************************
 
 //========================================================================
-// _glfwPlatformInit() - Initialize various GLFW state
+// Initialize various GLFW state
 //========================================================================
 
 int _glfwPlatformInit( void )
@@ -228,67 +228,67 @@
     // 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 );
+                          &_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;
+    _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;
+            _glfwLibrary.Sys.winVer = _GLFW_WIN_95;
         }
         else if( osi.dwMajorVersion == 4 && osi.dwMinorVersion < 90 )
         {
-            _glfwLibrary.Sys.WinVer = _GLFW_WIN_98;
+            _glfwLibrary.Sys.winVer = _GLFW_WIN_98;
         }
         else if( osi.dwMajorVersion == 4 && osi.dwMinorVersion == 90 )
         {
-            _glfwLibrary.Sys.WinVer = _GLFW_WIN_ME;
+            _glfwLibrary.Sys.winVer = _GLFW_WIN_ME;
         }
         else if( osi.dwMajorVersion >= 4 )
         {
-            _glfwLibrary.Sys.WinVer = _GLFW_WIN_UNKNOWN_9x;
+            _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;
+            _glfwLibrary.Sys.winVer = _GLFW_WIN_NT4;
         }
         else if( osi.dwMajorVersion == 5 && osi.dwMinorVersion == 0 )
         {
-            _glfwLibrary.Sys.WinVer = _GLFW_WIN_2K;
+            _glfwLibrary.Sys.winVer = _GLFW_WIN_2K;
         }
         else if( osi.dwMajorVersion == 5 && osi.dwMinorVersion == 1 )
         {
-            _glfwLibrary.Sys.WinVer = _GLFW_WIN_XP;
+            _glfwLibrary.Sys.winVer = _GLFW_WIN_XP;
         }
         else if( osi.dwMajorVersion == 5 && osi.dwMinorVersion == 2 )
         {
-            _glfwLibrary.Sys.WinVer = _GLFW_WIN_NET_SERVER;
+            _glfwLibrary.Sys.winVer = _GLFW_WIN_NET_SERVER;
         }
         else if( osi.dwMajorVersion >= 5 )
         {
-            _glfwLibrary.Sys.WinVer = _GLFW_WIN_UNKNOWN_NT;
+            _glfwLibrary.Sys.winVer = _GLFW_WIN_UNKNOWN_NT;
         }
     }
 
     // Do we have Unicode support?
-    if( _glfwLibrary.Sys.WinVer >= _GLFW_WIN_NT4 )
+    if( _glfwLibrary.Sys.winVer >= _GLFW_WIN_NT4 )
     {
         // Windows NT/2000/XP/.NET has Unicode support
-        _glfwLibrary.Sys.HasUnicode = GL_TRUE;
+        _glfwLibrary.Sys.hasUnicode = GL_TRUE;
     }
     else
     {
         // Windows 9x/ME does not have Unicode support
-        _glfwLibrary.Sys.HasUnicode = GL_FALSE;
+        _glfwLibrary.Sys.hasUnicode = GL_FALSE;
     }
 
     // Load libraries (DLLs)
@@ -304,10 +304,10 @@
 #endif
 
     // Retrieve GLFW instance handle
-    _glfwLibrary.Instance = GetModuleHandle( NULL );
+    _glfwLibrary.instance = GetModuleHandle( NULL );
 
     // System keys are not disabled
-    _glfwWin.KeyboardHook = NULL;
+    _glfwWin.keyboardHook = NULL;
 
     // Initialise thread package
     _glfwInitThreads();
@@ -323,7 +323,7 @@
 
 
 //========================================================================
-// _glfwPlatformTerminate() - Close window and kill all threads
+// Close window and kill all threads
 //========================================================================
 
 int _glfwPlatformTerminate( void )
@@ -348,7 +348,7 @@
 
     // Restore FOREGROUNDLOCKTIMEOUT system setting
     SystemParametersInfo( SPI_SETFOREGROUNDLOCKTIMEOUT, 0,
-                          (LPVOID)_glfwLibrary.Sys.ForegroundLockTimeout,
+                          (LPVOID) _glfwLibrary.Sys.foregroundLockTimeout,
                           SPIF_SENDCHANGE );
 
     return GL_TRUE;
diff --git a/glfw/lib/win32/win32_joystick.c b/glfw/lib/win32/win32_joystick.c
--- a/glfw/lib/win32/win32_joystick.c
+++ b/glfw/lib/win32/win32_joystick.c
@@ -1,11 +1,11 @@
 //========================================================================
 // GLFW - An OpenGL framework
-// File:        win32_joystick.c
-// Platform:    Windows
-// API version: 2.6
-// WWW:         http://glfw.sourceforge.net
+// Platform:    Win32/WGL
+// API version: 2.7
+// WWW:         http://www.glfw.org/
 //------------------------------------------------------------------------
-// Copyright (c) 2002-2006 Camilla Berglund
+// Copyright (c) 2002-2006 Marcus Geelnard
+// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org>
 //
 // This software is provided 'as-is', without any express or implied
 // warranty. In no event will the authors be held liable for any damages
@@ -36,8 +36,7 @@
 //************************************************************************
 
 //========================================================================
-// _glfwJoystickPresent() - Return GL_TRUE if joystick is present,
-// else return GL_FALSE.
+// Return GL_TRUE if joystick is present, else return GL_FALSE.
 //========================================================================
 
 static int _glfwJoystickPresent( int joy )
@@ -46,7 +45,7 @@
 
     // 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 )
+    if( _glfwLibrary.Sys.winVer == _GLFW_WIN_NT4 && joy > GLFW_JOYSTICK_2 )
     {
         return GL_FALSE;
     }
@@ -68,7 +67,7 @@
 
 
 //========================================================================
-// _glfwCalcJoystickPos() - Calculate joystick position
+// Calculate joystick position
 //========================================================================
 
 static float _glfwCalcJoystickPos( DWORD pos, DWORD min, DWORD max )
@@ -86,7 +85,7 @@
 //************************************************************************
 
 //========================================================================
-// _glfwPlatformGetJoystickParam() - Determine joystick capabilities
+// Determine joystick capabilities
 //========================================================================
 
 int _glfwPlatformGetJoystickParam( int joy, int param )
@@ -129,7 +128,7 @@
 
 
 //========================================================================
-// _glfwPlatformGetJoystickPos() - Get joystick axis positions
+// Get joystick axis positions
 //========================================================================
 
 int _glfwPlatformGetJoystickPos( int joy, float *pos, int numaxes )
@@ -194,7 +193,7 @@
 
 
 //========================================================================
-// _glfwPlatformGetJoystickButtons() - Get joystick button states
+// Get joystick button states
 //========================================================================
 
 int _glfwPlatformGetJoystickButtons( int joy, unsigned char *buttons,
diff --git a/glfw/lib/win32/win32_thread.c b/glfw/lib/win32/win32_thread.c
--- a/glfw/lib/win32/win32_thread.c
+++ b/glfw/lib/win32/win32_thread.c
@@ -1,11 +1,11 @@
 //========================================================================
 // GLFW - An OpenGL framework
-// File:        win32_thread.c
-// Platform:    Windows
-// API version: 2.6
-// WWW:         http://glfw.sourceforge.net
+// Platform:    Win32/WGL
+// API version: 2.7
+// WWW:         http://www.glfw.org/
 //------------------------------------------------------------------------
-// Copyright (c) 2002-2006 Camilla Berglund
+// Copyright (c) 2002-2006 Marcus Geelnard
+// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org>
 //
 // This software is provided 'as-is', without any express or implied
 // warranty. In no event will the authors be held liable for any damages
@@ -60,8 +60,7 @@
 //************************************************************************
 
 //========================================================================
-// _glfwNewThread() - This is simply a "wrapper" for calling the user
-// thread function.
+// This is simply a "wrapper" for calling the user thread function.
 //========================================================================
 
 DWORD WINAPI _glfwNewThread( LPVOID lpParam )
@@ -98,7 +97,7 @@
 //************************************************************************
 
 //========================================================================
-// _glfwPlatformCreateThread() - Create a new thread
+// Create a new thread
 //========================================================================
 
 GLFWthread _glfwPlatformCreateThread( GLFWthreadfun fun, void *arg )
@@ -168,9 +167,8 @@
 
 
 //========================================================================
-// _glfwPlatformDestroyThread() - Kill a thread. NOTE: THIS IS A VERY
-// DANGEROUS OPERATION, AND SHOULD NOT BE USED EXCEPT IN EXTREME
-// SITUATIONS!
+// Kill a thread. NOTE: THIS IS A VERY DANGEROUS OPERATION, AND SHOULD NOT
+// BE USED EXCEPT IN EXTREME SITUATIONS!
 //========================================================================
 
 void _glfwPlatformDestroyThread( GLFWthread ID )
@@ -204,7 +202,7 @@
 
 
 //========================================================================
-// _glfwPlatformWaitThread() - Wait for a thread to die
+// Wait for a thread to die
 //========================================================================
 
 int _glfwPlatformWaitThread( GLFWthread ID, int waitmode )
@@ -256,8 +254,7 @@
 
 
 //========================================================================
-// _glfwPlatformGetThreadID() - Return the thread ID for the current
-// thread
+// Return the thread ID for the current thread
 //========================================================================
 
 GLFWthread _glfwPlatformGetThreadID( void )
@@ -292,7 +289,7 @@
 
 
 //========================================================================
-// _glfwPlatformCreateMutex() - Create a mutual exclusion object
+// Create a mutual exclusion object
 //========================================================================
 
 GLFWmutex _glfwPlatformCreateMutex( void )
@@ -315,7 +312,7 @@
 
 
 //========================================================================
-// glfwDestroyMutex() - Destroy a mutual exclusion object
+// Destroy a mutual exclusion object
 //========================================================================
 
 void _glfwPlatformDestroyMutex( GLFWmutex mutex )
@@ -327,7 +324,7 @@
 
 
 //========================================================================
-// _glfwPlatformLockMutex() - Request access to a mutex
+// Request access to a mutex
 //========================================================================
 
 void _glfwPlatformLockMutex( GLFWmutex mutex )
@@ -338,7 +335,7 @@
 
 
 //========================================================================
-// _glfwPlatformUnlockMutex() - Release a mutex
+// Release a mutex
 //========================================================================
 
 void _glfwPlatformUnlockMutex( GLFWmutex mutex )
@@ -349,7 +346,7 @@
 
 
 //========================================================================
-// _glfwPlatformCreateCond() - Create a new condition variable object
+// Create a new condition variable object
 //========================================================================
 
 GLFWcond _glfwPlatformCreateCond( void )
@@ -377,7 +374,7 @@
 
 
 //========================================================================
-// _glfwPlatformDestroyCond() - Destroy a condition variable object
+// Destroy a condition variable object
 //========================================================================
 
 void _glfwPlatformDestroyCond( GLFWcond cond )
@@ -395,11 +392,10 @@
 
 
 //========================================================================
-// _glfwPlatformWaitCond() - Wait for a condition to be raised
+// Wait for a condition to be raised
 //========================================================================
 
-void _glfwPlatformWaitCond( GLFWcond cond, GLFWmutex mutex,
-    double timeout )
+void _glfwPlatformWaitCond( GLFWcond cond, GLFWmutex mutex, double timeout )
 {
     _GLFWcond *cv = (_GLFWcond *) cond;
     int       result, last_waiter;
@@ -453,7 +449,7 @@
 
 
 //========================================================================
-// _glfwPlatformSignalCond() - Signal a condition to one waiting thread
+// Signal a condition to one waiting thread
 //========================================================================
 
 void _glfwPlatformSignalCond( GLFWcond cond )
@@ -474,8 +470,7 @@
 
 
 //========================================================================
-// _glfwPlatformBroadcastCond() - Broadcast a condition to all waiting
-// threads
+// Broadcast a condition to all waiting threads
 //========================================================================
 
 void _glfwPlatformBroadcastCond( GLFWcond cond )
@@ -496,8 +491,7 @@
 
 
 //========================================================================
-// _glfwPlatformGetNumberOfProcessors() - Return the number of processors
-// in the system.
+// Return the number of processors in the system.
 //========================================================================
 
 int _glfwPlatformGetNumberOfProcessors( void )
@@ -509,3 +503,4 @@
 
     return (int) si.dwNumberOfProcessors;
 }
+
diff --git a/glfw/lib/win32/win32_time.c b/glfw/lib/win32/win32_time.c
--- a/glfw/lib/win32/win32_time.c
+++ b/glfw/lib/win32/win32_time.c
@@ -1,11 +1,11 @@
 //========================================================================
 // GLFW - An OpenGL framework
-// File:        win32_time.c
-// Platform:    Windows
-// API version: 2.6
-// WWW:         http://glfw.sourceforge.net
+// Platform:    Win32/WGL
+// API version: 2.7
+// WWW:         http://www.glfw.org/
 //------------------------------------------------------------------------
-// Copyright (c) 2002-2006 Camilla Berglund
+// Copyright (c) 2002-2006 Marcus Geelnard
+// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org>
 //
 // This software is provided 'as-is', without any express or implied
 // warranty. In no event will the authors be held liable for any damages
@@ -36,7 +36,7 @@
 //************************************************************************
 
 //========================================================================
-// _glfwInitTimer() - Initialise timer
+// Initialise timer
 //========================================================================
 
 void _glfwInitTimer( void )
diff --git a/glfw/lib/win32/win32_window.c b/glfw/lib/win32/win32_window.c
--- a/glfw/lib/win32/win32_window.c
+++ b/glfw/lib/win32/win32_window.c
@@ -1,1714 +1,1875 @@
 //========================================================================
 // GLFW - An OpenGL framework
-// File:        win32_window.c
-// Platform:    Windows
-// API version: 2.6
-// WWW:         http://glfw.sourceforge.net
-//------------------------------------------------------------------------
-// Copyright (c) 2002-2006 Camilla Berglund
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-//    claim that you wrote the original software. If you use this software
-//    in a product, an acknowledgment in the product documentation would
-//    be appreciated but is not required.
-//
-// 2. Altered source versions must be plainly marked as such, and must not
-//    be misrepresented as being the original software.
-//
-// 3. This notice may not be removed or altered from any source
-//    distribution.
-//
-//========================================================================
-
-#include "internal.h"
-
-
-
-//************************************************************************
-//****                  GLFW internal functions                       ****
-//************************************************************************
-
-#define _GLFW_WNDCLASSNAME "GLFW26"
-
-
-//========================================================================
-// Enable/disable minimize/restore animations
-//========================================================================
-
-static int _glfwMinMaxAnimations( int enable )
-{
-    ANIMATIONINFO AI;
-    int old_enable;
-
-    // Get old animation setting
-    AI.cbSize = sizeof( ANIMATIONINFO );
-    SystemParametersInfo( SPI_GETANIMATION, AI.cbSize, &AI, 0 );
-    old_enable = AI.iMinAnimate;
-
-    // If requested, change setting
-    if( old_enable != enable )
-    {
-        AI.iMinAnimate = enable;
-        SystemParametersInfo( SPI_SETANIMATION, AI.cbSize, &AI,
-                              SPIF_SENDCHANGE );
-    }
-
-    return old_enable;
-}
-
-
-//========================================================================
-// Function for bringing a window into focus and placing it on top of the
-// window z stack. Due to some nastiness with how Win98/ME/2k/XP handles
-// SetForegroundWindow, we have to go through some really bizarre measures to
-// achieve this (thanks again, MS, for making life so much easier)!
-//========================================================================
-
-static void _glfwSetForegroundWindow( HWND hWnd )
-{
-    int try_count = 0;
-    int old_animate;
-
-    // Try the standard approach first...
-    BringWindowToTop( hWnd );
-    SetForegroundWindow( hWnd );
-
-    // If it worked, return now
-    if( hWnd == GetForegroundWindow() )
-    {
-        // Try to modify the system settings (since this is the foreground
-        // process, we are allowed to do this)
-        SystemParametersInfo( SPI_SETFOREGROUNDLOCKTIMEOUT, 0, (LPVOID)0,
-                              SPIF_SENDCHANGE );
-        return;
-    }
-
-    // For other Windows versions than 95 & NT4.0, the standard approach
-    // may not work, so if we failed we have to "trick" Windows into
-    // making our window the foureground window: Iconify and restore
-    // again. It is ugly, but it seems to work (we turn off those annoying
-    // zoom animations to make it look a bit better at least).
-
-    // Turn off minimize/restore animations
-    old_animate = _glfwMinMaxAnimations( 0 );
-
-    // We try this a few times, just to be on the safe side of things...
-    do
-    {
-        // Iconify & restore
-        ShowWindow( hWnd, SW_HIDE );
-        ShowWindow( hWnd, SW_SHOWMINIMIZED );
-        ShowWindow( hWnd, SW_SHOWNORMAL );
-
-        // Try to get focus
-        BringWindowToTop( hWnd );
-        SetForegroundWindow( hWnd );
-
-        // We do not want to keep going on forever, so we keep track of
-        // how many times we tried
-        try_count ++;
-    }
-    while( hWnd != GetForegroundWindow() && try_count <= 3 );
-
-    // Restore the system minimize/restore animation setting
-    (void) _glfwMinMaxAnimations( old_animate );
-
-    // Try to modify the system settings (since this is now hopefully the
-    // foreground process, we are probably allowed to do this)
-    SystemParametersInfo( SPI_SETFOREGROUNDLOCKTIMEOUT, 0, (LPVOID)0,
-                          SPIF_SENDCHANGE );
-}
-
-
-//========================================================================
-// Sets the device context pixel format using a PFD
-//========================================================================
-
-static int _glfwSetPixelFormatPFD( int redbits, int greenbits, int bluebits,
-                                   int alphabits, int depthbits, int stencilbits,
-                                   int mode, _GLFWhints* hints )
-{
-    int PixelFormat;
-    PIXELFORMATDESCRIPTOR pfd;
-
-    // Set required pixel format
-    pfd.nSize           = sizeof(PIXELFORMATDESCRIPTOR);
-    pfd.nVersion        = 1;
-    pfd.dwFlags         = PFD_DRAW_TO_WINDOW | // Draw to window
-                          PFD_SUPPORT_OPENGL | // Support OpenGL
-                          PFD_DOUBLEBUFFER;    // Double buffered window
-    pfd.iPixelType      = PFD_TYPE_RGBA;       // Request an RGBA format
-    pfd.cColorBits      = (BYTE) (redbits +
-                                  greenbits +
-                                  bluebits);   // Color bits (ex. alpha)
-    pfd.cRedBits        = (BYTE) redbits;      // Red bits
-    pfd.cRedShift       = 0;                   // Red shift ignored
-    pfd.cGreenBits      = (BYTE) greenbits;    // Green bits
-    pfd.cGreenShift     = 0;                   // Green shift ignored
-    pfd.cBlueBits       = (BYTE) bluebits;     // Blue bits
-    pfd.cBlueShift      = 0;                   // Blue shift ignored
-    pfd.cAlphaBits      = (BYTE) alphabits;    // Alpha bits
-    pfd.cAlphaShift     = 0;                   // Alpha shift ignored
-    pfd.cAccumBits      = (BYTE) (hints->AccumRedBits +
-                                  hints->AccumGreenBits +
-                                  hints->AccumBlueBits +
-                                  hints->AccumAlphaBits); // Accum. bits
-    pfd.cAccumRedBits   = (BYTE) hints->AccumRedBits;   // Accum. red bits
-    pfd.cAccumGreenBits = (BYTE) hints->AccumGreenBits; // Accum. green bits
-    pfd.cAccumBlueBits  = (BYTE) hints->AccumBlueBits;  // Accum. blue bits
-    pfd.cAccumAlphaBits = (BYTE) hints->AccumAlphaBits; // Accum. alpha bits
-    pfd.cDepthBits      = (BYTE) depthbits;    // Depth buffer bits
-    pfd.cStencilBits    = (BYTE) stencilbits;  // Stencil buffer bits
-    pfd.cAuxBuffers     = (BYTE) hints->AuxBuffers;   // No. of aux buffers
-    pfd.iLayerType      = PFD_MAIN_PLANE;      // Drawing layer: main
-    pfd.bReserved       = 0;                   // (reserved)
-    pfd.dwLayerMask     = 0;                   // Ignored
-    pfd.dwVisibleMask   = 0;                   // "
-    pfd.dwDamageMask    = 0;                   // "
-
-    if( depthbits <= 0 )
-    {
-        // We do not need a depth buffer
-        pfd.dwFlags |= PFD_DEPTH_DONTCARE;
-    }
-
-    if( hints->Stereo )
-    {
-        // Request a stereo mode
-        pfd.dwFlags |= PFD_STEREO;
-    }
-
-    // Find a matching pixel format
-    PixelFormat = _glfw_ChoosePixelFormat( _glfwWin.DC, &pfd );
-    if( !PixelFormat )
-    {
-        return GL_FALSE;
-    }
-
-    // Get actual pixel format description
-    if( !_glfw_DescribePixelFormat( _glfwWin.DC, PixelFormat, sizeof(pfd), &pfd ) )
-    {
-        return GL_FALSE;
-    }
-
-    // "stereo" is a strict requirement
-    if( hints->Stereo && !(pfd.dwFlags & PFD_STEREO) )
-    {
-        return GL_FALSE;
-    }
-
-    // Set the pixel-format
-    if( !_glfw_SetPixelFormat( _glfwWin.DC, PixelFormat, &pfd ) )
-    {
-        return GL_FALSE;
-    }
-
-    return GL_TRUE;
-}
-
-
-//========================================================================
-// Sets the device context pixel format using attributes
-//========================================================================
-
-#define _glfwSetWGLAttribute( _glfwName, _glfwValue ) \
-    attribs[ count++ ] = _glfwName; \
-    attribs[ count++ ] = _glfwValue;
-
-static int _glfwSetPixelFormatAttrib( int redbits, int greenbits, int bluebits,
-                                      int alphabits, int depthbits, int stencilbits,
-                                      int mode, _GLFWhints* hints )
-{
-    int PixelFormat, dummy, count = 0;
-    int attribs[128];
-    PIXELFORMATDESCRIPTOR pfd;
-    
-    int accumredbits = hints->AccumRedBits;
-    int accumgreenbits = hints->AccumGreenBits;
-    int accumbluebits = hints->AccumBlueBits;
-    int accumalphabits = hints->AccumAlphaBits;
-
-    _glfwSetWGLAttribute( WGL_DRAW_TO_WINDOW_ARB, GL_TRUE );
-    _glfwSetWGLAttribute( WGL_ACCELERATION_ARB,   WGL_FULL_ACCELERATION_ARB );
-    _glfwSetWGLAttribute( WGL_SUPPORT_OPENGL_ARB, GL_TRUE );
-    _glfwSetWGLAttribute( WGL_DOUBLE_BUFFER_ARB,  GL_TRUE );
-    _glfwSetWGLAttribute( WGL_COLOR_BITS_ARB,     redbits + greenbits + bluebits );
-    _glfwSetWGLAttribute( WGL_RED_BITS_ARB,       redbits );
-    _glfwSetWGLAttribute( WGL_GREEN_BITS_ARB,     greenbits );
-    _glfwSetWGLAttribute( WGL_BLUE_BITS_ARB,      bluebits );
-    _glfwSetWGLAttribute( WGL_ALPHA_BITS_ARB,     alphabits );
-    _glfwSetWGLAttribute( WGL_DEPTH_BITS_ARB,     depthbits );
-    _glfwSetWGLAttribute( WGL_STENCIL_BITS_ARB,   stencilbits );
-    _glfwSetWGLAttribute( WGL_AUX_BUFFERS_ARB,    hints->AuxBuffers );
-    
-    if( accumredbits || accumgreenbits || accumbluebits || accumalphabits )
-    {
-        _glfwSetWGLAttribute( WGL_ACCUM_BITS_ARB, accumredbits +
-                                                  accumgreenbits +
-                                                  accumbluebits +
-                                                  accumalphabits );
-
-        _glfwSetWGLAttribute( WGL_ACCUM_RED_BITS_ARB, accumredbits );
-        _glfwSetWGLAttribute( WGL_ACCUM_GREEN_BITS_ARB, accumgreenbits );
-        _glfwSetWGLAttribute( WGL_ACCUM_BLUE_BITS_ARB, accumbluebits );
-        _glfwSetWGLAttribute( WGL_ACCUM_ALPHA_BITS_ARB, accumalphabits );
-    }
-
-    if( hints->Stereo )
-    {
-        _glfwSetWGLAttribute( WGL_STEREO_ARB, GL_TRUE );
-    }
-
-    if( hints->Samples > 0 )
-    {
-        _glfwSetWGLAttribute( WGL_SAMPLE_BUFFERS_ARB, 1 );
-        _glfwSetWGLAttribute( WGL_SAMPLES_ARB, hints->Samples );
-    }
-
-    _glfwSetWGLAttribute( 0, 0 );
-
-    if( !_glfwWin.ChoosePixelFormat( _glfwWin.DC, attribs, NULL, 1, &PixelFormat, &dummy ) )
-    {
-        return GL_FALSE;
-    }
-
-    if( !_glfw_DescribePixelFormat( _glfwWin.DC, PixelFormat, sizeof(pfd), &pfd ) )
-    {
-        return GL_FALSE;
-    }
-
-    // Set the pixel-format
-    if( !_glfw_SetPixelFormat( _glfwWin.DC, PixelFormat, &pfd ) )
-    {
-        return GL_FALSE;
-    }
-
-    return GL_TRUE; 
-}
-
-#undef _glfwSetWGLAttribute
-
-
-//========================================================================
-// Translates a Windows key to the corresponding GLFW key
-//========================================================================
-
-static int _glfwTranslateKey( WPARAM wParam, LPARAM lParam )
-{
-    MSG next_msg;
-    DWORD msg_time;
-    DWORD scan_code;
-
-    // Check which key was pressed or released
-    switch( wParam )
-    {
-        // The SHIFT keys require special handling
-        case VK_SHIFT:
-            // Compare scan code for this key with that of VK_RSHIFT in
-            // order to determine which shift key was pressed (left or
-            // right)
-            scan_code = MapVirtualKey( VK_RSHIFT, 0 );
-            if( ((lParam & 0x01ff0000) >> 16) == scan_code )
-            {
-                return GLFW_KEY_RSHIFT;
-            }
-            return GLFW_KEY_LSHIFT;
-
-        // The CTRL keys require special handling
-        case VK_CONTROL:
-            // Is this an extended key (i.e. right key)?
-            if( lParam & 0x01000000 )
-            {
-                return GLFW_KEY_RCTRL;
-            }
-            // Here is a trick: "Alt Gr" sends LCTRL, then RALT. We only
-            // want the RALT message, so we try to see if the next message
-            // is a RALT message. In that case, this is a false LCTRL!
-            msg_time = GetMessageTime();
-            if( PeekMessage( &next_msg, NULL, 0, 0, PM_NOREMOVE ) )
-            {
-                if( next_msg.message == WM_KEYDOWN ||
-                    next_msg.message == WM_SYSKEYDOWN )
-                {
-                    if( next_msg.wParam == VK_MENU &&
-                        (next_msg.lParam & 0x01000000) &&
-                        next_msg.time == msg_time )
-                    {
-                        // Next message is a RALT down message, which
-                        // means that this is NOT a proper LCTRL message!
-                        return GLFW_KEY_UNKNOWN;
-                    }
-                }
-            }
-            return GLFW_KEY_LCTRL;
-
-        // The ALT keys require special handling
-        case VK_MENU:
-            // Is this an extended key (i.e. right key)?
-            if( lParam & 0x01000000 )
-            {
-                return GLFW_KEY_RALT;
-            }
-            return GLFW_KEY_LALT;
-
-        // The ENTER keys require special handling
-        case VK_RETURN:
-            // Is this an extended key (i.e. right key)?
-            if( lParam & 0x01000000 )
-            {
-                return GLFW_KEY_KP_ENTER;
-            }
-            return GLFW_KEY_ENTER;
-
-        // Special keys (non character keys)
-        case VK_ESCAPE:        return GLFW_KEY_ESC;
-        case VK_TAB:           return GLFW_KEY_TAB;
-        case VK_BACK:          return GLFW_KEY_BACKSPACE;
-        case VK_HOME:          return GLFW_KEY_HOME;
-        case VK_END:           return GLFW_KEY_END;
-        case VK_PRIOR:         return GLFW_KEY_PAGEUP;
-        case VK_NEXT:          return GLFW_KEY_PAGEDOWN;
-        case VK_INSERT:        return GLFW_KEY_INSERT;
-        case VK_DELETE:        return GLFW_KEY_DEL;
-        case VK_LEFT:          return GLFW_KEY_LEFT;
-        case VK_UP:            return GLFW_KEY_UP;
-        case VK_RIGHT:         return GLFW_KEY_RIGHT;
-        case VK_DOWN:          return GLFW_KEY_DOWN;
-        case VK_F1:            return GLFW_KEY_F1;
-        case VK_F2:            return GLFW_KEY_F2;
-        case VK_F3:            return GLFW_KEY_F3;
-        case VK_F4:            return GLFW_KEY_F4;
-        case VK_F5:            return GLFW_KEY_F5;
-        case VK_F6:            return GLFW_KEY_F6;
-        case VK_F7:            return GLFW_KEY_F7;
-        case VK_F8:            return GLFW_KEY_F8;
-        case VK_F9:            return GLFW_KEY_F9;
-        case VK_F10:           return GLFW_KEY_F10;
-        case VK_F11:           return GLFW_KEY_F11;
-        case VK_F12:           return GLFW_KEY_F12;
-        case VK_F13:           return GLFW_KEY_F13;
-        case VK_F14:           return GLFW_KEY_F14;
-        case VK_F15:           return GLFW_KEY_F15;
-        case VK_F16:           return GLFW_KEY_F16;
-        case VK_F17:           return GLFW_KEY_F17;
-        case VK_F18:           return GLFW_KEY_F18;
-        case VK_F19:           return GLFW_KEY_F19;
-        case VK_F20:           return GLFW_KEY_F20;
-        case VK_F21:           return GLFW_KEY_F21;
-        case VK_F22:           return GLFW_KEY_F22;
-        case VK_F23:           return GLFW_KEY_F23;
-        case VK_F24:           return GLFW_KEY_F24;
-        case VK_SPACE:         return GLFW_KEY_SPACE;
-
-        // Numeric keypad
-        case VK_NUMPAD0:       return GLFW_KEY_KP_0;
-        case VK_NUMPAD1:       return GLFW_KEY_KP_1;
-        case VK_NUMPAD2:       return GLFW_KEY_KP_2;
-        case VK_NUMPAD3:       return GLFW_KEY_KP_3;
-        case VK_NUMPAD4:       return GLFW_KEY_KP_4;
-        case VK_NUMPAD5:       return GLFW_KEY_KP_5;
-        case VK_NUMPAD6:       return GLFW_KEY_KP_6;
-        case VK_NUMPAD7:       return GLFW_KEY_KP_7;
-        case VK_NUMPAD8:       return GLFW_KEY_KP_8;
-        case VK_NUMPAD9:       return GLFW_KEY_KP_9;
-        case VK_DIVIDE:        return GLFW_KEY_KP_DIVIDE;
-        case VK_MULTIPLY:      return GLFW_KEY_KP_MULTIPLY;
-        case VK_SUBTRACT:      return GLFW_KEY_KP_SUBTRACT;
-        case VK_ADD:           return GLFW_KEY_KP_ADD;
-        case VK_DECIMAL:       return GLFW_KEY_KP_DECIMAL;
-
-        // The rest (should be printable keys)
-        default:
-            // Convert to printable character (ISO-8859-1 or Unicode)
-            wParam = MapVirtualKey( (UINT) wParam, 2 ) & 0x0000FFFF;
-
-            // Make sure that the character is uppercase
-            if( _glfwLibrary.Sys.HasUnicode )
-            {
-                wParam = (WPARAM) CharUpperW( (LPWSTR) wParam );
-            }
-            else
-            {
-                wParam = (WPARAM) CharUpperA( (LPSTR) wParam );
-            }
-
-            // Valid ISO-8859-1 character?
-            if( (wParam >=  32 && wParam <= 126) ||
-                (wParam >= 160 && wParam <= 255) )
-            {
-                return (int) wParam;
-            }
-            return GLFW_KEY_UNKNOWN;
-    }
-}
-
-
-//========================================================================
-// Translates a windows key to Unicode
-//========================================================================
-
-static void _glfwTranslateChar( DWORD wParam, DWORD lParam, int action )
-{
-    BYTE  keyboard_state[ 256 ];
-    UCHAR char_buf[ 10 ];
-    WCHAR unicode_buf[ 10 ];
-    UINT  scan_code;
-    int   i, num_chars, unicode;
-
-    // Get keyboard state
-    GetKeyboardState( keyboard_state );
-
-    // Derive scan code from lParam and action
-    scan_code = (lParam & 0x01ff0000) >> 16;
-    if( action == GLFW_RELEASE )
-    {
-        scan_code |= 0x8000000;
-    }
-
-    // Do we have Unicode support?
-    if( _glfwLibrary.Sys.HasUnicode )
-    {
-        // Convert to Unicode
-        num_chars = ToUnicode(
-            wParam,          // virtual-key code
-            scan_code,       // scan code
-            keyboard_state,  // key-state array
-            unicode_buf,     // buffer for translated key
-            10,              // size of translated key buffer
-            0                // active-menu flag
-        );
-        unicode = 1;
-    }
-    else
-    {
-        // Convert to ISO-8859-1
-        num_chars = ToAscii(
-            wParam,            // virtual-key code
-            scan_code,         // scan code
-            keyboard_state,    // key-state array
-            (LPWORD) char_buf, // buffer for translated key
-            0                  // active-menu flag
-        );
-        unicode = 0;
-    }
-
-    // Report characters
-    for( i = 0;  i < num_chars;  i++ )
-    {
-        // Get next character from buffer
-        if( unicode )
-        {
-            _glfwInputChar( (int) unicode_buf[ i ], action );
-        }
-        else
-        {
-            _glfwInputChar( (int) char_buf[ i ], action );
-        }
-    }
-}
-
-
-//========================================================================
-// Window callback function (handles window events)
-//========================================================================
-
-static LRESULT CALLBACK _glfwWindowCallback( HWND hWnd, UINT uMsg,
-                                             WPARAM wParam, LPARAM lParam )
-{
-    int WheelDelta, Iconified;
-
-    // Handle certain window messages
-    switch( uMsg )
-    {
-        // Window activate message? (iconification?)
-        case WM_ACTIVATE:
-        {
-            _glfwWin.Active = LOWORD(wParam) != WA_INACTIVE ? GL_TRUE : GL_FALSE;
-
-            Iconified = HIWORD(wParam) ? GL_TRUE : GL_FALSE;
-
-            // Were we deactivated/iconified?
-            if( (!_glfwWin.Active || Iconified) && !_glfwWin.Iconified )
-            {
-                _glfwInputDeactivation();
-
-                // If we are in fullscreen mode we need to iconify
-                if( _glfwWin.Opened && _glfwWin.Fullscreen )
-                {
-                    // Do we need to manually iconify?
-                    if( !Iconified )
-                    {
-                        // Minimize window
-                        CloseWindow( _glfwWin.Wnd );
-
-                        // The window is now iconified
-                        Iconified = GL_TRUE;
-                    }
-
-                    // Change display settings to the desktop resolution
-                    ChangeDisplaySettings( NULL, CDS_FULLSCREEN );
-                }
-
-                // Unlock mouse
-                if( !_glfwWin.OldMouseLockValid )
-                {
-                    _glfwWin.OldMouseLock = _glfwWin.MouseLock;
-                    _glfwWin.OldMouseLockValid = GL_TRUE;
-                    glfwEnable( GLFW_MOUSE_CURSOR );
-                }
-            }
-            else if( _glfwWin.Active || !Iconified )
-            {
-                // If we are in fullscreen mode we need to maximize
-                if( _glfwWin.Opened && _glfwWin.Fullscreen && _glfwWin.Iconified )
-                {
-                    // Change display settings to the user selected mode
-                    _glfwSetVideoModeMODE( _glfwWin.ModeID );
-
-                    // Do we need to manually restore window?
-                    if( Iconified )
-                    {
-                        // Restore window
-                        OpenIcon( _glfwWin.Wnd );
-
-                        // The window is no longer iconified
-                        Iconified = GL_FALSE;
-
-                        // Activate window
-                        ShowWindow( hWnd, SW_SHOW );
-                        _glfwSetForegroundWindow( _glfwWin.Wnd );
-                        SetFocus( _glfwWin.Wnd );
-                    }
-                }
-
-                // Lock mouse, if necessary
-                if( _glfwWin.OldMouseLockValid && _glfwWin.OldMouseLock )
-                {
-                    glfwDisable( GLFW_MOUSE_CURSOR );
-                }
-                _glfwWin.OldMouseLockValid = GL_FALSE;
-            }
-
-            _glfwWin.Iconified = Iconified;
-            return 0;
-        }
-
-        // Intercept system commands (forbid certain actions/events)
-        case WM_SYSCOMMAND:
-        {
-            switch( wParam )
-            {
-                // Screensaver trying to start or monitor trying to enter
-                // powersave?
-                case SC_SCREENSAVE:
-                case SC_MONITORPOWER:
-                    if( _glfwWin.Fullscreen )
-                    {
-                        return 0;
-                    }
-                    else
-                    {
-                        break;
-                    }
-
-                // User trying to access application menu using ALT?
-                case SC_KEYMENU:
-                    return 0;
-            }
-            break;
-        }
-
-        // Did we receive a close message?
-        case WM_CLOSE:
-            PostQuitMessage( 0 );
-            return 0;
-
-        // Is a key being pressed?
-        case WM_KEYDOWN:
-        case WM_SYSKEYDOWN:
-        {
-            // Translate and report key press
-            _glfwInputKey( _glfwTranslateKey( wParam, lParam ),
-                           GLFW_PRESS );
-
-            // Translate and report character input
-            if( _glfwWin.CharCallback )
-            {
-                _glfwTranslateChar( (DWORD) wParam, (DWORD) lParam, GLFW_PRESS );
-            }
-            return 0;
-          }  
-
-        // Is a key being released?
-        case WM_KEYUP:
-        case WM_SYSKEYUP:
-        {
-            // Special trick: release both shift keys on SHIFT up event
-            if( wParam == VK_SHIFT )
-            {
-                _glfwInputKey( GLFW_KEY_LSHIFT, GLFW_RELEASE );
-                _glfwInputKey( GLFW_KEY_RSHIFT, GLFW_RELEASE );
-            }
-            else
-            {
-                // Translate and report key release
-                _glfwInputKey( _glfwTranslateKey( wParam, lParam ),
-                               GLFW_RELEASE );
-            }
-
-            // Translate and report character input
-            if( _glfwWin.CharCallback )
-            {
-                _glfwTranslateChar( (DWORD) wParam, (DWORD) lParam, GLFW_RELEASE );
-            }
-
-            return 0;
-        }
-
-        // Were any of the mouse-buttons pressed?
-        case WM_LBUTTONDOWN:
-            SetCapture(hWnd);
-            _glfwInputMouseClick( GLFW_MOUSE_BUTTON_LEFT, GLFW_PRESS );
-            return 0;
-        case WM_RBUTTONDOWN:
-            SetCapture(hWnd);
-            _glfwInputMouseClick( GLFW_MOUSE_BUTTON_RIGHT, GLFW_PRESS );
-            return 0;
-        case WM_MBUTTONDOWN:
-            SetCapture(hWnd);
-            _glfwInputMouseClick( GLFW_MOUSE_BUTTON_MIDDLE, GLFW_PRESS );
-            return 0;
-        case WM_XBUTTONDOWN:
-        {
-            if( HIWORD(wParam) == XBUTTON1 )
-            {
-                SetCapture(hWnd);
-                _glfwInputMouseClick( GLFW_MOUSE_BUTTON_4, GLFW_PRESS );
-            }
-            else if( HIWORD(wParam) == XBUTTON2 )
-            {
-                SetCapture(hWnd);
-                _glfwInputMouseClick( GLFW_MOUSE_BUTTON_5, GLFW_PRESS );
-            }
-            return 1;
-        }
-
-        // Were any of the mouse-buttons released?
-        case WM_LBUTTONUP:
-            ReleaseCapture();
-            _glfwInputMouseClick( GLFW_MOUSE_BUTTON_LEFT, GLFW_RELEASE );
-            return 0;
-        case WM_RBUTTONUP:
-            ReleaseCapture();
-            _glfwInputMouseClick( GLFW_MOUSE_BUTTON_RIGHT, GLFW_RELEASE );
-            return 0;
-        case WM_MBUTTONUP:
-            ReleaseCapture();
-            _glfwInputMouseClick( GLFW_MOUSE_BUTTON_MIDDLE, GLFW_RELEASE );
-            return 0;
-        case WM_XBUTTONUP:
-        {
-            if( HIWORD(wParam) == XBUTTON1 )
-            {
-                ReleaseCapture();
-                _glfwInputMouseClick( GLFW_MOUSE_BUTTON_4, GLFW_RELEASE );
-            }
-            else if( HIWORD(wParam) == XBUTTON2 )
-            {
-                ReleaseCapture();
-                _glfwInputMouseClick( GLFW_MOUSE_BUTTON_5, GLFW_RELEASE );
-            }
-            return 1;
-        }
-
-        // Did the mouse move?
-        case WM_MOUSEMOVE:
-        {
-            {
-                int NewMouseX, NewMouseY;
-
-                // Get signed (!) mouse position
-                NewMouseX = (int)((short)LOWORD(lParam));
-                NewMouseY = (int)((short)HIWORD(lParam));
-
-                if( NewMouseX != _glfwInput.OldMouseX ||
-                    NewMouseY != _glfwInput.OldMouseY )
-                {
-                    if( _glfwWin.MouseLock )
-                    {
-                        _glfwInput.MousePosX += NewMouseX -
-                                                _glfwInput.OldMouseX;
-                        _glfwInput.MousePosY += NewMouseY -
-                                                _glfwInput.OldMouseY;
-                    }
-                    else
-                    {
-                        _glfwInput.MousePosX = NewMouseX;
-                        _glfwInput.MousePosY = NewMouseY;
-                    }
-                    _glfwInput.OldMouseX = NewMouseX;
-                    _glfwInput.OldMouseY = NewMouseY;
-                    _glfwInput.MouseMoved = GL_TRUE;
-    
-                    // Call user callback function
-                    if( _glfwWin.MousePosCallback )
-                    {
-                        _glfwWin.MousePosCallback( _glfwInput.MousePosX,
-                                                   _glfwInput.MousePosY );
-                    }
-                }
-            }
-            return 0;
-        }
-
-        // Mouse wheel action?
-        case WM_MOUSEWHEEL:
-        {
-            // WM_MOUSEWHEEL is not supported under Windows 95
-            if( _glfwLibrary.Sys.WinVer != _GLFW_WIN_95 )
-            {
-                WheelDelta = (((int)wParam) >> 16) / WHEEL_DELTA;
-                _glfwInput.WheelPos += WheelDelta;
-                if( _glfwWin.MouseWheelCallback )
-                {
-                    _glfwWin.MouseWheelCallback( _glfwInput.WheelPos );
-                }
-                return 0;
-            }
-            break;
-        }
-
-        // Resize the window?
-        case WM_SIZE:
-        {
-            // get the new size
-            _glfwWin.Width  = LOWORD(lParam);
-            _glfwWin.Height = HIWORD(lParam);
-
-            // If the mouse is locked, update the clipping rect
-            if( _glfwWin.MouseLock )
-            {
-                RECT ClipWindowRect;
-                if( GetWindowRect( _glfwWin.Wnd, &ClipWindowRect ) )
-                {
-                    ClipCursor( &ClipWindowRect );
-                }
-            }
-
-            // Call the user-supplied callback, if it exists
-            if( _glfwWin.WindowSizeCallback )
-            {
-                _glfwWin.WindowSizeCallback( LOWORD(lParam),
-                                             HIWORD(lParam) );
-            }
-            return 0;
-        }
-
-        // Move the window?
-        case WM_MOVE:
-        {
-            // If the mouse is locked, update the clipping rect
-            if( _glfwWin.MouseLock )
-            {
-                RECT ClipWindowRect;
-                if( GetWindowRect( _glfwWin.Wnd, &ClipWindowRect ) )
-                {
-                    ClipCursor( &ClipWindowRect );
-                }
-            }
-            return 0;
-        }
-
-        // Was the window contents damaged?
-        case WM_PAINT:
-        {
-            // Call user callback function
-            if( _glfwWin.WindowRefreshCallback )
-            {
-                _glfwWin.WindowRefreshCallback();
-            }
-            break;
-        }
-
-	case WM_DISPLAYCHANGE:
-	{
-	    // TODO: Do stuff here.
-
-	    break;
-	}
-    }
-
-    // Pass all unhandled messages to DefWindowProc
-    return DefWindowProc( hWnd, uMsg, wParam, lParam );
-}
-
-
-//========================================================================
-// Translate client window size to full window size (including window borders)
-//========================================================================
-
-static void _glfwGetFullWindowSize( int w, int h, int *w2, int *h2 )
-{
-    RECT rect;
-
-    // Create a window rectangle
-    rect.left   = (long)0;
-    rect.right  = (long)w-1;
-    rect.top    = (long)0;
-    rect.bottom = (long)h-1;
-
-    // Adjust according to window styles
-    AdjustWindowRectEx( &rect, _glfwWin.dwStyle, FALSE,
-                        _glfwWin.dwExStyle );
-
-    // Calculate width and height of full window
-    *w2 = rect.right-rect.left+1;
-    *h2 = rect.bottom-rect.top+1;
-}
-
-
-//========================================================================
-// Initialize WGL-specific extensions
-//========================================================================
-
-static void _glfwInitWGLExtensions( void )
-{
-    GLubyte *extensions;
-    int     has_swap_control, has_pixel_format;
-
-    _glfwWin.GetExtensionsStringEXT = (WGLGETEXTENSIONSSTRINGEXT_T)
-        wglGetProcAddress( "wglGetExtensionsStringEXT" );
-    if( !_glfwWin.GetExtensionsStringEXT )
-    {
-	// Try wglGetExtensionsStringARB
-	_glfwWin.GetExtensionsStringARB = (WGLGETEXTENSIONSSTRINGARB_T)
-	    wglGetProcAddress( "wglGetExtensionsStringARB" );
-	if( !_glfwWin.GetExtensionsStringARB )
-	{
-	    return;
-	}
-    }
-
-    // Initialize OpenGL extension: WGL_EXT_swap_control
-    has_swap_control = GL_FALSE;
-    has_pixel_format = GL_FALSE;
-    extensions = (GLubyte *) glGetString( GL_EXTENSIONS );
-
-    if( extensions != NULL )
-    {
-        has_swap_control = _glfwStringInExtensionString(
-                               "WGL_EXT_swap_control",
-                               extensions
-                           );
-        has_pixel_format = _glfwStringInExtensionString(
-                               "WGL_ARB_pixel_format",
-                               extensions
-                           );
-    }
-
-    if( !has_swap_control )
-    {
-        has_swap_control = _glfwPlatformExtensionSupported(
-                               "WGL_EXT_swap_control"
-                           );
-    }
-
-    if( !has_pixel_format )
-    {
-        has_pixel_format = _glfwPlatformExtensionSupported(
-                               "WGL_ARB_pixel_format"
-                           );
-    }
-
-    if( has_swap_control )
-    {
-        _glfwWin.SwapInterval = (WGLSWAPINTERVALEXT_T)
-            wglGetProcAddress( "wglSwapIntervalEXT" );
-    }
-    else
-    {
-        _glfwWin.SwapInterval = NULL;
-    }
-    
-    if( has_pixel_format )
-    {
-        _glfwWin.ChoosePixelFormat = (WGLCHOOSEPIXELFORMATARB_T)
-            wglGetProcAddress( "wglChoosePixelFormatARB" );
-        _glfwWin.GetPixelFormatAttribiv = (WGLGETPIXELFORMATATTRIBIVARB_T)
-            wglGetProcAddress( "wglGetPixelFormatAttribivARB" );
-    }
-    else
-    {
-        _glfwWin.ChoosePixelFormat = NULL;
-        _glfwWin.GetPixelFormatAttribiv = NULL;
-    }  
-}
-
-
-//========================================================================
-// Creates the GLFW window and rendering context
-//========================================================================
-
-static int _glfwCreateWindow( int redbits, int greenbits, int bluebits,
-                              int alphabits, int depthbits, int stencilbits,
-                              int mode, _GLFWhints* hints )
-{
-    int    full_width, full_height;
-    RECT   wa;
-    POINT  pos;
-
-    _glfwWin.DC  = NULL;
-    _glfwWin.RC  = NULL;
-    _glfwWin.Wnd = NULL;
-
-    // Set window size to true requested size (adjust for window borders)
-    _glfwGetFullWindowSize( _glfwWin.Width, _glfwWin.Height, &full_width,
-                            &full_height );
-
-    // Adjust window position to working area (e.g. if the task bar is at
-    // the top of the display). Fullscreen windows are always opened in
-    // the upper left corner regardless of the desktop working area. 
-    if( _glfwWin.Fullscreen )
-    {
-        wa.left = wa.top = 0;
-    }
-    else
-    {
-        SystemParametersInfo( SPI_GETWORKAREA, 0, &wa, 0 );
-    }
-
-    // Create window
-    _glfwWin.Wnd = CreateWindowEx(
-               _glfwWin.dwExStyle,        // Extended style
-               _GLFW_WNDCLASSNAME,        // Class name
-               "GLFW Window",             // Window title
-               _glfwWin.dwStyle,          // Defined window style
-               wa.left, wa.top,           // Window position
-               full_width,                // Decorated window width
-               full_height,               // Decorated window height
-               NULL,                      // No parent window
-               NULL,                      // No menu
-               _glfwLibrary.Instance,     // Instance
-               NULL );                    // Nothing to WM_CREATE
-
-    if( !_glfwWin.Wnd )
-    {
-        return GL_FALSE;
-    }
-
-    // Get a device context
-    _glfwWin.DC = GetDC( _glfwWin.Wnd );
-    if( !_glfwWin.DC )
-    {
-        return GL_FALSE;
-    }
-
-    if( _glfwWin.ChoosePixelFormat )
-    {
-        if( !_glfwSetPixelFormatAttrib( redbits, greenbits, bluebits, alphabits,
-                                        depthbits, stencilbits, mode, hints ) )
-        {
-            return GL_FALSE;
-        }
-    }
-    else
-    {
-        if( !_glfwSetPixelFormatPFD( redbits, greenbits, bluebits, alphabits,
-                                     depthbits, stencilbits, mode, hints ) )
-        {
-            return GL_FALSE;
-        }
-    }
-
-    // Get a rendering context
-    _glfwWin.RC = wglCreateContext( _glfwWin.DC );
-    if( !_glfwWin.RC )
-    {
-        return GL_FALSE;
-    }
-
-    // Activate the OpenGL rendering context
-    if( !wglMakeCurrent( _glfwWin.DC, _glfwWin.RC ) )
-    {
-        return GL_FALSE;
-    }
-
-    // Initialize WGL-specific OpenGL extensions
-    _glfwInitWGLExtensions();
-
-    // Initialize mouse position
-    GetCursorPos( &pos );
-    ScreenToClient( _glfwWin.Wnd, &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 _glfwDestroyWindow( void )
-{
-    // Do we have a rendering context?
-    if( _glfwWin.RC )
-    {
-        // Release the DC and RC contexts
-        wglMakeCurrent( NULL, NULL );
-
-        // Delete the rendering context
-        wglDeleteContext( _glfwWin.RC );
-        _glfwWin.RC = NULL;
-    }
-
-    // Do we have a device context?
-    if( _glfwWin.DC )
-    {
-        // Release the device context
-        ReleaseDC( _glfwWin.Wnd, _glfwWin.DC );
-        _glfwWin.DC = NULL;
-    }
-
-    // Do we have a window?
-    if( _glfwWin.Wnd )
-    {
-        // Destroy the window
-        if( _glfwLibrary.Sys.WinVer <= _GLFW_WIN_NT4 )
-        {
-            // Note: Hiding the window first fixes an annoying W98/NT4
-            // remaining icon bug for fullscreen displays
-            ShowWindow( _glfwWin.Wnd, SW_HIDE );
-        }
-
-        DestroyWindow( _glfwWin.Wnd );
-        _glfwWin.Wnd = NULL;
-    }
-}
-
-
-
-//************************************************************************
-//****               Platform implementation functions                ****
-//************************************************************************
-
-//========================================================================
-// Here is where the window is created, and the OpenGL rendering context is
-// created
-//========================================================================
-
-int _glfwPlatformOpenWindow( int width, int height,
-                             int redbits, int greenbits, int bluebits,
-                             int alphabits, int depthbits, int stencilbits,
-                             int mode, _GLFWhints* hints )
-{
-    WNDCLASS    wc;
-    DWORD  dwStyle, dwExStyle;
-
-    // Clear platform specific GLFW window state
-    _glfwWin.ClassAtom         = 0;
-    _glfwWin.OldMouseLockValid = GL_FALSE;
-    _glfwWin.ChoosePixelFormat = NULL;
-    _glfwWin.GetPixelFormatAttribiv = NULL;
-
-    // Remember desired refresh rate for this window (used only in
-    // fullscreen mode)
-    _glfwWin.DesiredRefreshRate = hints->RefreshRate;
-
-    // Set window class parameters
-    wc.style         = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; // Redraw on...
-    wc.lpfnWndProc   = (WNDPROC)_glfwWindowCallback;  // Message handler
-    wc.cbClsExtra    = 0;                             // No extra class data
-    wc.cbWndExtra    = 0;                             // No extra window data
-    wc.hInstance     = _glfwLibrary.Instance;         // Set instance
-    wc.hCursor       = LoadCursor( NULL, IDC_ARROW ); // Load arrow pointer
-    wc.hbrBackground = NULL;                          // No background
-    wc.lpszMenuName  = NULL;                          // No menu
-    wc.lpszClassName = _GLFW_WNDCLASSNAME;            // Set class name
-
-    // Load user-provided icon if available
-    wc.hIcon = LoadIcon( _glfwLibrary.Instance, "GLFW_ICON" );
-    if( !wc.hIcon )
-    {
-        // Load default icon
-        wc.hIcon = LoadIcon( NULL, IDI_WINLOGO ); 
-    }
-
-    // Register the window class
-    _glfwWin.ClassAtom = RegisterClass( &wc );
-    if( !_glfwWin.ClassAtom )
-    {
-        _glfwPlatformCloseWindow();
-        return GL_FALSE;
-    }
-
-    // Do we want full-screen mode?
-    if( _glfwWin.Fullscreen )
-    {
-        _glfwSetVideoMode( &_glfwWin.Width, &_glfwWin.Height,
-                           redbits, greenbits, bluebits,
-                           hints->RefreshRate );
-    }
-
-    // Set common window styles
-    dwStyle   = WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_VISIBLE;
-    dwExStyle = WS_EX_APPWINDOW;
-
-    // Set window style, depending on fullscreen mode
-    if( _glfwWin.Fullscreen )
-    {
-        dwStyle |= WS_POPUP;
-
-        // Here's a trick for helping us getting window focus
-        // (SetForegroundWindow doesn't work properly under
-        // Win98/ME/2K/.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( !hints->WindowNoResize )
-        {
-            dwStyle |= ( WS_MAXIMIZEBOX | WS_SIZEBOX );
-            dwExStyle |= WS_EX_WINDOWEDGE;
-        }
-    }
-
-    // Remember window styles (used by _glfwGetFullWindowSize)
-    _glfwWin.dwStyle   = dwStyle;
-    _glfwWin.dwExStyle = dwExStyle;
-
-    if( !_glfwCreateWindow( redbits, greenbits, bluebits, alphabits,
-                            depthbits, stencilbits, mode, hints ) )
-    {
-        _glfwPlatformCloseWindow();
-        return GL_FALSE;
-    }
-
-    if( _glfwWin.ChoosePixelFormat && hints->Samples > 0 )
-    {
-	// Iteratively try to create a context with a decreasing number of
-	// FSAA samples (requires window recreation).
-
-        for (;;)
-        {
-            _glfwDestroyWindow();
-
-            if( _glfwCreateWindow( redbits, greenbits, bluebits, alphabits,
-                                   depthbits, stencilbits, mode, hints ) )
-            {
-                break;
-            }
-
-            if( hints->Samples > 0 )
-            {
-                hints->Samples--;
-            }
-            else
-            {
-                _glfwPlatformCloseWindow();
-                return GL_FALSE;
-            }
-        }
-    }
-
-    // Make sure that our window ends up on top of things
-    if( _glfwWin.Fullscreen )
-    {
-        // Place the window above all topmost windows
-        SetWindowPos( _glfwWin.Wnd, HWND_TOPMOST, 0,0,0,0,
-                      SWP_NOMOVE | SWP_NOSIZE );
-    }
-    _glfwSetForegroundWindow( _glfwWin.Wnd );
-    SetFocus( _glfwWin.Wnd );
-
-    // Start by clearing the front buffer to black (avoid ugly desktop
-    // remains in our OpenGL window)
-    glClear( GL_COLOR_BUFFER_BIT );
-    _glfw_SwapBuffers( _glfwWin.DC );
-
-    return GL_TRUE;
-}
-
-
-//========================================================================
-// Properly kill the window / video display
-//========================================================================
-
-void _glfwPlatformCloseWindow( void )
-{
-    _glfwDestroyWindow();
-
-    // Do we have an instance?
-    if( _glfwWin.ClassAtom )
-    {
-        // Unregister class
-        UnregisterClass( _GLFW_WNDCLASSNAME, _glfwLibrary.Instance );
-        _glfwWin.ClassAtom = 0;
-    }
-
-    // Are we in fullscreen mode?
-    if( _glfwWin.Fullscreen )
-    {
-        // Switch back to desktop resolution
-        ChangeDisplaySettings( NULL, CDS_FULLSCREEN );
-    }
-}
-
-
-//========================================================================
-// Set the window title
-//========================================================================
-
-void _glfwPlatformSetWindowTitle( const char *title )
-{
-    // Set window title
-    (void) SetWindowText( _glfwWin.Wnd, title );
-}
-
-
-//========================================================================
-// Set the window size.
-//========================================================================
-
-void _glfwPlatformSetWindowSize( int width, int height )
-{
-    int     bpp, mode = 0, refresh;
-    int     sizechanged = GL_FALSE;
-    GLint   drawbuffer;
-    GLfloat clearcolor[4];
-
-    // If we are in fullscreen mode, get some info about the current mode
-    if( _glfwWin.Fullscreen )
-    {
-        DEVMODE dm;
-
-        // Get current BPP settings
-        dm.dmSize = sizeof( DEVMODE );
-        if( EnumDisplaySettings( NULL, _glfwWin.ModeID, &dm ) )
-        {
-            // Get bpp
-            bpp = dm.dmBitsPerPel;
-
-            // Get closest match for target video mode
-            refresh = _glfwWin.DesiredRefreshRate;
-            mode = _glfwGetClosestVideoModeBPP( &width, &height, &bpp,
-                                                &refresh );
-        }
-        else
-        {
-            mode = _glfwWin.ModeID;
-        }
-    }
-    else
-    {
-        // If we are in windowed mode, adjust the window size to
-        // compensate for window decorations
-        _glfwGetFullWindowSize( width, height, &width, &height );
-    }
-
-    // Change window size before changing fullscreen mode?
-    if( _glfwWin.Fullscreen && (width > _glfwWin.Width) )
-    {
-        SetWindowPos( _glfwWin.Wnd, HWND_TOP, 0, 0, width, height,
-                      SWP_NOOWNERZORDER | SWP_NOMOVE | SWP_NOZORDER );
-        sizechanged = GL_TRUE;
-    }
-
-    // Change fullscreen video mode?
-    if( _glfwWin.Fullscreen && mode != _glfwWin.ModeID )
-    {
-        // Change video mode
-        _glfwSetVideoModeMODE( mode );
-
-        // Clear the front buffer to black (avoid ugly desktop remains in
-        // our OpenGL window)
-        glGetIntegerv( GL_DRAW_BUFFER, &drawbuffer );
-        glGetFloatv( GL_COLOR_CLEAR_VALUE, clearcolor );
-        glClearColor( 0.0f, 0.0f, 0.0f, 0.0f );
-        glClear( GL_COLOR_BUFFER_BIT );
-        if( drawbuffer == GL_BACK )
-        {
-            _glfw_SwapBuffers( _glfwWin.DC );
-        }
-        glClearColor( clearcolor[0], clearcolor[1], clearcolor[2],
-                      clearcolor[3] );
-    }
-
-    // Set window size (if not already changed)
-    if( !sizechanged )
-    {
-        SetWindowPos( _glfwWin.Wnd, HWND_TOP, 0, 0, width, height,
-                      SWP_NOOWNERZORDER | SWP_NOMOVE | SWP_NOZORDER );
-    }
-}
-
-
-//========================================================================
-// Set the window position
-//========================================================================
-
-void _glfwPlatformSetWindowPos( int x, int y )
-{
-    // Set window position
-    (void) SetWindowPos( _glfwWin.Wnd, HWND_TOP, x, y, 0, 0,
-                         SWP_NOOWNERZORDER | SWP_NOSIZE | SWP_NOZORDER );
-}
-
-
-//========================================================================
-// Window iconification
-//========================================================================
-
-void _glfwPlatformIconifyWindow( void )
-{
-    // Iconify window
-    CloseWindow( _glfwWin.Wnd );
-
-    // Window is now iconified
-    _glfwWin.Iconified = GL_TRUE;
-
-    // If we are in fullscreen mode we need to change video modes
-    if( _glfwWin.Fullscreen )
-    {
-        // Change display settings to the desktop resolution
-        ChangeDisplaySettings( NULL, CDS_FULLSCREEN );
-    }
-
-    // Unlock mouse
-    if( !_glfwWin.OldMouseLockValid )
-    {
-        _glfwWin.OldMouseLock = _glfwWin.MouseLock;
-        _glfwWin.OldMouseLockValid = GL_TRUE;
-        glfwEnable( GLFW_MOUSE_CURSOR );
-    }
-}
-
-
-//========================================================================
-// Window un-iconification
-//========================================================================
-
-void _glfwPlatformRestoreWindow( void )
-{
-    // If we are in fullscreen mode we need to change video modes
-    if( _glfwWin.Fullscreen )
-    {
-        // Change display settings to the user selected mode
-        _glfwSetVideoModeMODE( _glfwWin.ModeID );
-    }
-
-    // Un-iconify window
-    OpenIcon( _glfwWin.Wnd );
-
-    // Make sure that our window ends up on top of things
-    ShowWindow( _glfwWin.Wnd, SW_SHOW );
-    _glfwSetForegroundWindow( _glfwWin.Wnd );
-    SetFocus( _glfwWin.Wnd );
-
-    // Window is no longer iconified
-    _glfwWin.Iconified = GL_FALSE;
-
-    // Lock mouse, if necessary
-    if( _glfwWin.OldMouseLockValid && _glfwWin.OldMouseLock )
-    {
-        glfwDisable( GLFW_MOUSE_CURSOR );
-    }
-    _glfwWin.OldMouseLockValid = GL_FALSE;
-}
-
-
-//========================================================================
-// Swap buffers (double-buffering)
-//========================================================================
-
-void _glfwPlatformSwapBuffers( void )
-{
-    _glfw_SwapBuffers( _glfwWin.DC );
-}
-
-
-//========================================================================
-// Set double buffering swap interval
-//========================================================================
-
-void _glfwPlatformSwapInterval( int interval )
-{
-    if( _glfwWin.SwapInterval )
-    {
-        _glfwWin.SwapInterval( interval );
-    }
-}
-
-
-//========================================================================
-// Write back window parameters into GLFW window structure
-//========================================================================
-
-void _glfwPlatformRefreshWindowParams( void )
-{
-    PIXELFORMATDESCRIPTOR pfd;
-    DEVMODE dm;
-    int     PixelFormat, mode;
-
-    // Obtain a detailed description of current pixel format
-    PixelFormat = _glfw_GetPixelFormat( _glfwWin.DC );
-
-    if( !_glfwWin.GetPixelFormatAttribiv )
-    {
-        _glfw_DescribePixelFormat( _glfwWin.DC, PixelFormat,
-                                   sizeof(PIXELFORMATDESCRIPTOR), &pfd );
-
-        // Is current OpenGL context accelerated?
-        _glfwWin.Accelerated = (pfd.dwFlags & PFD_GENERIC_ACCELERATED) ||
-                               !(pfd.dwFlags & PFD_GENERIC_FORMAT) ? 1 : 0;
-
-        // "Standard" window parameters
-        _glfwWin.RedBits        = pfd.cRedBits;
-        _glfwWin.GreenBits      = pfd.cGreenBits;
-        _glfwWin.BlueBits       = pfd.cBlueBits;
-        _glfwWin.AlphaBits      = pfd.cAlphaBits;
-        _glfwWin.DepthBits      = pfd.cDepthBits;
-        _glfwWin.StencilBits    = pfd.cStencilBits;
-        _glfwWin.AccumRedBits   = pfd.cAccumRedBits;
-        _glfwWin.AccumGreenBits = pfd.cAccumGreenBits;
-        _glfwWin.AccumBlueBits  = pfd.cAccumBlueBits;
-        _glfwWin.AccumAlphaBits = pfd.cAccumAlphaBits;
-        _glfwWin.AuxBuffers     = pfd.cAuxBuffers;
-        _glfwWin.Stereo         = pfd.dwFlags & PFD_STEREO ? 1 : 0;
-        _glfwWin.Samples        = 0;
-    }
-    else
-    {
-        const int attribs[] = {
-            WGL_ACCELERATION_ARB,
-            WGL_RED_BITS_ARB,
-            WGL_GREEN_BITS_ARB,
-            WGL_BLUE_BITS_ARB,
-            WGL_ALPHA_BITS_ARB,
-            WGL_DEPTH_BITS_ARB,
-            WGL_STENCIL_BITS_ARB,
-            WGL_ACCUM_RED_BITS_ARB,
-            WGL_ACCUM_GREEN_BITS_ARB,
-            WGL_ACCUM_BLUE_BITS_ARB,
-            WGL_ACCUM_ALPHA_BITS_ARB,
-            WGL_AUX_BUFFERS_ARB,
-            WGL_STEREO_ARB,
-            WGL_SAMPLES_ARB
-        };
-
-        int values[sizeof(attribs) / sizeof(attribs[0])];
-
-        _glfwWin.GetPixelFormatAttribiv( _glfwWin.DC, PixelFormat, 0, 
-                                         sizeof(attribs) / sizeof(attribs[0]), 
-                                         attribs, values);
-
-        // Is current OpenGL context accelerated?
-        _glfwWin.Accelerated = (values[0] == WGL_FULL_ACCELERATION_ARB);
-
-        // "Standard" window parameters
-        _glfwWin.RedBits        = values[1];
-        _glfwWin.GreenBits      = values[2];
-        _glfwWin.BlueBits       = values[3];
-        _glfwWin.AlphaBits      = values[4];
-        _glfwWin.DepthBits      = values[5];
-        _glfwWin.StencilBits    = values[6];
-        _glfwWin.AccumRedBits   = values[7];
-        _glfwWin.AccumGreenBits = values[8]; 
-        _glfwWin.AccumBlueBits  = values[9];
-        _glfwWin.AccumAlphaBits = values[10];
-        _glfwWin.AuxBuffers     = values[11];
-        _glfwWin.Stereo         = values[12];
-        _glfwWin.Samples        = values[13];
-    }
-
-    // Get refresh rate
-    mode = _glfwWin.Fullscreen ? _glfwWin.ModeID : ENUM_CURRENT_SETTINGS;
-    dm.dmSize = sizeof( DEVMODE );
-
-    if( EnumDisplaySettings( NULL, mode, &dm ) )
-    {
-        _glfwWin.RefreshRate = dm.dmDisplayFrequency;
-        if( _glfwWin.RefreshRate <= 1 )
-        {
-            _glfwWin.RefreshRate = 0;
-        }
-    }
-    else
-    {
-        _glfwWin.RefreshRate = 0;
-    }
-}
-
-
-//========================================================================
-// Poll for new window and input events
-//========================================================================
-
-void _glfwPlatformPollEvents( void )
-{
-    MSG msg;
-    int winclosed = GL_FALSE;
-
-    // Flag: mouse was not moved (will be changed by _glfwGetNextEvent if
-    // there was a mouse move event)
-    _glfwInput.MouseMoved = GL_FALSE;
-    if( _glfwWin.MouseLock )
-    {
-        _glfwInput.OldMouseX = _glfwWin.Width/2;
-        _glfwInput.OldMouseY = _glfwWin.Height/2;
-    }
-    else
-    {
-        _glfwInput.OldMouseX = _glfwInput.MousePosX;
-        _glfwInput.OldMouseY = _glfwInput.MousePosY;
-    }
-
-    // Check for new window messages
-    while( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
-    {
-        switch( msg.message )
-        {
-            // QUIT-message (from close window)?
-            case WM_QUIT:
-                winclosed = GL_TRUE;
-                break;
-
-            // Ok, send it to the window message handler
-            default:
-                DispatchMessage( &msg );
-                break;
-        }
-    }
-
-    // LSHIFT/RSHIFT fixup (keys tend to "stick" without this fix)
-    // This is the only async event handling in GLFW, but it solves some
-    // nasty problems.
-    // Caveat: Does not work under Win 9x/ME.
-    if( _glfwLibrary.Sys.WinVer >= _GLFW_WIN_NT4 )
-    {
-        int lshift_down, rshift_down;
-
-        // Get current state of left and right shift keys
-        lshift_down = (GetAsyncKeyState( VK_LSHIFT ) >> 15) & 1;
-        rshift_down = (GetAsyncKeyState( VK_RSHIFT ) >> 15) & 1;
-
-        // See if this differs from our belief of what has happened
-        // (we only have to check for lost key up events)
-        if( !lshift_down && _glfwInput.Key[ GLFW_KEY_LSHIFT ] == 1 )
-        {
-            _glfwInputKey( GLFW_KEY_LSHIFT, GLFW_RELEASE );
-        }
-        if( !rshift_down && _glfwInput.Key[ GLFW_KEY_RSHIFT ] == 1 )
-        {
-            _glfwInputKey( GLFW_KEY_RSHIFT, GLFW_RELEASE );
-        }
-    }
-
-    // Did we have mouse movement in locked cursor mode?
-    if( _glfwInput.MouseMoved && _glfwWin.MouseLock )
-    {
-        _glfwPlatformSetMouseCursorPos( _glfwWin.Width / 2,
-                                        _glfwWin.Height / 2 );
-    }
-
-    // Was there a window close request?
-    if( winclosed && _glfwWin.WindowCloseCallback )
-    {
-        // Check if the program wants us to close the window
-        winclosed = _glfwWin.WindowCloseCallback();
-    }
-    if( winclosed )
-    {
-        glfwCloseWindow();
-    }
-}
-
-
-//========================================================================
-// _glfwPlatformWaitEvents() - Wait for new window and input events
-//========================================================================
-
-void _glfwPlatformWaitEvents( void )
-{
-    // Wait for new events
-    WaitMessage();
-
-    // Poll new events
-    _glfwPlatformPollEvents();
-}
-
-
-//========================================================================
-// Hide mouse cursor (lock it)
-//========================================================================
-
-void _glfwPlatformHideMouseCursor( void )
-{
-    RECT ClipWindowRect;
-
-    // Hide cursor
-    ShowCursor( FALSE );
-
-    // Clip cursor to the window
-    if( GetWindowRect( _glfwWin.Wnd, &ClipWindowRect ) )
-    {
-        ClipCursor( &ClipWindowRect );
-    }
-
-    // Capture cursor to user window
-    SetCapture( _glfwWin.Wnd );
-}
-
-
-//========================================================================
-// Show mouse cursor (unlock it)
-//========================================================================
-
-void _glfwPlatformShowMouseCursor( void )
-{
-    // Un-capture cursor
-    ReleaseCapture();
-
-    // Disable cursor clipping
-    ClipCursor( NULL );
-
-    // Show cursor
-    ShowCursor( TRUE );
-}
-
-
-//========================================================================
-// Set physical mouse cursor position
-//========================================================================
-
-void _glfwPlatformSetMouseCursorPos( int x, int y )
-{
-    POINT pos;
-
-    // Convert client coordinates to screen coordinates
-    pos.x = x;
-    pos.y = y;
-    ClientToScreen( _glfwWin.Wnd, &pos );
-
-    // Change cursor position
+// Platform:    Win32/WGL
+// API version: 2.7
+// WWW:         http://www.glfw.org/
+//------------------------------------------------------------------------
+// Copyright (c) 2002-2006 Marcus Geelnard
+// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org>
+//
+// 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;
+            }
+
+            // Only consider "hardware-accelerated" pixel formats
+            if( getPixelFormatAttrib( i, WGL_ACCELERATION_ARB ) ==
+                WGL_NO_ACCELERATION_ARB )
+            {
+                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 GLboolean createContext( HDC dc, const _GLFWwndconfig* wndconfig, int pixelFormat )
+{
+    PIXELFORMATDESCRIPTOR pfd;
+    int flags, i = 0, attribs[40];
+
+    if( !_glfw_DescribePixelFormat( dc, pixelFormat, sizeof(pfd), &pfd ) )
+    {
+        return GL_FALSE;
+    }
+
+    if( !_glfw_SetPixelFormat( dc, pixelFormat, &pfd ) )
+    {
+        return GL_FALSE;
+    }
+
+    if( _glfwWin.has_WGL_ARB_create_context )
+    {
+        // Use the newer wglCreateContextAttribsARB
+
+        if( wndconfig->glMajor != 1 || 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( !_glfwWin.has_WGL_ARB_create_context_profile )
+            {
+                return GL_FALSE;
+            }
+
+            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;
+
+        _glfwWin.context = _glfwWin.CreateContextAttribsARB( dc, NULL, attribs );
+        if( !_glfwWin.context )
+        {
+            return GL_FALSE;
+        }
+    }
+    else
+    {
+        _glfwWin.context = wglCreateContext( dc );
+        if( !_glfwWin.context )
+        {
+            return GL_FALSE;
+        }
+    }
+
+    return GL_TRUE;
+}
+
+
+//========================================================================
+// 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
+                        ShowWindow( _glfwWin.window, SW_MINIMIZE );
+                        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
+                        ShowWindow( _glfwWin.window, SW_RESTORE );
+                        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.has_WGL_ARB_create_context_profile = GL_FALSE;
+
+    _glfwWin.GetExtensionsStringEXT = (PFNWGLGETEXTENSIONSSTRINGEXTPROC)
+        wglGetProcAddress( "wglGetExtensionsStringEXT" );
+    if( !_glfwWin.GetExtensionsStringEXT )
+    {
+        _glfwWin.GetExtensionsStringARB = (PFNWGLGETEXTENSIONSSTRINGARBPROC)
+            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( _glfwWin.has_WGL_ARB_create_context )
+    {
+        if( _glfwPlatformExtensionSupported( "WGL_ARB_create_context_profile" ) )
+        {
+            _glfwWin.has_WGL_ARB_create_context_profile = GL_TRUE;
+        }
+    }
+
+    if( _glfwPlatformExtensionSupported( "WGL_EXT_swap_control" ) )
+    {
+        _glfwWin.has_WGL_EXT_swap_control = GL_TRUE;
+        _glfwWin.SwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC)
+            wglGetProcAddress( "wglSwapIntervalEXT" );
+    }
+
+    if( _glfwPlatformExtensionSupported( "WGL_ARB_pixel_format" ) )
+    {
+        _glfwWin.has_WGL_ARB_pixel_format = GL_TRUE;
+        _glfwWin.GetPixelFormatAttribivARB = (PFNWGLGETPIXELFORMATATTRIBIVARBPROC)
+            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;
+    }
+
+    if( !createContext( _glfwWin.DC, wndconfig, pixelFormat ) )
+    {
+        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" );
+        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" );
+        return GL_FALSE;
+    }
+
+    _glfwRefreshContextParams();
+
+    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( wndconfig->glMajor > 2 )
+    {
+        if ( wndconfig->glMajor != _glfwWin.glMajor ||
+             wndconfig->glMinor != _glfwWin.glMinor )
+        {
+            // We want a different OpenGL version, but can we get it?
+            // Otherwise, if we got a version greater than required, that's fine,
+            // whereas if we got a version lesser than required, it will be dealt
+            // with in glfwOpenWindow
+
+            if( _glfwWin.has_WGL_ARB_create_context )
+            {
+                recreateContext = GL_TRUE;
+            }
+        }
+
+        if( wndconfig->glForward )
+        {
+            if( !_glfwWin.has_WGL_ARB_create_context )
+            {
+                // Forward-compatibility is a hard constraint
+                return GL_FALSE;
+            }
+
+            recreateContext = GL_TRUE;
+        }
+
+        if( wndconfig->glProfile )
+        {
+            if( !_glfwWin.has_WGL_ARB_create_context_profile )
+            {
+                // Context profile is a hard constraint
+                return GL_FALSE;
+            }
+
+            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" );
+            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 );
+
+    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
+    ShowWindow( _glfwWin.window, SW_MINIMIZE );
+    _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
+    ShowWindow( _glfwWin.window, SW_RESTORE );
+
+    // 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();
+    }
+}
+
+
+//========================================================================
+// 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 );
 }
 
diff --git a/glfw/lib/window.c b/glfw/lib/window.c
--- a/glfw/lib/window.c
+++ b/glfw/lib/window.c
@@ -1,11 +1,11 @@
 //========================================================================
 // GLFW - An OpenGL framework
-// File:        window.c
 // Platform:    Any
-// API version: 2.6
-// WWW:         http://glfw.sourceforge.net
+// API version: 2.7
+// WWW:         http://www.glfw.org/
 //------------------------------------------------------------------------
-// Copyright (c) 2002-2006 Camilla Berglund
+// Copyright (c) 2002-2006 Marcus Geelnard
+// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org>
 //
 // This software is provided 'as-is', without any express or implied
 // warranty. In no event will the authors be held liable for any damages
@@ -30,27 +30,36 @@
 
 #include "internal.h"
 
+#include <limits.h>
 
 
+#ifndef GL_VERSION_3_2
+
+#define GL_CONTEXT_CORE_PROFILE_BIT       0x00000001
+#define GL_CONTEXT_COMPATIBILITY_PROFILE_BIT 0x00000002
+#define GL_CONTEXT_PROFILE_MASK           0x9126
+
+#endif /*GL_VERSION_3_2*/
+
+
+
 //************************************************************************
 //****                  GLFW internal functions                       ****
 //************************************************************************
 
+static int Max(int a, int b)
+{
+    return (a > b) ? a : b;
+}
+
 //========================================================================
 // Clear all open window hints
 //========================================================================
 
 void _glfwClearWindowHints( void )
 {
-    _glfwWinHints.RefreshRate    = 0;
-    _glfwWinHints.AccumRedBits   = 0;
-    _glfwWinHints.AccumGreenBits = 0;
-    _glfwWinHints.AccumBlueBits  = 0;
-    _glfwWinHints.AccumAlphaBits = 0;
-    _glfwWinHints.AuxBuffers     = 0;
-    _glfwWinHints.Stereo         = 0;
-    _glfwWinHints.WindowNoResize = 0;
-    _glfwWinHints.Samples        = 0;
+    memset( &_glfwLibrary.hints, 0, sizeof( _glfwLibrary.hints ) );
+    _glfwLibrary.hints.glMajor = 1;
 }
 
 
@@ -66,24 +75,24 @@
     for( i = 0; i <= GLFW_KEY_LAST; i ++ )
     {
         if( _glfwInput.Key[ i ] == GLFW_PRESS )
-	{
-	    _glfwInputKey( i, GLFW_RELEASE );
-	}
+        {
+            _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 );
-	}
+        {
+            _glfwInputMouseClick( i, GLFW_RELEASE );
+        }
     }
 }
 
 
 //========================================================================
-// _glfwClearInput() - Clear all input state
+// Clear all input state
 //========================================================================
 
 void _glfwClearInput( void )
@@ -122,7 +131,7 @@
 
 
 //========================================================================
-// _glfwInputKey() - Register keyboard activity
+// Register keyboard activity
 //========================================================================
 
 void _glfwInputKey( int key, int action )
@@ -131,37 +140,37 @@
 
     if( key < 0 || key > GLFW_KEY_LAST )
     {
-	return;
+        return;
     }
 
     // Are we trying to release an already released key?
     if( action == GLFW_RELEASE && _glfwInput.Key[ key ] != GLFW_PRESS )
     {
-	return;
+        return;
     }
 
     // Register key action
     if( action == GLFW_RELEASE && _glfwInput.StickyKeys )
     {
-	_glfwInput.Key[ key ] = GLFW_STICK;
+        _glfwInput.Key[ key ] = GLFW_STICK;
     }
     else
     {
-	keyrepeat = (_glfwInput.Key[ key ] == GLFW_PRESS) &&
-		    (action == GLFW_PRESS);
-	_glfwInput.Key[ key ] = (char) action;
+        keyrepeat = (_glfwInput.Key[ key ] == GLFW_PRESS) &&
+                    (action == GLFW_PRESS);
+        _glfwInput.Key[ key ] = (char) action;
     }
 
     // Call user callback function
-    if( _glfwWin.KeyCallback && (_glfwInput.KeyRepeat || !keyrepeat) )
+    if( _glfwWin.keyCallback && (_glfwInput.KeyRepeat || !keyrepeat) )
     {
-	_glfwWin.KeyCallback( key, action );
+        _glfwWin.keyCallback( key, action );
     }
 }
 
 
 //========================================================================
-// _glfwInputChar() - Register (keyboard) character activity
+// Register (keyboard) character activity
 //========================================================================
 
 void _glfwInputChar( int character, int action )
@@ -190,16 +199,33 @@
         _glfwInput.LastChar = 0;
     }
 
-    // Call user callback function
-    if( _glfwWin.CharCallback && (_glfwInput.KeyRepeat || !keyrepeat) )
+    if( action != GLFW_PRESS )
     {
-        _glfwWin.CharCallback( character, action );
+        // 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
+// Register mouse button clicks
 //========================================================================
 
 void _glfwInputMouseClick( int button, int action )
@@ -217,39 +243,258 @@
         }
 
         // Call user callback function
-        if( _glfwWin.MouseButtonCallback )
+        if( _glfwWin.mouseButtonCallback )
         {
-            _glfwWin.MouseButtonCallback( button, action );
+            _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;
+    const _GLFWfbconfig *current;
+    const _GLFWfbconfig *closest = NULL;
+
+    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( ( colorDiff < leastColorDiff ) ||
+                ( colorDiff == leastColorDiff && extraDiff < leastExtraDiff ) )
+            {
+                closest = current;
+            }
+        }
+
+        if( current == closest )
+        {
+            leastMissing = missing;
+            leastColorDiff = colorDiff;
+            leastExtraDiff = extraDiff;
+        }
+    }
+
+    return closest;
+}
+
+
 //************************************************************************
 //****                    GLFW user functions                         ****
 //************************************************************************
 
 //========================================================================
-// glfwOpenWindow() - Here is where the window is created, and the OpenGL
-// rendering context is created
+// 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 )
 {
-    int x;
-    _GLFWhints hints;
+    _GLFWfbconfig fbconfig;
+    _GLFWwndconfig wndconfig;
 
-    // Is GLFW initialized?
-    if( !_glfwInitialized || _glfwWin.Opened )
+    if( !_glfwInitialized || _glfwWin.opened )
     {
         return GL_FALSE;
     }
 
-    // Copy and clear window hints
-    hints = _glfwWinHints;
+    // Set up desired framebuffer config
+    fbconfig.redBits        = Max( redbits, 0 );
+    fbconfig.greenBits      = Max( greenbits, 0 );
+    fbconfig.blueBits       = Max( bluebits, 0 );
+    fbconfig.alphaBits      = Max( alphabits, 0 );
+    fbconfig.depthBits      = Max( depthbits, 0 );
+    fbconfig.stencilBits    = Max( stencilbits, 0 );
+    fbconfig.accumRedBits   = Max( _glfwLibrary.hints.accumRedBits, 0 );
+    fbconfig.accumGreenBits = Max( _glfwLibrary.hints.accumGreenBits, 0 );
+    fbconfig.accumBlueBits  = Max( _glfwLibrary.hints.accumBlueBits, 0 );
+    fbconfig.accumAlphaBits = Max( _glfwLibrary.hints.accumAlphaBits, 0 );
+    fbconfig.auxBuffers     = Max( _glfwLibrary.hints.auxBuffers, 0 );
+    fbconfig.stereo         = _glfwLibrary.hints.stereo ? GL_TRUE : GL_FALSE;
+    fbconfig.samples        = Max( _glfwLibrary.hints.samples, 0 );
+
+    // Set up desired window config
+    wndconfig.mode           = mode;
+    wndconfig.refreshRate    = Max( _glfwLibrary.hints.refreshRate, 0 );
+    wndconfig.windowNoResize = _glfwLibrary.hints.windowNoResize ? GL_TRUE : GL_FALSE;
+    wndconfig.glMajor        = Max( _glfwLibrary.hints.glMajor, 1 );
+    wndconfig.glMinor        = Max( _glfwLibrary.hints.glMinor, 0 );
+    wndconfig.glForward      = _glfwLibrary.hints.glForward ? GL_TRUE : GL_FALSE;
+    wndconfig.glDebug        = _glfwLibrary.hints.glDebug ? GL_TRUE : GL_FALSE;
+    wndconfig.glProfile      = _glfwLibrary.hints.glProfile;
+
+    if( wndconfig.glMajor == 1 && wndconfig.glMinor > 5 )
+    {
+        // OpenGL 1.x series ended with version 1.5
+        return GL_FALSE;
+    }
+    else if( wndconfig.glMajor == 2 && wndconfig.glMinor > 1 )
+    {
+        // OpenGL 2.x series ended with version 2.1
+        return GL_FALSE;
+    }
+    else if( wndconfig.glMajor == 3 && wndconfig.glMinor > 3 )
+    {
+        // OpenGL 3.x series ended with version 3.3
+        return GL_FALSE;
+    }
+    else
+    {
+        // For now, let everything else through
+    }
+
+    if( wndconfig.glProfile &&
+        ( wndconfig.glMajor < 3 || ( wndconfig.glMajor == 3 && wndconfig.glMinor < 2 ) ) )
+    {
+        // Context profiles are only defined for OpenGL version 3.2 and above
+        return GL_FALSE;
+    }
+
+    if( wndconfig.glForward && wndconfig.glMajor < 3 )
+    {
+        // Forward-compatible contexts are only defined for OpenGL version 3.0 and above
+        return GL_FALSE;
+    }
+
+    // Clear for next open call
     _glfwClearWindowHints();
 
     // Check input arguments
@@ -259,21 +504,21 @@
     }
 
     // Clear GLFW window state
-    _glfwWin.Active            = GL_TRUE;
-    _glfwWin.Iconified         = GL_FALSE;
-    _glfwWin.MouseLock         = GL_FALSE;
-    _glfwWin.AutoPollEvents    = GL_TRUE;
+    _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;
+    _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 )
@@ -294,52 +539,79 @@
     }
 
     // Remember window settings
-    _glfwWin.Width          = width;
-    _glfwWin.Height         = height;
-    _glfwWin.Fullscreen     = (mode == GLFW_FULLSCREEN ? 1 : 0);
+    _glfwWin.width      = width;
+    _glfwWin.height     = height;
+    _glfwWin.fullscreen = (mode == GLFW_FULLSCREEN ? GL_TRUE : GL_FALSE);
 
     // Platform specific window opening routine
-    if( !_glfwPlatformOpenWindow( width, height, redbits, greenbits,
-            bluebits, alphabits, depthbits, stencilbits, mode, &hints ) )
+    if( !_glfwPlatformOpenWindow( width, height, &wndconfig, &fbconfig ) )
     {
+        glfwCloseWindow();
         return GL_FALSE;
     }
 
     // Flag that window is now opened
-    _glfwWin.Opened = GL_TRUE;
+    _glfwWin.opened = GL_TRUE;
 
-    // Get window parameters (such as color buffer bits etc)
+    // Read back window and context parameters
     _glfwPlatformRefreshWindowParams();
+    _glfwRefreshContextParams();
 
-    // Get OpenGL version
-    glfwGetGLVersion( &_glfwWin.GLVerMajor, &_glfwWin.GLVerMinor, &x );
+    if( _glfwWin.glMajor < wndconfig.glMajor ||
+        ( _glfwWin.glMajor == wndconfig.glMajor &&
+          _glfwWin.glMinor < wndconfig.glMinor ) )
+    {
+        glfwCloseWindow();
+        return GL_FALSE;
+    }
 
-    // Do we have non-power-of-two textures?
-    _glfwWin.Has_GL_ARB_texture_non_power_of_two =
+    // Do we have non-power-of-two textures (added to core in version 2.0)?
+    _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.GLVerMajor >= 2) || (_glfwWin.GLVerMinor >= 4) ||
+    // Do we have automatic mipmap generation (added to core in version 1.4)?
+    _glfwWin.has_GL_SGIS_generate_mipmap =
+        ( _glfwWin.glMajor >= 2 ) || ( _glfwWin.glMinor >= 4 ) ||
         glfwExtensionSupported( "GL_SGIS_generate_mipmap" );
 
+    if( _glfwWin.glMajor > 2 )
+    {
+        _glfwWin.GetStringi = (PFNGLGETSTRINGIPROC) glfwGetProcAddress( "glGetStringi" );
+        if( !_glfwWin.GetStringi )
+        {
+            // This is a very common problem among people who compile GLFW
+            // on X11/GLX using custom build systems, as it needs explicit
+            // configuration in order to work
+            //
+            // See readme.html section 2.2 for details
+
+            glfwCloseWindow();
+            return GL_FALSE;
+        }
+    }
+
     // If full-screen mode was requested, disable mouse cursor
     if( mode == GLFW_FULLSCREEN )
     {
         glfwDisable( GLFW_MOUSE_CURSOR );
     }
 
+    // Start by clearing the front buffer to black (avoid ugly desktop
+    // remains in our OpenGL window)
+    glClear( GL_COLOR_BUFFER_BIT );
+    _glfwPlatformSwapBuffers();
+
     return GL_TRUE;
 }
 
 
 //========================================================================
-// glfwOpenWindowHint() - Set hints for opening the window
+// Set hints for opening the window
 //========================================================================
 
 GLFWAPI void GLFWAPIENTRY glfwOpenWindowHint( int target, int hint )
 {
-    // Is GLFW initialized?
     if( !_glfwInitialized )
     {
         return;
@@ -348,32 +620,47 @@
     switch( target )
     {
         case GLFW_REFRESH_RATE:
-            _glfwWinHints.RefreshRate = hint;
+            _glfwLibrary.hints.refreshRate = hint;
             break;
         case GLFW_ACCUM_RED_BITS:
-            _glfwWinHints.AccumRedBits = hint;
+            _glfwLibrary.hints.accumRedBits = hint;
             break;
         case GLFW_ACCUM_GREEN_BITS:
-            _glfwWinHints.AccumGreenBits = hint;
+            _glfwLibrary.hints.accumGreenBits = hint;
             break;
         case GLFW_ACCUM_BLUE_BITS:
-            _glfwWinHints.AccumBlueBits = hint;
+            _glfwLibrary.hints.accumBlueBits = hint;
             break;
         case GLFW_ACCUM_ALPHA_BITS:
-            _glfwWinHints.AccumAlphaBits = hint;
+            _glfwLibrary.hints.accumAlphaBits = hint;
             break;
         case GLFW_AUX_BUFFERS:
-            _glfwWinHints.AuxBuffers = hint;
+            _glfwLibrary.hints.auxBuffers = hint;
             break;
         case GLFW_STEREO:
-            _glfwWinHints.Stereo = hint;
+            _glfwLibrary.hints.stereo = hint;
             break;
         case GLFW_WINDOW_NO_RESIZE:
-            _glfwWinHints.WindowNoResize = hint;
+            _glfwLibrary.hints.windowNoResize = hint;
             break;
-	case GLFW_FSAA_SAMPLES:
-            _glfwWinHints.Samples = hint;
+        case GLFW_FSAA_SAMPLES:
+            _glfwLibrary.hints.samples = hint;
             break;
+        case GLFW_OPENGL_VERSION_MAJOR:
+            _glfwLibrary.hints.glMajor = hint;
+            break;
+        case GLFW_OPENGL_VERSION_MINOR:
+            _glfwLibrary.hints.glMinor = hint;
+            break;
+        case GLFW_OPENGL_FORWARD_COMPAT:
+            _glfwLibrary.hints.glForward = hint;
+            break;
+        case GLFW_OPENGL_DEBUG_CONTEXT:
+            _glfwLibrary.hints.glDebug = hint;
+            break;
+        case GLFW_OPENGL_PROFILE:
+            _glfwLibrary.hints.glProfile = hint;
+            break;
         default:
             break;
     }
@@ -381,12 +668,11 @@
 
 
 //========================================================================
-// glfwCloseWindow() - Properly kill the window / video display
+// Properly kill the window / video display
 //========================================================================
 
 GLFWAPI void GLFWAPIENTRY glfwCloseWindow( void )
 {
-    // Is GLFW initialized?
     if( !_glfwInitialized )
     {
         return;
@@ -395,22 +681,19 @@
     // Show mouse pointer again (if hidden)
     glfwEnable( GLFW_MOUSE_CURSOR );
 
-    // Close window
     _glfwPlatformCloseWindow();
 
-    // Window is no longer opened
-    _glfwWin.Opened = GL_FALSE;
+    memset( &_glfwWin, 0, sizeof(_glfwWin) );
 }
 
 
 //========================================================================
-// glfwSetWindowTitle() - Set the window title
+// Set the window title
 //========================================================================
 
 GLFWAPI void GLFWAPIENTRY glfwSetWindowTitle( const char *title )
 {
-    // Is GLFW initialized?
-    if( !_glfwInitialized || !_glfwWin.Opened )
+    if( !_glfwInitialized || !_glfwWin.opened )
     {
         return;
     }
@@ -421,36 +704,40 @@
 
 
 //========================================================================
-// glfwGetWindowSize() - Get the window size
+// Get the window size
 //========================================================================
 
 GLFWAPI void GLFWAPIENTRY glfwGetWindowSize( int *width, int *height )
 {
+    if( !_glfwInitialized || !_glfwWin.opened )
+    {
+        return;
+    }
+
     if( width != NULL )
     {
-        *width = _glfwWin.Width;
+        *width = _glfwWin.width;
     }
     if( height != NULL )
     {
-        *height = _glfwWin.Height;
+        *height = _glfwWin.height;
     }
 }
 
 
 //========================================================================
-// glfwSetWindowSize() - Set the window size
+// Set the window size
 //========================================================================
 
 GLFWAPI void GLFWAPIENTRY glfwSetWindowSize( int width, int height )
 {
-    // Is GLFW initialized?
-    if( !_glfwInitialized || !_glfwWin.Opened || _glfwWin.Iconified )
+    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 )
+    if( width == _glfwWin.width && height == _glfwWin.height )
     {
         return;
     }
@@ -465,14 +752,13 @@
 
 
 //========================================================================
-// glfwSetWindowPos() - Set the window position
+// Set the window position
 //========================================================================
 
 GLFWAPI void GLFWAPIENTRY glfwSetWindowPos( int x, int y )
 {
-    // Is GLFW initialized?
-    if( !_glfwInitialized || !_glfwWin.Opened || _glfwWin.Fullscreen ||
-        _glfwWin.Iconified )
+    if( !_glfwInitialized || !_glfwWin.opened || _glfwWin.fullscreen ||
+        _glfwWin.iconified )
     {
         return;
     }
@@ -483,13 +769,12 @@
 
 
 //========================================================================
-// glfwIconfyWindow() - Window iconification
+// Window iconification
 //========================================================================
 
 GLFWAPI void GLFWAPIENTRY glfwIconifyWindow( void )
 {
-    // Is GLFW initialized?
-    if( !_glfwInitialized || !_glfwWin.Opened || _glfwWin.Iconified )
+    if( !_glfwInitialized || !_glfwWin.opened || _glfwWin.iconified )
     {
         return;
     }
@@ -500,13 +785,12 @@
 
 
 //========================================================================
-// glfwRestoreWindow() - Window un-iconification
+// Window un-iconification
 //========================================================================
 
 GLFWAPI void GLFWAPIENTRY glfwRestoreWindow( void )
 {
-    // Is GLFW initialized?
-    if( !_glfwInitialized || !_glfwWin.Opened || !_glfwWin.Iconified )
+    if( !_glfwInitialized || !_glfwWin.opened || !_glfwWin.iconified )
     {
         return;
     }
@@ -520,40 +804,33 @@
 
 
 //========================================================================
-// glfwSwapBuffers() - Swap buffers (double-buffering) and poll any new
-// events
+// Swap buffers (double-buffering) and poll any new events
 //========================================================================
 
 GLFWAPI void GLFWAPIENTRY glfwSwapBuffers( void )
 {
-    // Is GLFW initialized?
-    if( !_glfwInitialized || !_glfwWin.Opened )
+    if( !_glfwInitialized || !_glfwWin.opened )
     {
         return;
     }
 
+    _glfwPlatformSwapBuffers();
+
     // Check for window messages
-    if( _glfwWin.AutoPollEvents )
+    if( _glfwWin.autoPollEvents )
     {
         glfwPollEvents();
     }
-
-    // Update display-buffer
-    if( _glfwWin.Opened )
-    {
-        _glfwPlatformSwapBuffers();
-    }
 }
 
 
 //========================================================================
-// glfwSwapInterval() - Set double buffering swap interval (0 = vsync off)
+// Set double buffering swap interval (0 = vsync off)
 //========================================================================
 
 GLFWAPI void GLFWAPIENTRY glfwSwapInterval( int interval )
 {
-    // Is GLFW initialized?
-    if( !_glfwInitialized || !_glfwWin.Opened )
+    if( !_glfwInitialized || !_glfwWin.opened )
     {
         return;
     }
@@ -564,19 +841,18 @@
 
 
 //========================================================================
-// glfwGetWindowParam() - Get window parameter
+// Get window parameter
 //========================================================================
 
 GLFWAPI int GLFWAPIENTRY glfwGetWindowParam( int param )
 {
-    // Is GLFW initialized?
     if( !_glfwInitialized )
     {
         return 0;
     }
 
     // Is the window opened?
-    if( !_glfwWin.Opened )
+    if( !_glfwWin.opened )
     {
         if( param == GLFW_OPENED )
         {
@@ -591,41 +867,51 @@
         case GLFW_OPENED:
             return GL_TRUE;
         case GLFW_ACTIVE:
-            return _glfwWin.Active;
+            return _glfwWin.active;
         case GLFW_ICONIFIED:
-            return _glfwWin.Iconified;
+            return _glfwWin.iconified;
         case GLFW_ACCELERATED:
-            return _glfwWin.Accelerated;
+            return _glfwWin.accelerated;
         case GLFW_RED_BITS:
-            return _glfwWin.RedBits;
+            return _glfwWin.redBits;
         case GLFW_GREEN_BITS:
-            return _glfwWin.GreenBits;
+            return _glfwWin.greenBits;
         case GLFW_BLUE_BITS:
-            return _glfwWin.BlueBits;
+            return _glfwWin.blueBits;
         case GLFW_ALPHA_BITS:
-            return _glfwWin.AlphaBits;
+            return _glfwWin.alphaBits;
         case GLFW_DEPTH_BITS:
-            return _glfwWin.DepthBits;
+            return _glfwWin.depthBits;
         case GLFW_STENCIL_BITS:
-            return _glfwWin.StencilBits;
+            return _glfwWin.stencilBits;
         case GLFW_ACCUM_RED_BITS:
-            return _glfwWin.AccumRedBits;
+            return _glfwWin.accumRedBits;
         case GLFW_ACCUM_GREEN_BITS:
-            return _glfwWin.AccumGreenBits;
+            return _glfwWin.accumGreenBits;
         case GLFW_ACCUM_BLUE_BITS:
-            return _glfwWin.AccumBlueBits;
+            return _glfwWin.accumBlueBits;
         case GLFW_ACCUM_ALPHA_BITS:
-            return _glfwWin.AccumAlphaBits;
+            return _glfwWin.accumAlphaBits;
         case GLFW_AUX_BUFFERS:
-            return _glfwWin.AuxBuffers;
+            return _glfwWin.auxBuffers;
         case GLFW_STEREO:
-            return _glfwWin.Stereo;
+            return _glfwWin.stereo;
         case GLFW_REFRESH_RATE:
-            return _glfwWin.RefreshRate;
+            return _glfwWin.refreshRate;
         case GLFW_WINDOW_NO_RESIZE:
-            return _glfwWin.WindowNoResize;
-	case GLFW_FSAA_SAMPLES:
-	    return _glfwWin.Samples;
+            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;
     }
@@ -633,73 +919,66 @@
 
 
 //========================================================================
-// glfwSetWindowSizeCallback() - Set callback function for window size
-// changes
+// Set callback function for window size changes
 //========================================================================
 
 GLFWAPI void GLFWAPIENTRY glfwSetWindowSizeCallback( GLFWwindowsizefun cbfun )
 {
-    // Is GLFW initialized?
-    if( !_glfwInitialized || !_glfwWin.Opened )
+    if( !_glfwInitialized || !_glfwWin.opened )
     {
         return;
     }
 
     // Set callback function
-    _glfwWin.WindowSizeCallback = cbfun;
+    _glfwWin.windowSizeCallback = cbfun;
 
     // Call the callback function to let the application know the current
     // window size
     if( cbfun )
     {
-        cbfun( _glfwWin.Width, _glfwWin.Height );
+        cbfun( _glfwWin.width, _glfwWin.height );
     }
 }
 
 //========================================================================
-// glfwSetWindowCloseCallback() - Set callback function for window close
-// events
+// Set callback function for window close events
 //========================================================================
 
 GLFWAPI void GLFWAPIENTRY glfwSetWindowCloseCallback( GLFWwindowclosefun cbfun )
 {
-    // Is GLFW initialized?
-    if( !_glfwInitialized || !_glfwWin.Opened )
+    if( !_glfwInitialized || !_glfwWin.opened )
     {
         return;
     }
 
     // Set callback function
-    _glfwWin.WindowCloseCallback = cbfun;
+    _glfwWin.windowCloseCallback = cbfun;
 }
 
 
 //========================================================================
-// glfwSetWindowRefreshCallback() - Set callback function for window
-// refresh events
+// Set callback function for window refresh events
 //========================================================================
 
 GLFWAPI void GLFWAPIENTRY glfwSetWindowRefreshCallback( GLFWwindowrefreshfun cbfun )
 {
-    // Is GLFW initialized?
-    if( !_glfwInitialized || !_glfwWin.Opened )
+    if( !_glfwInitialized || !_glfwWin.opened )
     {
         return;
     }
 
     // Set callback function
-    _glfwWin.WindowRefreshCallback = cbfun;
+    _glfwWin.windowRefreshCallback = cbfun;
 }
 
 
 //========================================================================
-// glfwPollEvents() - Poll for new window and input events
+// Poll for new window and input events
 //========================================================================
 
 GLFWAPI void GLFWAPIENTRY glfwPollEvents( void )
 {
-    // Is GLFW initialized?
-    if( !_glfwInitialized || !_glfwWin.Opened )
+    if( !_glfwInitialized || !_glfwWin.opened )
     {
         return;
     }
@@ -710,13 +989,12 @@
 
 
 //========================================================================
-// glfwWaitEvents() - Wait for new window and input events
+// Wait for new window and input events
 //========================================================================
 
 GLFWAPI void GLFWAPIENTRY glfwWaitEvents( void )
 {
-    // Is GLFW initialized?
-    if( !_glfwInitialized || !_glfwWin.Opened )
+    if( !_glfwInitialized || !_glfwWin.opened )
     {
         return;
     }
diff --git a/glfw/lib/x11/platform.h b/glfw/lib/x11/platform.h
--- a/glfw/lib/x11/platform.h
+++ b/glfw/lib/x11/platform.h
@@ -1,11 +1,11 @@
 //========================================================================
 // GLFW - An OpenGL framework
-// File:        platform.h
-// Platform:    X11 (Unix)
-// API version: 2.6
-// WWW:         http://glfw.sourceforge.net
+// Platform:    X11/GLX
+// API version: 2.7
+// WWW:         http://www.glfw.org/
 //------------------------------------------------------------------------
-// Copyright (c) 2002-2006 Camilla Berglund
+// Copyright (c) 2002-2006 Marcus Geelnard
+// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org>
 //
 // This software is provided 'as-is', without any express or implied
 // warranty. In no event will the authors be held liable for any damages
@@ -52,6 +52,16 @@
  #include <sched.h>
 #endif
 
+// We need declarations for GLX version 1.3 or above even if the server doesn't
+// support version 1.3
+#ifndef GLX_VERSION_1_3
+ #error "GLX header version 1.3 or above is required"
+#endif
+
+#if defined( _GLFW_HAS_XF86VIDMODE ) && defined( _GLFW_HAS_XRANDR )
+ #error "Xf86VidMode and RandR extensions cannot both be enabled"
+#endif
+
 // With XFree86, we can use the XF86VidMode extension
 #if defined( _GLFW_HAS_XF86VIDMODE )
  #include <X11/extensions/xf86vmode.h>
@@ -113,30 +123,84 @@
 
 #endif
 
-void (*glXGetProcAddress(const GLubyte *procName))();
-void (*glXGetProcAddressARB(const GLubyte *procName))();
-void (*glXGetProcAddressEXT(const GLubyte *procName))();
+// Pointer length integer
+// One day, this will most likely move into glfw.h
+typedef intptr_t GLFWintptr;
 
-// We support four different ways for getting addresses for GL/GLX
-// extension functions: glXGetProcAddress, glXGetProcAddressARB,
-// glXGetProcAddressEXT, and dlsym
-#if   defined( _GLFW_HAS_GLXGETPROCADDRESSARB )
- #define _glfw_glXGetProcAddress(x) glXGetProcAddressARB(x)
-#elif defined( _GLFW_HAS_GLXGETPROCADDRESS )
- #define _glfw_glXGetProcAddress(x) glXGetProcAddress(x)
-#elif defined( _GLFW_HAS_GLXGETPROCADDRESSEXT )
- #define _glfw_glXGetProcAddress(x) glXGetProcAddressEXT(x)
-#elif defined( _GLFW_HAS_DLOPEN )
- #define _glfw_glXGetProcAddress(x) dlsym(_glfwLibs.libGL,x)
- #define _GLFW_DLOPEN_LIBGL
-#else
-#define _glfw_glXGetProcAddress(x) NULL
-#endif
 
-// glXSwapIntervalSGI typedef (X11 buffer-swap interval control)
-typedef int ( * GLXSWAPINTERVALSGI_T) (int interval);
+#ifndef GLX_SGI_swap_control
 
+// Function signature for GLX_SGI_swap_control
+typedef int ( * PFNGLXSWAPINTERVALSGIPROC) (int interval);
 
+#endif /*GLX_SGI_swap_control*/
+
+
+#ifndef GLX_SGIX_fbconfig
+
+/* Type definitions for GLX_SGIX_fbconfig */
+typedef XID GLXFBConfigIDSGIX;
+typedef struct __GLXFBConfigRec *GLXFBConfigSGIX;
+
+/* Function signatures for GLX_SGIX_fbconfig */
+typedef int ( * PFNGLXGETFBCONFIGATTRIBSGIXPROC) (Display *dpy, GLXFBConfigSGIX config, int attribute, int *value);
+typedef GLXFBConfigSGIX * ( * PFNGLXCHOOSEFBCONFIGSGIXPROC) (Display *dpy, int screen, int *attrib_list, int *nelements);
+typedef GLXContext ( * PFNGLXCREATECONTEXTWITHCONFIGSGIXPROC) (Display *dpy, GLXFBConfigSGIX config, int render_type, GLXContext share_list, Bool direct);
+typedef XVisualInfo * ( * PFNGLXGETVISUALFROMFBCONFIGSGIXPROC) (Display *dpy, GLXFBConfigSGIX config);
+
+/* Tokens for GLX_SGIX_fbconfig */
+#define GLX_WINDOW_BIT_SGIX                0x00000001
+#define GLX_PIXMAP_BIT_SGIX                0x00000002
+#define GLX_RGBA_BIT_SGIX                  0x00000001
+#define GLX_COLOR_INDEX_BIT_SGIX           0x00000002
+#define GLX_DRAWABLE_TYPE_SGIX             0x8010
+#define GLX_RENDER_TYPE_SGIX               0x8011
+#define GLX_X_RENDERABLE_SGIX              0x8012
+#define GLX_FBCONFIG_ID_SGIX               0x8013
+#define GLX_RGBA_TYPE_SGIX                 0x8014
+#define GLX_COLOR_INDEX_TYPE_SGIX          0x8015
+#define GLX_SCREEN_EXT                     0x800C
+
+#endif /*GLX_SGIX_fbconfig*/
+
+
+#ifndef GLX_ARB_create_context
+
+/* Tokens for glXCreateContextAttribsARB attributes */
+#define GLX_CONTEXT_MAJOR_VERSION_ARB           0x2091
+#define GLX_CONTEXT_MINOR_VERSION_ARB           0x2092
+#define GLX_CONTEXT_FLAGS_ARB                   0x2094
+
+/* Bits for WGL_CONTEXT_FLAGS_ARB */
+#define GLX_CONTEXT_DEBUG_BIT_ARB               0x0001
+#define GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB  0x0002
+
+/* Prototype for glXCreateContextAttribs */
+typedef GLXContext (*PFNGLXCREATECONTEXTATTRIBSARBPROC)( Display *display, GLXFBConfig config, GLXContext share_context, Bool direct, const int *attrib_list);
+
+#endif /*GLX_ARB_create_context*/
+
+
+#ifndef GLX_ARB_create_context_profile
+
+/* Tokens for glXCreateContextAttribsARB attributes */
+#define GLX_CONTEXT_PROFILE_MASK_ARB            0x9126
+
+/* BIts for GLX_CONTEXT_PROFILE_MASK_ARB */
+#define GLX_CONTEXT_CORE_PROFILE_BIT_ARB        0x00000001
+#define GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002
+
+#endif /*GLX_ARB_create_context_profile*/
+
+
+#ifndef GL_VERSION_3_0
+
+typedef const GLubyte * (APIENTRY *PFNGLGETSTRINGIPROC) (GLenum, GLuint);
+
+#endif /*GL_VERSION_3_0*/
+
+
+
 //========================================================================
 // Global variables (GLFW internals)
 //========================================================================
@@ -151,91 +215,111 @@
 // ========= PLATFORM INDEPENDENT MANDATORY PART =========================
 
     // User callback functions
-    GLFWwindowsizefun    WindowSizeCallback;
-    GLFWwindowclosefun   WindowCloseCallback;
-    GLFWwindowrefreshfun WindowRefreshCallback;
-    GLFWmousebuttonfun   MouseButtonCallback;
-    GLFWmouseposfun      MousePosCallback;
-    GLFWmousewheelfun    MouseWheelCallback;
-    GLFWkeyfun           KeyCallback;
-    GLFWcharfun          CharCallback;
+    GLFWwindowsizefun    windowSizeCallback;
+    GLFWwindowclosefun   windowCloseCallback;
+    GLFWwindowrefreshfun windowRefreshCallback;
+    GLFWmousebuttonfun   mouseButtonCallback;
+    GLFWmouseposfun      mousePosCallback;
+    GLFWmousewheelfun    mouseWheelCallback;
+    GLFWkeyfun           keyCallback;
+    GLFWcharfun          charCallback;
 
     // User selected window settings
-    int       Fullscreen;      // Fullscreen flag
-    int       MouseLock;       // Mouse-lock flag
-    int       AutoPollEvents;  // Auto polling flag
-    int       SysKeysDisabled; // System keys disabled flag
-    int       WindowNoResize;  // Resize- and maximize gadgets disabled flag
+    int       fullscreen;      // Fullscreen flag
+    int       mouseLock;       // Mouse-lock flag
+    int       autoPollEvents;  // Auto polling flag
+    int       sysKeysDisabled; // System keys disabled flag
+    int       windowNoResize;  // Resize- and maximize gadgets disabled flag
+    int       refreshRate;     // Vertical monitor refresh rate
 
     // Window status & parameters
-    int       Opened;          // Flag telling if window is opened or not
-    int       Active;          // Application active flag
-    int       Iconified;       // Window iconified flag
-    int       Width, Height;   // Window width and heigth
-    int       Accelerated;     // GL_TRUE if window is HW accelerated
-    int       RedBits;
-    int       GreenBits;
-    int       BlueBits;
-    int       AlphaBits;
-    int       DepthBits;
-    int       StencilBits;
-    int       AccumRedBits;
-    int       AccumGreenBits;
-    int       AccumBlueBits;
-    int       AccumAlphaBits;
-    int       AuxBuffers;
-    int       Stereo;
-    int       RefreshRate;     // Vertical monitor refresh rate
-    int       Samples;
+    int       opened;          // Flag telling if window is opened or not
+    int       active;          // Application active flag
+    int       iconified;       // Window iconified flag
+    int       width, height;   // Window width and heigth
+    int       accelerated;     // GL_TRUE if window is HW accelerated
 
-    // Extensions & OpenGL version
-    int       Has_GL_SGIS_generate_mipmap;
-    int       Has_GL_ARB_texture_non_power_of_two;
-    int       GLVerMajor,GLVerMinor;
+    // Framebuffer attributes
+    int       redBits;
+    int       greenBits;
+    int       blueBits;
+    int       alphaBits;
+    int       depthBits;
+    int       stencilBits;
+    int       accumRedBits;
+    int       accumGreenBits;
+    int       accumBlueBits;
+    int       accumAlphaBits;
+    int       auxBuffers;
+    int       stereo;
+    int       samples;
 
+    // OpenGL extensions and context attributes
+    int       has_GL_SGIS_generate_mipmap;
+    int       has_GL_ARB_texture_non_power_of_two;
+    int       glMajor, glMinor, glRevision;
+    int       glForward, glDebug, glProfile;
 
+    PFNGLGETSTRINGIPROC GetStringi;
+
+
 // ========= PLATFORM SPECIFIC PART ======================================
 
     // Platform specific window resources
-    Window      Win;             // Window
-    int         Scrn;            // Screen ID
-    XVisualInfo *VI;             // Visual
-    GLXContext  CX;              // OpenGL rendering context
-    Atom        WMDeleteWindow;  // For WM close detection
-    Atom        WMPing;          // For WM ping response
-    XSizeHints  *Hints;          // WM size hints
+    Colormap      colormap;          // Window colormap
+    Window        window;            // Window
+    Window        root;              // Root window for screen
+    int           screen;            // Screen ID
+    XVisualInfo  *visual;            // Visual for selected GLXFBConfig
+    GLXFBConfigID fbconfigID;        // ID of selected GLXFBConfig
+    GLXContext    context;           // OpenGL rendering context
+    Atom          wmDeleteWindow;    // WM_DELETE_WINDOW atom
+    Atom          wmPing;            // _NET_WM_PING atom
+    Atom          wmState;           // _NET_WM_STATE atom
+    Atom          wmStateFullscreen; // _NET_WM_STATE_FULLSCREEN atom
+    Atom          wmActiveWindow;    // _NET_ACTIVE_WINDOW atom
+    Cursor        cursor;            // Invisible cursor for hidden cursor
 
-    // Platform specific extensions
-    GLXSWAPINTERVALSGI_T SwapInterval;
+    // GLX extensions
+    PFNGLXSWAPINTERVALSGIPROC             SwapIntervalSGI;
+    PFNGLXGETFBCONFIGATTRIBSGIXPROC       GetFBConfigAttribSGIX;
+    PFNGLXCHOOSEFBCONFIGSGIXPROC          ChooseFBConfigSGIX;
+    PFNGLXCREATECONTEXTWITHCONFIGSGIXPROC CreateContextWithConfigSGIX;
+    PFNGLXGETVISUALFROMFBCONFIGSGIXPROC   GetVisualFromFBConfigSGIX;
+    PFNGLXCREATECONTEXTATTRIBSARBPROC     CreateContextAttribsARB;
+    GLboolean   has_GLX_SGIX_fbconfig;
+    GLboolean   has_GLX_SGI_swap_control;
+    GLboolean   has_GLX_ARB_multisample;
+    GLboolean   has_GLX_ARB_create_context;
+    GLboolean   has_GLX_ARB_create_context_profile;
 
     // Various platform specific internal variables
-    int         OverrideRedirect; // True if window is OverrideRedirect
-    int         KeyboardGrabbed; // True if keyboard is currently grabbed
-    int         PointerGrabbed;  // True if pointer is currently grabbed
-    int         PointerHidden;   // True if pointer is currently hidden
-    int         MapNotifyCount;  // Used for during processing
-    int         FocusInCount;    // Used for during processing
+    GLboolean   hasEWMH;          // True if window manager supports EWMH
+    GLboolean   overrideRedirect; // True if window is OverrideRedirect
+    GLboolean   keyboardGrabbed;  // True if keyboard is currently grabbed
+    GLboolean   pointerGrabbed;   // True if pointer is currently grabbed
+    GLboolean   pointerHidden;    // True if pointer is currently hidden
 
     // Screensaver data
     struct {
-	int     Changed;
-	int     Timeout;
-	int     Interval;
-	int     Blanking;
-	int     Exposure;
+        int     changed;
+        int     timeout;
+        int     interval;
+        int     blanking;
+        int     exposure;
     } Saver;
 
     // Fullscreen data
     struct {
-	int     ModeChanged;
+        int     modeChanged;
 #if defined( _GLFW_HAS_XF86VIDMODE )
-	XF86VidModeModeInfo OldMode;
+        XF86VidModeModeInfo oldMode;
 #endif
 #if defined( _GLFW_HAS_XRANDR )
-        SizeID   OldSizeID;
-	int      OldWidth;
-	int      OldHeight;
-	Rotation OldRotation;
+        SizeID   oldSizeID;
+        int      oldWidth;
+        int      oldHeight;
+        Rotation oldRotation;
 #endif
     } FS;
 };
@@ -278,33 +362,39 @@
 //------------------------------------------------------------------------
 GLFWGLOBAL struct {
 
+// ========= PLATFORM INDEPENDENT MANDATORY PART =========================
+
+    // Window opening hints
+    _GLFWhints      hints;
+
 // ========= PLATFORM SPECIFIC PART ======================================
 
-    Display     *Dpy;
-    int         NumScreens;
-    int         DefaultScreen;
+    Display        *display;
 
+    // Server-side GLX version
+    int             glxMajor, glxMinor;
+
     struct {
-	int	Available;
-	int     EventBase;
-	int     ErrorBase;
+        int         available;
+        int         eventBase;
+        int         errorBase;
     } XF86VidMode;
 
     struct {
-	int	Available;
-	int     EventBase;
-	int     ErrorBase;
+        int         available;
+        int         eventBase;
+        int         errorBase;
     } XRandR;
 
     // Timer data
     struct {
-	double       Resolution;
-	long long    t0;
+        double      resolution;
+        long long   t0;
     } Timer;
 
-#if defined(_GLFW_DLOPEN_LIBGL)
+#if defined(_GLFW_HAS_DLOPEN)
     struct {
-	void        *libGL;          // dlopen handle for libGL.so
+        void       *libGL;  // dlopen handle for libGL.so
     } Libs;
 #endif
 } _glfwLibrary;
@@ -400,9 +490,7 @@
 int  _glfwGetClosestVideoMode( int screen, int *width, int *height, int *rate );
 void _glfwSetVideoModeMODE( int screen, int mode, int rate );
 void _glfwSetVideoMode( int screen, int *width, int *height, int *rate );
-
-// Cursor handling
-Cursor _glfwCreateNULLCursor( Display *display, Window root );
+void _glfwRestoreVideoMode( void );
 
 // Joystick input
 void _glfwInitJoysticks( void );
diff --git a/glfw/lib/x11/x11_enable.c b/glfw/lib/x11/x11_enable.c
--- a/glfw/lib/x11/x11_enable.c
+++ b/glfw/lib/x11/x11_enable.c
@@ -1,11 +1,11 @@
 //========================================================================
 // GLFW - An OpenGL framework
-// File:        x11_enable.c
 // Platform:    X11 (Unix)
-// API version: 2.6
-// WWW:         http://glfw.sourceforge.net
+// API version: 2.7
+// WWW:         http://www.glfw.org/
 //------------------------------------------------------------------------
-// Copyright (c) 2002-2006 Camilla Berglund
+// Copyright (c) 2002-2006 Marcus Geelnard
+// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org>
 //
 // This software is provided 'as-is', without any express or implied
 // warranty. In no event will the authors be held liable for any damages
@@ -36,16 +36,29 @@
 //************************************************************************
 
 //========================================================================
-// _glfwPlatformEnableSystemKeys() - Enable system keys
-// _glfwPlatformDisableSystemKeys() - Disable system keys
+// Enable system keys
 //========================================================================
 
 void _glfwPlatformEnableSystemKeys( void )
 {
-    // Not supported under X11 (yet)
+    if( _glfwWin.keyboardGrabbed )
+    {
+        XUngrabKeyboard( _glfwLibrary.display, CurrentTime );
+        _glfwWin.keyboardGrabbed = GL_FALSE;
+    }
 }
 
+//========================================================================
+// Disable system keys
+//========================================================================
+
 void _glfwPlatformDisableSystemKeys( void )
 {
-    // Not supported under X11 (yet)
+    if( XGrabKeyboard( _glfwLibrary.display, _glfwWin.window, True,
+                        GrabModeAsync, GrabModeAsync, CurrentTime ) ==
+        GrabSuccess )
+    {
+        _glfwWin.keyboardGrabbed = GL_TRUE;
+    }
 }
+
diff --git a/glfw/lib/x11/x11_fullscreen.c b/glfw/lib/x11/x11_fullscreen.c
--- a/glfw/lib/x11/x11_fullscreen.c
+++ b/glfw/lib/x11/x11_fullscreen.c
@@ -1,11 +1,11 @@
 //========================================================================
 // GLFW - An OpenGL framework
-// File:        x11_fullscreen.c
-// Platform:    X11 (Unix)
-// API version: 2.6
-// WWW:         http://glfw.sourceforge.net
+// Platform:    X11/GLX
+// API version: 2.7
+// WWW:         http://www.glfw.org/
 //------------------------------------------------------------------------
-// Copyright (c) 2002-2006 Camilla Berglund
+// Copyright (c) 2002-2006 Marcus Geelnard
+// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org>
 //
 // This software is provided 'as-is', without any express or implied
 // warranty. In no event will the authors be held liable for any damages
@@ -30,22 +30,24 @@
 
 #include "internal.h"
 
+#include <limits.h>
 
+
 //************************************************************************
 //****                  GLFW internal functions                       ****
 //************************************************************************
 
 //========================================================================
-// _glfwBPP2RGB() - Convert BPP to RGB bits (based on "best guess")
+// Convert BPP to RGB bits (based on "best guess")
 //========================================================================
 
-static void _glfwBPP2RGB( int bpp, int *r, int *g, int *b )
+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;
+        bpp = 24;
 
     // Convert "bits per pixel" to red, green & blue sizes
     *r = *g = *b = bpp / 3;
@@ -75,16 +77,16 @@
     XRRScreenConfiguration *sc;
     XRRScreenSize *sizelist;
 
-    if( _glfwLibrary.XRandR.Available )
+    if( _glfwLibrary.XRandR.available )
     {
-	sc = XRRGetScreenInfo( _glfwLibrary.Dpy,
-			       RootWindow( _glfwLibrary.Dpy, screen ) );
+        sc = XRRGetScreenInfo( _glfwLibrary.display,
+                               RootWindow( _glfwLibrary.display, screen ) );
 
-	sizelist = XRRConfigSizes( sc, &sizecount );
+        sizelist = XRRConfigSizes( sc, &sizecount );
 
         // Find the best matching mode
         bestsize  = -1;
-        bestmatch = 999999;
+        bestmatch = INT_MAX;
         for( i = 0; i < sizecount; i++ )
         {
             match = (*width - sizelist[i].width) *
@@ -98,57 +100,57 @@
             }
         }
 
-	if( bestsize != -1 )
-	{
-	    // Report width & height of best matching mode
-	    *width = sizelist[bestsize].width;
-	    *height = sizelist[bestsize].height;
+        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 );
+            if( *rate > 0 )
+            {
+                ratelist = XRRConfigRates( sc, bestsize, &ratecount );
 
-		bestrate = -1;
-		bestmatch = 999999;
-		for( i = 0; i < ratecount; i++ )
-		{
-		    match = abs( ratelist[i] - *rate );
-		    if( match < bestmatch )
-		    {
-			bestmatch = match;
-			bestrate = ratelist[i];
-		    }
-		}
-		
-		if( bestrate != -1 )
-		{
-		    *rate = bestrate;
-		}
-	    }
-	}
+                bestrate = -1;
+                bestmatch = INT_MAX;
+                for( i = 0; i < ratecount; i++ )
+                {
+                    match = abs( ratelist[i] - *rate );
+                    if( match < bestmatch )
+                    {
+                        bestmatch = match;
+                        bestrate = ratelist[i];
+                    }
+                }
 
-        // Free modelist
-	XRRFreeScreenConfigInfo( sc );
+                if( bestrate != -1 )
+                {
+                    *rate = bestrate;
+                }
+            }
+        }
 
-	if( bestsize != -1 )
-	{
-	    return bestsize;
-	}
+            // 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 )
+    if( _glfwLibrary.XF86VidMode.available )
     {
         // Get a list of all available display modes
-        XF86VidModeGetAllModeLines( _glfwLibrary.Dpy, screen,
+        XF86VidModeGetAllModeLines( _glfwLibrary.display, screen,
                                     &modecount, &modelist );
 
         // Find the best matching mode
         bestmode  = -1;
-        bestmatch = 999999;
+        bestmatch = INT_MAX;
         for( i = 0; i < modecount; i++ )
         {
             match = (*width - modelist[i]->hdisplay) *
@@ -162,26 +164,26 @@
             }
         }
 
-	if( bestmode != -1 )
-	{
-	    // Report width & height of best matching mode
-	    *width = modelist[ bestmode ]->hdisplay;
-	    *h = modelist[ bestmode ]->vdisplay;
-	}
+        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;
-	}
+        if( bestmode != -1 )
+        {
+            return bestmode;
+        }
     }
 #endif
 
     // Default: Simply use the screen resolution
-    *width = DisplayWidth( _glfwLibrary.Dpy, screen );
-    *height = DisplayHeight( _glfwLibrary.Dpy, screen );
+    *width = DisplayWidth( _glfwLibrary.display, screen );
+    *height = DisplayHeight( _glfwLibrary.display, screen );
 
     return 0;
 }
@@ -197,77 +199,77 @@
     XRRScreenConfiguration *sc;
     Window root;
 
-    if( _glfwLibrary.XRandR.Available )
+    if( _glfwLibrary.XRandR.available )
     {
-	root = RootWindow( _glfwLibrary.Dpy, screen );
-	sc   = XRRGetScreenInfo( _glfwLibrary.Dpy, root );
+        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 )
+        if( !_glfwWin.FS.modeChanged )
         {
-	    _glfwWin.FS.OldSizeID = XRRConfigCurrentConfiguration( sc, &_glfwWin.FS.OldRotation );
-	    _glfwWin.FS.OldWidth  = DisplayWidth( _glfwLibrary.Dpy, screen );
-	    _glfwWin.FS.OldHeight = DisplayHeight( _glfwLibrary.Dpy, screen );
+            _glfwWin.FS.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;
+            _glfwWin.FS.modeChanged = GL_TRUE;
         }
 
-	if( rate > 0 )
-	{
-	    // Set desired configuration
-	    XRRSetScreenConfigAndRate( _glfwLibrary.Dpy,
-				       sc,
-				       root,
-				       mode,
-				       RR_Rotate_0,
-				       (short) rate,
-				       CurrentTime );
-	}
-	else
-	{
-	    // Set desired configuration
-	    XRRSetScreenConfig( _glfwLibrary.Dpy,
-				sc,
-				root,
-				mode,
-				RR_Rotate_0,
-				CurrentTime );
-	}
+        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 );
+        XRRFreeScreenConfigInfo( sc );
     }
 #elif defined( _GLFW_HAS_XF86VIDMODE )
     XF86VidModeModeInfo **modelist;
     int modecount;
 
     // Use the XF86VidMode extension to control video resolution
-    if( _glfwLibrary.XF86VidMode.Available )
+    if( _glfwLibrary.XF86VidMode.available )
     {
         // Get a list of all available display modes
-        XF86VidModeGetAllModeLines( _glfwLibrary.Dpy, screen,
+        XF86VidModeGetAllModeLines( _glfwLibrary.display, screen,
                                     &modecount, &modelist );
 
         // Unlock mode switch if necessary
-        if( _glfwWin.FS.ModeChanged )
+        if( _glfwWin.FS.modeChanged )
         {
-            XF86VidModeLockModeSwitch( _glfwLibrary.Dpy, screen, 0 );
+            XF86VidModeLockModeSwitch( _glfwLibrary.display, screen, 0 );
         }
 
         // Change the video mode to the desired mode
-        XF86VidModeSwitchToMode(  _glfwLibrary.Dpy, screen,
+        XF86VidModeSwitchToMode(  _glfwLibrary.display, screen,
                                   modelist[ mode ] );
 
         // Set viewport to upper left corner (where our window will be)
-        XF86VidModeSetViewPort( _glfwLibrary.Dpy, screen, 0, 0 );
+        XF86VidModeSetViewPort( _glfwLibrary.display, screen, 0, 0 );
 
         // Lock mode switch
-        XF86VidModeLockModeSwitch( _glfwLibrary.Dpy, screen, 1 );
+        XF86VidModeLockModeSwitch( _glfwLibrary.display, screen, 1 );
 
         // Remember old mode and flag that we have changed the mode
-        if( !_glfwWin.FS.ModeChanged )
+        if( !_glfwWin.FS.modeChanged )
         {
-            _glfwWin.FS.OldMode = *modelist[ 0 ];
-            _glfwWin.FS.ModeChanged = GL_TRUE;
+            _glfwWin.FS.oldMode = *modelist[ 0 ];
+            _glfwWin.FS.modeChanged = GL_TRUE;
         }
 
         // Free mode list
@@ -293,12 +295,54 @@
 }
 
 
+//========================================================================
+// Restore the previously saved (original) video mode
+//========================================================================
 
+void _glfwRestoreVideoMode( void )
+{
+    if( _glfwWin.FS.modeChanged )
+    {
+#if defined( _GLFW_HAS_XRANDR )
+        if( _glfwLibrary.XRandR.available )
+        {
+            XRRScreenConfiguration *sc;
+
+            sc = XRRGetScreenInfo( _glfwLibrary.display, _glfwWin.root );
+
+            XRRSetScreenConfig( _glfwLibrary.display,
+                                sc,
+                                _glfwWin.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;
+    }
+}
+
+
+
 //************************************************************************
 //****               Platform implementation functions                ****
 //************************************************************************
 
-struct _glfwResolution {
+struct _glfwResolution
+{
     int width;
     int height;
 };
@@ -309,31 +353,31 @@
 
 int _glfwPlatformGetVideoModes( GLFWvidmode *list, int maxcount )
 {
-    int     count, k, l, r, g, b, rgba, gl;
-    int     depth, screen;
+    int count, k, l, r, g, b, rgba, gl;
+    int depth, screen;
     Display *dpy;
     XVisualInfo *vislist, dummy;
-    int     viscount, rgbcount, rescount;
-    int     *rgbarray;
+    int viscount, rgbcount, rescount;
+    int *rgbarray;
     struct _glfwResolution *resarray;
 #if defined( _GLFW_HAS_XRANDR )
     XRRScreenConfiguration *sc;
     XRRScreenSize *sizelist;
-    int     sizecount;
+    int sizecount;
 #elif defined( _GLFW_HAS_XF86VIDMODE )
     XF86VidModeModeInfo **modelist;
-    int     modecount, width, height;
+    int modecount, width, height;
 #endif
 
     // Get display and screen
-    dpy = _glfwLibrary.Dpy;
+    dpy = _glfwLibrary.display;
     screen = DefaultScreen( dpy );
 
     // Get list of visuals
     vislist = XGetVisualInfo( dpy, 0, &dummy, &viscount );
     if( vislist == NULL )
     {
-	return 0;
+        return 0;
     }
 
     rgbarray = (int*) malloc( sizeof(int) * viscount );
@@ -351,7 +395,7 @@
             depth = vislist[k].depth;
 
             // Convert to RGB
-            _glfwBPP2RGB( depth, &r, &g, &b );
+            BPP2RGB( depth, &r, &g, &b );
             depth = (r<<16) | (g<<8) | b;
 
             // Is this mode unique?
@@ -375,28 +419,28 @@
 
     // Build resolution array
 #if defined( _GLFW_HAS_XRANDR )
-    if( _glfwLibrary.XRandR.Available )
+    if( _glfwLibrary.XRandR.available )
     {
-	sc = XRRGetScreenInfo( dpy, RootWindow( dpy, screen ) );
-	sizelist = XRRConfigSizes( sc, &sizecount );
+        sc = XRRGetScreenInfo( dpy, RootWindow( dpy, screen ) );
+        sizelist = XRRConfigSizes( sc, &sizecount );
 
-	resarray = (struct _glfwResolution*) malloc( sizeof(struct _glfwResolution) * 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++;
+            resarray[ rescount ].width = sizelist[ k ].width;
+            resarray[ rescount ].height = sizelist[ k ].height;
+            rescount++;
         }
 
-	XRRFreeScreenConfigInfo( sc );
+        XRRFreeScreenConfigInfo( sc );
     }
 #elif defined( _GLFW_HAS_XF86VIDMODE )
-    if( _glfwLibrary.XF86VidMode.Available )
+    if( _glfwLibrary.XF86VidMode.available )
     {
         XF86VidModeGetAllModeLines( dpy, screen, &modecount, &modelist );
 
-	resarray = (struct _glfwResolution*) malloc( sizeof(struct _glfwResolution) * modecount );
+        resarray = (struct _glfwResolution*) malloc( sizeof(struct _glfwResolution) * modecount );
 
         for( k = 0; k < modecount; k++ )
         {
@@ -411,6 +455,7 @@
                     break;
                 }
             }
+
             if( l >= rescount )
             {
                 resarray[ rescount ].width = width;
@@ -419,17 +464,17 @@
             }
         }
 
-	XFree( modelist );
+        XFree( modelist );
     }
 #endif
 
     if( !resarray )
     {
-	rescount = 1;
-	resarray = (struct _glfwResolution*) malloc( sizeof(struct _glfwResolution) * rescount );
+        rescount = 1;
+        resarray = (struct _glfwResolution*) malloc( sizeof(struct _glfwResolution) * rescount );
 
-	resarray[ 0 ].width = DisplayWidth( dpy, screen );
-	resarray[ 0 ].height = DisplayHeight( dpy, screen );
+        resarray[ 0 ].width = DisplayWidth( dpy, screen );
+        resarray[ 0 ].height = DisplayHeight( dpy, screen );
     }
 
     // Build permutations of colors and resolutions
@@ -471,33 +516,33 @@
 #endif
 
     // Get display and screen
-    dpy = _glfwLibrary.Dpy;
+    dpy = _glfwLibrary.display;
     screen = DefaultScreen( dpy );
 
     // Get display depth
     bpp = DefaultDepth( dpy, screen );
 
     // Convert BPP to RGB bits
-    _glfwBPP2RGB( bpp, &mode->RedBits, &mode->GreenBits, &mode->BlueBits );
+    BPP2RGB( bpp, &mode->RedBits, &mode->GreenBits, &mode->BlueBits );
 
 #if defined( _GLFW_HAS_XRANDR )
-    if( _glfwLibrary.XRandR.Available )
+    if( _glfwLibrary.XRandR.available )
     {
-        if( _glfwWin.FS.ModeChanged )
+        if( _glfwWin.FS.modeChanged )
         {
-	    mode->Width  = _glfwWin.FS.OldWidth;
-	    mode->Height = _glfwWin.FS.OldHeight;
-	    return;
-	}
+            mode->Width  = _glfwWin.FS.oldWidth;
+            mode->Height = _glfwWin.FS.oldHeight;
+            return;
+        }
     }
 #elif defined( _GLFW_HAS_XF86VIDMODE )
-    if( _glfwLibrary.XF86VidMode.Available )
+    if( _glfwLibrary.XF86VidMode.available )
     {
-        if( _glfwWin.FS.ModeChanged )
+        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;
+            // The old (desktop) mode is stored in _glfwWin.FS.oldMode
+            mode->Width  = _glfwWin.FS.oldMode.hdisplay;
+            mode->Height = _glfwWin.FS.oldMode.vdisplay;
         }
         else
         {
@@ -513,7 +558,7 @@
             XFree( modelist );
         }
 
-	return;
+        return;
     }
 #endif
 
diff --git a/glfw/lib/x11/x11_glext.c b/glfw/lib/x11/x11_glext.c
--- a/glfw/lib/x11/x11_glext.c
+++ b/glfw/lib/x11/x11_glext.c
@@ -1,11 +1,11 @@
-//========================================================================
+//==================
 // GLFW - An OpenGL framework
-// File:        x11_glext.c
-// Platform:    X11 (Unix)
-// API version: 2.6
-// WWW:         http://glfw.sourceforge.net
+// Platform:    X11/GLX
+// API version: 2.7
+// WWW:         http://www.glfw.org/
 //------------------------------------------------------------------------
-// Copyright (c) 2002-2006 Camilla Berglund
+// Copyright (c) 2002-2006 Marcus Geelnard
+// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org>
 //
 // This software is provided 'as-is', without any express or implied
 // warranty. In no event will the authors be held liable for any damages
@@ -31,6 +31,26 @@
 #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(_glfwLibrary.Libs.libGL,x)
+#else
+#define _glfw_glXGetProcAddress(x) NULL
+#endif
+
+
 //************************************************************************
 //****               Platform implementation functions                ****
 //************************************************************************
@@ -44,8 +64,8 @@
     const GLubyte *extensions;
 
     // Get list of GLX extensions
-    extensions = (const GLubyte*) glXQueryExtensionsString( _glfwLibrary.Dpy,
-                                                            _glfwWin.Scrn );
+    extensions = (const GLubyte*) glXQueryExtensionsString( _glfwLibrary.display,
+                                                            _glfwWin.screen );
     if( extensions != NULL )
     {
         if( _glfwStringInExtensionString( extension, extensions ) )
diff --git a/glfw/lib/x11/x11_init.c b/glfw/lib/x11/x11_init.c
--- a/glfw/lib/x11/x11_init.c
+++ b/glfw/lib/x11/x11_init.c
@@ -1,11 +1,11 @@
 //========================================================================
 // GLFW - An OpenGL framework
-// File:        x11_init.c
-// Platform:    X11 (Unix)
-// API version: 2.6
-// WWW:         http://glfw.sourceforge.net
+// Platform:    X11/GLX
+// API version: 2.7
+// WWW:         http://www.glfw.org/
 //------------------------------------------------------------------------
-// Copyright (c) 2002-2006 Camilla Berglund
+// Copyright (c) 2002-2006 Marcus Geelnard
+// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org>
 //
 // This software is provided 'as-is', without any express or implied
 // warranty. In no event will the authors be held liable for any damages
@@ -40,7 +40,7 @@
 // Initialize GLFW thread package
 //========================================================================
 
-static void _glfwInitThreads( void )
+static void initThreads( void )
 {
     // Initialize critical section handle
 #ifdef _GLFW_HAS_PTHREAD
@@ -65,7 +65,7 @@
 // Terminate GLFW thread package
 //========================================================================
 
-static void _glfwTerminateThreads( void )
+static void terminateThreads( void )
 {
 #ifdef _GLFW_HAS_PTHREAD
 
@@ -106,29 +106,26 @@
 // Dynamically load libraries
 //========================================================================
 
-#ifdef _GLFW_DLOPEN_LIBGL
-static char * _glfw_libGL_name[ ] =
-{
-    "libGL.so",
-    "libGL.so.1",
-    "/usr/lib/libGL.so",
-    "/usr/lib/libGL.so.1",
-    NULL
-};
-#endif
-
-static void _glfwInitLibraries( void )
+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; !_glfw_libGL_name[ i ] != NULL; i ++ )
+    for( i = 0; !libGL_names[ i ] != NULL; i ++ )
     {
-        _glfwLibrary.Libs.libGL = dlopen( _glfw_libGL_name[ i ],
+        _glfwLibrary.Libs.libGL = dlopen( libGL_names[ i ],
                                           RTLD_LAZY | RTLD_GLOBAL );
-	if( _glfwLibrary.Libs.libGL )
-	    break;
+        if( _glfwLibrary.Libs.libGL )
+            break;
     }
 #endif
 }
@@ -138,7 +135,7 @@
 // Terminate GLFW when exiting application
 //========================================================================
 
-void _glfwTerminate_atexit(int c, void* p)
+static void glfw_atexit( void )
 {
     glfwTerminate();
 }
@@ -148,40 +145,54 @@
 // Initialize X11 display
 //========================================================================
 
-static int _glfwInitDisplay( void )
+static int initDisplay( void )
 {
     // Open display
-    _glfwLibrary.Dpy = XOpenDisplay( 0 );
-    if( !_glfwLibrary.Dpy )
+    _glfwLibrary.display = XOpenDisplay( 0 );
+    if( !_glfwLibrary.display )
     {
+        fprintf(stderr, "Failed to open X display\n");
         return GL_FALSE;
     }
 
-    // Check screens
-    _glfwLibrary.NumScreens = ScreenCount( _glfwLibrary.Dpy );
-    _glfwLibrary.DefaultScreen = DefaultScreen( _glfwLibrary.Dpy );
-
     // Check for XF86VidMode extension
 #ifdef _GLFW_HAS_XF86VIDMODE
-    _glfwLibrary.XF86VidMode.Available =
-        XF86VidModeQueryExtension( _glfwLibrary.Dpy,
-	                           &_glfwLibrary.XF86VidMode.EventBase,
-	                           &_glfwLibrary.XF86VidMode.ErrorBase);
+    _glfwLibrary.XF86VidMode.available =
+        XF86VidModeQueryExtension( _glfwLibrary.display,
+                                   &_glfwLibrary.XF86VidMode.eventBase,
+                                   &_glfwLibrary.XF86VidMode.errorBase);
 #else
-    _glfwLibrary.XF86VidMode.Available = 0;
+    _glfwLibrary.XF86VidMode.available = 0;
 #endif
 
     // Check for XRandR extension
 #ifdef _GLFW_HAS_XRANDR
-    _glfwLibrary.XRandR.Available =
-        XRRQueryExtension( _glfwLibrary.Dpy,
-	                   &_glfwLibrary.XRandR.EventBase,
-			   &_glfwLibrary.XRandR.ErrorBase );
+    _glfwLibrary.XRandR.available =
+        XRRQueryExtension( _glfwLibrary.display,
+                           &_glfwLibrary.XRandR.eventBase,
+                           &_glfwLibrary.XRandR.errorBase );
 #else
-    _glfwLibrary.XRandR.Available = 0;
+    _glfwLibrary.XRandR.available = 0;
 #endif
 
-     return GL_TRUE;
+    // 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;
 }
 
 
@@ -189,13 +200,13 @@
 // Terminate X11 display
 //========================================================================
 
-static void _glfwTerminateDisplay( void )
+static void terminateDisplay( void )
 {
     // Open display
-    if( _glfwLibrary.Dpy )
+    if( _glfwLibrary.display )
     {
-        XCloseDisplay( _glfwLibrary.Dpy );
-        _glfwLibrary.Dpy = NULL;
+        XCloseDisplay( _glfwLibrary.display );
+        _glfwLibrary.display = NULL;
     }
 }
 
@@ -211,19 +222,19 @@
 int _glfwPlatformInit( void )
 {
     // Initialize display
-    if( !_glfwInitDisplay() )
+    if( !initDisplay() )
     {
         return GL_FALSE;
     }
 
     // Initialize thread package
-    _glfwInitThreads();
+    initThreads();
 
     // Try to load libGL.so if necessary
-    _glfwInitLibraries();
+    initLibraries();
 
     // Install atexit() routine
-    on_exit( _glfwTerminate_atexit, NULL );
+    atexit( glfw_atexit );
 
     // Initialize joysticks
     _glfwInitJoysticks();
@@ -253,10 +264,10 @@
     glfwCloseWindow();
 
     // Kill thread package
-    _glfwTerminateThreads();
+    terminateThreads();
 
     // Terminate display
-    _glfwTerminateDisplay();
+    terminateDisplay();
 
     // Terminate joysticks
     _glfwTerminateJoysticks();
diff --git a/glfw/lib/x11/x11_joystick.c b/glfw/lib/x11/x11_joystick.c
--- a/glfw/lib/x11/x11_joystick.c
+++ b/glfw/lib/x11/x11_joystick.c
@@ -1,11 +1,11 @@
 //========================================================================
 // GLFW - An OpenGL framework
-// File:        x11_joystick.c
-// Platform:    X11 (Unix)
-// API version: 2.6
-// WWW:         http://glfw.sourceforge.net
+// Platform:    X11/GLX
+// API version: 2.7
+// WWW:         http://www.glfw.org/
 //------------------------------------------------------------------------
-// Copyright (c) 2002-2006 Camilla Berglund
+// Copyright (c) 2002-2006 Marcus Geelnard
+// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org>
 //
 // This software is provided 'as-is', without any express or implied
 // warranty. In no event will the authors be held liable for any damages
@@ -36,12 +36,7 @@
 // systems will behave as if there are no joysticks connected.
 //========================================================================
 
-#ifdef linux
-#define _GLFW_USE_LINUX_JOYSTICKS
-#endif // linux
 
-
-
 //************************************************************************
 //****                  GLFW internal functions                       ****
 //************************************************************************
@@ -79,7 +74,7 @@
 
 
 //========================================================================
-// _glfwInitJoysticks() - Initialize joystick interface
+// Initialize joystick interface
 //========================================================================
 
 void _glfwInitJoysticks( void )
@@ -126,7 +121,7 @@
             {
                 // 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 )
@@ -135,15 +130,15 @@
                     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) *
@@ -154,7 +149,7 @@
                     continue;
                 }
                 _glfwJoy[ joy_count ].Button =
-                    (char *) malloc( sizeof(char) *
+                    (unsigned char *) malloc( sizeof(char) *
                                      _glfwJoy[ joy_count ].NumButtons );
                 if( _glfwJoy[ joy_count ].Button == NULL )
                 {
@@ -172,7 +167,7 @@
                 {
                     _glfwJoy[ joy_count ].Button[ n ] = GLFW_RELEASE;
                 }
-    
+
                 // The joystick is supported and connected
                 _glfwJoy[ joy_count ].Present = GL_TRUE;
                 joy_count ++;
@@ -186,7 +181,7 @@
 
 
 //========================================================================
-// _glfwTerminateJoysticks() - Close all opened joystick handles
+// Close all opened joystick handles
 //========================================================================
 
 void _glfwTerminateJoysticks( void )
@@ -214,16 +209,16 @@
 
 
 //========================================================================
-// _glfwPollJoystickEvents() - Empty joystick event queue
+// Empty joystick event queue
 //========================================================================
 
-static void _glfwPollJoystickEvents( void )
+static void pollJoystickEvents( void )
 {
 
 #ifdef _GLFW_USE_LINUX_JOYSTICKS
 
     struct js_event e;
-    int    i;
+    int i;
 
     // Get joystick events for all GLFW joysticks
     for( i = 0; i <= GLFW_JOYSTICK_LAST; ++ i )
@@ -274,7 +269,7 @@
 //************************************************************************
 
 //========================================================================
-// _glfwPlatformGetJoystickParam() - Determine joystick capabilities
+// Determine joystick capabilities
 //========================================================================
 
 int _glfwPlatformGetJoystickParam( int joy, int param )
@@ -305,12 +300,12 @@
 
 
 //========================================================================
-// _glfwPlatformGetJoystickPos() - Get joystick axis positions
+// Get joystick axis positions
 //========================================================================
 
 int _glfwPlatformGetJoystickPos( int joy, float *pos, int numaxes )
 {
-    int       i;
+    int i;
 
     // Is joystick present?
     if( !_glfwJoy[ joy ].Present )
@@ -319,7 +314,7 @@
     }
 
     // Update joystick state
-    _glfwPollJoystickEvents();
+    pollJoystickEvents();
 
     // Does the joystick support less axes than requested?
     if( _glfwJoy[ joy ].NumAxes < numaxes )
@@ -338,13 +333,13 @@
 
 
 //========================================================================
-// _glfwPlatformGetJoystickButtons() - Get joystick button states
+// Get joystick button states
 //========================================================================
 
 int _glfwPlatformGetJoystickButtons( int joy, unsigned char *buttons,
     int numbuttons )
 {
-    int       i;
+    int i;
 
     // Is joystick present?
     if( !_glfwJoy[ joy ].Present )
@@ -353,7 +348,7 @@
     }
 
     // Update joystick state
-    _glfwPollJoystickEvents();
+    pollJoystickEvents();
 
     // Does the joystick support less buttons than requested?
     if( _glfwJoy[ joy ].NumButtons < numbuttons )
@@ -369,3 +364,4 @@
 
     return numbuttons;
 }
+
diff --git a/glfw/lib/x11/x11_keysym2unicode.c b/glfw/lib/x11/x11_keysym2unicode.c
--- a/glfw/lib/x11/x11_keysym2unicode.c
+++ b/glfw/lib/x11/x11_keysym2unicode.c
@@ -1,11 +1,11 @@
 //========================================================================
 // GLFW - An OpenGL framework
-// File:        x11_keysym2unicode.c
-// Platform:    X11 (Unix)
-// API version: 2.6
-// WWW:         http://glfw.sourceforge.net
+// Platform:    X11/GLX
+// API version: 2.7
+// WWW:         http://www.glfw.org/
 //------------------------------------------------------------------------
-// Copyright (c) 2002-2006 Camilla Berglund
+// Copyright (c) 2002-2006 Marcus Geelnard
+// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org>
 //
 // This software is provided 'as-is', without any express or implied
 // warranty. In no event will the authors be held liable for any damages
@@ -828,8 +828,8 @@
   { 0x13bc, 0x0152 },
   { 0x13bd, 0x0153 },
   { 0x13be, 0x0178 },
-  { 0x20ac, 0x20ac }, 
-  // Numeric keypad with numlock on 
+  { 0x20ac, 0x20ac },
+  // Numeric keypad with numlock on
   { XK_KP_Space, ' ' },
   { XK_KP_Equal, '=' },
   { XK_KP_Multiply, '*' },
@@ -838,16 +838,16 @@
   { 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 } 
+  { 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 }
 };
 
 
@@ -856,7 +856,7 @@
 //************************************************************************
 
 //========================================================================
-// _glfwKeySym2Unicode() - Convert X11 KeySym to Unicode
+// Convert X11 KeySym to Unicode
 //========================================================================
 
 long _glfwKeySym2Unicode( KeySym keysym )
@@ -868,8 +868,7 @@
     /* First check for Latin-1 characters (1:1 mapping) */
     if( (keysym >= 0x0020 && keysym <= 0x007e) ||
         (keysym >= 0x00a0 && keysym <= 0x00ff) )
-    {
-        return keysym;
+    { return keysym;
     }
 
     /* Also check for directly encoded 24-bit UCS characters */
diff --git a/glfw/lib/x11/x11_thread.c b/glfw/lib/x11/x11_thread.c
--- a/glfw/lib/x11/x11_thread.c
+++ b/glfw/lib/x11/x11_thread.c
@@ -1,11 +1,11 @@
 //========================================================================
 // GLFW - An OpenGL framework
-// File:        x11_thread.c
-// Platform:    X11 (Unix)
-// API version: 2.6
-// WWW:         http://glfw.sourceforge.net
+// Platform:    X11/GLX
+// API version: 2.7
+// WWW:         http://www.glfw.org/
 //------------------------------------------------------------------------
-// Copyright (c) 2002-2006 Camilla Berglund
+// Copyright (c) 2002-2006 Marcus Geelnard
+// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org>
 //
 // This software is provided 'as-is', without any express or implied
 // warranty. In no event will the authors be held liable for any damages
@@ -39,8 +39,7 @@
 #ifdef _GLFW_HAS_PTHREAD
 
 //========================================================================
-// _glfwNewThread() - This is simply a "wrapper" for calling the user
-// thread function.
+// This is simply a "wrapper" for calling the user thread function.
 //========================================================================
 
 void * _glfwNewThread( void * arg )
@@ -97,7 +96,7 @@
 //************************************************************************
 
 //========================================================================
-// _glfwPlatformCreateThread() - Create a new thread
+// Create a new thread
 //========================================================================
 
 GLFWthread _glfwPlatformCreateThread( GLFWthreadfun fun, void *arg )
@@ -161,9 +160,8 @@
 
 
 //========================================================================
-// _glfwPlatformDestroyThread() - Kill a thread. NOTE: THIS IS A VERY
-// DANGEROUS OPERATION, AND SHOULD NOT BE USED EXCEPT IN EXTREME
-// SITUATIONS!
+// Kill a thread. NOTE: THIS IS A VERY DANGEROUS OPERATION, AND SHOULD NOT
+// BE USED EXCEPT IN EXTREME SITUATIONS!
 //========================================================================
 
 void _glfwPlatformDestroyThread( GLFWthread ID )
@@ -197,7 +195,7 @@
 
 
 //========================================================================
-// _glfwPlatformWaitThread() - Wait for a thread to die
+// Wait for a thread to die
 //========================================================================
 
 int _glfwPlatformWaitThread( GLFWthread ID, int waitmode )
@@ -247,8 +245,7 @@
 
 
 //========================================================================
-// _glfwPlatformGetThreadID() - Return the thread ID for the current
-// thread
+// Return the thread ID for the current thread
 //========================================================================
 
 GLFWthread _glfwPlatformGetThreadID( void )
@@ -291,7 +288,7 @@
 
 
 //========================================================================
-// _glfwPlatformCreateMutex() - Create a mutual exclusion object
+// Create a mutual exclusion object
 //========================================================================
 
 GLFWmutex _glfwPlatformCreateMutex( void )
@@ -322,7 +319,7 @@
 
 
 //========================================================================
-// _glfwPlatformDestroyMutex() - Destroy a mutual exclusion object
+// Destroy a mutual exclusion object
 //========================================================================
 
 void _glfwPlatformDestroyMutex( GLFWmutex mutex )
@@ -340,7 +337,7 @@
 
 
 //========================================================================
-// _glfwPlatformLockMutex() - Request access to a mutex
+// Request access to a mutex
 //========================================================================
 
 void _glfwPlatformLockMutex( GLFWmutex mutex )
@@ -355,7 +352,7 @@
 
 
 //========================================================================
-// _glfwPlatformUnlockMutex() - Release a mutex
+// Release a mutex
 //========================================================================
 
 void _glfwPlatformUnlockMutex( GLFWmutex mutex )
@@ -370,7 +367,7 @@
 
 
 //========================================================================
-// _glfwPlatformCreateCond() - Create a new condition variable object
+// Create a new condition variable object
 //========================================================================
 
 GLFWcond _glfwPlatformCreateCond( void )
@@ -401,7 +398,7 @@
 
 
 //========================================================================
-// _glfwPlatformDestroyCond() - Destroy a condition variable object
+// Destroy a condition variable object
 //========================================================================
 
 void _glfwPlatformDestroyCond( GLFWcond cond )
@@ -419,7 +416,7 @@
 
 
 //========================================================================
-// _glfwPlatformWaitCond() - Wait for a condition to be raised
+// Wait for a condition to be raised
 //========================================================================
 
 void _glfwPlatformWaitCond( GLFWcond cond, GLFWmutex mutex,
@@ -462,7 +459,7 @@
 
 
 //========================================================================
-// _glfwPlatformSignalCond() - Signal a condition to one waiting thread
+// Signal a condition to one waiting thread
 //========================================================================
 
 void _glfwPlatformSignalCond( GLFWcond cond )
@@ -477,8 +474,7 @@
 
 
 //========================================================================
-// _glfwPlatformBroadcastCond() - Broadcast a condition to all waiting
-// threads
+// Broadcast a condition to all waiting threads
 //========================================================================
 
 void _glfwPlatformBroadcastCond( GLFWcond cond )
@@ -493,8 +489,7 @@
 
 
 //========================================================================
-// _glfwPlatformGetNumberOfProcessors() - Return the number of processors
-// in the system.
+// Return the number of processors in the system.
 //========================================================================
 
 int _glfwPlatformGetNumberOfProcessors( void )
@@ -505,3 +500,4 @@
     _glfw_numprocessors( n );
     return n;
 }
+
diff --git a/glfw/lib/x11/x11_time.c b/glfw/lib/x11/x11_time.c
--- a/glfw/lib/x11/x11_time.c
+++ b/glfw/lib/x11/x11_time.c
@@ -1,11 +1,11 @@
 //========================================================================
 // GLFW - An OpenGL framework
-// File:        x11_time.c
-// Platform:    X11 (Unix)
-// API version: 2.6
-// WWW:         http://glfw.sourceforge.net
+// Platform:    X11/GLX
+// API version: 2.7
+// WWW:         http://www.glfw.org/
 //------------------------------------------------------------------------
-// Copyright (c) 2002-2006 Camilla Berglund
+// Copyright (c) 2002-2006 Marcus Geelnard
+// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org>
 //
 // This software is provided 'as-is', without any express or implied
 // warranty. In no event will the authors be held liable for any damages
@@ -40,7 +40,7 @@
     struct timeval  tv;
 
     // "Resolution" is 1 us
-    _glfwLibrary.Timer.Resolution = 1e-6;
+    _glfwLibrary.Timer.resolution = 1e-6;
 
     // Set start-time for timer
     gettimeofday( &tv, NULL );
@@ -66,7 +66,7 @@
     t = (long long) tv.tv_sec * (long long) 1000000 +
 	(long long) tv.tv_usec;
 
-    return (double)(t - _glfwLibrary.Timer.t0) * _glfwLibrary.Timer.Resolution;
+    return (double)(t - _glfwLibrary.Timer.t0) * _glfwLibrary.Timer.resolution;
 }
 
 
@@ -84,7 +84,7 @@
 	 (long long) tv.tv_usec;
 
     // Calulate new starting time
-    _glfwLibrary.Timer.t0 = t0 - (long long)(t/_glfwLibrary.Timer.Resolution);
+    _glfwLibrary.Timer.t0 = t0 - (long long)(t/_glfwLibrary.Timer.resolution);
 }
 
 
diff --git a/glfw/lib/x11/x11_window.c b/glfw/lib/x11/x11_window.c
--- a/glfw/lib/x11/x11_window.c
+++ b/glfw/lib/x11/x11_window.c
@@ -1,1746 +1,1891 @@
 //========================================================================
 // GLFW - An OpenGL framework
-// File:        x11_window.c
-// Platform:    X11 (Unix)
-// API version: 2.6
-// WWW:         http://glfw.sourceforge.net
-//------------------------------------------------------------------------
-// Copyright (c) 2002-2006 Camilla Berglund
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-//    claim that you wrote the original software. If you use this software
-//    in a product, an acknowledgment in the product documentation would
-//    be appreciated but is not required.
-//
-// 2. Altered source versions must be plainly marked as such, and must not
-//    be misrepresented as being the original software.
-//
-// 3. This notice may not be removed or altered from any source
-//    distribution.
-//
-//========================================================================
-
-#include "internal.h"
-
-
-/* Defines some GLX FSAA tokens if not yet defined */
-#ifndef GLX_SAMPLE_BUFFERS
-# define GLX_SAMPLE_BUFFERS  100000
-#endif 
-#ifndef GLX_SAMPLES 
-# define GLX_SAMPLES         100001
-#endif 
-
-
-/* KDE decoration values */
-enum {
-  KDE_noDecoration = 0,
-  KDE_normalDecoration = 1,
-  KDE_tinyDecoration = 2,
-  KDE_noFocus = 256,
-  KDE_standaloneMenuBar = 512,
-  KDE_desktopIcon = 1024 ,
-  KDE_staysOnTop = 2048
-};
-
-
-//************************************************************************
-//****                  GLFW internal functions                       ****
-//************************************************************************
-
-//========================================================================
-// _glfwWaitForMapNotify()
-//========================================================================
-
-Bool _glfwWaitForMapNotify( Display *d, XEvent *e, char *arg )
-{
-    return (e->type == MapNotify) && (e->xmap.window == (Window)arg);
-}
-
-
-//========================================================================
-// _glfwWaitForUnmapNotify()
-//========================================================================
-
-Bool _glfwWaitForUnmapNotify( Display *d, XEvent *e, char *arg )
-{
-    return (e->type == UnmapNotify) && (e->xmap.window == (Window)arg);
-}
-
-
-//========================================================================
-// _glfwDisableDecorations() - Turn off window decorations
-// Based on xawdecode: src/wmhooks.c
-//========================================================================
-
-#define MWM_HINTS_DECORATIONS (1L << 1)
-
-static void _glfwDisableDecorations( void )
-{
-    int                   RemovedDecorations;
-    Atom                  HintAtom;
-    XSetWindowAttributes  attributes;
-
-    RemovedDecorations = 0;
-
-    // First try to set MWM hints
-    HintAtom = XInternAtom( _glfwLibrary.Dpy, "_MOTIF_WM_HINTS", True );
-    if ( HintAtom != None )
-    {
-        struct {
-            unsigned long flags;
-            unsigned long functions;
-            unsigned long decorations;
-                     long input_mode;
-            unsigned long status;
-        } MWMHints = { MWM_HINTS_DECORATIONS, 0, 0, 0, 0 };
-
-        XChangeProperty( _glfwLibrary.Dpy, _glfwWin.Win, HintAtom, HintAtom,
-                         32, PropModeReplace, (unsigned char *)&MWMHints,
-                         sizeof(MWMHints)/4 );
-        RemovedDecorations = 1;
-    }
-
-    // Now try to set KWM hints
-    HintAtom = XInternAtom( _glfwLibrary.Dpy, "KWM_WIN_DECORATION", True );
-    if ( HintAtom != None )
-    {
-        long KWMHints = KDE_tinyDecoration;
-
-        XChangeProperty( _glfwLibrary.Dpy, _glfwWin.Win, HintAtom, HintAtom,
-                         32, PropModeReplace, (unsigned char *)&KWMHints,
-                         sizeof(KWMHints)/4 );
-        RemovedDecorations = 1;
-    }
-
-    // Now try to set GNOME hints
-    HintAtom = XInternAtom(_glfwLibrary.Dpy, "_WIN_HINTS", True );
-    if ( HintAtom != None )
-    {
-        long GNOMEHints = 0;
-
-        XChangeProperty( _glfwLibrary.Dpy, _glfwWin.Win, HintAtom, HintAtom,
-                         32, PropModeReplace, (unsigned char *)&GNOMEHints,
-                         sizeof(GNOMEHints)/4 );
-        RemovedDecorations = 1;
-    }
-
-    // Now try to set KDE NET_WM hints
-    HintAtom = XInternAtom( _glfwLibrary.Dpy, "_NET_WM_WINDOW_TYPE", True );
-    if ( HintAtom != None )
-    {
-        Atom NET_WMHints[2];
-
-        NET_WMHints[0] = XInternAtom( _glfwLibrary.Dpy, "_KDE_NET_WM_WINDOW_TYPE_OVERRIDE", True );
-        /* define a fallback... */
-        NET_WMHints[1] = XInternAtom( _glfwLibrary.Dpy, "_NET_WM_WINDOW_TYPE_NORMAL", True );
-
-        XChangeProperty( _glfwLibrary.Dpy, _glfwWin.Win, HintAtom, XA_ATOM,
-                         32, PropModeReplace, (unsigned char *)&NET_WMHints,
-                         2 );
-        RemovedDecorations = 1;
-    }
-
-    // Set ICCCM fullscreen WM hint
-    HintAtom = XInternAtom( _glfwLibrary.Dpy, "_NET_WM_STATE", True );
-    if ( HintAtom != None )
-    {
-        Atom NET_WMHints[1];
-
-        NET_WMHints[0] = XInternAtom( _glfwLibrary.Dpy, "_NET_WM_STATE_FULLSCREEN", True );
-
-        XChangeProperty( _glfwLibrary.Dpy, _glfwWin.Win, HintAtom, XA_ATOM,
-                         32, PropModeReplace, (unsigned char *)&NET_WMHints, 1 );
-    }
-
-
-    // Did we sucessfully remove the window decorations?
-    if( RemovedDecorations )
-    {
-        // Finally set the transient hints
-        XSetTransientForHint( _glfwLibrary.Dpy, _glfwWin.Win, RootWindow(_glfwLibrary.Dpy, _glfwWin.Scrn) );
-        XUnmapWindow( _glfwLibrary.Dpy, _glfwWin.Win );
-        XMapWindow( _glfwLibrary.Dpy, _glfwWin.Win );
-    }
-    else
-    {
-        // The Butcher way of removing window decorations
-        attributes.override_redirect = True;
-        XChangeWindowAttributes( _glfwLibrary.Dpy, _glfwWin.Win,
-                                 CWOverrideRedirect, &attributes );
-        _glfwWin.OverrideRedirect = GL_TRUE;
-    }
-}
-
-
-//========================================================================
-// _glfwEnableDecorations() - Turn on window decorations
-//========================================================================
-
-static void _glfwEnableDecorations( void )
-{
-    int                   ActivatedDecorations;
-    Atom                  HintAtom;
-
-    // If this is an override redirect window, skip it...
-    if( _glfwWin.OverrideRedirect )
-    {
-        return;
-    }
-
-    ActivatedDecorations = 0;
-
-    // First try to unset MWM hints
-    HintAtom = XInternAtom( _glfwLibrary.Dpy, "_MOTIF_WM_HINTS", True );
-    if ( HintAtom != None )
-    {
-        XDeleteProperty( _glfwLibrary.Dpy, _glfwWin.Win, HintAtom );
-        ActivatedDecorations = 1;
-    }
-
-    // Now try to unset KWM hints
-    HintAtom = XInternAtom( _glfwLibrary.Dpy, "KWM_WIN_DECORATION", True );
-    if ( HintAtom != None )
-    {
-        XDeleteProperty( _glfwLibrary.Dpy, _glfwWin.Win, HintAtom );
-        ActivatedDecorations = 1;
-    }
-
-    // Now try to unset GNOME hints
-    HintAtom = XInternAtom( _glfwLibrary.Dpy, "_WIN_HINTS", True );
-    if ( HintAtom != None )
-    {
-        XDeleteProperty( _glfwLibrary.Dpy, _glfwWin.Win, HintAtom );
-        ActivatedDecorations = 1;
-    }
-
-    // Now try to unset NET_WM hints
-    HintAtom = XInternAtom( _glfwLibrary.Dpy, "_NET_WM_WINDOW_TYPE", True );
-    if ( HintAtom != None )
-    {
-        Atom NET_WMHints = XInternAtom( _glfwLibrary.Dpy, "_NET_WM_WINDOW_TYPE_NORMAL", True);
-        if( NET_WMHints != None )
-        {
-            XChangeProperty( _glfwLibrary.Dpy, _glfwWin.Win,
-                            HintAtom, XA_ATOM, 32, PropModeReplace,
-                            (unsigned char *)&NET_WMHints, 1 );
-            ActivatedDecorations = 1;
-        }
-    }
-
-    // Finally unset the transient hints if necessary
-    if( ActivatedDecorations )
-    {
-        // NOTE: Does this work?
-        XSetTransientForHint( _glfwLibrary.Dpy, _glfwWin.Win, None);
-        XUnmapWindow( _glfwLibrary.Dpy, _glfwWin.Win );
-        XMapWindow( _glfwLibrary.Dpy, _glfwWin.Win );
-    }
-}
-
-
-//========================================================================
-// _glfwChooseVisual() - We do our own function here, since
-// glXChooseVisual does not behave as we want it to (not according to the
-// GLFW specs)
-//========================================================================
-
-XVisualInfo * _glfwChooseVisual( Display *Dpy, int Screen, int r, int g,
-    int b, int a, int d, int s, int ar, int ag, int ab, int aa, int aux,
-				 int fsaa, int stereo)
-{
-    XVisualInfo *VI, *VI_list, VI_tmp;
-    int  nitems_return, i;
-    int  vi_gl, vi_rgba, vi_double, vi_stereo;
-    int  vi_r, vi_g, vi_b, vi_a, vi_d, vi_s, vi_ar, vi_ag, vi_ab, vi_aa;
-    int  vi_aux;
-    int  color, accum, vi_accum;
-    int  missing, color_diff, extra_diff;
-    int  best_vis, best_missing, best_color_diff, best_extra_diff;
-    int  samples, samplebuffers, vi_samples, vi_samplebuffers;
-
-    // Get list of visuals for this screen & display
-    VI_tmp.screen = Screen;
-    VI_list = XGetVisualInfo( Dpy, VisualScreenMask, &VI_tmp,
-                              &nitems_return );
-    if( VI_list == NULL )
-    {
-        return NULL;
-    }
-
-    // Pick some prefered color depth if the user did not request a
-    // specific depth (note: if the user did not request a specific color
-    // depth, this will not be a driving demand, it's only here to avoid
-    // selection randomness)
-    color = (r > 0 || g > 0 || b > 0);
-    if( !color )
-    {
-        r = g = b = 8;
-    }
-
-    // Make sure that stereo is 1 or 0
-    stereo = stereo ? 1 : 0;
-
-    // Convenience pre-calculation
-    accum = (ar > 0 || ag > 0 || ab > 0 || aa > 0);
-    
-    samples = fsaa;
-    samplebuffers = (fsaa > 0) ? 1 : 0;
-    
-    
-
-    // Loop through list of visuals to find best match
-    best_vis        = -1;
-    best_missing    = 0x7fffffff;
-    best_color_diff = 0x7fffffff;
-    best_extra_diff = 0x7fffffff;
-    for( i = 0; i < nitems_return; i ++ )
-    {
-        // We want GL, RGBA & DOUBLEBUFFER, and NOT STEREO / STEREO
-        glXGetConfig( Dpy, &VI_list[i], GLX_USE_GL, &vi_gl );
-        glXGetConfig( Dpy, &VI_list[i], GLX_RGBA, &vi_rgba );
-        glXGetConfig( Dpy, &VI_list[i], GLX_DOUBLEBUFFER, &vi_double );
-        glXGetConfig( Dpy, &VI_list[i], GLX_STEREO, &vi_stereo );
-        vi_stereo = vi_stereo ? 1 : 0;
-        if( vi_gl && vi_rgba && vi_double && (vi_stereo == stereo) )
-        {
-            // Get visual color parameters
-            glXGetConfig( Dpy, &VI_list[i], GLX_RED_SIZE, &vi_r );
-            glXGetConfig( Dpy, &VI_list[i], GLX_GREEN_SIZE, &vi_g );
-            glXGetConfig( Dpy, &VI_list[i], GLX_BLUE_SIZE, &vi_b );
-
-            // Get visual "extra" parameters
-            glXGetConfig( Dpy, &VI_list[i], GLX_ALPHA_SIZE, &vi_a );
-            glXGetConfig( Dpy, &VI_list[i], GLX_DEPTH_SIZE, &vi_d );
-            glXGetConfig( Dpy, &VI_list[i], GLX_STENCIL_SIZE, &vi_s );
-            glXGetConfig( Dpy, &VI_list[i], GLX_ACCUM_RED_SIZE, &vi_ar );
-            glXGetConfig( Dpy, &VI_list[i], GLX_ACCUM_GREEN_SIZE, &vi_ag );
-            glXGetConfig( Dpy, &VI_list[i], GLX_ACCUM_BLUE_SIZE, &vi_ab );
-            glXGetConfig( Dpy, &VI_list[i], GLX_ACCUM_ALPHA_SIZE, &vi_aa );
-            glXGetConfig( Dpy, &VI_list[i], GLX_AUX_BUFFERS, &vi_aux );
-	    glXGetConfig( Dpy, &VI_list[i], GLX_SAMPLE_BUFFERS, &vi_samplebuffers );
-	    glXGetConfig( Dpy, &VI_list[i], GLX_SAMPLES, &vi_samples );
-	    
-            vi_accum = (vi_ar > 0 || vi_ag > 0 || vi_ab > 0 || vi_aa > 0);
-
-            // Check how many buffers are missing
-            missing = 0;
-            if( a > 0 && vi_a == 0 ) missing ++;
-            if( d > 0 && vi_d == 0 ) missing ++;
-            if( s > 0 && vi_s == 0 ) missing ++;
-            if( accum && !vi_accum ) missing ++;
-            if( aux > 0 && vi_aux == 0 ) missing ++;
-	    if( samplebuffers > 0 && vi_samplebuffers == 0 ) missing ++;
-	    
-
-            // Calculate color diff
-            color_diff = (r - vi_r) * (r - vi_r) +
-                         (g - vi_g) * (g - vi_g) +
-                         (b - vi_b) * (b - vi_b);
-
-            // Calculate "extra" diff
-            extra_diff = 0;
-            if( a > 0 )
-            {
-                extra_diff += (a - vi_a) * (a - vi_a);
-            }
-            if( d > 0 )
-            {
-                extra_diff += (d - vi_d) * (d - vi_d);
-            }
-            if( s > 0 )
-            {
-                extra_diff += (s - vi_s) * (s - vi_s);
-            }
-            if( accum )
-            {
-                extra_diff += (ar - vi_ar) * (ar - vi_ar) +
-                              (ag - vi_ag) * (ag - vi_ag) +
-                              (ab - vi_ab) * (ab - vi_ab) +
-                              (aa - vi_aa) * (aa - vi_aa);
-            }
-            if( aux > 0 )
-            {
-                extra_diff += (aux - vi_aux) * (aux - vi_aux);
-            }
-	    if( samples > 0 )
-	    {
-	      extra_diff += (samples - vi_samples) * (samples - vi_samples);
-	      
-	    }
-            // Check if this is a better match. We implement some
-            // complicated rules, by prioritizing in this order:
-            //  1) Visuals with the least number of missing buffers always
-            //     have priority
-            //  2a) If (r,g,b)!=(0,0,0), color depth has priority over
-            //      other buffers
-            //  2b) If (r,g,b)==(0,0,0), other buffers have priority over
-            //      color depth
-            if( missing < best_missing )
-            {
-                best_vis = i;
-            }
-            else if( missing == best_missing )
-            {
-                if( color )
-                {
-                    if( (color_diff < best_color_diff) ||
-                        (color_diff == best_color_diff &&
-                         extra_diff < best_extra_diff) )
-                    {
-                        best_vis = i;
-                    }
-                }
-                else
-                {
-                    if( (extra_diff < best_extra_diff) ||
-                        (extra_diff == best_extra_diff &&
-                         color_diff < best_color_diff) )
-                    {
-                        best_vis = i;
-                    }
-                }
-            }
-            if( best_vis == i )
-            {
-                best_missing    = missing;
-                best_color_diff = color_diff;
-                best_extra_diff = extra_diff;
-            }
-        }
-    }
-
-    // Copy best visual to a visual to return
-    if( best_vis >= 0 )
-    {
-        VI = XGetVisualInfo( Dpy, VisualIDMask, &VI_list[ best_vis ],
-                             &nitems_return );
-    }
-    else
-    {
-        VI = NULL;
-    }
-
-    // Free visuals list
-    XFree( VI_list );
-
-    return VI;
-}
-
-
-//========================================================================
-// _glfwTranslateKey() - Translates an X Window key to internal coding
-//========================================================================
-
-static int _glfwTranslateKey( int keycode )
-{
-    KeySym key, key_lc, key_uc;
-
-    // Try secondary keysym, for numeric keypad keys
-    // Note: This way we always force "NumLock = ON", which at least
-    // enables GLFW users to detect numeric keypad keys
-    key = XKeycodeToKeysym( _glfwLibrary.Dpy, keycode, 1 );
-    switch( key )
-    {
-        // Numeric keypad
-        case XK_KP_0:         return GLFW_KEY_KP_0;
-        case XK_KP_1:         return GLFW_KEY_KP_1;
-        case XK_KP_2:         return GLFW_KEY_KP_2;
-        case XK_KP_3:         return GLFW_KEY_KP_3;
-        case XK_KP_4:         return GLFW_KEY_KP_4;
-        case XK_KP_5:         return GLFW_KEY_KP_5;
-        case XK_KP_6:         return GLFW_KEY_KP_6;
-        case XK_KP_7:         return GLFW_KEY_KP_7;
-        case XK_KP_8:         return GLFW_KEY_KP_8;
-        case XK_KP_9:         return GLFW_KEY_KP_9;
-        case XK_KP_Separator:
-        case XK_KP_Decimal:   return GLFW_KEY_KP_DECIMAL;
-        case XK_KP_Equal:     return GLFW_KEY_KP_EQUAL;
-        case XK_KP_Enter:     return GLFW_KEY_KP_ENTER;
-        default:              break;
-    }
-
-    // Now try pimary keysym
-    key = XKeycodeToKeysym( _glfwLibrary.Dpy, keycode, 0 );
-    switch( key )
-    {
-        // Special keys (non character keys)
-        case XK_Escape:       return GLFW_KEY_ESC;
-        case XK_Tab:          return GLFW_KEY_TAB;
-        case XK_Shift_L:      return GLFW_KEY_LSHIFT;
-        case XK_Shift_R:      return GLFW_KEY_RSHIFT;
-        case XK_Control_L:    return GLFW_KEY_LCTRL;
-        case XK_Control_R:    return GLFW_KEY_RCTRL;
-        case XK_Meta_L:
-        case XK_Alt_L:        return GLFW_KEY_LALT;
-        case XK_Mode_switch:  // Mapped to Alt_R on many keyboards
-        case XK_Meta_R:
-        case XK_Alt_R:        return GLFW_KEY_RALT;
-        case XK_KP_Delete:
-        case XK_Delete:       return GLFW_KEY_DEL;
-        case XK_BackSpace:    return GLFW_KEY_BACKSPACE;
-        case XK_Return:       return GLFW_KEY_ENTER;
-        case XK_KP_Home:
-        case XK_Home:         return GLFW_KEY_HOME;
-        case XK_KP_End:
-        case XK_End:          return GLFW_KEY_END;
-        case XK_KP_Page_Up:
-        case XK_Page_Up:      return GLFW_KEY_PAGEUP;
-        case XK_KP_Page_Down:
-        case XK_Page_Down:    return GLFW_KEY_PAGEDOWN;
-        case XK_KP_Insert:
-        case XK_Insert:       return GLFW_KEY_INSERT;
-        case XK_KP_Left:
-        case XK_Left:         return GLFW_KEY_LEFT;
-        case XK_KP_Right:
-        case XK_Right:        return GLFW_KEY_RIGHT;
-        case XK_KP_Down:
-        case XK_Down:         return GLFW_KEY_DOWN;
-        case XK_KP_Up:
-        case XK_Up:           return GLFW_KEY_UP;
-        case XK_F1:           return GLFW_KEY_F1;
-        case XK_F2:           return GLFW_KEY_F2;
-        case XK_F3:           return GLFW_KEY_F3;
-        case XK_F4:           return GLFW_KEY_F4;
-        case XK_F5:           return GLFW_KEY_F5;
-        case XK_F6:           return GLFW_KEY_F6;
-        case XK_F7:           return GLFW_KEY_F7;
-        case XK_F8:           return GLFW_KEY_F8;
-        case XK_F9:           return GLFW_KEY_F9;
-        case XK_F10:          return GLFW_KEY_F10;
-        case XK_F11:          return GLFW_KEY_F11;
-        case XK_F12:          return GLFW_KEY_F12;
-        case XK_F13:          return GLFW_KEY_F13;
-        case XK_F14:          return GLFW_KEY_F14;
-        case XK_F15:          return GLFW_KEY_F15;
-        case XK_F16:          return GLFW_KEY_F16;
-        case XK_F17:          return GLFW_KEY_F17;
-        case XK_F18:          return GLFW_KEY_F18;
-        case XK_F19:          return GLFW_KEY_F19;
-        case XK_F20:          return GLFW_KEY_F20;
-        case XK_F21:          return GLFW_KEY_F21;
-        case XK_F22:          return GLFW_KEY_F22;
-        case XK_F23:          return GLFW_KEY_F23;
-        case XK_F24:          return GLFW_KEY_F24;
-        case XK_F25:          return GLFW_KEY_F25;
-
-        // Numeric keypad (should have been detected in secondary keysym!)
-        case XK_KP_Divide:    return GLFW_KEY_KP_DIVIDE;
-        case XK_KP_Multiply:  return GLFW_KEY_KP_MULTIPLY;
-        case XK_KP_Subtract:  return GLFW_KEY_KP_SUBTRACT;
-        case XK_KP_Add:       return GLFW_KEY_KP_ADD;
-        case XK_KP_Equal:     return GLFW_KEY_KP_EQUAL;
-        case XK_KP_Enter:     return GLFW_KEY_KP_ENTER;
-
-        // The rest (should be printable keys)
-        default:
-            // Make uppercase
-            XConvertCase( key, &key_lc, &key_uc );
-            key = key_uc;
-
-            // Valid ISO 8859-1 character?
-            if( (key >=  32 && key <= 126) ||
-                (key >= 160 && key <= 255) )
-            {
-                return (int) key;
-            }
-            return GLFW_KEY_UNKNOWN;
-    }
-}
-
-
-//========================================================================
-// _glfwTranslateChar() - Translates an X Window event to Unicode
-//========================================================================
-
-static int _glfwTranslateChar( XKeyEvent *event )
-{
-    KeySym keysym;
-
-    // Get X11 keysym
-    XLookupString( event, NULL, 0, &keysym, NULL );
-
-    // Convert to Unicode (see x11_keysym2unicode.c)
-    return (int) _glfwKeySym2Unicode( keysym );
-}
-
-
-
-//========================================================================
-// Get next X event (called by glfwPollEvents)
-//========================================================================
-
-static int _glfwGetNextEvent( void )
-{
-    XEvent event, next_event;
-
-    // Pull next event from event queue
-    XNextEvent( _glfwLibrary.Dpy, &event );
-
-    // Handle certain window messages
-    switch( event.type )
-    {
-        // Is a key being pressed?
-        case KeyPress:
-	{
-            // Translate and report key press
-            _glfwInputKey( _glfwTranslateKey( event.xkey.keycode ), GLFW_PRESS );
-
-            // Translate and report character input
-            if( _glfwWin.CharCallback )
-            {
-                _glfwInputChar( _glfwTranslateChar( &event.xkey ), GLFW_PRESS );
-            }
-            break;
-	}
-
-        // Is a key being released?
-        case KeyRelease:
-	{
-            // Do not report key releases for key repeats. For key repeats
-            // we will get KeyRelease/KeyPress pairs with identical time
-            // stamps. User selected key repeat filtering is handled in
-            // _glfwInputKey()/_glfwInputChar().
-            if( XEventsQueued( _glfwLibrary.Dpy, QueuedAfterReading ) )
-            {
-                XPeekEvent( _glfwLibrary.Dpy, &next_event );
-                if( next_event.type == KeyPress &&
-                    next_event.xkey.window == event.xkey.window &&
-                    next_event.xkey.keycode == event.xkey.keycode &&
-                    next_event.xkey.time == event.xkey.time )
-                {
-                    // Do not report anything for this event
-                    break;
-                }
-            }
-
-            // Translate and report key release
-            _glfwInputKey( _glfwTranslateKey( event.xkey.keycode ), GLFW_RELEASE );
-
-            // Translate and report character input
-            if( _glfwWin.CharCallback )
-            {
-                _glfwInputChar( _glfwTranslateChar( &event.xkey ), GLFW_RELEASE );
-            }
-            break;
-	}
-
-        // Were any of the mouse-buttons pressed?
-        case ButtonPress:
-	{
-            if( event.xbutton.button == Button1 )
-            {
-                _glfwInputMouseClick( GLFW_MOUSE_BUTTON_LEFT, GLFW_PRESS );
-            }
-            else if( event.xbutton.button == Button2 )
-            {
-                _glfwInputMouseClick( GLFW_MOUSE_BUTTON_MIDDLE, GLFW_PRESS );
-            }
-            else if( event.xbutton.button == Button3 )
-            {
-                _glfwInputMouseClick( GLFW_MOUSE_BUTTON_RIGHT, GLFW_PRESS );
-            }
-
-            // XFree86 3.3.2 and later translates mouse wheel up/down into
-            // mouse button 4 & 5 presses
-            else if( event.xbutton.button == Button4 )
-            {
-                _glfwInput.WheelPos++;  // To verify: is this up or down?
-                if( _glfwWin.MouseWheelCallback )
-                {
-                    _glfwWin.MouseWheelCallback( _glfwInput.WheelPos );
-                }
-            }
-            else if( event.xbutton.button == Button5 )
-            {
-                _glfwInput.WheelPos--;
-                if( _glfwWin.MouseWheelCallback )
-                {
-                    _glfwWin.MouseWheelCallback( _glfwInput.WheelPos );
-                }
-            }
-            break;
-	}
-
-        // Were any of the mouse-buttons released?
-        case ButtonRelease:
-	{
-            if( event.xbutton.button == Button1 )
-            {
-                _glfwInputMouseClick( GLFW_MOUSE_BUTTON_LEFT,
-                                      GLFW_RELEASE );
-            }
-            else if( event.xbutton.button == Button2 )
-            {
-                _glfwInputMouseClick( GLFW_MOUSE_BUTTON_MIDDLE,
-                                      GLFW_RELEASE );
-            }
-            else if( event.xbutton.button == Button3 )
-            {
-                _glfwInputMouseClick( GLFW_MOUSE_BUTTON_RIGHT,
-                                      GLFW_RELEASE );
-            }
-            break;
-	}
-
-        // Was the mouse moved?
-        case MotionNotify:
-	{
-            if( event.xmotion.x != _glfwInput.CursorPosX ||
-                event.xmotion.y != _glfwInput.CursorPosY )
-            {
-                if( _glfwWin.MouseLock )
-                {
-                    _glfwInput.MousePosX += event.xmotion.x -
-                                            _glfwInput.CursorPosX;
-                    _glfwInput.MousePosY += event.xmotion.y -
-                                            _glfwInput.CursorPosY;
-                }
-                else
-                {
-                    _glfwInput.MousePosX = event.xmotion.x;
-                    _glfwInput.MousePosY = event.xmotion.y;
-                }
-                _glfwInput.CursorPosX = event.xmotion.x;
-                _glfwInput.CursorPosY = event.xmotion.y;
-                _glfwInput.MouseMoved = GL_TRUE;
-
-                // Call user callback function
-                if( _glfwWin.MousePosCallback )
-                {
-                    _glfwWin.MousePosCallback( _glfwInput.MousePosX,
-                                               _glfwInput.MousePosY );
-                }
-            }
-            break;
-	}
-
-        // Was the window resized?
-        case ConfigureNotify:
-	{
-            if( event.xconfigure.width != _glfwWin.Width ||
-                event.xconfigure.height != _glfwWin.Height )
-            {
-                _glfwWin.Width = event.xconfigure.width;
-                _glfwWin.Height = event.xconfigure.height;
-                if( _glfwWin.WindowSizeCallback )
-                {
-                    _glfwWin.WindowSizeCallback( _glfwWin.Width,
-                                                 _glfwWin.Height );
-                }
-            }
-            break;
-	}
-
-        // Was the window closed by the window manager?
-        case ClientMessage:
-	{
-            if( (Atom) event.xclient.data.l[ 0 ] == _glfwWin.WMDeleteWindow )
-            {
-                return GL_TRUE;
-            }
-
-	    if( (Atom) event.xclient.data.l[ 0 ] == _glfwWin.WMPing )
-	    {
-		XSendEvent( _glfwLibrary.Dpy,
-			    RootWindow( _glfwLibrary.Dpy, _glfwWin.VI->screen ),
-			    False, SubstructureNotifyMask | SubstructureRedirectMask, &event );
-	    }
-            break;
-	}
-
-        // Was the window mapped (un-iconified)?
-        case MapNotify:
-            _glfwWin.MapNotifyCount++;
-            break;
-
-        // Was the window unmapped (iconified)?
-        case UnmapNotify:
-            _glfwWin.MapNotifyCount--;
-            break;
-
-        // Was the window activated?
-        case FocusIn:
-            _glfwWin.FocusInCount++;
-            break;
-
-        // Was the window de-activated?
-        case FocusOut:
-            _glfwWin.FocusInCount--;
-            break;
-
-        // Was the window contents damaged?
-        case Expose:
-	{
-            // Call user callback function
-            if( _glfwWin.WindowRefreshCallback )
-            {
-                _glfwWin.WindowRefreshCallback();
-            }
-            break;
-	}
-
-        // Was the window destroyed?
-        case DestroyNotify:
-            return GL_TRUE;
-
-        default:
-	{
-#if defined( _GLFW_HAS_XRANDR )
-	    switch( event.type - _glfwLibrary.XRandR.EventBase )
-	    {
-		case RRScreenChangeNotify:
-		{
-		    // Show XRandR that we really care
-		    XRRUpdateConfiguration( &event );
-		    break;
-		}
-	    }
-#endif
-            break;
-	}
-    }
-
-    // The window was not destroyed
-    return GL_FALSE;
-}
-
-
-//========================================================================
-// _glfwCreateNULLCursor() - Create a blank cursor (for locked mouse mode)
-//========================================================================
-
-Cursor _glfwCreateNULLCursor( Display *display, Window root )
-{
-    Pixmap    cursormask;
-    XGCValues xgc;
-    GC        gc;
-    XColor    col;
-    Cursor    cursor;
-
-    cursormask = XCreatePixmap( display, root, 1, 1, 1 );
-    xgc.function = GXclear;
-    gc = XCreateGC( display, cursormask, GCFunction, &xgc );
-    XFillRectangle( display, cursormask, gc, 0, 0, 1, 1 );
-    col.pixel = 0;
-    col.red = 0;
-    col.flags = 4;
-    cursor = XCreatePixmapCursor( display, cursormask, cursormask,
-                                  &col,&col, 0,0 );
-    XFreePixmap( display, cursormask );
-    XFreeGC( display, gc );
-
-    return cursor;
-}
-
-
-//========================================================================
-// _glfwInitGLXExtensions() - Initialize GLX-specific extensions
-//========================================================================
-
-static void _glfwInitGLXExtensions( void )
-{
-    int has_swap_control;
-
-    // Initialize OpenGL extension: GLX_SGI_swap_control
-    has_swap_control = _glfwPlatformExtensionSupported(
-                           "GLX_SGI_swap_control"
-                       );
-
-    if( has_swap_control )
-    {
-        _glfwWin.SwapInterval = (GLXSWAPINTERVALSGI_T)
-            _glfw_glXGetProcAddress( (GLubyte*) "glXSwapIntervalSGI" );
-    }
-    else
-    {
-        _glfwWin.SwapInterval = NULL;
-    }
-}
-
-
-
-//************************************************************************
-//****               Platform implementation functions                ****
-//************************************************************************
-
-//========================================================================
-// _glfwPlatformOpenWindow() - Here is where the window is created, and
-// the OpenGL rendering context is created
-//========================================================================
-
-int _glfwPlatformOpenWindow( int width, int height, int redbits,
-    int greenbits, int bluebits, int alphabits, int depthbits,
-    int stencilbits, int mode, _GLFWhints* hints )
-{
-    Colormap    cmap;
-    XSetWindowAttributes wa;
-    XEvent      event;
-    Atom protocols[2];
-
-    // Clear platform specific GLFW window state
-    _glfwWin.VI               = NULL;
-    _glfwWin.CX               = (GLXContext)0;
-    _glfwWin.Win              = (Window)0;
-    _glfwWin.Hints            = NULL;
-    _glfwWin.PointerGrabbed   = GL_FALSE;
-    _glfwWin.KeyboardGrabbed  = GL_FALSE;
-    _glfwWin.OverrideRedirect = GL_FALSE;
-    _glfwWin.FS.ModeChanged   = GL_FALSE;
-    _glfwWin.Saver.Changed    = GL_FALSE;
-    _glfwWin.RefreshRate      = hints->RefreshRate;
-
-    // Fullscreen & screen saver settings
-    // Check if GLX is supported on this display
-    if( !glXQueryExtension( _glfwLibrary.Dpy, NULL, NULL ) )
-    {
-        _glfwPlatformCloseWindow();
-        return GL_FALSE;
-    }
-
-    // Get screen ID for this window
-    _glfwWin.Scrn = _glfwLibrary.DefaultScreen;
-
-    // Get an appropriate visual
-    _glfwWin.VI = _glfwChooseVisual( _glfwLibrary.Dpy,
-                                     _glfwWin.Scrn,
-                                     redbits, greenbits, bluebits,
-                                     alphabits, depthbits, stencilbits,
-                                     hints->AccumRedBits, hints->AccumGreenBits,
-                                     hints->AccumBlueBits, hints->AccumAlphaBits,
-                                     hints->AuxBuffers, hints->Samples, hints->Stereo );
-    if( _glfwWin.VI == NULL )
-    {
-        _glfwPlatformCloseWindow();
-        return GL_FALSE;
-    }
-
-    // Create a GLX context
-    _glfwWin.CX = glXCreateContext( _glfwLibrary.Dpy, _glfwWin.VI, 0, GL_TRUE );
-    if( _glfwWin.CX == NULL )
-    {
-        _glfwPlatformCloseWindow();
-        return GL_FALSE;
-    }
-
-    // Create a colormap
-    cmap = XCreateColormap( _glfwLibrary.Dpy, RootWindow( _glfwLibrary.Dpy,
-               _glfwWin.VI->screen), _glfwWin.VI->visual, AllocNone );
-
-    // Do we want fullscreen?
-    if( mode == GLFW_FULLSCREEN )
-    {
-        // Change video mode
-        _glfwSetVideoMode( _glfwWin.Scrn, &_glfwWin.Width,
-                           &_glfwWin.Height, &_glfwWin.RefreshRate );
-
-        // Remember old screen saver settings
-        XGetScreenSaver( _glfwLibrary.Dpy, &_glfwWin.Saver.Timeout,
-                         &_glfwWin.Saver.Interval, &_glfwWin.Saver.Blanking,
-                         &_glfwWin.Saver.Exposure );
-
-        // Disable screen saver
-        XSetScreenSaver( _glfwLibrary.Dpy, 0, 0, DontPreferBlanking,
-                         DefaultExposures );
-    }
-
-    // Attributes for window
-    wa.colormap = cmap;
-    wa.border_pixel = 0;
-    wa.event_mask = StructureNotifyMask | KeyPressMask | KeyReleaseMask |
-        PointerMotionMask | ButtonPressMask | ButtonReleaseMask |
-        ExposureMask | FocusChangeMask | VisibilityChangeMask;
-
-    // Create a window
-    _glfwWin.Win = XCreateWindow(
-        _glfwLibrary.Dpy,
-        RootWindow( _glfwLibrary.Dpy, _glfwWin.VI->screen ),
-        0, 0,                            // Upper left corner
-        _glfwWin.Width, _glfwWin.Height, // Width, height
-        0,                               // Borderwidth
-        _glfwWin.VI->depth,              // Depth
-        InputOutput,
-        _glfwWin.VI->visual,
-        CWBorderPixel | CWColormap | CWEventMask,
-        &wa
-    );
-    if( !_glfwWin.Win )
-    {
-        _glfwPlatformCloseWindow();
-        return GL_FALSE;
-    }
-
-    // Get the delete window WM protocol atom
-    _glfwWin.WMDeleteWindow = XInternAtom( _glfwLibrary.Dpy,
-                                           "WM_DELETE_WINDOW",
-                                           False );
-
-    // Get the ping WM protocol atom
-    _glfwWin.WMPing = XInternAtom( _glfwLibrary.Dpy, "_NET_WM_PING", False );
-
-    protocols[0] = _glfwWin.WMDeleteWindow;
-    protocols[1] = _glfwWin.WMPing;
-
-    // Allow us to trap the Window Close protocol
-    XSetWMProtocols( _glfwLibrary.Dpy, _glfwWin.Win, protocols,
-                     sizeof(protocols) / sizeof(Atom) );
-
-    // Remove window decorations for fullscreen windows
-    if( mode == GLFW_FULLSCREEN )
-    {
-        _glfwDisableDecorations();
-    }
-
-    _glfwWin.Hints = XAllocSizeHints();
-
-    if( hints->WindowNoResize )
-    {
-	_glfwWin.Hints->flags |= (PMinSize | PMaxSize);
-        _glfwWin.Hints->min_width = _glfwWin.Hints->max_width = _glfwWin.Width;
-        _glfwWin.Hints->min_height = _glfwWin.Hints->max_height = _glfwWin.Height;
-    }
-
-    if( mode == GLFW_FULLSCREEN )
-    {
-	_glfwWin.Hints->flags |= PPosition;
-	_glfwWin.Hints->x = 0;
-	_glfwWin.Hints->y = 0;
-    }
-
-    XSetWMNormalHints( _glfwLibrary.Dpy, _glfwWin.Win, _glfwWin.Hints );
-
-    // Map window
-    XMapWindow( _glfwLibrary.Dpy, _glfwWin.Win );
-
-    // Wait for map notification
-    XIfEvent( _glfwLibrary.Dpy, &event, _glfwWaitForMapNotify,
-              (char*)_glfwWin.Win );
-
-    // Make sure that our window ends up on top of things
-    XRaiseWindow( _glfwLibrary.Dpy, _glfwWin.Win );
-
-    // Fullscreen mode "post processing"
-    if( mode == GLFW_FULLSCREEN )
-    {
-#if defined( _GLFW_HAS_XRANDR )
-	// Request screen change notifications
-	if( _glfwLibrary.XRandR.Available )
-	{
-	    XRRSelectInput( _glfwLibrary.Dpy,
-	                    _glfwWin.Win,
-			    RRScreenChangeNotifyMask );
-	}
-#endif
-
-        // Force window position/size (some WMs do their own window
-        // geometry, which we want to override)
-        XMoveWindow( _glfwLibrary.Dpy, _glfwWin.Win, 0, 0 );
-        XResizeWindow( _glfwLibrary.Dpy, _glfwWin.Win, _glfwWin.Width,
-                       _glfwWin.Height );
-
-        // Grab keyboard
-        if( XGrabKeyboard( _glfwLibrary.Dpy, _glfwWin.Win, True,
-                           GrabModeAsync, GrabModeAsync, CurrentTime ) ==
-            GrabSuccess )
-        {
-            _glfwWin.KeyboardGrabbed = GL_TRUE;
-        }
-
-        // Grab mouse cursor
-        if( XGrabPointer( _glfwLibrary.Dpy, _glfwWin.Win, True,
-                          ButtonPressMask | ButtonReleaseMask |
-                          PointerMotionMask, GrabModeAsync, GrabModeAsync,
-                          _glfwWin.Win, None, CurrentTime ) ==
-            GrabSuccess )
-        {
-            _glfwWin.PointerGrabbed = GL_TRUE;
-        }
-
-        // Try to get window inside viewport (for virtual displays) by
-        // moving the mouse cursor to the upper left corner (and then to
-        // the center) - this works for XFree86
-        XWarpPointer( _glfwLibrary.Dpy, None, _glfwWin.Win, 0,0,0,0, 0,0 );
-        XWarpPointer( _glfwLibrary.Dpy, None, _glfwWin.Win, 0,0,0,0,
-                      _glfwWin.Width/2, _glfwWin.Height/2 );
-    }
-
-    // Set window & icon name
-    _glfwPlatformSetWindowTitle( "GLFW Window" );
-
-    // Connect the context to the window
-    glXMakeCurrent( _glfwLibrary.Dpy, _glfwWin.Win, _glfwWin.CX );
-
-    // Start by clearing the front buffer to black (avoid ugly desktop
-    // remains in our OpenGL window)
-    glClear( GL_COLOR_BUFFER_BIT );
-    glXSwapBuffers( _glfwLibrary.Dpy, _glfwWin.Win );
-
-    // Initialize GLX-specific OpenGL extensions
-    _glfwInitGLXExtensions();
-
-    return GL_TRUE;
-}
-
-
-//========================================================================
-// Properly kill the window/video display
-//========================================================================
-
-void _glfwPlatformCloseWindow( void )
-{
-#if defined( _GLFW_HAS_XRANDR )
-    XRRScreenConfiguration *sc;
-    Window root;
-#endif
-
-    // Free WM size hints
-    if( _glfwWin.Hints )
-    {
-	XFree( _glfwWin.Hints );
-	_glfwWin.Hints = NULL;
-    }
-
-    // Do we have a rendering context?
-    if( _glfwWin.CX )
-    {
-        // Release the context
-        glXMakeCurrent( _glfwLibrary.Dpy, None, NULL );
-
-        // Delete the context
-        glXDestroyContext( _glfwLibrary.Dpy, _glfwWin.CX );
-        _glfwWin.CX = NULL;
-    }
-
-    // Ungrab pointer and/or keyboard?
-    if( _glfwWin.KeyboardGrabbed )
-    {
-        XUngrabKeyboard( _glfwLibrary.Dpy, CurrentTime );
-        _glfwWin.KeyboardGrabbed = GL_FALSE;
-    }
-    if( _glfwWin.PointerGrabbed )
-    {
-        XUngrabPointer( _glfwLibrary.Dpy, CurrentTime );
-        _glfwWin.PointerGrabbed = GL_FALSE;
-    }
-
-    // Do we have a window?
-    if( _glfwWin.Win )
-    {
-        // Unmap the window
-        XUnmapWindow( _glfwLibrary.Dpy, _glfwWin.Win );
-
-        // Destroy the window
-        XDestroyWindow( _glfwLibrary.Dpy, _glfwWin.Win );
-        _glfwWin.Win = (Window) 0;
-    }
-
-    // Did we change the fullscreen resolution?
-    if( _glfwWin.FS.ModeChanged )
-    {
-#if defined( _GLFW_HAS_XRANDR )
-	if( _glfwLibrary.XRandR.Available )
-	{
-	    root = RootWindow( _glfwLibrary.Dpy, _glfwWin.Scrn );
-	    sc = XRRGetScreenInfo( _glfwLibrary.Dpy, root );
-
-	    XRRSetScreenConfig( _glfwLibrary.Dpy,
-	                        sc,
-				root,
-			        _glfwWin.FS.OldSizeID,
-				_glfwWin.FS.OldRotation,
-				CurrentTime );
-
-	    XRRFreeScreenConfigInfo( sc );
-	}
-#elif defined( _GLFW_HAS_XF86VIDMODE )
-        if( _glfwLibrary.XF86VidMode.Available )
-        {
-            // Unlock mode switch
-            XF86VidModeLockModeSwitch( _glfwLibrary.Dpy,
-                                       _glfwWin.Scrn,
-                                       0 );
-
-            // Change the video mode back to the old mode
-            XF86VidModeSwitchToMode( _glfwLibrary.Dpy,
-                _glfwWin.Scrn, &_glfwWin.FS.OldMode );
-        }
-#endif
-        _glfwWin.FS.ModeChanged = GL_FALSE;
-    }
-
-    // Did we change the screen saver setting?
-    if( _glfwWin.Saver.Changed )
-    {
-        // Restore old screen saver settings
-        XSetScreenSaver( _glfwLibrary.Dpy, _glfwWin.Saver.Timeout,
-                         _glfwWin.Saver.Interval, _glfwWin.Saver.Blanking,
-                         _glfwWin.Saver.Exposure );
-        _glfwWin.Saver.Changed = GL_FALSE;
-    }
-
-    XSync( _glfwLibrary.Dpy, True );
-}
-
-
-//========================================================================
-// _glfwPlatformSetWindowTitle() - Set the window title.
-//========================================================================
-
-void _glfwPlatformSetWindowTitle( const char *title )
-{
-    // Set window & icon title
-    XStoreName( _glfwLibrary.Dpy, _glfwWin.Win, title );
-    XSetIconName( _glfwLibrary.Dpy, _glfwWin.Win, title );
-}
-
-
-//========================================================================
-// _glfwPlatformSetWindowSize() - Set the window size.
-//========================================================================
-
-void _glfwPlatformSetWindowSize( int width, int height )
-{
-    int     mode = 0, rate, sizechanged = GL_FALSE;
-    GLint   drawbuffer;
-    GLfloat clearcolor[4];
-
-    rate = _glfwWin.RefreshRate;
-
-    // If we are in fullscreen mode, get some info about the current mode
-    if( _glfwWin.Fullscreen )
-    {
-        // Get closest match for target video mode
-        mode = _glfwGetClosestVideoMode( _glfwWin.Scrn, &width, &height, &rate );
-    }
-
-    if( _glfwWin.WindowNoResize )
-    {
-        _glfwWin.Hints->min_width = _glfwWin.Hints->max_width = width;
-        _glfwWin.Hints->min_height = _glfwWin.Hints->max_height = height;
-    }
-
-    XSetWMNormalHints( _glfwLibrary.Dpy, _glfwWin.Win, _glfwWin.Hints );
-
-    // Change window size before changing fullscreen mode?
-    if( _glfwWin.Fullscreen && (width > _glfwWin.Width) )
-    {
-        XResizeWindow( _glfwLibrary.Dpy, _glfwWin.Win, width, height );
-        sizechanged = GL_TRUE;
-    }
-
-    // Change fullscreen video mode?
-    if( _glfwWin.Fullscreen )
-    {
-        // Change video mode (keeping current rate)
-        _glfwSetVideoModeMODE( _glfwWin.Scrn, mode, _glfwWin.RefreshRate );
-
-        // Clear the front buffer to black (avoid ugly desktop remains in
-        // our OpenGL window)
-        glGetIntegerv( GL_DRAW_BUFFER, &drawbuffer );
-        glGetFloatv( GL_COLOR_CLEAR_VALUE, clearcolor );
-        glClearColor( 0.0f, 0.0f, 0.0f, 0.0f );
-        glClear( GL_COLOR_BUFFER_BIT );
-        if( drawbuffer == GL_BACK )
-        {
-            glXSwapBuffers( _glfwLibrary.Dpy, _glfwWin.Win );
-        }
-        glClearColor( clearcolor[0], clearcolor[1], clearcolor[2],
-                      clearcolor[3] );
-    }
-
-    // Set window size (if not already changed)
-    if( !sizechanged )
-    {
-        XResizeWindow( _glfwLibrary.Dpy, _glfwWin.Win, width, height );
-    }
-}
-
-
-//========================================================================
-// _glfwPlatformSetWindowPos() - Set the window position.
-//========================================================================
-
-void _glfwPlatformSetWindowPos( int x, int y )
-{
-    // Set window position
-    XMoveWindow( _glfwLibrary.Dpy, _glfwWin.Win, x, y );
-}
-
-
-//========================================================================
-// _glfwPlatformIconfyWindow() - Window iconification
-//========================================================================
-
-void _glfwPlatformIconifyWindow( void )
-{
-    // We can't do this for override redirect windows
-    if( _glfwWin.OverrideRedirect )
-    {
-        return;
-    }
-
-    // In fullscreen mode, we need to restore the desktop video mode
-    if( _glfwWin.Fullscreen )
-    {
-#if defined( _GLFW_HAS_XF86VIDMODE )
-        if( _glfwLibrary.XF86VidMode.Available )
-        {
-            // Unlock mode switch
-            XF86VidModeLockModeSwitch( _glfwLibrary.Dpy,
-                                       _glfwWin.Scrn,
-                                       0 );
-
-            // Change the video mode back to the old mode
-            XF86VidModeSwitchToMode( _glfwLibrary.Dpy,
-                _glfwWin.Scrn, &_glfwWin.FS.OldMode );
-        }
-#endif
-        _glfwWin.FS.ModeChanged = GL_FALSE;
-    }
-
-    // Show mouse pointer
-    if( _glfwWin.PointerHidden )
-    {
-        XUndefineCursor( _glfwLibrary.Dpy, _glfwWin.Win );
-        _glfwWin.PointerHidden = GL_FALSE;
-    }
-
-    // Un-grab mouse pointer
-    if( _glfwWin.PointerGrabbed )
-    {
-        XUngrabPointer( _glfwLibrary.Dpy, CurrentTime );
-        _glfwWin.PointerGrabbed = GL_FALSE;
-    }
-
-    // Iconify window
-    XIconifyWindow( _glfwLibrary.Dpy, _glfwWin.Win,
-                    _glfwWin.Scrn );
-
-    // Window is now iconified
-    _glfwWin.Iconified = GL_TRUE;
-}
-
-
-//========================================================================
-// Window un-iconification
-//========================================================================
-
-void _glfwPlatformRestoreWindow( void )
-{
-    // We can't do this for override redirect windows
-    if( _glfwWin.OverrideRedirect )
-    {
-        return;
-    }
-
-    // In fullscreen mode, change back video mode to user selected mode
-    if( _glfwWin.Fullscreen )
-    {
-        _glfwSetVideoMode( _glfwWin.Scrn,
-	                   &_glfwWin.Width, &_glfwWin.Height, &_glfwWin.RefreshRate );
-    }
-
-    // Un-iconify window
-    XMapWindow( _glfwLibrary.Dpy, _glfwWin.Win );
-
-    // In fullscreen mode...
-    if( _glfwWin.Fullscreen )
-    {
-        // Make sure window is in upper left corner
-        XMoveWindow( _glfwLibrary.Dpy, _glfwWin.Win, 0, 0 );
-
-        // Get input focus
-        XSetInputFocus( _glfwLibrary.Dpy, _glfwWin.Win, RevertToParent,
-                        CurrentTime );
-    }
-
-    // Lock mouse, if necessary
-    if( _glfwWin.MouseLock )
-    {
-        // Hide cursor
-        if( !_glfwWin.PointerHidden )
-        {
-            XDefineCursor( _glfwLibrary.Dpy, _glfwWin.Win,
-                           _glfwCreateNULLCursor( _glfwLibrary.Dpy,
-                                                  _glfwWin.Win ) );
-            _glfwWin.PointerHidden = GL_TRUE;
-        }
-
-        // Grab cursor
-        if( !_glfwWin.PointerGrabbed )
-        {
-            if( XGrabPointer( _glfwLibrary.Dpy, _glfwWin.Win, True,
-                              ButtonPressMask | ButtonReleaseMask |
-                              PointerMotionMask, GrabModeAsync,
-                              GrabModeAsync, _glfwWin.Win, None,
-                              CurrentTime ) == GrabSuccess )
-            {
-                _glfwWin.PointerGrabbed = GL_TRUE;
-            }
-        }
-    }
-
-    // Window is no longer iconified
-    _glfwWin.Iconified = GL_FALSE;
-}
-
-
-//========================================================================
-// _glfwPlatformSwapBuffers() - Swap buffers (double-buffering) and poll
-// any new events.
-//========================================================================
-
-void _glfwPlatformSwapBuffers( void )
-{
-    // Update display-buffer
-    glXSwapBuffers( _glfwLibrary.Dpy, _glfwWin.Win );
-}
-
-
-//========================================================================
-// _glfwPlatformSwapInterval() - Set double buffering swap interval
-//========================================================================
-
-void _glfwPlatformSwapInterval( int interval )
-{
-    if( _glfwWin.SwapInterval )
-    {
-        _glfwWin.SwapInterval( interval );
-    }
-}
-
-
-//========================================================================
-// _glfwPlatformRefreshWindowParams()
-//========================================================================
-
-void _glfwPlatformRefreshWindowParams( void )
-{
-#if defined( _GLFW_HAS_XRANDR )
-    XRRScreenConfiguration *sc;
-#elif defined( _GLFW_HAS_XF86VIDMODE )
-    XF86VidModeModeLine modeline;
-    int dotclock;
-    float pixels_per_second, pixels_per_frame;
-#endif
-    int sample_buffers;
-
-    // AFAIK, there is no easy/sure way of knowing if OpenGL is hardware
-    // accelerated
-    _glfwWin.Accelerated = GL_TRUE;
-
-    // "Standard" window parameters
-    glXGetConfig( _glfwLibrary.Dpy, _glfwWin.VI, GLX_RED_SIZE,
-                  &_glfwWin.RedBits );
-    glXGetConfig( _glfwLibrary.Dpy, _glfwWin.VI, GLX_GREEN_SIZE,
-                  &_glfwWin.GreenBits );
-    glXGetConfig( _glfwLibrary.Dpy, _glfwWin.VI, GLX_BLUE_SIZE,
-                  &_glfwWin.BlueBits );
-    glXGetConfig( _glfwLibrary.Dpy, _glfwWin.VI, GLX_ALPHA_SIZE,
-                  &_glfwWin.AlphaBits );
-    glXGetConfig( _glfwLibrary.Dpy, _glfwWin.VI, GLX_DEPTH_SIZE,
-                  &_glfwWin.DepthBits );
-    glXGetConfig( _glfwLibrary.Dpy, _glfwWin.VI, GLX_STENCIL_SIZE,
-                  &_glfwWin.StencilBits );
-    glXGetConfig( _glfwLibrary.Dpy, _glfwWin.VI, GLX_ACCUM_RED_SIZE,
-                  &_glfwWin.AccumRedBits );
-    glXGetConfig( _glfwLibrary.Dpy, _glfwWin.VI, GLX_ACCUM_GREEN_SIZE,
-                  &_glfwWin.AccumGreenBits );
-    glXGetConfig( _glfwLibrary.Dpy, _glfwWin.VI, GLX_ACCUM_BLUE_SIZE,
-                  &_glfwWin.AccumBlueBits );
-    glXGetConfig( _glfwLibrary.Dpy, _glfwWin.VI, GLX_ACCUM_ALPHA_SIZE,
-                  &_glfwWin.AccumAlphaBits );
-    glXGetConfig( _glfwLibrary.Dpy, _glfwWin.VI, GLX_AUX_BUFFERS,
-                  &_glfwWin.AuxBuffers );
-
-    // Get stereo rendering setting
-    glXGetConfig( _glfwLibrary.Dpy, _glfwWin.VI, GLX_STEREO,
-                  &_glfwWin.Stereo );
-    _glfwWin.Stereo = _glfwWin.Stereo ? 1 : 0;
-
-    // Get multisample buffer samples
-    glXGetConfig( _glfwLibrary.Dpy, _glfwWin.VI, GLX_SAMPLES,
-		  &_glfwWin.Samples );
-    glXGetConfig( _glfwLibrary.Dpy, _glfwWin.VI, GLX_SAMPLE_BUFFERS, 
-		  &sample_buffers );
-    if( sample_buffers == 0 )
-      _glfwWin.Samples = 0;
-    
-    // Default to refresh rate unknown (=0 according to GLFW spec)
-    _glfwWin.RefreshRate = 0;
-		  
-    // Retrieve refresh rate, if possible
-#if defined( _GLFW_HAS_XRANDR )
-    if( _glfwLibrary.XRandR.Available )
-    {
-	sc = XRRGetScreenInfo( _glfwLibrary.Dpy,
-	                       RootWindow( _glfwLibrary.Dpy, _glfwWin.Scrn ) );
-	_glfwWin.RefreshRate = XRRConfigCurrentRate( sc );
-	XRRFreeScreenConfigInfo( sc );
-    }
-#elif defined( _GLFW_HAS_XF86VIDMODE )
-    if( _glfwLibrary.XF86VidMode.Available )
-    {
-        // Use the XF86VidMode extension to get current video mode
-        XF86VidModeGetModeLine( _glfwLibrary.Dpy, _glfwWin.Scrn,
-                                &dotclock, &modeline );
-        pixels_per_second = 1000.0f * (float) dotclock;
-        pixels_per_frame  = (float) modeline.htotal * modeline.vtotal;
-        _glfwWin.RefreshRate = (int)(pixels_per_second/pixels_per_frame+0.5);
-    }
-#endif
-}
-
-
-//========================================================================
-// _glfwPlatformPollEvents() - Poll for new window and input events
-//========================================================================
-
-void _glfwPlatformPollEvents( void )
-{
-    int winclosed = GL_FALSE;
-
-    // Flag that the cursor has not moved
-    _glfwInput.MouseMoved = GL_FALSE;
-
-    // Clear MapNotify and FocusIn counts
-    _glfwWin.MapNotifyCount = 0;
-    _glfwWin.FocusInCount = 0;
-
-    // Use XSync to synchronise events to the X display.
-    // I don't know if this can have a serious performance impact. My
-    // benchmarks with a GeForce card under Linux shows no difference with
-    // or without XSync, but when the GL window is rendered over a slow
-    // network I have noticed bad event syncronisation problems when XSync
-    // is not used, so I decided to use it.
-    XSync( _glfwLibrary.Dpy, False );
-
-    // Empty the window event queue
-    while( XPending( _glfwLibrary.Dpy ) )
-    {
-        if( _glfwGetNextEvent() )
-        {
-            winclosed = GL_TRUE;
-        }
-    }
-
-    // Did we get mouse movement in locked cursor mode?
-    if( _glfwInput.MouseMoved && _glfwWin.MouseLock )
-    {
-        int maxx, minx, maxy, miny;
-
-        // Calculate movement threshold
-        minx = _glfwWin.Width / 4;
-        maxx = (_glfwWin.Width * 3) / 4;
-        miny = _glfwWin.Height / 4;
-        maxy = (_glfwWin.Height * 3) / 4;
-
-        // Did the mouse cursor move beyond our movement threshold
-        if(_glfwInput.CursorPosX < minx || _glfwInput.CursorPosX > maxx ||
-           _glfwInput.CursorPosY < miny || _glfwInput.CursorPosY > maxy)
-        {
-            // Move the mouse pointer back to the window center so that it
-            // does not wander off...
-            _glfwPlatformSetMouseCursorPos( _glfwWin.Width/2,
-                                            _glfwWin.Height/2 );
-            XSync( _glfwLibrary.Dpy, False );
-        }
-    }
-
-    // Was the window (un)iconified?
-    if( _glfwWin.MapNotifyCount < 0 && !_glfwWin.Iconified )
-    {
-        // Show mouse pointer
-        if( _glfwWin.PointerHidden )
-        {
-            XUndefineCursor( _glfwLibrary.Dpy, _glfwWin.Win );
-            _glfwWin.PointerHidden = GL_FALSE;
-        }
-
-        // Un-grab mouse pointer
-        if( _glfwWin.PointerGrabbed )
-        {
-            XUngrabPointer( _glfwLibrary.Dpy, CurrentTime );
-            _glfwWin.PointerGrabbed = GL_FALSE;
-        }
-
-        _glfwWin.Iconified = GL_TRUE;
-    }
-    else if( _glfwWin.MapNotifyCount > 0 && _glfwWin.Iconified )
-    {
-        // Restore fullscreen mode properties
-        if( _glfwWin.Fullscreen )
-        {
-            // Change back video mode to user selected mode
-            _glfwSetVideoMode( _glfwWin.Scrn, &_glfwWin.Width,
-                               &_glfwWin.Height, &_glfwWin.RefreshRate );
-
-            // Disable window manager decorations
-            _glfwEnableDecorations();
-
-            // Make sure window is in upper left corner
-            XMoveWindow( _glfwLibrary.Dpy, _glfwWin.Win, 0, 0 );
-
-            // Get input focus
-            XSetInputFocus( _glfwLibrary.Dpy, _glfwWin.Win,
-                            RevertToParent, CurrentTime );
-        }
-
-        // Hide cursor if necessary
-        if( _glfwWin.MouseLock && !_glfwWin.PointerHidden )
-        {
-            if( !_glfwWin.PointerHidden )
-            {
-                XDefineCursor( _glfwLibrary.Dpy, _glfwWin.Win,
-                    _glfwCreateNULLCursor( _glfwLibrary.Dpy,
-                                           _glfwWin.Win ) );
-                _glfwWin.PointerHidden = GL_TRUE;
-            }
-        }
-
-        // Grab cursor if necessary
-        if( (_glfwWin.MouseLock || _glfwWin.Fullscreen) &&
-            !_glfwWin.PointerGrabbed )
-        {
-            if( XGrabPointer( _glfwLibrary.Dpy, _glfwWin.Win, True,
-                    ButtonPressMask | ButtonReleaseMask |
-                    PointerMotionMask, GrabModeAsync,
-                    GrabModeAsync, _glfwWin.Win, None,
-                    CurrentTime ) == GrabSuccess )
-            {
-                _glfwWin.PointerGrabbed = GL_TRUE;
-            }
-        }
-
-        _glfwWin.Iconified = GL_FALSE;
-    }
-
-    // Did the window get/lose focus
-    if( _glfwWin.FocusInCount > 0 && !_glfwWin.Active )
-    {
-        // If we are in fullscreen mode, restore window
-        if( _glfwWin.Fullscreen && _glfwWin.Iconified )
-        {
-            _glfwPlatformRestoreWindow();
-        }
-
-        // Window is now active
-        _glfwWin.Active = GL_TRUE;
-    }
-    else if( _glfwWin.FocusInCount < 0 && _glfwWin.Active )
-    {
-        // If we are in fullscreen mode, iconfify window
-        if( _glfwWin.Fullscreen )
-        {
-            _glfwPlatformIconifyWindow();
-        }
-
-        // Window is not active
-        _glfwWin.Active = GL_FALSE;
-	_glfwInputDeactivation();
-    }
-
-    // Was there a window close request?
-    if( winclosed && _glfwWin.WindowCloseCallback )
-    {
-        // Check if the program wants us to close the window
-        winclosed = _glfwWin.WindowCloseCallback();
-    }
-    if( winclosed )
-    {
-        glfwCloseWindow();
-    }
-}
-
-
-//========================================================================
-// _glfwPlatformWaitEvents() - Wait for new window and input events
-//========================================================================
-
-void _glfwPlatformWaitEvents( void )
-{
-    XEvent event;
-
-    // Wait for new events (blocking)
-    XNextEvent( _glfwLibrary.Dpy, &event );
-    XPutBackEvent( _glfwLibrary.Dpy, &event );
-
-    // Poll events from queue
-    _glfwPlatformPollEvents();
-}
-
-
-//========================================================================
-// _glfwPlatformHideMouseCursor() - Hide mouse cursor (lock it)
-//========================================================================
-
-void _glfwPlatformHideMouseCursor( void )
-{
-    // Hide cursor
-    if( !_glfwWin.PointerHidden )
-    {
-        XDefineCursor( _glfwLibrary.Dpy, _glfwWin.Win,
-                       _glfwCreateNULLCursor( _glfwLibrary.Dpy,
-                                              _glfwWin.Win ) );
-        _glfwWin.PointerHidden = GL_TRUE;
-    }
-
-    // Grab cursor to user window
-    if( !_glfwWin.PointerGrabbed )
-    {
-        if( XGrabPointer( _glfwLibrary.Dpy, _glfwWin.Win, True,
-                          ButtonPressMask | ButtonReleaseMask |
-                          PointerMotionMask, GrabModeAsync, GrabModeAsync,
-                          _glfwWin.Win, None, CurrentTime ) ==
-            GrabSuccess )
-        {
-            _glfwWin.PointerGrabbed = GL_TRUE;
-        }
-    }
-}
-
-
-//========================================================================
-// _glfwPlatformShowMouseCursor() - Show mouse cursor (unlock it)
-//========================================================================
-
-void _glfwPlatformShowMouseCursor( void )
-{
-    // Un-grab cursor (only in windowed mode: in fullscreen mode we still
-    // want the mouse grabbed in order to confine the cursor to the window
-    // area)
-    if( _glfwWin.PointerGrabbed && !_glfwWin.Fullscreen )
-    {
-        XUngrabPointer( _glfwLibrary.Dpy, CurrentTime );
-        _glfwWin.PointerGrabbed = GL_FALSE;
-    }
-
-    // Show cursor
-    if( _glfwWin.PointerHidden )
-    {
-        XUndefineCursor( _glfwLibrary.Dpy, _glfwWin.Win );
-        _glfwWin.PointerHidden = GL_FALSE;
-    }
-}
-
-
-//========================================================================
-// _glfwPlatformSetMouseCursorPos() - Set physical mouse cursor position
-//========================================================================
-
-void _glfwPlatformSetMouseCursorPos( int x, int y )
-{
-    // Change cursor position
-    _glfwInput.CursorPosX = x;
-    _glfwInput.CursorPosY = y;
-    XWarpPointer( _glfwLibrary.Dpy, None, _glfwWin.Win, 0,0,0,0, x, y );
+// Platform:    X11/GLX
+// API version: 2.7
+// WWW:         http://www.glfw.org/
+//------------------------------------------------------------------------
+// Copyright (c) 2002-2006 Marcus Geelnard
+// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org>
+//
+// 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>
+
+
+/* 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*/
+
+// Action for EWMH client messages
+#define _NET_WM_STATE_REMOVE        0
+#define _NET_WM_STATE_ADD           1
+#define _NET_WM_STATE_TOGGLE        2
+
+
+//************************************************************************
+//****                  GLFW internal functions                       ****
+//************************************************************************
+
+//========================================================================
+// Error handler for BadMatch errors when requesting context with
+// unavailable OpenGL versions using the GLX_ARB_create_context extension
+//========================================================================
+
+static int errorHandler( Display *display, XErrorEvent *event )
+{
+    return 0;
+}
+
+
+//========================================================================
+// 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);
+}
+
+
+//========================================================================
+// Retrieve a single window property of the specified type
+// Inspired by fghGetWindowProperty from freeglut
+//========================================================================
+
+static unsigned long getWindowProperty( Window window,
+                                        Atom property,
+                                        Atom type,
+                                        unsigned char** value )
+{
+    Atom actualType;
+    int actualFormat;
+    unsigned long itemCount, bytesAfter;
+
+    XGetWindowProperty( _glfwLibrary.display,
+                        window,
+                        property,
+                        0,
+                        LONG_MAX,
+                        False,
+                        type,
+                        &actualType,
+                        &actualFormat,
+                        &itemCount,
+                        &bytesAfter,
+                        value );
+
+    if( actualType != type )
+    {
+        return 0;
+    }
+
+    return itemCount;
+}
+
+
+//========================================================================
+// Check whether the specified atom is supported
+//========================================================================
+
+static Atom getSupportedAtom( Atom* supportedAtoms,
+                              unsigned long atomCount,
+                              const char* atomName )
+{
+    Atom atom = XInternAtom( _glfwLibrary.display, atomName, True );
+    if( atom != None )
+    {
+        unsigned long i;
+
+        for( i = 0;  i < atomCount;  i++ )
+        {
+            if( supportedAtoms[i] == atom )
+            {
+                return atom;
+            }
+        }
+    }
+
+    return None;
+}
+
+
+//========================================================================
+// Check whether the running window manager is EWMH-compliant
+//========================================================================
+
+static GLboolean checkForEWMH( void )
+{
+    Window *windowFromRoot = NULL;
+    Window *windowFromChild = NULL;
+
+    // Hey kids; let's see if the window manager supports EWMH!
+
+    // First we need a couple of atoms, which should already be there
+    Atom supportingWmCheck = XInternAtom( _glfwLibrary.display,
+                                          "_NET_SUPPORTING_WM_CHECK",
+                                          True );
+    Atom wmSupported = XInternAtom( _glfwLibrary.display,
+                                    "_NET_SUPPORTED",
+                                    True );
+    if( supportingWmCheck == None || wmSupported == None )
+    {
+        return GL_FALSE;
+    }
+
+    // Then we look for the _NET_SUPPORTING_WM_CHECK property of the root window
+    if( getWindowProperty( _glfwWin.root,
+                           supportingWmCheck,
+                           XA_WINDOW,
+                           (unsigned char**) &windowFromRoot ) != 1 )
+    {
+        XFree( windowFromRoot );
+        return GL_FALSE;
+    }
+
+    // It should be the ID of a child window (of the root)
+    // Then we look for the same property on the child window
+    if( getWindowProperty( *windowFromRoot,
+                           supportingWmCheck,
+                           XA_WINDOW,
+                           (unsigned char**) &windowFromChild ) != 1 )
+    {
+        XFree( windowFromRoot );
+        XFree( windowFromChild );
+        return GL_FALSE;
+    }
+
+    // It should be the ID of that same child window
+    if( *windowFromRoot != *windowFromChild )
+    {
+        XFree( windowFromRoot );
+        XFree( windowFromChild );
+        return GL_FALSE;
+    }
+
+    XFree( windowFromRoot );
+    XFree( windowFromChild );
+
+    // We are now fairly sure that an EWMH-compliant window manager is running
+
+    Atom *supportedAtoms;
+    unsigned long atomCount;
+
+    // Now we need to check the _NET_SUPPORTED property of the root window
+    atomCount = getWindowProperty( _glfwWin.root,
+                                   wmSupported,
+                                   XA_ATOM,
+                                   (unsigned char**) &supportedAtoms );
+
+    // See which of the atoms we support that are supported by the WM
+
+    _glfwWin.wmState = getSupportedAtom( supportedAtoms,
+                                         atomCount,
+                                         "_NET_WM_STATE" );
+
+    _glfwWin.wmStateFullscreen = getSupportedAtom( supportedAtoms,
+                                                   atomCount,
+                                                   "_NET_WM_STATE_FULLSCREEN" );
+
+    _glfwWin.wmPing = getSupportedAtom( supportedAtoms,
+                                        atomCount,
+                                        "_NET_WM_PING" );
+
+    _glfwWin.wmActiveWindow = getSupportedAtom( supportedAtoms,
+                                                atomCount,
+                                                "_NET_ACTIVE_WINDOW" );
+
+    XFree( supportedAtoms );
+
+    return GL_TRUE;
+}
+
+//========================================================================
+// 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 );
+}
+
+
+//========================================================================
+// 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\n" );
+            return NULL;
+        }
+    }
+    else
+    {
+        fbconfigs = glXGetFBConfigs( _glfwLibrary.display, _glfwWin.screen, &count );
+        if( !count )
+        {
+            fprintf( stderr, "No GLXFBConfigs returned\n" );
+            return NULL;
+        }
+    }
+
+    result = (_GLFWfbconfig*) malloc( sizeof(_GLFWfbconfig) * count );
+    if( !result )
+    {
+        fprintf( stderr, "Out of memory\n" );
+        return NULL;
+    }
+
+    for( i = 0;  i < count;  i++ )
+    {
+        if( !getFBConfigAttrib( fbconfigs[i], GLX_DOUBLEBUFFER ) ||
+            !getFBConfigAttrib( fbconfigs[i], GLX_VISUAL_ID ) )
+        {
+            // Only consider double-buffered 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;
+
+    // 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 != 1 || 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 );
+
+        // This is the only place we set an Xlib error handler, and we only do
+        // it because glXCreateContextAttribsARB generates a BadMatch error if
+        // the requested OpenGL version is unavailable (instead of a civilized
+        // response like returning NULL)
+        XSetErrorHandler( errorHandler );
+
+        _glfwWin.context = _glfwWin.CreateContextAttribsARB( _glfwLibrary.display,
+                                                             *fbconfig,
+                                                             NULL,
+                                                             True,
+                                                             attribs );
+
+        // We are done, so unset the error handler again (see above)
+        XSetErrorHandler( NULL );
+    }
+    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;
+}
+
+#undef setGLXattrib
+
+
+//========================================================================
+// 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;
+    unsigned long wamask;
+    XSetWindowAttributes wa;
+
+    // Every window needs a colormap
+    // Create one based on the visual used by the current context
+
+    _glfwWin.colormap = XCreateColormap( _glfwLibrary.display,
+                                         _glfwWin.root,
+                                         _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
+            // that 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,
+            _glfwWin.root,
+            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;
+        }
+    }
+
+    // Check whether an EWMH-compliant window manager is running
+    _glfwWin.hasEWMH = checkForEWMH();
+
+    if( _glfwWin.fullscreen && !_glfwWin.hasEWMH )
+    {
+        // This is the butcher's way of removing window decorations
+        // Setting the override-redirect attribute on a window makes the window
+        // manager ignore the window completely (ICCCM, section 4)
+        // The good thing is that this makes undecorated fullscreen windows
+        // easy to do; the bad thing is that we have to do everything manually
+        // and some things (like iconify/restore) won't work at all, as they're
+        // usually performed by the window manager
+
+        XSetWindowAttributes attributes;
+        attributes.override_redirect = True;
+        XChangeWindowAttributes( _glfwLibrary.display,
+                                 _glfwWin.window,
+                                 CWOverrideRedirect,
+                                 &attributes );
+
+        _glfwWin.overrideRedirect = GL_TRUE;
+    }
+
+    // Find or create the protocol atom for window close notifications
+    _glfwWin.wmDeleteWindow = XInternAtom( _glfwLibrary.display,
+                                            "WM_DELETE_WINDOW",
+                                            False );
+
+    // Declare the WM protocols we support
+    {
+        int count = 0;
+        Atom protocols[2];
+
+        // The WM_DELETE_WINDOW ICCCM protocol
+        // Basic window close notification protocol
+        if( _glfwWin.wmDeleteWindow != None )
+        {
+            protocols[count++] = _glfwWin.wmDeleteWindow;
+        }
+
+        // The _NET_WM_PING EWMH protocol
+        // Tells the WM to ping our window and flag us as unresponsive if we
+        // don't reply within a few seconds
+        if( _glfwWin.wmPing != None )
+        {
+            protocols[count++] = _glfwWin.wmPing;
+        }
+
+        if( count > 0 )
+        {
+            XSetWMProtocols( _glfwLibrary.display, _glfwWin.window,
+                             protocols, count );
+        }
+    }
+
+    // Set ICCCM WM_HINTS property
+    {
+        XWMHints *hints = XAllocWMHints();
+        if( !hints )
+        {
+            _glfwPlatformCloseWindow();
+            return GL_FALSE;
+        }
+
+        hints->flags = StateHint;
+        hints->initial_state = NormalState;
+
+        XSetWMHints( _glfwLibrary.display, _glfwWin.window, hints );
+        XFree( hints );
+    }
+
+    // Set ICCCM WM_NORMAL_HINTS property (even if no parts are set)
+    {
+        XSizeHints *hints = XAllocSizeHints();
+        if( !hints )
+        {
+            _glfwPlatformCloseWindow();
+            return GL_FALSE;
+        }
+
+        hints->flags = 0;
+
+        if( wndconfig->windowNoResize && !_glfwWin.fullscreen )
+        {
+            hints->flags |= (PMinSize | PMaxSize);
+            hints->min_width  = hints->max_width  = _glfwWin.width;
+            hints->min_height = hints->max_height = _glfwWin.height;
+        }
+
+        XSetWMNormalHints( _glfwLibrary.display, _glfwWin.window, hints );
+        XFree( hints );
+    }
+
+    _glfwPlatformSetWindowTitle( "GLFW Window" );
+
+    // Make sure the window is mapped before proceeding
+    XMapWindow( _glfwLibrary.display, _glfwWin.window );
+    XPeekIfEvent( _glfwLibrary.display, &event, isMapNotify,
+                  (char*)_glfwWin.window );
+
+    return GL_TRUE;
+}
+
+
+//========================================================================
+// Enter fullscreen mode
+//========================================================================
+
+static void enterFullscreenMode( void )
+{
+    if( !_glfwWin.Saver.changed )
+    {
+        // 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 );
+
+        _glfwWin.Saver.changed = GL_TRUE;
+    }
+
+    _glfwSetVideoMode( _glfwWin.screen,
+                       &_glfwWin.width, &_glfwWin.height,
+                       &_glfwWin.refreshRate );
+
+    if( _glfwWin.hasEWMH &&
+        _glfwWin.wmState != None &&
+        _glfwWin.wmStateFullscreen != None )
+    {
+        if( _glfwWin.wmActiveWindow != None )
+        {
+            // Ask the window manager to raise and focus the GLFW window
+            // Only focused windows with the _NET_WM_STATE_FULLSCREEN state end
+            // up on top of all other windows ("Stacking order" in EWMH spec)
+
+            XEvent event;
+            memset( &event, 0, sizeof(event) );
+
+            event.type = ClientMessage;
+            event.xclient.window = _glfwWin.window;
+            event.xclient.format = 32; // Data is 32-bit longs
+            event.xclient.message_type = _glfwWin.wmActiveWindow;
+            event.xclient.data.l[0] = 1; // Sender is a normal application
+            event.xclient.data.l[1] = 0; // We don't really know the timestamp
+
+            XSendEvent( _glfwLibrary.display,
+                        _glfwWin.root,
+                        False,
+                        SubstructureNotifyMask | SubstructureRedirectMask,
+                        &event );
+        }
+
+        // Ask the window manager to make the GLFW window a fullscreen window
+        // Fullscreen windows are undecorated and, when focused, are kept
+        // on top of all other windows
+
+        XEvent event;
+        memset( &event, 0, sizeof(event) );
+
+        event.type = ClientMessage;
+        event.xclient.window = _glfwWin.window;
+        event.xclient.format = 32; // Data is 32-bit longs
+        event.xclient.message_type = _glfwWin.wmState;
+        event.xclient.data.l[0] = _NET_WM_STATE_ADD;
+        event.xclient.data.l[1] = _glfwWin.wmStateFullscreen;
+        event.xclient.data.l[2] = 0; // No secondary property
+        event.xclient.data.l[3] = 1; // Sender is a normal application
+
+        XSendEvent( _glfwLibrary.display,
+                    _glfwWin.root,
+                    False,
+                    SubstructureNotifyMask | SubstructureRedirectMask,
+                    &event );
+    }
+    else if( _glfwWin.overrideRedirect )
+    {
+        // In override-redirect mode, we have divorced ourselves from the
+        // window manager, so we need to do everything manually
+
+        XRaiseWindow( _glfwLibrary.display, _glfwWin.window );
+        XSetInputFocus( _glfwLibrary.display, _glfwWin.window,
+                        RevertToParent, CurrentTime );
+        XMoveWindow( _glfwLibrary.display, _glfwWin.window, 0, 0 );
+        XResizeWindow( _glfwLibrary.display, _glfwWin.window,
+                       _glfwWin.width, _glfwWin.height );
+    }
+
+    if( _glfwWin.mouseLock )
+    {
+        _glfwPlatformHideMouseCursor();
+    }
+
+    // HACK: 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 hack should be harmless on saner systems as well
+    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 );
+}
+
+//========================================================================
+// Leave fullscreen mode
+//========================================================================
+
+static void leaveFullscreenMode( void )
+{
+    _glfwRestoreVideoMode();
+
+    // 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;
+    }
+
+    if( _glfwWin.hasEWMH &&
+        _glfwWin.wmState != None &&
+        _glfwWin.wmStateFullscreen != None )
+    {
+        // Ask the window manager to make the GLFW window a normal window
+        // Normal windows usually have frames and other decorations
+
+        XEvent event;
+        memset( &event, 0, sizeof(event) );
+
+        event.type = ClientMessage;
+        event.xclient.window = _glfwWin.window;
+        event.xclient.format = 32; // Data is 32-bit longs
+        event.xclient.message_type = _glfwWin.wmState;
+        event.xclient.data.l[0] = _NET_WM_STATE_REMOVE;
+        event.xclient.data.l[1] = _glfwWin.wmStateFullscreen;
+        event.xclient.data.l[2] = 0; // No secondary property
+        event.xclient.data.l[3] = 1; // Sender is a normal application
+
+        XSendEvent( _glfwLibrary.display,
+                    _glfwWin.root,
+                    False,
+                    SubstructureNotifyMask | SubstructureRedirectMask,
+                    &event );
+    }
+
+    if( _glfwWin.mouseLock )
+    {
+        _glfwPlatformShowMouseCursor();
+    }
+}
+
+//========================================================================
+// Get and process next X event (called by _glfwPlatformPollEvents)
+// Returns GL_TRUE if a window close request was received
+//========================================================================
+
+static GLboolean processSingleEvent( void )
+{
+    XEvent event;
+    XNextEvent( _glfwLibrary.display, &event );
+
+    switch( event.type )
+    {
+        case KeyPress:
+        {
+            // A keyboard key was pressed
+
+            // 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;
+        }
+
+        case KeyRelease:
+        {
+            // A keyboard key was released
+
+            // Do not report key releases for key repeats. For key repeats we
+            // will get KeyRelease/KeyPress pairs with similar or identical
+            // time stamps. User selected key repeat filtering is handled in
+            // _glfwInputKey()/_glfwInputChar().
+            if( XEventsQueued( _glfwLibrary.display, QueuedAfterReading ) )
+            {
+                XEvent nextEvent;
+                XPeekEvent( _glfwLibrary.display, &nextEvent );
+
+                if( nextEvent.type == KeyPress &&
+                    nextEvent.xkey.window == event.xkey.window &&
+                    nextEvent.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( ( nextEvent.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;
+        }
+
+        case ButtonPress:
+        {
+            // A mouse button was pressed or a scrolling event occurred
+
+            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;
+        }
+
+        case ButtonRelease:
+        {
+            // A mouse button was released
+
+            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;
+        }
+
+        case MotionNotify:
+        {
+            // The mouse cursor was moved
+
+            if( event.xmotion.x != _glfwInput.CursorPosX ||
+                event.xmotion.y != _glfwInput.CursorPosY )
+            {
+                // The mouse cursor was moved and we didn't do it
+
+                if( _glfwWin.mouseLock )
+                {
+                    if( _glfwWin.pointerHidden )
+                    {
+                        _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;
+
+                if( _glfwWin.mousePosCallback )
+                {
+                    _glfwWin.mousePosCallback( _glfwInput.MousePosX,
+                                               _glfwInput.MousePosY );
+                }
+            }
+            break;
+        }
+
+        case ConfigureNotify:
+        {
+            if( event.xconfigure.width != _glfwWin.width ||
+                event.xconfigure.height != _glfwWin.height )
+            {
+                // The window was resized
+
+                _glfwWin.width = event.xconfigure.width;
+                _glfwWin.height = event.xconfigure.height;
+                if( _glfwWin.windowSizeCallback )
+                {
+                    _glfwWin.windowSizeCallback( _glfwWin.width,
+                                                 _glfwWin.height );
+                }
+            }
+            break;
+        }
+
+        case ClientMessage:
+        {
+            if( (Atom) event.xclient.data.l[ 0 ] == _glfwWin.wmDeleteWindow )
+            {
+                // The window manager was asked to close the window, for example by
+                // the user pressing a 'close' window decoration button
+
+                return GL_TRUE;
+            }
+            else if( _glfwWin.wmPing != None &&
+                     (Atom) event.xclient.data.l[ 0 ] == _glfwWin.wmPing )
+            {
+                // The window manager is pinging us to make sure we are still
+                // responding to events
+
+                event.xclient.window = _glfwWin.root;
+                XSendEvent( _glfwLibrary.display,
+                            event.xclient.window,
+                            False,
+                            SubstructureNotifyMask | SubstructureRedirectMask,
+                            &event );
+            }
+
+            break;
+        }
+
+        case MapNotify:
+        {
+            // The window was mapped
+
+            _glfwWin.iconified = GL_FALSE;
+            break;
+        }
+
+        case UnmapNotify:
+        {
+            // The window was unmapped
+
+            _glfwWin.iconified = GL_TRUE;
+            break;
+        }
+
+        case FocusIn:
+        {
+            // The window gained focus
+
+            _glfwWin.active = GL_TRUE;
+
+            if( _glfwWin.mouseLock )
+            {
+                _glfwPlatformHideMouseCursor();
+            }
+
+            break;
+        }
+
+        case FocusOut:
+        {
+            // The window lost focus
+
+            _glfwWin.active = GL_FALSE;
+            _glfwInputDeactivation();
+
+            if( _glfwWin.mouseLock )
+            {
+                _glfwPlatformShowMouseCursor();
+            }
+
+            break;
+        }
+
+        case Expose:
+        {
+            // The window's contents was damaged
+
+            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;
+}
+
+
+
+//************************************************************************
+//****               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 )
+{
+    _GLFWfbconfig closest;
+
+    // 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;
+
+    _glfwWin.wmDeleteWindow    = None;
+    _glfwWin.wmPing            = None;
+    _glfwWin.wmState           = None;
+    _glfwWin.wmStateFullscreen = None;
+    _glfwWin.wmActiveWindow    = None;
+
+    // As the 2.x API doesn't understand multiple display devices, we hardcode
+    // this choice and hope for the best
+    _glfwWin.screen = DefaultScreen( _glfwLibrary.display );
+    _glfwWin.root = RootWindow( _glfwLibrary.display, _glfwWin.screen );
+
+    // Create the invisible cursor for hidden cursor mode
+    _glfwWin.cursor = createNULLCursor( _glfwLibrary.display, _glfwWin.root );
+
+    initGLXExtensions();
+
+    // Choose the best available fbconfig
+    {
+        unsigned int fbcount;
+        _GLFWfbconfig *fbconfigs;
+        const _GLFWfbconfig *result;
+
+        fbconfigs = getFBConfigs( &fbcount );
+        if( !fbconfigs )
+        {
+            return GL_FALSE;
+        }
+
+        result = _glfwChooseFBConfig( fbconfig, fbconfigs, fbcount );
+        if( !result )
+        {
+            free( fbconfigs );
+            return GL_FALSE;
+        }
+
+        closest = *result;
+        free( fbconfigs );
+    }
+
+    if( !createContext( wndconfig, (GLXFBConfigID) closest.platformID ) )
+    {
+        return GL_FALSE;
+    }
+
+    if( !createWindow( width, height, wndconfig ) )
+    {
+        return GL_FALSE;
+    }
+
+    if( wndconfig->mode == GLFW_FULLSCREEN )
+    {
+#if defined( _GLFW_HAS_XRANDR )
+        // Request screen change notifications
+        if( _glfwLibrary.XRandR.available )
+        {
+            XRRSelectInput( _glfwLibrary.display,
+                            _glfwWin.window,
+                            RRScreenChangeNotifyMask );
+        }
+#endif
+        enterFullscreenMode();
+    }
+
+    // Process the window map event and any other that may have arrived
+    _glfwPlatformPollEvents();
+
+    // Retrieve and set initial cursor position
+    {
+        Window window, root;
+        int windowX, windowY, rootX, rootY;
+        unsigned int mask;
+
+        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 );
+
+    return GL_TRUE;
+}
+
+
+//========================================================================
+// Properly kill the window/video display
+//========================================================================
+
+void _glfwPlatformCloseWindow( void )
+{
+    if( _glfwWin.fullscreen )
+    {
+        leaveFullscreenMode();
+    }
+
+    if( _glfwWin.context )
+    {
+        // Release and destroy the context
+        glXMakeCurrent( _glfwLibrary.display, None, NULL );
+        glXDestroyContext( _glfwLibrary.display, _glfwWin.context );
+        _glfwWin.context = NULL;
+    }
+
+    if( _glfwWin.visual )
+    {
+        XFree( _glfwWin.visual );
+        _glfwWin.visual = NULL;
+    }
+
+    if( _glfwWin.window )
+    {
+        XUnmapWindow( _glfwLibrary.display, _glfwWin.window );
+        XDestroyWindow( _glfwLibrary.display, _glfwWin.window );
+        _glfwWin.window = (Window) 0;
+    }
+
+    if( _glfwWin.colormap )
+    {
+        XFreeColormap( _glfwLibrary.display, _glfwWin.colormap );
+        _glfwWin.colormap = (Colormap) 0;
+    }
+
+    if( _glfwWin.cursor )
+    {
+        XFreeCursor( _glfwLibrary.display, _glfwWin.cursor );
+        _glfwWin.cursor = (Cursor) 0;
+    }
+}
+
+
+//========================================================================
+// 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 );
+}
+
+
+//========================================================================
+// Set the window size
+//========================================================================
+
+void _glfwPlatformSetWindowSize( int width, int height )
+{
+    int     mode = 0, rate, sizeChanged = GL_FALSE;
+    XSizeHints *sizehints;
+
+    rate = _glfwWin.refreshRate;
+
+    if( _glfwWin.fullscreen )
+    {
+        // Get the closest matching video mode for the specified window size
+        mode = _glfwGetClosestVideoMode( _glfwWin.screen, &width, &height, &rate );
+    }
+
+    if( _glfwWin.windowNoResize )
+    {
+        // Update window size restrictions to match new window size
+
+        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;
+    }
+
+    if( _glfwWin.fullscreen )
+    {
+        // Change video mode, keeping current refresh rate
+        _glfwSetVideoModeMODE( _glfwWin.screen, mode, _glfwWin.refreshRate );
+    }
+
+    // Set window size (if not already changed)
+    if( !sizeChanged )
+    {
+        XResizeWindow( _glfwLibrary.display, _glfwWin.window, width, height );
+    }
+}
+
+
+//========================================================================
+// Set the window position.
+//========================================================================
+
+void _glfwPlatformSetWindowPos( int x, int y )
+{
+    XMoveWindow( _glfwLibrary.display, _glfwWin.window, x, y );
+}
+
+
+//========================================================================
+// Window iconification
+//========================================================================
+
+void _glfwPlatformIconifyWindow( void )
+{
+    if( _glfwWin.overrideRedirect )
+    {
+        // We can't iconify/restore override-redirect windows, as that's
+        // performed by the window manager
+        return;
+    }
+
+    XIconifyWindow( _glfwLibrary.display, _glfwWin.window, _glfwWin.screen );
+}
+
+
+//========================================================================
+// Window un-iconification
+//========================================================================
+
+void _glfwPlatformRestoreWindow( void )
+{
+    if( _glfwWin.overrideRedirect )
+    {
+        // We can't iconify/restore override-redirect windows, as that's
+        // performed by the window manager
+        return;
+    }
+
+    XMapWindow( _glfwLibrary.display, _glfwWin.window );
+}
+
+
+//========================================================================
+// Swap OpenGL buffers and poll any new events
+//========================================================================
+
+void _glfwPlatformSwapBuffers( void )
+{
+    // Update display-buffer
+    glXSwapBuffers( _glfwLibrary.display, _glfwWin.window );
+}
+
+
+//========================================================================
+// 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;
+
+    _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 );
+    _glfwWin.stereo = getFBConfigAttrib( *fbconfig, GLX_STEREO ) ? 1 : 0;
+
+    // Get FSAA buffer sample count
+    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, _glfwWin.root );
+        _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 );
+}
+
+
+//========================================================================
+// Poll for new window and input events
+//========================================================================
+
+void _glfwPlatformPollEvents( void )
+{
+    GLboolean closeRequested = GL_FALSE;
+
+    // Flag that the cursor has not moved
+    _glfwInput.MouseMoved = GL_FALSE;
+
+    // Process all pending events
+    while( XPending( _glfwLibrary.display ) )
+    {
+        if( processSingleEvent() )
+        {
+            closeRequested = GL_TRUE;
+        }
+    }
+
+    // Did we get mouse movement in fully enabled hidden cursor mode?
+    if( _glfwInput.MouseMoved && _glfwWin.pointerHidden )
+    {
+        _glfwPlatformSetMouseCursorPos( _glfwWin.width/2,
+                                        _glfwWin.height/2 );
+    }
+
+    if( closeRequested && _glfwWin.windowCloseCallback )
+    {
+        closeRequested = _glfwWin.windowCloseCallback();
+    }
+    if( closeRequested )
+    {
+        glfwCloseWindow();
+    }
+}
+
+
+//========================================================================
+// Wait for new window and input events
+//========================================================================
+
+void _glfwPlatformWaitEvents( void )
+{
+    XEvent event;
+
+    // Block waiting for an event to arrive
+    XNextEvent( _glfwLibrary.display, &event );
+    XPutBackEvent( _glfwLibrary.display, &event );
+
+    _glfwPlatformPollEvents();
+}
+
+
+//========================================================================
+// Hide mouse cursor (lock it)
+//========================================================================
+
+void _glfwPlatformHideMouseCursor( void )
+{
+    // Hide cursor
+    if( !_glfwWin.pointerHidden )
+    {
+        XDefineCursor( _glfwLibrary.display, _glfwWin.window, _glfwWin.cursor );
+        _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;
+        }
+    }
+}
+
+
+//========================================================================
+// 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 )
+    {
+        XUngrabPointer( _glfwLibrary.display, CurrentTime );
+        _glfwWin.pointerGrabbed = GL_FALSE;
+    }
+
+    // Show cursor
+    if( _glfwWin.pointerHidden )
+    {
+        XUndefineCursor( _glfwLibrary.display, _glfwWin.window );
+        _glfwWin.pointerHidden = GL_FALSE;
+    }
+}
+
+
+//========================================================================
+// Set physical mouse cursor position
+//========================================================================
+
+void _glfwPlatformSetMouseCursorPos( int x, int y )
+{
+    // Store the new position so we can recognise it later
+    _glfwInput.CursorPosX = x;
+    _glfwInput.CursorPosY = y;
+
+    XWarpPointer( _glfwLibrary.display, None, _glfwWin.window, 0,0,0,0, x, y );
 }
 
diff --git a/glfw/license.txt b/glfw/license.txt
deleted file mode 100644
--- a/glfw/license.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-Copyright (c) 2002-2007 Camilla Berglund <elmindreda@users.sourceforge.net>
-
-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.
-
