diff --git a/Changelog.txt b/Changelog.txt
--- a/Changelog.txt
+++ b/Changelog.txt
@@ -1,3 +1,27 @@
+Sat Nov  3 21:41:09 PDT 2012  paul@thev.net
+  * Bump version to 0.5.1.0 for release
+
+Sat Nov  3 21:39:46 PDT 2012  paul@thev.net
+  * Enable 64-bit fix for MouseWheelCallback
+
+Thu Aug 30 20:07:02 PDT 2012  paul@thev.net
+  * Use Int for MouseWheelCallback
+
+Wed Jun 13 21:53:39 PDT 2012  paul@thev.net
+  * use C types for FFI
+
+Sat Jun  2 03:58:54 PDT 2012  Marc Sunet <jeannekamikaze@gmail.com>
+  * Previous GLint was not quite working (linker error). Now fixed.
+
+Sat Jun  2 03:38:31 PDT 2012  Marc Sunet <jeannekamikaze@gmail.com>
+  * GLint warning fixed.
+
+Mon May 28 02:46:56 PDT 2012  Marc Sunet <jeannekamikaze@gmail.com>
+  * Update to version 2.7.5
+  C sources updated, nothing to be done on the Haskell side.
+  Fixed a warning about unsafePerformIO being deprecated. Using the new function from System.Unsafe.
+  There are still a few warnings about GLint that could be supressed.
+
 Fri Jan 27 11:07:48 PST 2012  paul@thev.net
   * merge the source of StateT into Setup.hs since mtl is not a default library; bump up version
 
diff --git a/GLFW.cabal b/GLFW.cabal
--- a/GLFW.cabal
+++ b/GLFW.cabal
@@ -1,5 +1,5 @@
 name:          GLFW
-version:       0.5.0.1
+version:       0.5.1.0
 homepage:      http://haskell.org/haskellwiki/GLFW
 maintainer:    Paul H. Liu <paul@thev.net>, Marc Sunet <jeannekamikaze@gmail.com>
 cabal-version: >= 1.10
diff --git a/Graphics/UI/GLFW.hs b/Graphics/UI/GLFW.hs
--- a/Graphics/UI/GLFW.hs
+++ b/Graphics/UI/GLFW.hs
@@ -1,5 +1,5 @@
 -- | Haskell Interface to GLFW (<http://www.glfw.org>).
---   Supports GLFW API version 2.7.2.
+--   Supports GLFW API version 2.7.5.
 --
 --   GLFW thread functions are not supported by this module; use
 --   Haskell thread instead.
@@ -115,8 +115,9 @@
 
 import Control.Monad (liftM, liftM2)
 import Data.IORef    (IORef, atomicModifyIORef, newIORef, readIORef, writeIORef)
-import Foreign
+import Foreign hiding (unsafePerformIO) -- deprecated in next release.
 import Foreign.C
+import System.IO.Unsafe (unsafePerformIO)
 import Graphics.Rendering.OpenGL (GLfloat, ($=))
 import qualified Graphics.Rendering.OpenGL as GL
 
@@ -612,22 +613,27 @@
 _GLFW_INFINITY = 100000
 
 -- Callback function type
-type GLFWwindowsizefun    = Int -> Int -> IO ()
-type GLFWwindowclosefun   = IO Bool
+type GLFWwindowsizefun    = CInt -> CInt -> IO ()
+type GLFWwindowclosefun   = IO CInt
 type GLFWwindowrefreshfun = IO ()
-type GLFWmousebuttonfun   = Int -> Int -> IO ()
-type GLFWmouseposfun      = Int -> Int -> IO ()
-type GLFWmousewheelfun    = Int -> IO ()
-type GLFWkeyfun           = Int -> Int -> IO ()
-type GLFWcharfun          = Int -> Int -> IO ()
+type GLFWmousebuttonfun   = CInt -> CInt -> IO ()
+type GLFWmouseposfun      = CInt -> CInt -> IO ()
+type GLFWmousewheelfun    = CInt -> IO ()
+type GLFWkeyfun           = CInt -> CInt -> IO ()
+type GLFWcharfun          = CInt -> CInt -> IO ()
 
 -- | Initialize GLFW library. Returns 'True' if successful, 'False' otherwise. Must
 --   be called before any other GLFW functions.
 initialize :: IO Bool
-initialize = liftM toEnum glfwInit
+initialize = liftM toEnum' glfwInit
 
-foreign import ccall unsafe glfwInit :: IO Int
+toEnum' :: (Integral a, Enum b) => a -> b
+toEnum' = toEnum . fromIntegral
+fromEnum' :: (Enum a, Integral b) => a -> b
+fromEnum' = fromIntegral . fromEnum 
 
+foreign import ccall unsafe glfwInit :: IO CInt
+
 -- | Terminate GLFW library after use. Before a program terminates, GLFW has to
 --   be terminated in order to free up resources, etc.
 terminate :: IO ()
@@ -644,7 +650,7 @@
     glfwGetVersion x y z
     peek3 (x, y, z)
 
-foreign import ccall unsafe glfwGetVersion :: Ptr Int -> Ptr Int -> Ptr Int -> IO ()
+foreign import ccall unsafe glfwGetVersion :: Ptr CInt -> Ptr CInt -> Ptr CInt -> IO ()
 
 -- | Open a window. Returns 'True' if successful, 'False' otherwise. GLFW
 --   applications can only open one window.
@@ -664,7 +670,10 @@
 openWindow :: GL.Size -> [DisplayBits] -> WindowMode -> IO Bool
 openWindow (GL.Size w h) bits mode = do
   writeIORef fontTextures []
-  liftM toEnum $ glfwOpenWindow (fromIntegral w) (fromIntegral h) r' g' b' a' d' s' $ fromEnum mode
+  liftM toEnum' $ 
+    glfwOpenWindow (fromIntegral w) (fromIntegral h) 
+                   (fromIntegral r') (fromIntegral g')  (fromIntegral b') 
+                   (fromIntegral a') (fromIntegral d') (fromIntegral s') (fromEnum' mode)
   where
     (r', g', b', a', d', s') = gather bits (0, 0, 0, 0, 0, 0)
 
@@ -676,7 +685,7 @@
       DisplayStencilBits s_       -> (r , g , b , a , d , s_)
     gather [] vs = vs
 
-foreign import ccall unsafe glfwOpenWindow :: Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> IO Int
+foreign import ccall unsafe glfwOpenWindow :: CInt -> CInt -> CInt -> CInt -> CInt -> CInt -> CInt -> CInt -> CInt -> IO CInt
 
 -- | Close the open window and destroy the associated OpenGL context.
 foreign import ccall unsafe "glfwCloseWindow" closeWindow :: IO ()
@@ -685,64 +694,64 @@
 --   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 
+    openWindowHint RefreshRate = glfwOpenWindowHint 0x0002000B . fromIntegral
     
 -- | Specify the number of bits for the red channel of the accumulation buffer.
 instance Hint AccumRedBits where
-    openWindowHint AccumRedBits = glfwOpenWindowHint 0x0002000C 
+    openWindowHint AccumRedBits = glfwOpenWindowHint 0x0002000C . fromIntegral
     
 -- | Specify the number of bits for the green channel of the accumulation buffer.
 instance Hint AccumGreenBits where
-    openWindowHint AccumGreenBits = glfwOpenWindowHint 0x0002000D 
+    openWindowHint AccumGreenBits = glfwOpenWindowHint 0x0002000D . fromIntegral
     
 -- | Specify the number of bits for the blue channel of the accumulation buffer.
 instance Hint AccumBlueBits where
-    openWindowHint AccumBlueBits = glfwOpenWindowHint 0x0002000E 
+    openWindowHint AccumBlueBits = glfwOpenWindowHint 0x0002000E . fromIntegral
     
 -- | Specify the number of bits for the alpha channel of the accumulation buffer.
 instance Hint AccumAlphaBits where
-    openWindowHint AccumAlphaBits = glfwOpenWindowHint 0x0002000F 
+    openWindowHint AccumAlphaBits = glfwOpenWindowHint 0x0002000F . fromIntegral
 
 -- | Specify the number of auxiliary buffers.
 instance Hint AuxBuffers where
-    openWindowHint AuxBuffers = glfwOpenWindowHint 0x00020010 
+    openWindowHint AuxBuffers = glfwOpenWindowHint 0x00020010 . fromIntegral
     
 -- | 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 
+    openWindowHint Stereo = glfwOpenWindowHint 0x00020011 . fromEnum'
 
 -- | Specify whether the window can be resized by the user.
 instance Hint NoResize where
-    openWindowHint NoResize = glfwOpenWindowHint 0x00020012 . fromEnum 
+    openWindowHint NoResize = glfwOpenWindowHint 0x00020012 . fromEnum'
     
 -- | Specify the number of samples to use for the multisampling buffer.
 instance Hint FSAASamples where
-    openWindowHint FSAASamples = glfwOpenWindowHint 0x00020013
+    openWindowHint FSAASamples = glfwOpenWindowHint 0x00020013 . fromIntegral
     
 -- | Specify the major number of the desired minimum OpenGL version.
 instance Hint OpenGLVersionMajor where
-    openWindowHint OpenGLVersionMajor = glfwOpenWindowHint 0x00020014 
+    openWindowHint OpenGLVersionMajor = glfwOpenWindowHint 0x00020014 . fromIntegral
     
 -- | Specify the minor number of the desired minimum OpenGL version.
 instance Hint OpenGLVersionMinor where
-    openWindowHint OpenGLVersionMinor = glfwOpenWindowHint 0x00020015 
+    openWindowHint OpenGLVersionMinor = glfwOpenWindowHint 0x00020015 . fromIntegral
 
 -- | 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 
+    openWindowHint OpenGLForwardCompat = glfwOpenWindowHint 0x00020016 . fromEnum'
    
 -- | Specify whether a debug context should be created.
 instance Hint OpenGLDebugContext where
-    openWindowHint OpenGLDebugContext = glfwOpenWindowHint 0x00020017 . fromEnum 
+    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 
+    openWindowHint OpenGLProfile = glfwOpenWindowHint 0x00020018 . fromEnum'
 
-foreign import ccall unsafe glfwOpenWindowHint :: Int -> Int -> IO ()
+foreign import ccall unsafe glfwOpenWindowHint :: CInt -> CInt -> IO ()
 
 -- | Set the title of the opened window.
 windowTitle :: GL.SettableStateVar String
@@ -771,8 +780,8 @@
             liftM2 GL.Size (fmap fromIntegral $ peek w) (fmap fromIntegral $ peek h)
         setter (GL.Size w h) = glfwSetWindowSize (fromIntegral w) (fromIntegral h)
 
-foreign import ccall unsafe glfwGetWindowSize :: Ptr Int -> Ptr Int -> IO ()
-foreign import ccall unsafe glfwSetWindowSize :: Int -> Int -> IO ()
+foreign import ccall unsafe glfwGetWindowSize :: Ptr CInt -> Ptr CInt -> IO ()
+foreign import ccall unsafe glfwSetWindowSize :: CInt -> CInt -> IO ()
 
 -- | Set the position of the opened window.
 --
@@ -782,8 +791,11 @@
 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 ()
+foreign import ccall unsafe "glfwSetWindowPos" glfwSetWindowPosC :: CInt -> CInt -> IO ()
 
+glfwSetWindowPos :: GL.GLint -> GL.GLint -> IO ()
+glfwSetWindowPos x y = glfwSetWindowPosC (fromIntegral x) (fromIntegral y)
+
 -- | Iconify the window.
 foreign import ccall unsafe "glfwIconifyWindow" iconifyWindow :: IO ()
 
@@ -799,107 +811,107 @@
 --   performed by 'swapBuffers'. If set to zero, buffer swaps will not be
 --   synchronized to the vertical refresh of the monitor.
 swapInterval :: GL.SettableStateVar Int
-swapInterval = GL.makeSettableStateVar glfwSwapInterval
+swapInterval = GL.makeSettableStateVar (glfwSwapInterval . fromIntegral)
 
-foreign import ccall unsafe glfwSwapInterval :: Int -> IO ()
+foreign import ccall unsafe glfwSwapInterval :: CInt -> IO ()
 
 -- | Query the window opened status.
 instance Param Opened where
-    getParam Opened = fmap toEnum $ glfwGetWindowParam 0x00020001
+    getParam Opened = fmap toEnum' $ glfwGetWindowParam 0x00020001
 
 -- | Query the window active status.
 instance Param Active where
-    getParam Active = fmap toEnum $ glfwGetWindowParam 0x00020002
+    getParam Active = fmap toEnum' $ glfwGetWindowParam 0x00020002
     
 -- | Query the window iconified status.
 instance Param Iconified where
-    getParam Iconified = fmap toEnum $ glfwGetWindowParam 0x00020003
+    getParam Iconified = fmap toEnum' $ glfwGetWindowParam 0x00020003
     
 -- | Query the window hardware accelerated status.
 instance Param Accelerated where
-    getParam Accelerated = fmap toEnum $ glfwGetWindowParam 0x00020004
+    getParam Accelerated = fmap toEnum' $ glfwGetWindowParam 0x00020004
     
 -- | Query the number of bits for the red color component.
 instance Param RedBits where
-    getParam RedBits = glfwGetWindowParam 0x00020005
+    getParam RedBits = fmap fromIntegral $ glfwGetWindowParam 0x00020005
     
 -- | Query the number of bits for the green color component.
 instance Param GreenBits where
-    getParam GreenBits = glfwGetWindowParam 0x00020006
+    getParam GreenBits = fmap fromIntegral $ glfwGetWindowParam 0x00020006
     
 -- | Query the number of bits for the blue color component.
 instance Param BlueBits where
-    getParam BlueBits = glfwGetWindowParam 0x00020007
+    getParam BlueBits = fmap fromIntegral $ glfwGetWindowParam 0x00020007
     
 -- | Query the number of bits for the alpha buffer.
 instance Param AlphaBits where
-    getParam AlphaBits = glfwGetWindowParam 0x00020008
+    getParam AlphaBits = fmap fromIntegral $ glfwGetWindowParam 0x00020008
     
 -- | Query the number of bits for the depth buffer.
 instance Param DepthBits where
-    getParam DepthBits = glfwGetWindowParam 0x00020009
+    getParam DepthBits = fmap fromIntegral $ glfwGetWindowParam 0x00020009
     
 -- | Query the number of bits for the stencil buffer.
 instance Param StencilBits where
-    getParam StencilBits = glfwGetWindowParam 0x0002000A
+    getParam StencilBits = fmap fromIntegral $ glfwGetWindowParam 0x0002000A
     
 -- | Query the vertical monitor refresh rate in Hz (only used for fullscreen windows).
 instance Param RefreshRate where
-    getParam RefreshRate = glfwGetWindowParam 0x0002000B
+    getParam RefreshRate = fmap fromIntegral $ glfwGetWindowParam 0x0002000B
     
 -- | Query the number of bits for the red channel of the accumulation buffer.
 instance Param AccumRedBits where
-    getParam AccumRedBits = glfwGetWindowParam 0x0002000C
+    getParam AccumRedBits = fmap fromIntegral $ glfwGetWindowParam 0x0002000C
     
 -- | Query the number of bits for the green channel of the accumulation buffer.
 instance Param AccumGreenBits where
-    getParam AccumGreenBits = glfwGetWindowParam 0x0002000D
+    getParam AccumGreenBits = fmap fromIntegral $ glfwGetWindowParam 0x0002000D
     
 -- | Query the number of bits for the blue channel of the accumulation buffer.
 instance Param AccumBlueBits where
-    getParam AccumBlueBits = glfwGetWindowParam 0x0002000E
+    getParam AccumBlueBits = fmap fromIntegral $ glfwGetWindowParam 0x0002000E
     
 -- | Query the number of bits for the alpha channel of the accumulation buffer.
 instance Param AccumAlphaBits where
-    getParam AccumAlphaBits = glfwGetWindowParam 0x0002000F
+    getParam AccumAlphaBits = fmap fromIntegral $ glfwGetWindowParam 0x0002000F
     
 -- | Query the number of auxiliary buffers.
 instance Param AuxBuffers where
-    getParam AuxBuffers = glfwGetWindowParam 0x00020010
+    getParam AuxBuffers = fmap fromIntegral $ glfwGetWindowParam 0x00020010
     
 -- | Query whether the window supports stereo rendering.
 instance Param Stereo where
-    getParam Stereo = fmap toEnum $ glfwGetWindowParam 0x00020011
+    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
+    getParam NoResize = fmap toEnum' $ glfwGetWindowParam 0x00020012
     
 -- | Query the number used for the multisampling buffer.
 instance Param FSAASamples where
-    getParam FSAASamples = glfwGetWindowParam 0x00020013
+    getParam FSAASamples = fmap fromIntegral $ glfwGetWindowParam 0x00020013
     
 -- | Query the OpenGL major version.
 instance Param OpenGLVersionMajor where
-    getParam OpenGLVersionMajor = glfwGetWindowParam 0x00020014
+    getParam OpenGLVersionMajor = fmap fromIntegral $ glfwGetWindowParam 0x00020014
     
 -- | Query the OpenGL minor version.
 instance Param OpenGLVersionMinor where
-    getParam OpenGLVersionMinor = glfwGetWindowParam 0x00020015
+    getParam OpenGLVersionMinor = fmap fromIntegral $ glfwGetWindowParam 0x00020015
     
 -- | Query whether the current OpenGL context is forward-compatible.
 instance Param OpenGLForwardCompat where
-    getParam OpenGLForwardCompat = fmap toEnum $ glfwGetWindowParam 0x000200016
+    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
+    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
+    getParam OpenGLProfile = fmap toEnum' $ glfwGetWindowParam 0x00020018
 
-foreign import ccall unsafe glfwGetWindowParam :: Int -> IO Int
+foreign import ccall unsafe glfwGetWindowParam :: CInt -> IO CInt
 
 -- | Callback type for 'windowSizeCallback'.
 type WindowSizeCallback = GL.Size -> IO ()
@@ -921,7 +933,7 @@
 -- | Set the function that will be called when the window is closed.
 windowCloseCallback :: GL.SettableStateVar WindowCloseCallback
 windowCloseCallback = GL.makeSettableStateVar (\f -> do
-  ptr <- glfwWrapFunB f
+  ptr <- glfwWrapFunB (liftM fromEnum' f)
   glfwSetCallbackIORef glfwWindowclosefun ptr
   glfwSetWindowCloseCallback ptr)
 
@@ -950,15 +962,15 @@
 videoModes = GL.makeGettableStateVar getter
   where
     getter = withArray (replicate (sizeOfVideoMode * maxCount) 0) $ \arr ->
-      glfwGetVideoModes arr maxCount >>= filterMode arr
+      glfwGetVideoModes arr (fromIntegral maxCount) >>= filterMode arr
     filterMode _ 0 = return []
     filterMode a c = do
       [w, h, r, b, g] <- peekArray 5 a
       let a' = advancePtr a sizeOfVideoMode
       rest <- filterMode a' (pred c)
-      return $ VideoMode w h r b g : rest
+      return $ videoMode w h r b g : rest
 
-foreign import ccall unsafe glfwGetVideoModes :: Ptr Int -> Int -> IO Int
+foreign import ccall unsafe glfwGetVideoModes :: Ptr CInt -> CInt -> IO CInt
 
 sizeOfVideoMode :: Int
 sizeOfVideoMode = 5
@@ -966,6 +978,9 @@
 maxCount :: Int
 maxCount = 256
 
+videoMode :: CInt -> CInt -> CInt -> CInt -> CInt -> VideoMode
+videoMode w h r b g = VideoMode (fromIntegral w) (fromIntegral h) (fromIntegral r) (fromIntegral b) (fromIntegral g)
+
 -- | Get the 'VideoMode' of current desktop.
 desktopMode :: GL.GettableStateVar VideoMode
 desktopMode = GL.makeGettableStateVar getter
@@ -973,9 +988,9 @@
     getter = withArray (replicate sizeOfVideoMode 0) $ \arr -> do
       glfwGetDesktopMode arr
       [w, h, r, b, g] <- peekArray 5 arr
-      return $ VideoMode w h r b g
+      return $ videoMode w h r b g
 
-foreign import ccall unsafe glfwGetDesktopMode :: Ptr Int -> IO ()
+foreign import ccall unsafe glfwGetDesktopMode :: Ptr CInt -> IO ()
 
 -- | Poll events, such as user input and window events. Upon calling this
 --   function, all window states, keyboard states and mouse states are updated.
@@ -999,9 +1014,9 @@
 --   '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
+getKey = fmap toEnum' . glfwGetKey . fromEnum'
 
-foreign import ccall unsafe glfwGetKey :: Int -> IO Int
+foreign import ccall unsafe glfwGetKey :: CInt -> IO CInt
 
 -- | Return a 'KeyButtonState', either 'Release' or 'Press', of the indicated
 --   mouse button.
@@ -1010,9 +1025,9 @@
 --   '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
+getMouseButton = fmap toEnum' . glfwGetMouseButton . fromEnum' 
 
-foreign import ccall unsafe glfwGetMouseButton :: Int -> IO Int
+foreign import ccall unsafe glfwGetMouseButton :: CInt -> IO CInt
 
 -- | Set or get the mouse position.
 --
@@ -1035,8 +1050,8 @@
       return $ GL.Position (fromIntegral mx) (fromIntegral my)))
     setter (GL.Position x y) = glfwSetMousePos (fromIntegral x) (fromIntegral y)
 
-foreign import ccall unsafe glfwGetMousePos :: Ptr Int -> Ptr Int -> IO ()
-foreign import ccall unsafe glfwSetMousePos :: Int -> Int -> IO ()
+foreign import ccall unsafe glfwGetMousePos :: Ptr CInt -> Ptr CInt -> IO ()
+foreign import ccall unsafe glfwSetMousePos :: CInt -> CInt -> IO ()
 
 -- | Set or get the mouse wheel position.
 --
@@ -1044,20 +1059,20 @@
 --   '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
+mouseWheel = GL.makeStateVar (liftM fromIntegral glfwGetMouseWheel) (glfwSetMouseWheel . fromIntegral)
 
-foreign import ccall unsafe glfwGetMouseWheel :: IO Int
-foreign import ccall unsafe glfwSetMouseWheel :: Int -> IO ()
+foreign import ccall unsafe glfwGetMouseWheel :: IO CInt
+foreign import ccall unsafe glfwSetMouseWheel :: CInt -> 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))
+joystickParam :: Joystick -> JoystickParam -> GL.GettableStateVar CInt
+joystickParam j param = GL.makeGettableStateVar (glfwGetJoystickParam (fromEnum' j) (fromEnum' param))
 
-foreign import ccall unsafe glfwGetJoystickParam :: Int -> Int -> IO Int
+foreign import ccall unsafe glfwGetJoystickParam :: CInt -> CInt -> IO CInt
 
 -- | 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
@@ -1069,7 +1084,7 @@
 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 (fromIntegral n)
     peekArray n a
 
 -- | Get joystick positions. The returned list contains the positions
@@ -1080,12 +1095,12 @@
 --   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)
-  allocaArray n $ \a -> do
-    n' <- glfwGetJoystickPos (fromEnum j) a n
-    peekArray n' a
+  n <- glfwGetJoystickParam (fromEnum' j) (fromEnum' Axes)
+  allocaArray (fromIntegral n) $ \a -> do
+    n' <- glfwGetJoystickPos (fromEnum' j) a n
+    peekArray (fromIntegral n') a
 
-foreign import ccall unsafe glfwGetJoystickPos :: Int -> Ptr Float -> Int -> IO Int
+foreign import ccall unsafe glfwGetJoystickPos :: CInt -> Ptr Float -> CInt -> IO CInt
 
 -- | Get joystick button states. The returned list contains the states
 --   for all available buttons for the given joystick.
@@ -1095,13 +1110,13 @@
 --   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)
-  allocaArray n $ \a -> do
-    n' <- glfwGetJoystickButtons (fromEnum j) a n
-    l  <- peekArray n' a
-    return $ map (toEnum . fromEnum) l
+  n <- glfwGetJoystickParam (fromEnum' j) (fromEnum' Buttons)
+  allocaArray (fromIntegral n) $ \a -> do
+    n' <- glfwGetJoystickButtons (fromEnum' j) a n
+    l  <- peekArray (fromIntegral n') a
+    return $ map (toEnum . fromEnum') l
 
-foreign import ccall unsafe glfwGetJoystickButtons :: Int -> Ptr Int8 -> Int -> IO Int
+foreign import ccall unsafe glfwGetJoystickButtons :: CInt -> Ptr Int8 -> CInt -> IO CInt
 
 -- | Callback type for 'keyCallback'.
 type KeyCallback = Key -> KeyButtonState -> IO ()
@@ -1113,7 +1128,7 @@
 keyCallback = GL.makeSettableStateVar setter
   where
     setter f = do
-      let g k s = f (toEnum k) (toEnum s)
+      let g k s = f (toEnum' k) (toEnum' s)
       ptr <- glfwWrapFun2 g
       glfwSetCallbackIORef glfwKeyfun ptr
       glfwSetKeyCallback ptr
@@ -1131,7 +1146,7 @@
 charCallback = GL.makeSettableStateVar setter
   where
     setter f = do
-      let g k s = f (toEnum k) (toEnum s)
+      let g k s = f (toEnum' k) (toEnum' s)
       ptr <- glfwWrapFun2 g
       glfwSetCallbackIORef glfwCharfun ptr
       glfwSetCharCallback ptr
@@ -1147,7 +1162,7 @@
 mouseButtonCallback = GL.makeSettableStateVar setter
   where
     setter f = do
-      let g b s = f (toEnum b) (toEnum s)
+      let g b s = f (toEnum' b) (toEnum' s)
       ptr <- glfwWrapFun2 g
       glfwSetCallbackIORef glfwMousebuttonfun ptr
       glfwSetMouseButtonCallback ptr
@@ -1192,17 +1207,18 @@
 mouseWheelCallback  = GL.makeSettableStateVar setter
   where
     setter f = do
-#if __GLASGOW_HASKELL__ >= 610
-      ptr <- glfwWrapFun1 f
+      let g x = f =<< do
+#if 0 
+                return (fromIntegral x)
 #else
       -- Work around bug in GHC FFI
       -- See http://hackage.haskell.org/trac/ghc/ticket/2594
-      let g x = with 0 \ptr -> do
-                    poke ptr x
-                    x32 <- peek (castPtr ptr) :: IO Int32
-                    f (fromIntegral x32)
-      ptr <- glfwWrapFun1 g
+                with 0 $ \ptr -> do
+                  poke ptr x
+                  x32 <- peek (castPtr ptr) :: IO Int32
+                  return $ fromIntegral x32
 #endif
+      ptr <- glfwWrapFun1 g
       glfwSetCallbackIORef glfwMousewheelfun ptr
       glfwSetMouseWheelCallback ptr
 
@@ -1231,9 +1247,9 @@
 
 -- | Return 'True' if the extension is supported, 'False' otherwise.
 extensionSupported :: String -> IO Bool
-extensionSupported = liftM toEnum . flip withCString glfwExtensionSupported
+extensionSupported = liftM toEnum' . flip withCString glfwExtensionSupported
 
-foreign import ccall unsafe glfwExtensionSupported :: CString -> IO Int
+foreign import ccall unsafe glfwExtensionSupported :: CString -> IO CInt
 
 -- | Returns the version numbers for the currently used OpenGL implementation.
 glVersion :: GL.GettableStateVar Version
@@ -1244,7 +1260,7 @@
     glfwGetGLVersion x y z
     peek3 (x, y, z)
     
-foreign import ccall unsafe glfwGetGLVersion :: Ptr Int -> Ptr Int -> Ptr Int -> IO ()
+foreign import ccall unsafe glfwGetGLVersion :: Ptr CInt -> Ptr CInt -> Ptr CInt -> IO ()
 
 -- TODO:
 -- foreign import ccall unsafe glfwGetProcAddress :: Ptr CChar -> FunPtr ?
@@ -1252,15 +1268,15 @@
 
 -- | Enable a 'SpecialFeature'.
 enableSpecial :: SpecialFeature -> IO ()
-enableSpecial = glfwEnable . fromEnum
+enableSpecial = glfwEnable . fromEnum'
 
-foreign import ccall unsafe glfwEnable :: Int -> IO ()
+foreign import ccall unsafe glfwEnable :: CInt -> IO ()
 
 -- | Disable a 'SpecialFeature'.
 disableSpecial :: SpecialFeature -> IO ()
-disableSpecial = glfwDisable . fromEnum
+disableSpecial = glfwDisable . fromEnum'
 
-foreign import ccall unsafe glfwDisable :: Int -> IO ()
+foreign import ccall unsafe glfwDisable :: CInt -> IO ()
 
 --foreign import ccall unsafe glfwReadImage :: Ptr CChar -> Ptr GLFWimage -> Int -> IO ()
 --foreign import ccall unsafe glfwFreeImage :: Ptr GLFWimage -> IO ()
@@ -1291,22 +1307,22 @@
 loadTexture2D :: String -> [TextureFlag] -> IO Bool
 loadTexture2D fname flag = do
   r <- withCString fname (`glfwLoadTexture2D` readFlag flag) 
-  return $ toEnum r
+  return $ toEnum' r
 
-foreign import ccall unsafe glfwLoadTexture2D :: CString -> Int -> IO Int
+foreign import ccall unsafe glfwLoadTexture2D :: CString -> CInt -> IO CInt
 
-readFlag :: forall t. (Enum t) => [t] -> Int
-readFlag = foldr ((.|.) . fromEnum) 0
+readFlag :: forall t. (Enum t) => [t] -> CInt
+readFlag = foldr ((.|.) . fromEnum') 0
 
 -- | Read an image from the memory buffer (the given byte string) and
 --   upload the image to OpenGL texture memory. The rest is similar
 --   to 'loadTexture2D'.
 loadMemoryTexture2D :: String -> [TextureFlag] -> IO Bool
 loadMemoryTexture2D arr flag = withCAStringLen arr (\(ptr, len) -> do
-  r <- glfwLoadMemoryTexture2D ptr len (readFlag flag)
-  return $ toEnum r)
+  r <- glfwLoadMemoryTexture2D ptr (fromIntegral len) (readFlag flag)
+  return $ toEnum' r)
 
-foreign import ccall unsafe glfwLoadMemoryTexture2D :: Ptr CChar -> Int -> Int -> IO Int
+foreign import ccall unsafe glfwLoadMemoryTexture2D :: Ptr CChar -> CInt -> CInt -> IO CInt
 
 glfwWindowsizefun    :: IORef (Maybe (FunPtr GLFWwindowsizefun))
 glfwWindowclosefun   :: IORef (Maybe (FunPtr GLFWwindowclosefun))
@@ -1325,9 +1341,9 @@
 glfwKeyfun           = unsafePerformIO (newIORef Nothing)
 glfwCharfun          = unsafePerformIO (newIORef Nothing)
 
-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" glfwWrapFun2 :: (CInt -> CInt -> IO ()) -> IO (FunPtr (CInt -> CInt -> IO ()))
+foreign import ccall unsafe "wrapper" glfwWrapFun1 :: (CInt -> IO ()) -> IO (FunPtr (CInt -> IO ()))
+foreign import ccall unsafe "wrapper" glfwWrapFunB :: IO CInt -> IO (FunPtr (IO CInt))
 foreign import ccall unsafe "wrapper" glfwWrapFun0 :: IO () -> IO (FunPtr (IO ()))
 
 glfwSetCallbackIORef :: forall a. IORef (Maybe (FunPtr a)) -> FunPtr a -> IO ()
@@ -1410,12 +1426,12 @@
   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 :: (Ptr CInt, Ptr CInt, Ptr CInt) -> IO (Int, Int, Int)
 peek3 (x, y, z) = do
   x' <- peek x
   y' <- peek y
   z' <- peek z
-  return (x', y', z')
+  return (fromIntegral x', fromIntegral y', fromIntegral z')
 
 vector3 :: GLfloat -> GLfloat -> GLfloat -> GL.Vector3 GLfloat
 vector3 = GL.Vector3
diff --git a/glfw/COPYING.txt b/glfw/COPYING.txt
--- a/glfw/COPYING.txt
+++ b/glfw/COPYING.txt
@@ -1,22 +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.
-
+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
@@ -160,12 +160,21 @@
  * (which is not a nice solution for portable programs).
  */
 #if defined(__APPLE_CC__)
- #include <OpenGL/gl.h>
+ #if defined(GLFW_INCLUDE_GL3)
+  #include <OpenGL/gl3.h>
+ #else
+  #define GL_GLEXT_LEGACY
+  #include <OpenGL/gl.h>
+ #endif
  #ifndef GLFW_NO_GLU
   #include <OpenGL/glu.h>
  #endif
 #else
- #include <GL/gl.h>
+ #if defined(GLFW_INCLUDE_GL3)
+  #include <GL3/gl3.h>
+ #else
+  #include <GL/gl.h>
+ #endif
  #ifndef GLFW_NO_GLU
   #include <GL/glu.h>
  #endif
@@ -178,7 +187,7 @@
 
 #define GLFW_VERSION_MAJOR    2
 #define GLFW_VERSION_MINOR    7
-#define GLFW_VERSION_REVISION 2
+#define GLFW_VERSION_REVISION 5
 
 
 /*************************************************************************
diff --git a/glfw/lib/cocoa/cocoa_fullscreen.m b/glfw/lib/cocoa/cocoa_fullscreen.m
--- a/glfw/lib/cocoa/cocoa_fullscreen.m
+++ b/glfw/lib/cocoa/cocoa_fullscreen.m
@@ -46,6 +46,7 @@
            [mode objectForKey:(id)kCGDisplayModeIsStretched] == nil;
 }
 
+
 //========================================================================
 // Convert Core Graphics display mode to GLFW video mode
 //========================================================================
@@ -91,12 +92,13 @@
     return j;
 }
 
+
 //========================================================================
 // Get the desktop video mode
 //========================================================================
 
 void _glfwPlatformGetDesktopMode( GLFWvidmode *mode )
 {
-    *mode = vidmodeFromCGDisplayMode( _glfwLibrary.DesktopMode );
+    *mode = vidmodeFromCGDisplayMode( CGDisplayCurrentMode( CGMainDisplayID() ) );
 }
 
diff --git a/glfw/lib/cocoa/cocoa_glext.m b/glfw/lib/cocoa/cocoa_glext.m
--- a/glfw/lib/cocoa/cocoa_glext.m
+++ b/glfw/lib/cocoa/cocoa_glext.m
@@ -43,6 +43,7 @@
     return GL_FALSE;
 }
 
+
 //========================================================================
 // Get the function pointer to an OpenGL function
 //========================================================================
diff --git a/glfw/lib/cocoa/cocoa_init.m b/glfw/lib/cocoa/cocoa_init.m
--- a/glfw/lib/cocoa/cocoa_init.m
+++ b/glfw/lib/cocoa/cocoa_init.m
@@ -27,8 +27,7 @@
 //
 //========================================================================
 
-// Needed for _NSGetProgname
-#include <crt_externs.h>
+#include <sys/param.h>
 
 #include "internal.h"
 
@@ -43,158 +42,45 @@
 
 @end
 
-@interface GLFWApplication : NSApplication
-@end
-
-@implementation GLFWApplication
+//========================================================================
+// Change to our application bundle's resources directory, if present
+//========================================================================
 
-// 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
+static void changeToResourcesDirectory( void )
 {
-    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
+    char resourcesPath[MAXPATHLEN];
 
-// Keys to search for as potential application names
-NSString *GLFWNameKeys[] =
-{
-    @"CFBundleDisplayName",
-    @"CFBundleName",
-    @"CFBundleExecutable",
-};
+    CFBundleRef bundle = CFBundleGetMainBundle();
+    if( !bundle )
+        return;
 
-//========================================================================
-// Try to figure out what the calling application is called
-//========================================================================
-static NSString *findAppName( void )
-{
-    NSDictionary *infoDictionary = [[NSBundle mainBundle] infoDictionary];
+    CFURLRef resourcesURL = CFBundleCopyResourcesDirectoryURL( bundle );
 
-    unsigned int i;
-    for( i = 0; i < sizeof(GLFWNameKeys) / sizeof(GLFWNameKeys[0]); i++ )
+    CFStringRef last = CFURLCopyLastPathComponent( resourcesURL );
+    if( CFStringCompare( CFSTR( "Resources" ), last, 0 ) != kCFCompareEqualTo )
     {
-        id name = [infoDictionary objectForKey:GLFWNameKeys[i]];
-        if (name &&
-            [name isKindOfClass:[NSString class]] &&
-            ![@"" isEqualToString:name])
-        {
-            return name;
-        }
+        CFRelease( last );
+        CFRelease( resourcesURL );
+        return;
     }
 
-    // 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;
-    }
+    CFRelease( last );
 
-    char **progname = _NSGetProgname();
-    if( progname && *progname )
+    if( !CFURLGetFileSystemRepresentation( resourcesURL,
+                                           true,
+                                           (UInt8*) resourcesPath,
+                                           MAXPATHLEN) )
     {
-        // TODO: UTF8?
-        return [NSString stringWithUTF8String:*progname];
+        CFRelease( resourcesURL );
+        return;
     }
 
-    // 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:@""];
+    CFRelease( resourcesURL );
 
-    // 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];
-    }
+    chdir( resourcesPath );
 }
 
+
 //========================================================================
 // Terminate GLFW when exiting application
 //========================================================================
@@ -225,6 +111,7 @@
     _glfwThrd.First.Next     = NULL;
 }
 
+
 //************************************************************************
 //****               Platform implementation functions                ****
 //************************************************************************
@@ -235,10 +122,7 @@
 
 int _glfwPlatformInit( void )
 {
-    _glfwLibrary.AutoreleasePool = [[NSAutoreleasePool alloc] init];
-
-    // Implicitly create shared NSApplication instance
-    [GLFWApplication sharedApplication];
+    _glfwLibrary.autoreleasePool = [[NSAutoreleasePool alloc] init];
 
     _glfwLibrary.OpenGLFramework =
         CFBundleGetBundleWithIdentifier( CFSTR( "com.apple.opengl" ) );
@@ -251,31 +135,32 @@
     [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();
+    changeToResourcesDirectory();
 
-    [NSApp finishLaunching];
+    _glfwPlatformGetDesktopMode( &_glfwLibrary.desktopMode );
 
     // Install atexit routine
     atexit( glfw_atexit );
 
     initThreads();
 
-    _glfwPlatformSetTime( 0.0 );
+    _glfwInitTimer();
 
-    _glfwLibrary.DesktopMode =
-	(NSDictionary *)CGDisplayCurrentMode( CGMainDisplayID() );
+    _glfwLibrary.eventSource = CGEventSourceCreate( kCGEventSourceStateHIDSystemState );
+    if( !_glfwLibrary.eventSource )
+    {
+        return GL_FALSE;
+    }
 
+    CGEventSourceSetLocalEventsSuppressionInterval( _glfwLibrary.eventSource,
+                                                    0.0 );
+
+    _glfwPlatformSetTime( 0.0 );
+
     return GL_TRUE;
 }
 
+
 //========================================================================
 // Close window, if open, and shut down GLFW
 //========================================================================
@@ -289,8 +174,14 @@
     // TODO: Kill all non-main threads?
     // TODO: Probably other cleanup
 
-    [_glfwLibrary.AutoreleasePool release];
-    _glfwLibrary.AutoreleasePool = nil;
+    if( _glfwLibrary.eventSource )
+    {
+        CFRelease( _glfwLibrary.eventSource );
+        _glfwLibrary.eventSource = NULL;
+    }
+
+    [_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
--- a/glfw/lib/cocoa/cocoa_joystick.m
+++ b/glfw/lib/cocoa/cocoa_joystick.m
@@ -43,6 +43,7 @@
     return 0;
 }
 
+
 //========================================================================
 // Get joystick axis positions
 //========================================================================
@@ -52,6 +53,7 @@
     // TODO: Implement this.
     return 0;
 }
+
 
 //========================================================================
 // Get joystick button states
diff --git a/glfw/lib/cocoa/cocoa_thread.c b/glfw/lib/cocoa/cocoa_thread.c
--- a/glfw/lib/cocoa/cocoa_thread.c
+++ b/glfw/lib/cocoa/cocoa_thread.c
@@ -70,7 +70,6 @@
 }
 
 
-
 //************************************************************************
 //****               Platform implementation functions                ****
 //************************************************************************
diff --git a/glfw/lib/cocoa/cocoa_time.m b/glfw/lib/cocoa/cocoa_time.m
--- a/glfw/lib/cocoa/cocoa_time.m
+++ b/glfw/lib/cocoa/cocoa_time.m
@@ -29,8 +29,34 @@
 
 #include "internal.h"
 
+#include <mach/mach_time.h>
 #include <sys/time.h>
 
+
+//========================================================================
+// Return raw time
+//========================================================================
+
+static uint64_t getRawTime( void )
+{
+    return mach_absolute_time();
+}
+
+
+//========================================================================
+// Initialise timer
+//========================================================================
+
+void _glfwInitTimer( void )
+{
+    mach_timebase_info_data_t info;
+    mach_timebase_info( &info );
+
+    _glfwLibrary.timer.resolution = (double) info.numer / ( info.denom * 1.0e9 );
+    _glfwLibrary.timer.base = getRawTime();
+}
+
+
 //************************************************************************
 //****               Platform implementation functions                ****
 //************************************************************************
@@ -41,17 +67,21 @@
 
 double _glfwPlatformGetTime( void )
 {
-    return [NSDate timeIntervalSinceReferenceDate] - _glfwLibrary.Timer.t0;
+    return (double) ( getRawTime() - _glfwLibrary.timer.base ) *
+        _glfwLibrary.timer.resolution;
 }
 
+
 //========================================================================
 // Set timer value in seconds
 //========================================================================
 
 void _glfwPlatformSetTime( double time )
 {
-    _glfwLibrary.Timer.t0 = [NSDate timeIntervalSinceReferenceDate] - time;
+    _glfwLibrary.timer.base = getRawTime() -
+        (uint64_t) ( time / _glfwLibrary.timer.resolution );
 }
+
 
 //========================================================================
 // Put a thread to sleep for a specified amount of time
diff --git a/glfw/lib/cocoa/cocoa_window.m b/glfw/lib/cocoa/cocoa_window.m
--- a/glfw/lib/cocoa/cocoa_window.m
+++ b/glfw/lib/cocoa/cocoa_window.m
@@ -31,7 +31,189 @@
 
 #include <AvailabilityMacros.h>
 
+// Needed for _NSGetProgname
+#include <crt_externs.h>
+
 //========================================================================
+// GLFW application class
+//========================================================================
+
+@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
+
+//========================================================================
+// Try to figure out what the calling application is called
+//========================================================================
+
+static NSString *findAppName( void )
+{
+    // Keys to search for as potential application names
+    NSString *keys[] =
+    {
+        @"CFBundleDisplayName",
+        @"CFBundleName",
+        @"CFBundleExecutable",
+    };
+
+    NSDictionary *infoDictionary = [[NSBundle mainBundle] infoDictionary];
+
+    unsigned int i;
+    for( i = 0; i < sizeof(keys) / sizeof(keys[0]); i++ )
+    {
+        id name = [infoDictionary objectForKey:keys[i]];
+        if( name &&
+            [name isKindOfClass:[NSString class]] &&
+            ![@"" isEqualToString:name] )
+        {
+            return name;
+        }
+    }
+
+    // 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 );
+
+    char **progname = _NSGetProgname();
+    if( progname && *progname )
+    {
+        // TODO: UTF8?
+        return [NSString stringWithUTF8String:*progname];
+    }
+
+    // Really shouldn't get here
+    return @"GLFW Application";
+}
+
+
+//========================================================================
+// Set up the menu bar (manually)
+// This is nasty, nasty stuff -- calls to undocumented semi-private APIs that
+// could go away at any moment, lots of stuff that really should be
+// localize(d|able), etc.  Loading a nib would save us this horror, but that
+// doesn't seem like a good thing to require of GLFW's clients.
+//========================================================================
+
+static void setUpMenuBar( void )
+{
+    NSString *appName = findAppName();
+
+    NSMenu *bar = [[NSMenu alloc] init];
+    [NSApp setMainMenu:bar];
+
+    NSMenuItem *appMenuItem =
+        [bar addItemWithTitle:@"" action:NULL keyEquivalent:@""];
+    NSMenu *appMenu = [[NSMenu alloc] init];
+    [appMenuItem setSubmenu:appMenu];
+
+    [appMenu addItemWithTitle:[NSString stringWithFormat:@"About %@", appName]
+                       action:@selector(orderFrontStandardAboutPanel:)
+                keyEquivalent:@""];
+    [appMenu addItem:[NSMenuItem separatorItem]];
+    NSMenu *servicesMenu = [[NSMenu alloc] init];
+    [NSApp setServicesMenu:servicesMenu];
+    [[appMenu addItemWithTitle:@"Services"
+                       action:NULL
+                keyEquivalent:@""] setSubmenu:servicesMenu];
+    [appMenu addItem:[NSMenuItem separatorItem]];
+    [appMenu addItemWithTitle:[NSString stringWithFormat:@"Hide %@", appName]
+                       action:@selector(hide:)
+                keyEquivalent:@"h"];
+    [[appMenu addItemWithTitle:@"Hide Others"
+                       action:@selector(hideOtherApplications:)
+                keyEquivalent:@"h"]
+        setKeyEquivalentModifierMask:NSAlternateKeyMask | NSCommandKeyMask];
+    [appMenu addItemWithTitle:@"Show All"
+                       action:@selector(unhideAllApplications:)
+                keyEquivalent:@""];
+    [appMenu addItem:[NSMenuItem separatorItem]];
+    [appMenu addItemWithTitle:[NSString stringWithFormat:@"Quit %@", appName]
+                       action:@selector(terminate:)
+                keyEquivalent:@"q"];
+
+    NSMenuItem *windowMenuItem =
+        [bar addItemWithTitle:@"" action:NULL keyEquivalent:@""];
+    NSMenu *windowMenu = [[NSMenu alloc] initWithTitle:@"Window"];
+    [NSApp setWindowsMenu:windowMenu];
+    [windowMenuItem setSubmenu:windowMenu];
+
+    [windowMenu addItemWithTitle:@"Miniaturize"
+                          action:@selector(performMiniaturize:)
+                   keyEquivalent:@"m"];
+    [windowMenu addItemWithTitle:@"Zoom"
+                          action:@selector(performZoom:)
+                   keyEquivalent:@""];
+    [windowMenu addItem:[NSMenuItem separatorItem]];
+    [windowMenu addItemWithTitle:@"Bring All to Front"
+                          action:@selector(arrangeInFront:)
+                   keyEquivalent:@""];
+
+    // At least guard the call to private API to avoid an exception if it
+    // goes away.  Hopefully that means the worst we'll break in future is to
+    // look ugly...
+    if( [NSApp respondsToSelector:@selector(setAppleMenu:)] )
+    {
+        [NSApp setAppleMenu:appMenu];
+    }
+}
+
+
+//========================================================================
+// Initialize the Cocoa Application Kit
+//========================================================================
+
+static GLboolean initializeAppKit( void )
+{
+    if( NSApp )
+    {
+        return GL_TRUE;
+    }
+
+    // Implicitly create shared NSApplication instance
+    [GLFWApplication sharedApplication];
+
+    // Setting up the menu bar must go between sharedApplication
+    // above and finishLaunching below, in order to properly emulate the
+    // behavior of NSApplicationMain
+    setUpMenuBar();
+
+    [NSApp finishLaunching];
+
+    return GL_TRUE;
+}
+
+
+//========================================================================
 // Delegate for window related notifications
 // (but also used as an application delegate)
 //========================================================================
@@ -109,145 +291,145 @@
 
 @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 )
 {
+    // TODO: Need to find mappings for F13-F15, volume down/up/mute, and eject.
+    static const unsigned int table[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,
+    };
+
     if( macKeyCode >= 128 )
     {
         return -1;
@@ -256,9 +438,10 @@
     // 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];
+    return table[macKeyCode];
 }
 
+
 //========================================================================
 // Content view class for the GLFW window
 //========================================================================
@@ -395,7 +578,7 @@
     }
 
     _glfwWin.modifierFlags = newModifierFlags;
-    _glfwInputKey( MAC_TO_GLFW_KEYCODE_MAPPING[[event keyCode]], mode );
+    _glfwInputKey( convertMacKeyCode( [event keyCode] ), mode );
 }
 
 - (void)keyUp:(NSEvent *)event
@@ -421,7 +604,7 @@
 - (void)scrollWheel:(NSEvent *)event
 {
     _glfwInput.WheelPosFloating += [event deltaY];
-    _glfwInput.WheelPos = lrint(_glfwInput.WheelPosFloating);
+    _glfwInput.WheelPos = lrint( _glfwInput.WheelPosFloating );
 
     if( _glfwWin.mouseWheelCallback )
     {
@@ -431,6 +614,7 @@
 
 @end
 
+
 //************************************************************************
 //****               Platform implementation functions                ****
 //************************************************************************
@@ -446,14 +630,17 @@
 {
     int colorBits;
 
-    _glfwWin.pixelFormat = nil;
-    _glfwWin.window = nil;
-    _glfwWin.context = nil;
-    _glfwWin.delegate = nil;
+    _glfwWin.windowNoResize = wndconfig->windowNoResize;
 
+    if( !initializeAppKit() )
+    {
+        return GL_FALSE;
+    }
+
 #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 )
+    // Fail if any OpenGL version above 2.1 other than 3.2 was requested
+    if( wndconfig->glMajor > 3 ||
+        ( wndconfig->glMajor == 3 && wndconfig->glMinor != 2 ) )
     {
         return GL_FALSE;
     }
@@ -537,7 +724,7 @@
     }
 
     _glfwWin.window = [[NSWindow alloc]
-        initWithContentRect:NSMakeRect(0, 0, width, height)
+        initWithContentRect:NSMakeRect( 0, 0, width, height )
                   styleMask:styleMask
                     backing:NSBackingStoreBuffered
                       defer:NO];
@@ -548,6 +735,9 @@
 
     if( wndconfig->mode == GLFW_FULLSCREEN )
     {
+        _glfwLibrary.originalMode = (NSDictionary*)
+            CGDisplayCurrentMode( CGMainDisplayID() );
+
         CGCaptureAllDisplays();
         CGDisplaySwitchToMode( CGMainDisplayID(), fullscreenMode );
     }
@@ -616,7 +806,7 @@
         ADD_ATTR2( NSOpenGLPFASamples, fbconfig->samples );
     }
 
-    ADD_ATTR(0);
+    ADD_ATTR( 0 );
 
     _glfwWin.pixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:attributes];
     if( _glfwWin.pixelFormat == nil )
@@ -650,6 +840,7 @@
     return GL_TRUE;
 }
 
+
 //========================================================================
 // Properly kill the window / video display
 //========================================================================
@@ -662,7 +853,7 @@
     {
         [[_glfwWin.window contentView] exitFullScreenModeWithOptions:nil];
         CGDisplaySwitchToMode( CGMainDisplayID(),
-                               (CFDictionaryRef)_glfwLibrary.DesktopMode );
+                               (CFDictionaryRef)_glfwLibrary.originalMode );
         CGReleaseAllDisplays();
     }
 
@@ -684,6 +875,7 @@
     // TODO: Probably more cleanup
 }
 
+
 //========================================================================
 // Set the window title
 //========================================================================
@@ -694,15 +886,17 @@
                      encoding:NSISOLatin1StringEncoding]];
 }
 
+
 //========================================================================
 // Set the window size
 //========================================================================
 
 void _glfwPlatformSetWindowSize( int width, int height )
 {
-    [_glfwWin.window setContentSize:NSMakeSize(width, height)];
+    [_glfwWin.window setContentSize:NSMakeSize( width, height )];
 }
 
+
 //========================================================================
 // Set the window position
 //========================================================================
@@ -722,6 +916,7 @@
                       display:YES];
 }
 
+
 //========================================================================
 // Iconify the window
 //========================================================================
@@ -731,6 +926,7 @@
     [_glfwWin.window miniaturize:nil];
 }
 
+
 //========================================================================
 // Restore (un-iconify) the window
 //========================================================================
@@ -740,6 +936,7 @@
     [_glfwWin.window deminiaturize:nil];
 }
 
+
 //========================================================================
 // Swap buffers
 //========================================================================
@@ -750,6 +947,7 @@
     [_glfwWin.context flushBuffer];
 }
 
+
 //========================================================================
 // Set double buffering swap interval
 //========================================================================
@@ -760,6 +958,7 @@
     [_glfwWin.context setValues:&sync forParameter:NSOpenGLCPSwapInterval];
 }
 
+
 //========================================================================
 // Write back window parameters into GLFW window structure
 //========================================================================
@@ -827,6 +1026,7 @@
     _glfwWin.glDebug = GL_FALSE;
 }
 
+
 //========================================================================
 // Poll for new window and input events
 //========================================================================
@@ -842,17 +1042,18 @@
                                       inMode:NSDefaultRunLoopMode
                                      dequeue:YES];
 
-        if (event)
+        if( event )
         {
             [NSApp sendEvent:event];
         }
     }
-    while (event);
+    while( event );
 
-    [_glfwLibrary.AutoreleasePool drain];
-    _glfwLibrary.AutoreleasePool = [[NSAutoreleasePool alloc] init];
+    [_glfwLibrary.autoreleasePool drain];
+    _glfwLibrary.autoreleasePool = [[NSAutoreleasePool alloc] init];
 }
 
+
 //========================================================================
 // Wait for new window and input events
 //========================================================================
@@ -871,6 +1072,7 @@
     _glfwPlatformPollEvents();
 }
 
+
 //========================================================================
 // Hide mouse cursor (lock it)
 //========================================================================
@@ -881,6 +1083,7 @@
     CGAssociateMouseAndMouseCursorPosition( false );
 }
 
+
 //========================================================================
 // Show mouse cursor (unlock it)
 //========================================================================
@@ -891,6 +1094,7 @@
     CGAssociateMouseAndMouseCursorPosition( true );
 }
 
+
 //========================================================================
 // Set physical mouse cursor position
 //========================================================================
@@ -907,11 +1111,6 @@
     // 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];
diff --git a/glfw/lib/cocoa/platform.h b/glfw/lib/cocoa/platform.h
--- a/glfw/lib/cocoa/platform.h
+++ b/glfw/lib/cocoa/platform.h
@@ -37,6 +37,7 @@
 #if defined(__OBJC__)
 #import <Cocoa/Cocoa.h>
 #else
+#include <ApplicationServices/ApplicationServices.h>
 typedef void *id;
 #endif
 
@@ -140,21 +141,25 @@
     // Window opening hints
     _GLFWhints      hints;
 
+    // Initial desktop mode
+    GLFWvidmode     desktopMode;
+
 // ========= PLATFORM SPECIFIC PART ======================================
 
     // Timer data
     struct {
-        double t0;
-    } Timer;
+        double base;
+        double resolution;
+    } timer;
 
     // dlopen handle for dynamically-loading extension function pointers
     void *OpenGLFramework;
 
-    int Unbundled;
+    id originalMode;
 
-    id DesktopMode;
+    id autoreleasePool;
 
-    id AutoreleasePool;
+    CGEventSourceRef eventSource;
 
 } _glfwLibrary;
 
@@ -247,6 +252,14 @@
 pthread_mutex_lock( &_glfwThrd.CriticalSection );
 #define LEAVE_THREAD_CRITICAL_SECTION \
 pthread_mutex_unlock( &_glfwThrd.CriticalSection );
+
+
+//========================================================================
+// Prototypes for platform specific internal functions
+//========================================================================
+
+// Time
+void _glfwInitTimer( void );
 
 
 #endif // _platform_h_
diff --git a/glfw/lib/fullscreen.c b/glfw/lib/fullscreen.c
--- a/glfw/lib/fullscreen.c
+++ b/glfw/lib/fullscreen.c
@@ -84,11 +84,11 @@
 
 GLFWAPI void GLFWAPIENTRY glfwGetDesktopMode( GLFWvidmode *mode )
 {
-    if( !_glfwInitialized || mode == (GLFWvidmode*) 0 )
+    if( !_glfwInitialized || !mode )
     {
         return;
     }
 
-    _glfwPlatformGetDesktopMode( mode );
+    *mode = _glfwLibrary.desktopMode;
 }
 
diff --git a/glfw/lib/glext.c b/glfw/lib/glext.c
--- a/glfw/lib/glext.c
+++ b/glfw/lib/glext.c
@@ -183,8 +183,6 @@
 {
     const GLubyte *extensions;
     GLubyte *where;
-    GLint count;
-    int i;
 
     // Is GLFW initialized?
     if( !_glfwInitialized || !_glfwWin.opened )
@@ -215,6 +213,9 @@
     else
     {
         // Check if extension is in the modern OpenGL extensions string list
+
+        GLint count;
+        int i;
 
         glGetIntegerv( GL_NUM_EXTENSIONS, &count );
 
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
@@ -417,6 +417,9 @@
     // Window opening hints
     _GLFWhints      hints;
 
+    // Initial desktop mode
+    GLFWvidmode     desktopMode;
+
 // ========= PLATFORM SPECIFIC PART ======================================
 
   HINSTANCE instance;        // Instance of the application
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
@@ -313,7 +313,7 @@
     (void) EnumDisplaySettings( NULL, ENUM_REGISTRY_SETTINGS, &dm );
 
     // Return desktop mode parameters
-    mode->Width  = dm.dmPelsWidth;
+    mode->Width = dm.dmPelsWidth;
     mode->Height = dm.dmPelsHeight;
     bpp2rgb( dm.dmBitsPerPel, &mode->RedBits, &mode->GreenBits, &mode->BlueBits );
 }
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
@@ -312,6 +312,8 @@
     // Initialise thread package
     _glfwInitThreads();
 
+    _glfwPlatformGetDesktopMode( &_glfwLibrary.desktopMode );
+
     // Install atexit() routine
     atexit( _glfwTerminate_atexit );
 
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
@@ -775,7 +775,7 @@
             {
                 translateChar( (DWORD) wParam, (DWORD) lParam, GLFW_PRESS );
             }
-            return 0;
+            break;
           }
 
         case WM_KEYUP:
@@ -797,7 +797,7 @@
                 translateChar( (DWORD) wParam, (DWORD) lParam, GLFW_RELEASE );
             }
 
-            return 0;
+            break;
         }
 
         case WM_LBUTTONDOWN:
@@ -1069,16 +1069,13 @@
 static ATOM registerWindowClass( void )
 {
     WNDCLASS wc;
+    ZeroMemory( &wc, sizeof( 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.lpfnWndProc   = (WNDPROC) windowProc;          // Message handler
     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
@@ -1302,11 +1299,8 @@
 {
     GLboolean recreateContext = GL_FALSE;
 
-    // Clear platform specific GLFW window state
-    _glfwWin.classAtom         = 0;
-    _glfwWin.oldMouseLockValid = GL_FALSE;
-
     _glfwWin.desiredRefreshRate = wndconfig->refreshRate;
+    _glfwWin.windowNoResize     = wndconfig->windowNoResize;
 
     _glfwWin.classAtom = registerWindowClass();
     if( !_glfwWin.classAtom )
diff --git a/glfw/lib/window.c b/glfw/lib/window.c
--- a/glfw/lib/window.c
+++ b/glfw/lib/window.c
@@ -581,8 +581,8 @@
         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
+            // on X11/GLX using custom build systems, as the glfwGetProcAddress
+            // code path selection needs explicit configuration
             //
             // See readme.html section 2.2 for details
 
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
@@ -39,6 +39,7 @@
 // Include files
 #include <sys/time.h>
 #include <unistd.h>
+#include <stdint.h>
 #include <signal.h>
 #include <X11/Xlib.h>
 #include <X11/keysym.h>
@@ -367,6 +368,9 @@
     // Window opening hints
     _GLFWhints      hints;
 
+    // Initial desktop mode
+    GLFWvidmode     desktopMode;
+
 // ========= PLATFORM SPECIFIC PART ======================================
 
     Display        *display;
@@ -388,8 +392,9 @@
 
     // Timer data
     struct {
+        GLboolean   monotonic;
         double      resolution;
-        long long   t0;
+        long long   base;
     } Timer;
 
 #if defined(_GLFW_HAS_DLOPEN)
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
@@ -360,14 +360,6 @@
     int viscount, rgbcount, rescount;
     int *rgbarray;
     struct _glfwResolution *resarray;
-#if defined( _GLFW_HAS_XRANDR )
-    XRRScreenConfiguration *sc;
-    XRRScreenSize *sizelist;
-    int sizecount;
-#elif defined( _GLFW_HAS_XF86VIDMODE )
-    XF86VidModeModeInfo **modelist;
-    int modecount, width, height;
-#endif
 
     // Get display and screen
     dpy = _glfwLibrary.display;
@@ -421,6 +413,10 @@
 #if defined( _GLFW_HAS_XRANDR )
     if( _glfwLibrary.XRandR.available )
     {
+        XRRScreenConfiguration *sc;
+        XRRScreenSize *sizelist;
+        int sizecount;
+
         sc = XRRGetScreenInfo( dpy, RootWindow( dpy, screen ) );
         sizelist = XRRConfigSizes( sc, &sizecount );
 
@@ -438,6 +434,9 @@
 #elif defined( _GLFW_HAS_XF86VIDMODE )
     if( _glfwLibrary.XF86VidMode.available )
     {
+        XF86VidModeModeInfo **modelist;
+        int modecount, width, height;
+
         XF86VidModeGetAllModeLines( dpy, screen, &modecount, &modelist );
 
         resarray = (struct _glfwResolution*) malloc( sizeof(struct _glfwResolution) * modecount );
@@ -509,11 +508,7 @@
 void _glfwPlatformGetDesktopMode( GLFWvidmode *mode )
 {
     Display *dpy;
-    int     bpp, screen;
-#if defined( _GLFW_HAS_XF86VIDMODE )
-    XF86VidModeModeInfo **modelist;
-    int     modecount;
-#endif
+    int bpp, screen;
 
     // Get display and screen
     dpy = _glfwLibrary.display;
@@ -538,6 +533,9 @@
 #elif defined( _GLFW_HAS_XF86VIDMODE )
     if( _glfwLibrary.XF86VidMode.available )
     {
+        XF86VidModeModeInfo **modelist;
+        int modecount;
+
         if( _glfwWin.FS.modeChanged )
         {
             // The old (desktop) mode is stored in _glfwWin.FS.oldMode
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,4 +1,4 @@
-//==================
+//========================================================================
 // GLFW - An OpenGL framework
 // Platform:    X11/GLX
 // API version: 2.7
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
@@ -233,6 +233,8 @@
     // Try to load libGL.so if necessary
     initLibraries();
 
+    _glfwPlatformGetDesktopMode( &_glfwLibrary.desktopMode );
+
     // Install atexit() routine
     atexit( glfw_atexit );
 
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
@@ -30,22 +30,55 @@
 
 #include "internal.h"
 
+#include <time.h>
 
+
 //========================================================================
+// Return raw time
+//========================================================================
+
+static uint64_t getRawTime(void)
+{
+#if defined( CLOCK_MONOTONIC )
+    if( _glfwLibrary.Timer.monotonic )
+    {
+        struct timespec ts;
+
+        clock_gettime( CLOCK_MONOTONIC, &ts );
+        return (uint64_t) ts.tv_sec * (uint64_t) 1000000000 + (uint64_t) ts.tv_nsec;
+    }
+    else
+#endif
+    {
+        struct timeval tv;
+
+        gettimeofday( &tv, NULL );
+        return (uint64_t) tv.tv_sec * (uint64_t) 1000000 + (uint64_t) tv.tv_usec;
+    }
+}
+
+
+//========================================================================
 // Initialise timer
 //========================================================================
 
 void _glfwInitTimer( void )
 {
-    struct timeval  tv;
+#if defined( CLOCK_MONOTONIC )
+    struct timespec ts;
 
-    // "Resolution" is 1 us
-    _glfwLibrary.Timer.resolution = 1e-6;
+    if( clock_gettime( CLOCK_MONOTONIC, &ts ) == 0 )
+    {
+        _glfwLibrary.Timer.monotonic = GL_TRUE;
+        _glfwLibrary.Timer.resolution = 1e-9;
+    }
+    else
+#endif
+    {
+        _glfwLibrary.Timer.resolution = 1e-6;
+    }
 
-    // Set start-time for timer
-    gettimeofday( &tv, NULL );
-    _glfwLibrary.Timer.t0 = (long long) tv.tv_sec * (long long) 1000000 +
-		            (long long) tv.tv_usec;
+    _glfwLibrary.Timer.base = getRawTime();
 }
 
 
@@ -59,14 +92,8 @@
 
 double _glfwPlatformGetTime( void )
 {
-    long long t;
-    struct timeval  tv;
-
-    gettimeofday( &tv, NULL );
-    t = (long long) tv.tv_sec * (long long) 1000000 +
-	(long long) tv.tv_usec;
-
-    return (double)(t - _glfwLibrary.Timer.t0) * _glfwLibrary.Timer.resolution;
+    return (double) (getRawTime() - _glfwLibrary.Timer.base) *
+        _glfwLibrary.Timer.resolution;
 }
 
 
@@ -74,17 +101,10 @@
 // Set timer value in seconds
 //========================================================================
 
-void _glfwPlatformSetTime( double t )
+void _glfwPlatformSetTime( double time )
 {
-    long long t0;
-    struct timeval  tv;
-
-    gettimeofday( &tv, NULL );
-    t0 = (long long) tv.tv_sec * (long long) 1000000 +
-	 (long long) tv.tv_usec;
-
-    // Calulate new starting time
-    _glfwLibrary.Timer.t0 = t0 - (long long)(t/_glfwLibrary.Timer.resolution);
+    _glfwLibrary.Timer.base = getRawTime() -
+        (uint64_t) (time / _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
@@ -1388,25 +1388,9 @@
     _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 );
@@ -1795,6 +1779,11 @@
     {
         _glfwPlatformSetMouseCursorPos( _glfwWin.width/2,
                                         _glfwWin.height/2 );
+
+        // NOTE: This is a temporary fix.  It works as long as you use offsets
+        //       accumulated over the course of a frame, instead of performing
+        //       the necessary actions per callback call.
+        XFlush( _glfwLibrary.display );
     }
 
     if( closeRequested && _glfwWin.windowCloseCallback )
