GLFW-b 3.2.1.0 → 3.2.1.1
raw patch · 6 files changed
+3470/−3464 lines, 6 filesdep ~basedep ~bindings-GLFW
Dependency ranges changed: base, bindings-GLFW
Files
- GLFW-b.cabal +86/−86
- Graphics/UI/GLFW.hs +1671/−1665
- Graphics/UI/GLFW/C.hs +567/−567
- Graphics/UI/GLFW/Types.hs +530/−530
- README.md +2/−2
- Test.hs +614/−614
GLFW-b.cabal view
@@ -1,86 +1,86 @@-name: GLFW-b-version: 3.2.1.0-category: Graphics--author: Brian Lewis <brian@lorf.org>-maintainer: Brian Lewis <brian@lorf.org>- , Schell Scivally <schell.scivally@synapsegroup.com>- , Pavel Krajcevski <krajcevski@gmail.com>--license: BSD3-license-file: LICENSE--synopsis: Bindings to GLFW OpenGL library-description:- Bindings to GLFW (<http://www.glfw.org/>), an open source, multi-platform- library for creating windows with OpenGL contexts and managing input and- events.- .- GLFW-b depends on bindings-GLFW- (<http://hackage.haskell.org/package/bindings-GLFW>), which, as of the time- of this writing, binds to GLFW 3.2.1, released 2016-08-18- (<http://www.glfw.org/Version-3.2.1-released.html>- <http://www.glfw.org/changelog.html>).- .- If you've used GLFW < 3 before, you should read the transition guide- (<http://www.glfw.org/docs/3.0/moving.html>).--cabal-version: >= 1.10-build-type: Simple------------------------------------------------------------------------------------extra-source-files:- README.md- TODO------------------------------------------------------------------------------------library- default-language: Haskell2010-- ghc-options: -Wall- if impl(ghc >= 6.8)- ghc-options: -fwarn-tabs-- exposed-modules:- Graphics.UI.GLFW-- other-modules:- Graphics.UI.GLFW.C- Graphics.UI.GLFW.Types-- build-depends:- base < 5- , deepseq >= 1.1.0.0- , bindings-GLFW >= 3.2.1.1------------------------------------------------------------------------------------test-suite main- default-language: Haskell2010-- ghc-options: -Wall- if impl(ghc >= 6.8)- ghc-options: -fwarn-tabs-- type: exitcode-stdio-1.0-- main-is: Test.hs- other-modules:- Graphics.UI.GLFW- Graphics.UI.GLFW.C- Graphics.UI.GLFW.Types- build-depends:- base < 5- , HUnit >= 1.3 && < 1.7- , bindings-GLFW >= 3.2.1.0- , deepseq >= 1.1.0.0- , test-framework == 0.8.*- , test-framework-hunit == 0.3.*------------------------------------------------------------------------------------source-repository head- type: git- location: git://github.com/bsl/GLFW-b.git+name: GLFW-b +version: 3.2.1.1 +category: Graphics + +author: Brian Lewis <brian@lorf.org> +maintainer: Brian Lewis <brian@lorf.org> + , Schell Scivally <schell.scivally@synapsegroup.com> + , Pavel Krajcevski <krajcevski@gmail.com> + +license: BSD3 +license-file: LICENSE + +synopsis: Bindings to GLFW OpenGL library +description: + Bindings to GLFW (<http://www.glfw.org/>), an open source, multi-platform + library for creating windows with OpenGL contexts and managing input and + events. + . + GLFW-b depends on bindings-GLFW + (<http://hackage.haskell.org/package/bindings-GLFW>), which, as of the time + of this writing, binds to GLFW 3.2.1, released 2016-08-18 + (<http://www.glfw.org/Version-3.2.1-released.html> + <http://www.glfw.org/changelog.html>). + . + If you've used GLFW < 3 before, you should read the transition guide + (<http://www.glfw.org/docs/3.0/moving.html>). + +cabal-version: >= 1.10 +build-type: Simple + +-------------------------------------------------------------------------------- + +extra-source-files: + README.md + TODO + +-------------------------------------------------------------------------------- + +library + default-language: Haskell2010 + + ghc-options: -Wall + if impl(ghc >= 6.8) + ghc-options: -fwarn-tabs + + exposed-modules: + Graphics.UI.GLFW + + other-modules: + Graphics.UI.GLFW.C + Graphics.UI.GLFW.Types + + build-depends: + base < 5 + , deepseq >= 1.1.0.0 + , bindings-GLFW >= 3.2.1.1 && < 3.3 + +-------------------------------------------------------------------------------- + +test-suite main + default-language: Haskell2010 + + ghc-options: -Wall + if impl(ghc >= 6.8) + ghc-options: -fwarn-tabs + + type: exitcode-stdio-1.0 + + main-is: Test.hs + other-modules: + Graphics.UI.GLFW + Graphics.UI.GLFW.C + Graphics.UI.GLFW.Types + build-depends: + base < 5 + , HUnit >= 1.3 && < 1.7 + , bindings-GLFW >= 3.2.1.0 && < 3.3 + , deepseq >= 1.1.0.0 + , test-framework == 0.8.* + , test-framework-hunit == 0.3.* + +-------------------------------------------------------------------------------- + +source-repository head + type: git + location: git://github.com/bsl/GLFW-b.git
Graphics/UI/GLFW.hs view
@@ -1,1665 +1,1671 @@-{-|--Threading restrictions which apply to the C version of GLFW still apply when-writing @GLFW-b@ programs. See-<http://www.glfw.org/docs/3.2/intro.html#thread_safety GLFW thread safety documentation>-(applies here).--Current context restructions which apply to the C version of GLFW still apply.-See <http://www.glfw.org/docs/3.2/context.html#context_current GLFW current context documentation>-(applies here).--@GLFW-b@ wraps callbacks and schedules them to be run after 'pollEvents' and-'waitEvents' in the normal GHC runtime where they aren't subject to the usual-GLFW reentrancy restrictions. See-<http://www.glfw.org/docs/3.2/intro.html#reentrancy GLFW reentrancy documentation>-(does not apply here).---}-module Graphics.UI.GLFW- ( -- * Error handling- Error (..)- --- , setErrorCallback, ErrorCallback-- -- * Initialization and version information- , Version (..)- --- , init- , terminate- , getVersion- , getVersionString-- -- * Monitor handling- , Monitor- , MonitorState (..)- , VideoMode (..)- , GammaRamp (gammaRampRed, gammaRampGreen, gammaRampBlue)- , makeGammaRamp- --- , getMonitors- , getPrimaryMonitor- , getMonitorPos- , getMonitorPhysicalSize- , getMonitorName- , setMonitorCallback, MonitorCallback- , getVideoModes- , getVideoMode- , setGamma- , getGammaRamp- , setGammaRamp-- -- * Window handling- , Window- , WindowHint (..)- , ContextRobustness (..)- , OpenGLProfile (..)- , ClientAPI (..)- , ContextCreationAPI (..)- , ContextReleaseBehavior (..)- --- , defaultWindowHints- , windowHint- , createWindow- , destroyWindow- , windowShouldClose- , setWindowShouldClose- , setWindowTitle- , getWindowPos- , setWindowPos- , getWindowSize- , setWindowSize- , setWindowSizeLimits- , setWindowAspectRatio- , getWindowFrameSize- , getFramebufferSize- , setWindowIcon- , iconifyWindow- , restoreWindow- , focusWindow- , maximizeWindow- , showWindow- , hideWindow- , getWindowMonitor- , setCursorPos- , setFullscreen- , setWindowed- -- related to c'glfwGetWindowAttrib --.- , getWindowFocused -- |- , getWindowMaximized -- |- , getWindowFloating -- |- , getWindowIconified -- |- , getWindowResizable -- |- , getWindowDecorated -- |- , getWindowVisible -- |- , getWindowClientAPI -- |- , getWindowContextCreationAPI -- |- , getWindowContextVersionMajor -- |- , getWindowContextVersionMinor -- |- , getWindowContextVersionRevision -- |- , getWindowContextRobustness -- |- , getWindowContextReleaseBehavior -- |- , getWindowContextNoError -- |- , getWindowOpenGLForwardCompat -- |- , getWindowOpenGLDebugContext -- |- , getWindowOpenGLProfile --------------'- , setWindowPosCallback, WindowPosCallback- , setWindowSizeCallback, WindowSizeCallback- , setWindowCloseCallback, WindowCloseCallback- , setWindowRefreshCallback, WindowRefreshCallback- , setWindowFocusCallback, WindowFocusCallback- , setWindowIconifyCallback, WindowIconifyCallback- , setFramebufferSizeCallback, FramebufferSizeCallback- , pollEvents- , waitEvents- , waitEventsTimeout- , postEmptyEvent-- -- * Input handling- , Key (..)- , KeyState (..)- , Joystick (..)- , JoystickState (..)- , JoystickButtonState (..)- , MouseButton (..)- , MouseButtonState (..)- , CursorState (..)- , CursorInputMode (..)- , StickyKeysInputMode (..)- , StickyMouseButtonsInputMode (..)- , ModifierKeys (..)- , Image- , mkImage- , Cursor (..)- , StandardCursorShape (..)- --- -- related to c'glfwSetInputMode ----.- , getCursorInputMode -- |- , setCursorInputMode -- |- , getStickyKeysInputMode -- |- , setStickyKeysInputMode -- |- , getStickyMouseButtonsInputMode -- |- , setStickyMouseButtonsInputMode -----'- , getKey- , getKeyName- , getMouseButton- , getCursorPos- , setKeyCallback, KeyCallback- , setCharCallback, CharCallback- , setCharModsCallback, CharModsCallback- , setMouseButtonCallback, MouseButtonCallback- , setCursorPosCallback, CursorPosCallback- , setCursorEnterCallback, CursorEnterCallback- , createCursor- , createStandardCursor- , setCursor- , destroyCursor- , setScrollCallback, ScrollCallback- , setDropCallback, DropCallback- , joystickPresent- , getJoystickAxes- , getJoystickButtons- , getJoystickName- , setJoystickCallback, JoystickCallback-- -- * Time- , getTime- , setTime- , getTimerValue- , getTimerFrequency-- -- * Context- , makeContextCurrent- , getCurrentContext- , swapBuffers- , swapInterval- , extensionSupported-- -- * Clipboard- , getClipboardString- , setClipboardString-- -- * Vulkan-related functions- , vulkanSupported- , getRequiredInstanceExtensions- , getInstanceProcAddress- , getPhysicalDevicePresentationSupport- , createWindowSurface-- -- * Native access functions- -- $nativeaccess- , getWin32Adapter- , getWin32Monitor- , getWin32Window- , getWGLContext- , getCocoaMonitor- , getCocoaWindow- , getNSGLContext- , getX11Display- , getX11Adapter- , getX11Monitor- , getX11Window- , getGLXContext- , getGLXWindow- , getWaylandDisplay- , getWaylandMonitor- , getWaylandWindow- , getMirDisplay- , getMirMonitor- , getMirWindow- , getEGLDisplay- , getEGLContext- , getEGLSurface-- ) where------------------------------------------------------------------------------------import Prelude hiding (init)--import Control.Monad (when, liftM)-import Data.IORef (IORef, atomicModifyIORef, newIORef, readIORef)-import Data.Word (Word32, Word64)-import Foreign.C.String (peekCString, withCString, CString)-import Foreign.C.Types (CUInt, CUShort)-import Foreign.Marshal.Alloc (alloca, allocaBytes)-import Foreign.Marshal.Array (advancePtr, allocaArray, peekArray, withArray)-import Foreign.Ptr (FunPtr, freeHaskellFunPtr, nullFunPtr, nullPtr- ,Ptr)-import Foreign.StablePtr-import Foreign.Storable (Storable (..))-import System.IO.Unsafe (unsafePerformIO)--import Graphics.UI.GLFW.C-import Graphics.UI.GLFW.Types--import Bindings.GLFW-------------------------------------------------------------------------------------- We store FunPtrs from mk'GLFW*fun in these stored*Fun IORefs. Initialized--- with unsafePerformIO, they are basically mutable global variables.--storedErrorFun :: IORef C'GLFWerrorfun-storedMonitorFun :: IORef C'GLFWmonitorfun-storedJoystickFun :: IORef C'GLFWjoystickfun--storedErrorFun = unsafePerformIO $ newIORef nullFunPtr-storedMonitorFun = unsafePerformIO $ newIORef nullFunPtr-storedJoystickFun = unsafePerformIO $ newIORef nullFunPtr---- These NOINLINE pragmas are due to use of unsafePerformIO.--- See http://hackage.haskell.org/packages/archive/base/latest/doc/html/System-IO-Unsafe.html#v:unsafePerformIO .--{-# NOINLINE storedErrorFun #-}-{-# NOINLINE storedMonitorFun #-}-{-# NOINLINE storedJoystickFun #-}--setWindowCallback- :: (c -> IO (FunPtr c)) -- wf wrapper function- -> (h -> c) -- af adapter function- -> (FunPtr c -> IO (FunPtr c)) -- gf c'glfwSet*Callback function- -> (WindowCallbacks -> IORef (FunPtr c)) -- ior accessor for storage location- -> Window -- win window- -> Maybe h -- mcb Haskell callback- -> IO ()-setWindowCallback wr af gf ior win mcb = do- pcallbacks <- castPtrToStablePtr `liftM` c'glfwGetWindowUserPointer (unWindow win)- callbacks <- deRefStablePtr pcallbacks- setCallback wr af gf (ior callbacks) mcb--setCallback- :: (c -> IO (FunPtr c)) -- wf wrapper function- -> (h -> c) -- af adapter function- -> (FunPtr c -> IO (FunPtr c)) -- gf c'glfwSet*Callback function- -> IORef (FunPtr c) -- ior storage location- -> Maybe h -- mcb Haskell callback- -> IO ()-setCallback wf af gf ior mcb = do- -- If mcb is Just, make ccb the FunPtr of the adapted callback. Otherwise a- -- null FunPtr.- ccb <- maybe (return nullFunPtr) (wf . af) mcb- -- Call the GLFW callback-setting function.- _ <- gf ccb- -- Store it.- storeCallback ior ccb--storeCallback :: IORef (FunPtr a) -> FunPtr a -> IO ()-storeCallback ior new = do- -- Store the new FunPtr, retrieve the previous one.- prev <- atomicModifyIORef ior (\cur -> (new, cur))- -- Free the old FunPtr if necessary.- when (prev /= nullFunPtr) $ freeHaskellFunPtr prev-------------------------------------------------------------------------------------- | The error code and also a human-readable error message.-type ErrorCallback = Error -> String -> IO ()--- | Fires when the window position changes.-type WindowPosCallback = Window -> Int -> Int -> IO ()--- | Fires when the window is resized (in Screen Coordinates, which might not map 1:1 with pixels).-type WindowSizeCallback = Window -> Int -> Int -> IO ()--- | Fires when the user is attempting to close the window-type WindowCloseCallback = Window -> IO ()--- | Fires when the contents of the window are damaged and they must be refreshed.-type WindowRefreshCallback = Window -> IO ()--- | Fires when the window gains or loses input focus.-type WindowFocusCallback = Window -> Bool -> IO ()--- | Fires when the window is iconified (minimized) or not.-type WindowIconifyCallback = Window -> Bool -> IO ()--- | Fires when the size of the framebuffer for the window changes (in Pixels).-type FramebufferSizeCallback = Window -> Int -> Int -> IO ()--- | Fires whenever a mouse button is clicked.-type MouseButtonCallback = Window -> MouseButton -> MouseButtonState -> ModifierKeys -> IO ()--- | Fires every time the cursor position changes. Sub-pixel accuracy is used, when available.-type CursorPosCallback = Window -> Double -> Double -> IO ()--- | Fires when the cursor enters or exits the client area of the window.-type CursorEnterCallback = Window -> CursorState -> IO ()--- | Fires when the user scrolls the mouse wheel or via touch gesture.-type ScrollCallback = Window -> Double -> Double -> IO ()--- | Fires for each press or repeat of keyboard keys (regardless of if it has textual meaning or not, eg Shift)-type KeyCallback = Window -> Key -> Int -> KeyState -> ModifierKeys -> IO ()--- | Fires when a complete character codepoint is typed by the user, Shift then 'b' generates "B".-type CharCallback = Window -> Char -> IO ()--- | Similar to 'CharCallback', fires when a complete unicode codepoint is typed by the user.-type CharModsCallback = Window -> Char -> ModifierKeys -> IO ()--- | Fires when a monitor is connected or disconnected.-type MonitorCallback = Monitor -> MonitorState -> IO ()--- | Fires when a joystick is connected or disconnected.-type JoystickCallback = Joystick -> JoystickState -> IO ()---- 3.1 additions------------------------------------------------------------------------------------- CB scheduling--data ScheduledCallbacks = ScheduledCallbacks- { _forward :: [IO ()] -- Execution iterates this list- , _backward :: [IO ()] -- New schedules prepend here- }--storedScheduledCallbacks :: IORef ScheduledCallbacks-storedScheduledCallbacks = unsafePerformIO . newIORef $ ScheduledCallbacks [] []---- This NOINLINE pragma is due to use of unsafePerformIO.--- See http://hackage.haskell.org/packages/archive/base/latest/doc/html/System-IO-Unsafe.html#v:unsafePerformIO .--{-# NOINLINE storedScheduledCallbacks #-}---- This is provided in newer "base" versions. To avoid depending on--- it, it's reimplemented here. Should remove if/when compatibility--- with older base is not an issue:-atomicModifyIORef' :: IORef a -> (a -> (a,b)) -> IO b-atomicModifyIORef' ref f = do- b <- atomicModifyIORef ref- (\x -> let (a, b) = f x- in (a, a `seq` b))- b `seq` return b--schedule :: IO () -> IO ()-schedule act =- atomicModifyIORef' storedScheduledCallbacks $- \(ScheduledCallbacks oldForward oldBackward) ->- (ScheduledCallbacks oldForward (act : oldBackward), ())--splitFirst :: [a] -> (Maybe a, [a])-splitFirst [] = (Nothing, [])-splitFirst (x:xs) = (Just x, xs)--getNextScheduled :: IO (Maybe (IO ()))-getNextScheduled =- atomicModifyIORef storedScheduledCallbacks $- \(ScheduledCallbacks oldForward oldBackward) ->- case oldForward of- [] ->- let (mCb, newForward) = splitFirst (reverse oldBackward)- in (ScheduledCallbacks newForward [], mCb)- (cb:rest) -> -- Eat forward first- (ScheduledCallbacks rest oldBackward, Just cb)--executeScheduled :: IO ()-executeScheduled = do- mcb <- getNextScheduled- case mcb of- Nothing -> return ()- Just cb -> cb >> executeScheduled------------------------------------------------------------------------------------- Error handling---- | Can (and probably should) be used before GLFW initialization.--- See <http://www.glfw.org/docs/3.2/group__init.html#gaa5d796c3cf7c1a7f02f845486333fb5f glfwSetErrorCallback>-setErrorCallback :: Maybe ErrorCallback -> IO ()-setErrorCallback = setCallback- mk'GLFWerrorfun- (\cb a0 a1 -> do- s <- peekCString a1- schedule $ cb (fromC a0) s)- c'glfwSetErrorCallback- storedErrorFun------------------------------------------------------------------------------------- Image utility functions--withGLFWImage :: Image -> (Ptr C'GLFWimage -> IO a) -> IO a-withGLFWImage (Image w h pxs) f =- alloca $ \p'img ->- withArray pxs $ \p'pxs -> do- poke p'img $ C'GLFWimage (toC w) (toC h) p'pxs- f p'img------------------------------------------------------------------------------------- Initialization and version information---- | Attempts to initialize the GLFW library. When the library is not initialized, the only--- allowed functions to call are 'getVersion', 'getVersionString', 'setErrorCallback',--- 'init', and 'terminate'. Returns if the initialization was successful or not.--- See <http://www.glfw.org/docs/3.2/group__init.html#ga317aac130a235ab08c6db0834907d85e glfwInit>--- and <http://www.glfw.org/docs/3.2/intro.html#intro_init Initialization and Termination>-init :: IO Bool-init =- fromC `fmap` c'glfwInit---- | Cleans up GLFW and puts the library into an uninitialized state.--- Once you call this, you must initilize the library again.--- Warning: No window's context may be current in another thread when this is called.--- See <http://www.glfw.org/docs/3.2/group__init.html#gaaae48c0a18607ea4a4ba951d939f0901 glfwTerminate>--- and <http://www.glfw.org/docs/3.2/intro.html#intro_init Initialization and Termination>-terminate :: IO ()-terminate = do- c'glfwTerminate- -- Free all stored FunPtrs.- storeCallback storedErrorFun nullFunPtr- storeCallback storedMonitorFun nullFunPtr- storeCallback storedJoystickFun nullFunPtr---- | Gets the version of the GLFW library that's being used with the current program.--- See <http://www.glfw.org/docs/3.2/group__init.html#ga9f8ffaacf3c269cc48eafbf8b9b71197 glfwGetVersion>-getVersion :: IO Version-getVersion =- allocaArray 3 $ \p -> do- let p0 = p- p1 = p `advancePtr` 1- p2 = p `advancePtr` 2- c'glfwGetVersion p0 p1 p2- v0 <- fromC `fmap` peek p0- v1 <- fromC `fmap` peek p1- v2 <- fromC `fmap` peek p2- return $ Version v0 v1 v2---- | Gets the compile-time version string of the GLFW library binary.--- Gives extra info like platform and compile time options used, but you should not--- attempt to parse this to get the GLFW version number. Use 'getVersion' instead.--- See <http://www.glfw.org/docs/3.2/group__init.html#ga23d47dc013fce2bf58036da66079a657 glfwGetVersionString>-getVersionString :: IO (Maybe String)-getVersionString = do- p'vs <- c'glfwGetVersionString- if p'vs /= nullPtr- then Just `fmap` peekCString p'vs- else return Nothing------------------------------------------------------------------------------------- Monitor handling---- | Gets the list of available monitors, if possible.--- See <http://www.glfw.org/docs/3.2/group__monitor.html#ga3fba51c8bd36491d4712aa5bd074a537 glfwGetMonitors>-getMonitors :: IO (Maybe [Monitor])-getMonitors =- alloca $ \p'n -> do- p'mon <- c'glfwGetMonitors p'n- n <- fromC `fmap` peek p'n- if p'mon == nullPtr || n <= 0- then return Nothing- else (Just . map fromC) `fmap` peekArray n p'mon---- | Gets the primary monitor.--- See <http://www.glfw.org/docs/3.2/group__monitor.html#ga721867d84c6d18d6790d64d2847ca0b1 glfwGetPrimaryMonitor>-getPrimaryMonitor :: IO (Maybe Monitor)-getPrimaryMonitor = do- p'mon <- c'glfwGetPrimaryMonitor- return $- if p'mon == nullPtr- then Nothing- else Just $ fromC p'mon---- | Gets the position of the specified monitor within the coordinate space.--- See <http://www.glfw.org/docs/3.2/group__monitor.html#ga102f54e7acc9149edbcf0997152df8c9 glfwGetMonitorPos>-getMonitorPos :: Monitor -> IO (Int, Int)-getMonitorPos mon =- allocaArray 2 $ \p -> do- let p'x = p- p'y = p `advancePtr` 1- c'glfwGetMonitorPos (toC mon) p'x p'y- x <- fromC `fmap` peek p'x- y <- fromC `fmap` peek p'y- return (x, y)---- | The physical width and height of the monitor.--- See <http://www.glfw.org/docs/3.2/group__monitor.html#ga7d8bffc6c55539286a6bd20d32a8d7ea glfwGetMonitorPhysicalSize>-getMonitorPhysicalSize :: Monitor -> IO (Int, Int)-getMonitorPhysicalSize mon =- allocaArray 2 $ \p -> do- let p'w = p- p'h = p `advancePtr` 1- c'glfwGetMonitorPhysicalSize (toC mon) p'w p'h- w <- fromC `fmap` peek p'w- h <- fromC `fmap` peek p'h- return (w, h)---- | A human-readable name for the monitor specified.--- See <http://www.glfw.org/docs/3.2/group__monitor.html#ga79a34ee22ff080ca954a9663e4679daf getMonitorName>-getMonitorName :: Monitor -> IO (Maybe String)-getMonitorName mon = do- p'name <- c'glfwGetMonitorName (toC mon)- if p'name == nullPtr- then return Nothing- else Just `fmap` peekCString p'name---- | Sets a callback for when a monitor is connected or disconnected.--- See <http://www.glfw.org/docs/3.2/group__monitor.html#gac3fe0f647f68b731f99756cd81897378 glfwSetMonitorCallback>-setMonitorCallback :: Maybe MonitorCallback -> IO ()-setMonitorCallback = setCallback- mk'GLFWmonitorfun- (\cb a0 a1 -> schedule $ cb (fromC a0) (fromC a1))- c'glfwSetMonitorCallback- storedMonitorFun---- | Obtains the possible video modes of the monitor.--- See <http://www.glfw.org/docs/3.2/group__monitor.html#ga820b0ce9a5237d645ea7cbb4bd383458 glfwGetVideoModes>-getVideoModes :: Monitor -> IO (Maybe [VideoMode])-getVideoModes mon =- alloca $ \p'n -> do- p'vms <- c'glfwGetVideoModes (toC mon) p'n- n <- fromC `fmap` peek p'n- if p'vms == nullPtr || n <= 0- then return Nothing- else (Just . map fromC) `fmap` peekArray n p'vms---- | Gets the active video mode of the monitor.--- See <http://www.glfw.org/docs/3.2/group__monitor.html#gafc1bb972a921ad5b3bd5d63a95fc2d52 glfwGetVideoMode>-getVideoMode :: Monitor -> IO (Maybe VideoMode)-getVideoMode mon = do- p'vm <- c'glfwGetVideoMode (toC mon)- if p'vm == nullPtr- then return Nothing- else (Just . fromC) `fmap` peek p'vm---- | Sets the gamma of a monitor.--- See <http://www.glfw.org/docs/3.2/group__monitor.html#ga6ac582625c990220785ddd34efa3169a glfwSetGamma>-setGamma :: Monitor -> Double -> IO ()-setGamma mon e =- c'glfwSetGamma (toC mon) (toC e)---- | Gets the gamma ramp in use with the monitor.--- See <http://www.glfw.org/docs/3.2/group__monitor.html#gab7c41deb2219bde3e1eb756ddaa9ec80 glfwGetGammaRamp>-getGammaRamp :: Monitor -> IO (Maybe GammaRamp)-getGammaRamp m = do- p'ggr <- c'glfwGetGammaRamp (toC m)- if p'ggr == nullPtr- then return Nothing- else do- ggr <- peek p'ggr- let p'rs = c'GLFWgammaramp'red ggr- p'gs = c'GLFWgammaramp'green ggr- p'bs = c'GLFWgammaramp'blue ggr- cn = c'GLFWgammaramp'size ggr- n = fromC cn- if n == 0 || nullPtr `elem` [p'rs, p'gs, p'bs]- then return Nothing- else do- rs <- map fromC `fmap` peekArray n p'rs- gs <- map fromC `fmap` peekArray n p'gs- bs <- map fromC `fmap` peekArray n p'bs- return $ Just GammaRamp- { gammaRampRed = rs- , gammaRampGreen = gs- , gammaRampBlue = bs- }---- | Assigns a gamma ramp to use with the given monitor.--- See <http://www.glfw.org/docs/3.2/group__monitor.html#ga583f0ffd0d29613d8cd172b996bbf0dd glfwSetGammaRamp>-setGammaRamp :: Monitor -> GammaRamp -> IO ()-setGammaRamp mon gr =- let rs = map toC $ gammaRampRed gr :: [CUShort]- gs = map toC $ gammaRampGreen gr :: [CUShort]- bs = map toC $ gammaRampBlue gr :: [CUShort]- -- GammaRamp's smart constructor ensures that the RGB lists all have- -- equal length, so just use the number of reds.- cn = toC $ length rs :: CUInt- in alloca $ \p'ggr ->- withArray rs $ \p'rs ->- withArray gs $ \p'gs ->- withArray bs $ \p'bs -> do- let ggr = C'GLFWgammaramp- { c'GLFWgammaramp'red = p'rs- , c'GLFWgammaramp'green = p'gs- , c'GLFWgammaramp'blue = p'bs- , c'GLFWgammaramp'size = cn- }- poke p'ggr ggr- c'glfwSetGammaRamp (toC mon) p'ggr------------------------------------------------------------------------------------- Window handling---- | Sets all the window hints to default.--- See <http://www.glfw.org/docs/3.2/group__window.html#gaa77c4898dfb83344a6b4f76aa16b9a4a glfwDefaultWindowHints>-defaultWindowHints :: IO ()-defaultWindowHints =- c'glfwDefaultWindowHints---- | Hints something to the GLFW windowing system.--- See <http://www.glfw.org/docs/3.2/group__window.html#ga7d9c8c62384b1e2821c4dc48952d2033 glfwWindowHint>-windowHint :: WindowHint -> IO ()-windowHint wh =- let (t, v) = unpack- in c'glfwWindowHint t v- where- unpack = case wh of- (WindowHint'Resizable x) -> (c'GLFW_RESIZABLE, toC x)- (WindowHint'Visible x) -> (c'GLFW_VISIBLE, toC x)- (WindowHint'Decorated x) -> (c'GLFW_DECORATED, toC x)- (WindowHint'RedBits x) -> (c'GLFW_RED_BITS, toC x)- (WindowHint'GreenBits x) -> (c'GLFW_GREEN_BITS, toC x)- (WindowHint'BlueBits x) -> (c'GLFW_BLUE_BITS, toC x)- (WindowHint'AlphaBits x) -> (c'GLFW_ALPHA_BITS, toC x)- (WindowHint'DepthBits x) -> (c'GLFW_DEPTH_BITS, toC x)- (WindowHint'StencilBits x) -> (c'GLFW_STENCIL_BITS, toC x)- (WindowHint'AccumRedBits x) -> (c'GLFW_ACCUM_RED_BITS, toC x)- (WindowHint'AccumGreenBits x) -> (c'GLFW_ACCUM_GREEN_BITS, toC x)- (WindowHint'AccumBlueBits x) -> (c'GLFW_ACCUM_BLUE_BITS, toC x)- (WindowHint'AccumAlphaBits x) -> (c'GLFW_ACCUM_ALPHA_BITS, toC x)- (WindowHint'AuxBuffers x) -> (c'GLFW_AUX_BUFFERS, toC x)- (WindowHint'Samples x) -> (c'GLFW_SAMPLES, toC x)- (WindowHint'RefreshRate x) -> (c'GLFW_REFRESH_RATE, toC x)- (WindowHint'DoubleBuffer x) -> (c'GLFW_DOUBLEBUFFER, toC x)- (WindowHint'Stereo x) -> (c'GLFW_STEREO, toC x)- (WindowHint'sRGBCapable x) -> (c'GLFW_SRGB_CAPABLE, toC x)- (WindowHint'Floating x) -> (c'GLFW_FLOATING, toC x)- (WindowHint'Focused x) -> (c'GLFW_FOCUSED, toC x)- (WindowHint'Maximized x) -> (c'GLFW_MAXIMIZED, toC x)- (WindowHint'AutoIconify x) -> (c'GLFW_AUTO_ICONIFY, toC x)- (WindowHint'ClientAPI x) -> (c'GLFW_CLIENT_API, toC x)- (WindowHint'ContextCreationAPI x) -> (c'GLFW_CONTEXT_CREATION_API, toC x)- (WindowHint'ContextVersionMajor x) -> (c'GLFW_CONTEXT_VERSION_MAJOR, toC x)- (WindowHint'ContextVersionMinor x) -> (c'GLFW_CONTEXT_VERSION_MINOR, toC x)- (WindowHint'ContextRobustness x) -> (c'GLFW_CONTEXT_ROBUSTNESS, toC x)- (WindowHint'ContextReleaseBehavior x) -> (c'GLFW_CONTEXT_RELEASE_BEHAVIOR, toC x)- (WindowHint'ContextNoError x) -> (c'GLFW_CONTEXT_NO_ERROR, toC x)- (WindowHint'OpenGLForwardCompat x) -> (c'GLFW_OPENGL_FORWARD_COMPAT, toC x)- (WindowHint'OpenGLDebugContext x) -> (c'GLFW_OPENGL_DEBUG_CONTEXT, toC x)- (WindowHint'OpenGLProfile x) -> (c'GLFW_OPENGL_PROFILE, toC x)---- | Creates a new window.--- Note: If running in GHCI don't forget to `:set -fno-ghci-sandbox` or you--- may run into an assertion failure, segfault or other nasty crash.--- See <http://www.glfw.org/docs/3.2/group__window.html#ga5c336fddf2cbb5b92f65f10fb6043344 glfwCreateWindow>-createWindow :: Int -- ^ Desired width for the window.- -> Int -- ^ Desired height for the window.- -> String -- ^ Desired title for the window.- -> Maybe Monitor -- ^ Monitor to use in fullscreen mode.- -> Maybe Window -- ^ Window for context object sharing, see- -- <http://www.glfw.org/docs/3.2/context.html#context_sharing here>.- -> IO (Maybe Window)-createWindow w h title mmon mwin =- withCString title $ \ptitle -> do- charFun <- newIORef nullFunPtr- charModsFun <- newIORef nullFunPtr- cursorEnterFun <- newIORef nullFunPtr- cursorPosFun <- newIORef nullFunPtr- framebufferSizeFun <- newIORef nullFunPtr- keyFun <- newIORef nullFunPtr- mouseButtonFun <- newIORef nullFunPtr- scrollFun <- newIORef nullFunPtr- windowCloseFun <- newIORef nullFunPtr- windowFocusFun <- newIORef nullFunPtr- windowIconifyFun <- newIORef nullFunPtr- windowPosFun <- newIORef nullFunPtr- windowRefreshFun <- newIORef nullFunPtr- windowSizeFun <- newIORef nullFunPtr- dropFun <- newIORef nullFunPtr- let callbacks = WindowCallbacks- { storedCharFun = charFun- , storedCharModsFun = charModsFun- , storedCursorEnterFun = cursorEnterFun- , storedCursorPosFun = cursorPosFun- , storedFramebufferSizeFun = framebufferSizeFun- , storedKeyFun = keyFun- , storedMouseButtonFun = mouseButtonFun- , storedScrollFun = scrollFun- , storedWindowCloseFun = windowCloseFun- , storedWindowFocusFun = windowFocusFun- , storedWindowIconifyFun = windowIconifyFun- , storedWindowPosFun = windowPosFun- , storedWindowRefreshFun = windowRefreshFun- , storedWindowSizeFun = windowSizeFun- , storedDropFun = dropFun- }- p'win <- c'glfwCreateWindow- (toC w)- (toC h)- ptitle- (maybe nullPtr toC mmon)- (maybe nullPtr toC mwin)- if p'win == nullPtr- then return Nothing- else do callbackPtr <- newStablePtr callbacks- c'glfwSetWindowUserPointer p'win (castStablePtrToPtr callbackPtr)- return $ Just $ fromC p'win---- | Cleans up a window and all associated resources--- See <http://www.glfw.org/docs/3.2/group__window.html#gacdf43e51376051d2c091662e9fe3d7b2 glfwDestroyWindow>-destroyWindow :: Window -> IO ()-destroyWindow win = do- pcb <- castPtrToStablePtr `liftM` c'glfwGetWindowUserPointer (toC win)- cbs <- deRefStablePtr pcb- c'glfwDestroyWindow (toC win)-- let free callback = do funptr <- readIORef (callback cbs)- when (funptr /= nullFunPtr) $ freeHaskellFunPtr funptr- free storedCharFun- free storedCharModsFun- free storedCursorEnterFun- free storedCursorPosFun- free storedFramebufferSizeFun- free storedKeyFun- free storedMouseButtonFun- free storedScrollFun- free storedWindowCloseFun- free storedWindowFocusFun- free storedWindowIconifyFun- free storedWindowPosFun- free storedWindowRefreshFun- free storedWindowSizeFun- freeStablePtr pcb---- | If the window should close or not.--- See <http://www.glfw.org/docs/3.2/group__window.html#ga24e02fbfefbb81fc45320989f8140ab5 glfwWindowShouldClose>-windowShouldClose :: Window -> IO Bool-windowShouldClose win =- fromC `fmap` c'glfwWindowShouldClose (toC win)---- | Sets if the window should close or not.--- See <http://www.glfw.org/docs/3.2/group__window.html#ga49c449dde2a6f87d996f4daaa09d6708 glfwSetWindowShouldClose>-setWindowShouldClose :: Window -> Bool -> IO ()-setWindowShouldClose win b =- c'glfwSetWindowShouldClose (toC win) (toC b)---- | Sets the Title string of the window.--- See <http://www.glfw.org/docs/3.2/group__window.html#ga5d877f09e968cef7a360b513306f17ff glfwSetWindowTitle>-setWindowTitle :: Window -> String -> IO ()-setWindowTitle win title =- withCString title $ c'glfwSetWindowTitle (toC win)---- | Gets the window's position (in Screen Coordinates).--- See <http://www.glfw.org/docs/3.2/group__window.html#ga73cb526c000876fd8ddf571570fdb634 glfwGetWindowPos>-getWindowPos :: Window -> IO (Int, Int)-getWindowPos win =- allocaArray 2 $ \p -> do- let p'x = p- p'y = p `advancePtr` 1- c'glfwGetWindowPos (toC win) p'x p'y- x <- fromC `fmap` peek p'x- y <- fromC `fmap` peek p'y- return (x, y)---- | Sets the window's position (in Screen Coordinates).--- See <http://www.glfw.org/docs/3.2/group__window.html#ga1abb6d690e8c88e0c8cd1751356dbca8 glfwSetWindowPos>-setWindowPos :: Window -> Int -> Int -> IO ()-setWindowPos win x y =- c'glfwSetWindowPos (toC win) (toC x) (toC y)---- | Gets the size of the window (in Screen Coordinates).--- See <http://www.glfw.org/docs/3.2/group__window.html#gaeea7cbc03373a41fb51cfbf9f2a5d4c6 glfwGetWindowSize>-getWindowSize :: Window -> IO (Int, Int)-getWindowSize win =- allocaArray 2 $ \p -> do- let p'w = p- p'h = p `advancePtr` 1- c'glfwGetWindowSize (toC win) p'w p'h- w <- fromC `fmap` peek p'w- h <- fromC `fmap` peek p'h- return (w, h)---- | Gets the size of the frame around the window (in Screen Coordinates). This--- size includes the title bar, if the window has one. Not to be confused with--- 'getFramebufferSize', which gets the size of the rendering area.--- See <http://www.glfw.org/docs/3.2/group__window.html#ga1a9fd382058c53101b21cf211898f1f1 glfwGetWindowFrameSize>-getWindowFrameSize :: Window -> IO (Int, Int, Int, Int)-getWindowFrameSize win =- allocaArray 4 $ \p -> do- let p'l = p- p't = p `advancePtr` 1- p'r = p `advancePtr` 2- p'b = p `advancePtr` 3- c'glfwGetWindowFrameSize (toC win) p'l p't p'r p'b- l <- fromC `fmap` peek p'l- t <- fromC `fmap` peek p't- r <- fromC `fmap` peek p'r- b <- fromC `fmap` peek p'b- return (l, t, r, b)---- | Sets the size of the client area for the window (in Screen Coordinates).--- See <http://www.glfw.org/docs/3.2/group__window.html#ga371911f12c74c504dd8d47d832d095cb glfwSetWindowSize>-setWindowSize :: Window -> Int -> Int -> IO ()-setWindowSize win w h =- c'glfwSetWindowSize (toC win) (toC w) (toC h)---- | Sets the size limits of the client area of the specified window. If the--- window is full screen, the size limits only take effect once it is made--- windowed. If the window is not resizable this function does nothing. Pass--- 'Nothing' in any argument to disable the limit.--- See <http://www.glfw.org/docs/3.2/group__window.html#gac314fa6cec7d2d307be9963e2709cc90 glfwSetWindowSizeLimits>-setWindowSizeLimits :: Window- -> Maybe Int- -- ^ The minimum width, in screen coordinates, of the client- -- area.- -> Maybe Int- -- ^ The minimum height, in screen coordinates, of the- -- client area.- -> Maybe Int- -- ^ The maximum width, in screen coordinates, of the client- -- area.- -> Maybe Int- -- ^ The maximum height, in screen coordinates, of the- -- client area.- -> IO ()-setWindowSizeLimits win min'w min'h max'w max'h =- c'glfwSetWindowSizeLimits (toC win) (toC min'w) (toC min'h)- (toC max'w) (toC max'h)---- | Sets the required aspect ratio of the client area of the specified window.--- Pass Nothing to disable the limit.--- See <http://www.glfw.org/docs/3.2/group__window.html#ga72ac8cb1ee2e312a878b55153d81b937 glfwSetWindowAspectRatio>-setWindowAspectRatio :: Window -> Maybe (Int, Int) -> IO ()-setWindowAspectRatio win Nothing =- c'glfwSetWindowAspectRatio (toC win) c'GLFW_DONT_CARE c'GLFW_DONT_CARE-setWindowAspectRatio win (Just (w, h)) =- c'glfwSetWindowAspectRatio (toC win) (toC w) (toC h)---- | The size of the framebuffer (in Pixels)--- See <http://www.glfw.org/docs/3.2/group__window.html#ga0e2637a4161afb283f5300c7f94785c9 glfwGetFramebufferSize>-getFramebufferSize :: Window -> IO (Int, Int)-getFramebufferSize win =- allocaArray 2 $ \p -> do- let p'w = p- p'h = p `advancePtr` 1- c'glfwGetFramebufferSize (toC win) p'w p'h- w <- fromC `fmap` peek p'w- h <- fromC `fmap` peek p'h- return (w, h)---- | Sets the icon of the specified window. The system will try to find the--- image with the dimensions closest to the ones required by the platform. This--- image is then scaled and used as the icon for that size. Good sizes are--- 16x16, 32x32, and 48x48. Pass the empty list to reset to the default icon.--- Has no effect on OS X (See the <https://developer.apple.com/library/content/documentation/CoreFoundation/Conceptual/CFBundles/Introduction/Introduction.html Bundle Programming Guide>)-setWindowIcon :: Window -> [Image] -> IO ()-setWindowIcon win [] = c'glfwSetWindowIcon (toC win) 0 nullPtr-setWindowIcon win imgs =- let arrSizeBytes = length imgs * sizeOf (undefined :: C'GLFWimage)-- addNextImage :: [Image] -> Int -> Ptr C'GLFWimage -> IO ()- addNextImage [] numImages ptr =- c'glfwSetWindowIcon (toC win) (toC numImages) ptr-- addNextImage (img:rest) idx ptr =- withGLFWImage img $ \p'img -> do- c'img <- peek p'img- pokeElemOff ptr idx c'img- addNextImage rest (idx + 1) ptr- in allocaBytes arrSizeBytes $ addNextImage imgs 0---- | Iconifies (minimizes) the window.--- See <http://www.glfw.org/docs/3.2/group__window.html#ga1bb559c0ebaad63c5c05ad2a066779c4 glfwIconifyWindow>-iconifyWindow :: Window -> IO ()-iconifyWindow =- c'glfwIconifyWindow . toC---- | Restores the window from an iconified/minimized state.--- See <http://www.glfw.org/docs/3.2/group__window.html#ga52527a5904b47d802b6b4bb519cdebc7 glfwRestoreWindow>-restoreWindow :: Window -> IO ()-restoreWindow =- c'glfwRestoreWindow . toC---- | Brings the specified window to front and sets input focus. The window--- should already be visible and not iconified.--- See <http://www.glfw.org/docs/latest/group__window.html#ga873780357abd3f3a081d71a40aae45a1 glfwFocusWindow>-focusWindow :: Window -> IO ()-focusWindow = c'glfwFocusWindow . toC---- | Maximizes the specified window if it was not already maximized.--- See <http://www.glfw.org/docs/3.2/group__window.html#ga3f541387449d911274324ae7f17ec56b glfwMaximizeWindow>-maximizeWindow :: Window -> IO ()-maximizeWindow = c'glfwMaximizeWindow . toC---- | Shows the window.--- See <http://www.glfw.org/docs/3.2/group__window.html#ga61be47917b72536a148300f46494fc66 glfwShowWindow>-showWindow :: Window -> IO ()-showWindow =- c'glfwShowWindow . toC---- | Hides the window.--- See <http://www.glfw.org/docs/3.2/group__window.html#ga49401f82a1ba5f15db5590728314d47c glfwHideWindow>-hideWindow :: Window -> IO ()-hideWindow =- c'glfwHideWindow . toC---- | Gets the monitor that this window is running on, provided the window is--- fullscreen.--- See <http://www.glfw.org/docs/3.2/group__window.html#gaeac25e64789974ccbe0811766bd91a16 glfwGetWindowMonitor>-getWindowMonitor :: Window -> IO (Maybe Monitor)-getWindowMonitor win = do- p'mon <- c'glfwGetWindowMonitor (toC win)- return $ if p'mon == nullPtr- then Nothing- else Just $ fromC p'mon---- | Sets the position of the cursor within the window.--- See <http://www.glfw.org/docs/3.2/group__input.html#ga04b03af936d906ca123c8f4ee08b39e7 glfwSetCursorPos>-setCursorPos :: Window -> Double -> Double -> IO ()-setCursorPos win x y =- c'glfwSetCursorPos (toC win) (toC x) (toC y)---- | Makes a window fullscreen on the given monitor. The number of red, green,--- and blue bits is ignored. Note, this shouldn't be used to update the--- resolution of a fullscreen window. Use 'setWindowSize' instead.--- See <http://www.glfw.org/docs/3.2/group__window.html#ga81c76c418af80a1cce7055bccb0ae0a7 glfwSetWindowMonitor>-setFullscreen :: Window -> Monitor -> VideoMode -> IO ()-setFullscreen win mon (VideoMode width height _ _ _ refresh) =- c'glfwSetWindowMonitor (toC win) (toC mon) 0 0 (toC width) (toC height) (toC refresh)---- | Updates a window to be windowed instead of fullscreen. Note, this shouldn't--- be used to update the position or size of a window. Use 'setWindowPos' and--- 'setWindowSize' instead.--- See <http://www.glfw.org/docs/3.2/group__window.html#ga81c76c418af80a1cce7055bccb0ae0a7 glfwSetWindowMonitor>-setWindowed :: Window- -> Int -- ^ The width of the client area- -> Int -- ^ The height of the client area- -> Int -- ^ The x position of the window- -> Int -- ^ The y position of the window- -> IO ()-setWindowed win width height x y =- c'glfwSetWindowMonitor (toC win) nullPtr (toC x) (toC y) (toC width) (toC height) 0---- start of functions related to c'glfwGetWindowAttrib---- | If the window has focus or not.--- See <http://www.glfw.org/docs/3.2/group__window.html#gacccb29947ea4b16860ebef42c2cb9337 glfwGetWindowAttrib>-getWindowFocused :: Window -> IO Bool-getWindowFocused win =- fromC `fmap` c'glfwGetWindowAttrib (toC win) c'GLFW_FOCUSED---- | If the window is maximized or not.--- See <http://www.glfw.org/docs/3.2/group__window.html#gacccb29947ea4b16860ebef42c2cb9337 glfwGetWindowAttrib>-getWindowMaximized :: Window -> IO Bool-getWindowMaximized win =- fromC `fmap` c'glfwGetWindowAttrib (toC win) c'GLFW_MAXIMIZED---- | If the window has been set to be 'always on top' or not.--- See <http://www.glfw.org/docs/latest/group__window.html#gacccb29947ea4b16860ebef42c2cb9337 glfwGetWindowAttrib>-getWindowFloating :: Window -> IO Bool-getWindowFloating win =- fromC `fmap` c'glfwGetWindowAttrib (toC win) c'GLFW_FLOATING---- | If the window is iconified (minimized) or not.--- See <http://www.glfw.org/docs/3.2/group__window.html#gacccb29947ea4b16860ebef42c2cb9337 glfwGetWindowAttrib>-getWindowIconified :: Window -> IO Bool-getWindowIconified win =- fromC `fmap` c'glfwGetWindowAttrib (toC win) c'GLFW_ICONIFIED---- | If the window is resizable or not.--- See <http://www.glfw.org/docs/3.2/group__window.html#gacccb29947ea4b16860ebef42c2cb9337 glfwGetWindowAttrib>-getWindowResizable :: Window -> IO Bool-getWindowResizable win =- fromC `fmap` c'glfwGetWindowAttrib (toC win) c'GLFW_RESIZABLE---- | If the window is decorated or not.--- See <http://www.glfw.org/docs/3.2/group__window.html#gacccb29947ea4b16860ebef42c2cb9337 glfwGetWindowAttrib>-getWindowDecorated :: Window -> IO Bool-getWindowDecorated win =- fromC `fmap` c'glfwGetWindowAttrib (toC win) c'GLFW_DECORATED---- | If the window is visible or not.--- See <http://www.glfw.org/docs/3.2/group__window.html#gacccb29947ea4b16860ebef42c2cb9337 glfwGetWindowAttrib>-getWindowVisible :: Window -> IO Bool-getWindowVisible win =- fromC `fmap` c'glfwGetWindowAttrib (toC win) c'GLFW_VISIBLE---- | The client api for this window.--- See <http://www.glfw.org/docs/3.2/group__window.html#gacccb29947ea4b16860ebef42c2cb9337 glfwGetWindowAttrib>-getWindowClientAPI :: Window -> IO ClientAPI-getWindowClientAPI win =- fromC `fmap` c'glfwGetWindowAttrib (toC win) c'GLFW_CLIENT_API---- | Returns the context creation API used to create the specified window.--- See <http://www.glfw.org/docs/3.2/group__window.html#gacccb29947ea4b16860ebef42c2cb9337 glfwGetWindowAttrib>-getWindowContextCreationAPI :: Window -> IO ContextCreationAPI-getWindowContextCreationAPI win =- fromC `fmap` c'glfwGetWindowAttrib (toC win) c'GLFW_CONTEXT_CREATION_API---- | The context's "major" version, x.0.0--- See <http://www.glfw.org/docs/3.2/group__window.html#gacccb29947ea4b16860ebef42c2cb9337 glfwGetWindowAttrib>-getWindowContextVersionMajor :: Window -> IO Int-getWindowContextVersionMajor win =- fromC `fmap` c'glfwGetWindowAttrib (toC win) c'GLFW_CONTEXT_VERSION_MAJOR---- | The context's "minor" version, 0.y.0--- See <http://www.glfw.org/docs/3.2/group__window.html#gacccb29947ea4b16860ebef42c2cb9337 glfwGetWindowAttrib>-getWindowContextVersionMinor :: Window -> IO Int-getWindowContextVersionMinor win =- fromC `fmap` c'glfwGetWindowAttrib (toC win) c'GLFW_CONTEXT_VERSION_MINOR---- | The context's "revision" version, 0.0.z--- See <http://www.glfw.org/docs/3.2/group__window.html#gacccb29947ea4b16860ebef42c2cb9337 glfwGetWindowAttrib>-getWindowContextVersionRevision :: Window -> IO Int-getWindowContextVersionRevision win =- fromC `fmap` c'glfwGetWindowAttrib (toC win) c'GLFW_CONTEXT_REVISION---- | The context robustness of this window.--- See <http://www.glfw.org/docs/3.2/group__window.html#gacccb29947ea4b16860ebef42c2cb9337 glfwGetWindowAttrib>-getWindowContextRobustness :: Window -> IO ContextRobustness-getWindowContextRobustness win =- fromC `fmap` c'glfwGetWindowAttrib (toC win) c'GLFW_CONTEXT_ROBUSTNESS---- | Returns the context release behavior.--- See <http://www.glfw.org/docs/3.2/group__window.html#gacccb29947ea4b16860ebef42c2cb9337 glfwGetWindowAttrib>-getWindowContextReleaseBehavior :: Window -> IO ContextReleaseBehavior-getWindowContextReleaseBehavior win =- fromC `fmap` c'glfwGetWindowAttrib (toC win) c'GLFW_CONTEXT_RELEASE_BEHAVIOR---- | Returns true if the window is set to NO_ERROR (see the--- <https://www.khronos.org/registry/OpenGL/extensions/KHR/KHR_no_error.txt KHR_no_error>--- extension.-getWindowContextNoError :: Window -> IO Bool-getWindowContextNoError win =- fromC `fmap` c'glfwGetWindowAttrib (toC win) c'GLFW_CONTEXT_NO_ERROR---- | If this window is set for opengl to be forward compatible.--- See <http://www.glfw.org/docs/3.2/group__window.html#gacccb29947ea4b16860ebef42c2cb9337 glfwGetWindowAttrib>-getWindowOpenGLForwardCompat :: Window -> IO Bool-getWindowOpenGLForwardCompat win =- fromC `fmap` c'glfwGetWindowAttrib (toC win) c'GLFW_OPENGL_FORWARD_COMPAT---- | If the window has an opengl debug context--- See <http://www.glfw.org/docs/3.2/group__window.html#gacccb29947ea4b16860ebef42c2cb9337 glfwGetWindowAttrib>-getWindowOpenGLDebugContext :: Window -> IO Bool-getWindowOpenGLDebugContext win =- fromC `fmap` c'glfwGetWindowAttrib (toC win) c'GLFW_OPENGL_DEBUG_CONTEXT---- | Obtains the current opengl profile.--- See <http://www.glfw.org/docs/3.2/group__window.html#gacccb29947ea4b16860ebef42c2cb9337 glfwGetWindowAttrib>-getWindowOpenGLProfile :: Window -> IO OpenGLProfile-getWindowOpenGLProfile win =- fromC `fmap` c'glfwGetWindowAttrib (toC win) c'GLFW_OPENGL_PROFILE---- end of functions related to c'glfwGetWindowAttrib---- | Sets the callback to use when the window position changes.--- See <http://www.glfw.org/docs/3.2/group__window.html#ga2837d4d240659feb4268fcb6530a6ba1 glfwSetWindowPosCallback>-setWindowPosCallback :: Window -> Maybe WindowPosCallback -> IO ()-setWindowPosCallback win = setWindowCallback- mk'GLFWwindowposfun- (\cb a0 a1 a2 ->- schedule $ cb (fromC a0) (fromC a1) (fromC a2))- (c'glfwSetWindowPosCallback (toC win))- storedWindowPosFun- win---- | Sets the callback to use when the window's size changes.--- See <http://www.glfw.org/docs/3.2/group__window.html#gaa40cd24840daa8c62f36cafc847c72b6 glfwSetWindowSizeCallback>-setWindowSizeCallback :: Window -> Maybe WindowSizeCallback -> IO ()-setWindowSizeCallback win = setWindowCallback- mk'GLFWwindowsizefun- (\cb a0 a1 a2 ->- schedule $ cb (fromC a0) (fromC a1) (fromC a2))- (c'glfwSetWindowSizeCallback (toC win))- storedWindowSizeFun- win---- | Sets the callback to use when the user attempts to close the window.--- See <http://www.glfw.org/docs/3.2/group__window.html#gaade9264e79fae52bdb78e2df11ee8d6a glfwSetWindowCloseCallback>-setWindowCloseCallback :: Window -> Maybe WindowCloseCallback -> IO ()-setWindowCloseCallback win = setWindowCallback- mk'GLFWwindowclosefun- (. fromC)- (c'glfwSetWindowCloseCallback (toC win))- storedWindowCloseFun- win---- | Sets the callback to use when the window's data is partly dead and it should refresh.--- See <http://www.glfw.org/docs/3.2/group__window.html#ga4569b76e8ac87c55b53199e6becd97eb glfwSetWindowRefreshCallback>-setWindowRefreshCallback :: Window -> Maybe WindowRefreshCallback -> IO ()-setWindowRefreshCallback win = setWindowCallback- mk'GLFWwindowrefreshfun- (. fromC)- (c'glfwSetWindowRefreshCallback (toC win))- storedWindowRefreshFun- win---- | Sets the callback to use when the window gains or loses focus.--- See <http://www.glfw.org/docs/3.2/group__window.html#ga25d1c584edb375d7711c5c3548ba711f glfwSetWindowFocusCallback>-setWindowFocusCallback :: Window -> Maybe WindowFocusCallback -> IO ()-setWindowFocusCallback win = setWindowCallback- mk'GLFWwindowfocusfun- (\cb a0 a1 -> schedule $ cb (fromC a0) (fromC a1))- (c'glfwSetWindowFocusCallback (toC win))- storedWindowFocusFun- win---- | Sets the callback to use when the window is iconified or not (aka, minimized or not).--- See <http://www.glfw.org/docs/3.2/group__window.html#gab1ea7263081c0e073b8d5b91d6ffd367 glfwSetWindowIconifyCallback>-setWindowIconifyCallback :: Window -> Maybe WindowIconifyCallback -> IO ()-setWindowIconifyCallback win = setWindowCallback- mk'GLFWwindowiconifyfun- (\cb a0 a1 -> schedule $ cb (fromC a0) (fromC a1))- (c'glfwSetWindowIconifyCallback (toC win))- storedWindowIconifyFun- win---- | Sets the callback to use when the framebuffer's size changes.--- See <http://www.glfw.org/docs/3.2/group__window.html#ga3203461a5303bf289f2e05f854b2f7cf glfwSetFramebufferSizeCallback>-setFramebufferSizeCallback :: Window -> Maybe FramebufferSizeCallback -> IO ()-setFramebufferSizeCallback win = setWindowCallback- mk'GLFWframebuffersizefun- (\cb a0 a1 a2 -> schedule $ cb (fromC a0) (fromC a1) (fromC a2))- (c'glfwSetFramebufferSizeCallback (toC win))- storedFramebufferSizeFun- win---- | Checks for any pending events, processes them, and then immediately returns.--- This is most useful for continual rendering, such as games.--- See the <http://www.glfw.org/docs/3.2/input.html#events Event Processing Guide>-pollEvents :: IO ()-pollEvents = c'glfwPollEvents >> executeScheduled---- | Waits until at least one event is in the queue then processes the queue and returns.--- Requires at least one window to be active for it to sleep. This saves a lot of CPU, and--- is better if you're doing only periodic rendering, such as with an editor program.--- See the <http://www.glfw.org/docs/3.2/input.html#events Event Processing Guide>-waitEvents :: IO ()-waitEvents = c'glfwWaitEvents >> executeScheduled---- | Same as 'waitEvents', with a timeout after which the function returns.--- See the <http://www.glfw.org/docs/3.2/input.html#events Event Processing Guide>-waitEventsTimeout :: Double -> IO ()-waitEventsTimeout seconds =- c'glfwWaitEventsTimeout (toC seconds) >> executeScheduled---- | Creates an empty event within the event queue. Can be called from any--- thread, so you can use this to wake up the main thread that's using--- 'waitEvents' from a secondary thread.--- See the <http://www.glfw.org/docs/3.2/input.html#events Event Processing Guide>-postEmptyEvent :: IO ()-postEmptyEvent = c'glfwPostEmptyEvent------------------------------------------------------------------------------------- Input handling---- start of glfw{GS}etInputMode-related functions---- | Gets the current cursor input mode.--- See <http://www.glfw.org/docs/3.2/group__input.html#gaa92336e173da9c8834558b54ee80563b glfwSetInputMode>-getCursorInputMode :: Window -> IO CursorInputMode-getCursorInputMode win =- fromC `fmap` c'glfwGetInputMode (toC win) c'GLFW_CURSOR---- | Set the cursor input mode.--- See <http://www.glfw.org/docs/3.2/group__input.html#gaa92336e173da9c8834558b54ee80563b glfwSetInputMode>-setCursorInputMode :: Window -> CursorInputMode -> IO ()-setCursorInputMode win c =- c'glfwSetInputMode (toC win) c'GLFW_CURSOR (toC c)---- | Gets the current sticky keys mode.--- See <http://www.glfw.org/docs/3.2/group__input.html#gaa92336e173da9c8834558b54ee80563b glfwSetInputMode>-getStickyKeysInputMode :: Window -> IO StickyKeysInputMode-getStickyKeysInputMode win =- fromC `fmap` c'glfwGetInputMode (toC win) c'GLFW_STICKY_KEYS---- | Sets if sticky keys should be used or not.--- See <http://www.glfw.org/docs/3.2/group__input.html#gaa92336e173da9c8834558b54ee80563b glfwSetInputMode>-setStickyKeysInputMode :: Window -> StickyKeysInputMode -> IO ()-setStickyKeysInputMode win sk =- c'glfwSetInputMode (toC win) c'GLFW_STICKY_KEYS (toC sk)---- | Gets if sticky mouse buttons are on or not.--- See <http://www.glfw.org/docs/3.2/group__input.html#gaa92336e173da9c8834558b54ee80563b glfwSetInputMode>-getStickyMouseButtonsInputMode :: Window -> IO StickyMouseButtonsInputMode-getStickyMouseButtonsInputMode win =- fromC `fmap` c'glfwGetInputMode (toC win) c'GLFW_STICKY_MOUSE_BUTTONS---- | Sets if sticky mouse buttons should be used or not.--- See <http://www.glfw.org/docs/3.2/group__input.html#gaa92336e173da9c8834558b54ee80563b glfwSetInputMode>-setStickyMouseButtonsInputMode :: Window -> StickyMouseButtonsInputMode -> IO ()-setStickyMouseButtonsInputMode win smb =- c'glfwSetInputMode (toC win) c'GLFW_STICKY_MOUSE_BUTTONS (toC smb)---- end of glfw{GS}etInputMode-related functions---- | Gets the state of the specified key. If Stickey Keys isn't enabled then it's possible for--- keyboard polling to miss individual key presses. Use the callback to avoid this.--- See <http://www.glfw.org/docs/3.2/group__input.html#gadd341da06bc8d418b4dc3a3518af9ad2 glfwGetKey>-getKey :: Window -> Key -> IO KeyState-getKey win k =- fromC `fmap` c'glfwGetKey (toC win) (toC k)---- | Returns the localized name of the specified printable key. This is intended--- for displaying key bindings to the user. The scancode is used if the provided--- 'Key' isn't printable. If the scancode maps to a non-printable key as well,--- then 'Nothing' is returned.--- See <http://www.glfw.org/docs/3.2/group__input.html#ga237a182e5ec0b21ce64543f3b5e7e2be glfwGetKeyName>-getKeyName :: Key -> Int -> IO (Maybe String)-getKeyName k scancode = do- cstr <- c'glfwGetKeyName (toC k) (toC scancode)- if cstr == nullPtr- then return Nothing- else Just `fmap` peekCString cstr---- | Gets the state of a single specified mouse button. If sticky mouse button--- mode isn't enabled it's possible for mouse polling to miss individual mouse events. Use--- the call back to avoid this.--- See <http://www.glfw.org/docs/3.2/group__input.html#gac1473feacb5996c01a7a5a33b5066704 glfwGetMouseButton>-getMouseButton :: Window -> MouseButton -> IO MouseButtonState-getMouseButton win b =- fromC `fmap` c'glfwGetMouseButton (toC win) (toC b)---- | Returns the position, in screen coodinates, relative to the upper left.--- If the 'CursorInputMode' is "disabled", then results are unbounded by the window size.--- See <http://www.glfw.org/docs/3.2/group__input.html#ga01d37b6c40133676b9cea60ca1d7c0cc glfwGetCursorPos>-getCursorPos :: Window -> IO (Double, Double)-getCursorPos win =- allocaArray 2 $ \p -> do- let p'x = p- p'y = p `advancePtr` 1- c'glfwGetCursorPos (toC win) p'x p'y- x <- fromC `fmap` peek p'x- y <- fromC `fmap` peek p'y- return (x, y)---- | Assigns the given callback to use for all keyboard presses and repeats.--- See <http://www.glfw.org/docs/3.2/group__input.html#ga7e496507126f35ea72f01b2e6ef6d155 glfwSetKeyCallback>-setKeyCallback :: Window -> Maybe KeyCallback -> IO ()-setKeyCallback win = setWindowCallback- mk'GLFWkeyfun- (\cb a0 a1 a2 a3 a4 ->- schedule $ cb (fromC a0) (fromC a1) (fromC a2) (fromC a3) (fromC a4))- (c'glfwSetKeyCallback (toC win))- storedKeyFun- win---- | Sets the callback to use when the user types a character--- See <http://www.glfw.org/docs/3.2/group__input.html#ga556239421c6a5a243c66fca28da9f742 glfwSetCharCallback>-setCharCallback :: Window -> Maybe CharCallback -> IO ()-setCharCallback win = setWindowCallback- mk'GLFWcharfun- (\cb a0 a1 -> schedule $ cb (fromC a0) (fromC a1))- (c'glfwSetCharCallback (toC win))- storedCharFun- win---- | Sets the callback to use with Unicode characters regardless of what--- modifier keys are used.--- See <http://www.glfw.org/docs/3.2/group__input.html#ga3f55ef5dc03a374e567f068b13c94afc glfwSetCharModsCallback>-setCharModsCallback :: Window -> Maybe CharModsCallback -> IO ()-setCharModsCallback win = setWindowCallback- mk'GLFWcharmodsfun- (\cb a0 a1 a2 -> schedule $ cb (fromC a0) (fromC a1) (fromC a2))- (c'glfwSetCharModsCallback (toC win))- storedCharModsFun- win---- | Assigns the callback to run whenver a mouse button is clicked.--- See <http://www.glfw.org/docs/3.2/group__input.html#gaef49b72d84d615bca0a6ed65485e035d glfwSetMouseButtonCallback>-setMouseButtonCallback :: Window -> Maybe MouseButtonCallback -> IO ()-setMouseButtonCallback win = setWindowCallback- mk'GLFWmousebuttonfun- (\cb a0 a1 a2 a3 -> schedule $ cb (fromC a0) (fromC a1) (fromC a2) (fromC a3))- (c'glfwSetMouseButtonCallback (toC win))- storedMouseButtonFun- win---- | Assigns the callback to run whenver the cursor position changes.--- See <http://www.glfw.org/docs/3.2/group__input.html#ga7dad39486f2c7591af7fb25134a2501d glfwSetCursorPosCallback>-setCursorPosCallback :: Window -> Maybe CursorPosCallback -> IO ()-setCursorPosCallback win = setWindowCallback- mk'GLFWcursorposfun- (\cb a0 a1 a2 -> schedule $ cb (fromC a0) (fromC a1) (fromC a2))- (c'glfwSetCursorPosCallback (toC win))- storedCursorPosFun- win---- | Sets the callback for when the cursor enters or leaves the client area.--- See <http://www.glfw.org/docs/3.2/input.html#cursor_enter Cursor Enter/Leave Events>-setCursorEnterCallback :: Window -> Maybe CursorEnterCallback -> IO ()-setCursorEnterCallback win = setWindowCallback- mk'GLFWcursorenterfun- (\cb a0 a1 -> schedule $ cb (fromC a0) (fromC a1))- (c'glfwSetCursorEnterCallback (toC win))- storedCursorEnterFun- win---- | Sets the callback to run when the user scrolls with the mouse wheel or a touch gesture.--- See <http://www.glfw.org/docs/3.2/input.html#scrolling Scroll Input>-setScrollCallback :: Window -> Maybe ScrollCallback -> IO ()-setScrollCallback win = setWindowCallback- mk'GLFWscrollfun- (\cb a0 a1 a2 -> schedule $ cb (fromC a0) (fromC a1) (fromC a2))- (c'glfwSetScrollCallback (toC win))- storedScrollFun- win---- | Tests if the joystick is present at all--- See <http://www.glfw.org/docs/3.2/group__input.html#gaffcbd9ac8ee737fcdd25475123a3c790 glfwJoystickPresent>-joystickPresent :: Joystick -> IO Bool-joystickPresent js =- fromC `fmap` c'glfwJoystickPresent (toC js)---- | Returns the values of all axes of the specified joystick, normalized to between -1.0 and 1.0--- See <http://www.glfw.org/docs/3.2/group__input.html#ga6271d46a5901ec2c99601ccf4dd14731 glfwGetJoystickAxes>-getJoystickAxes :: Joystick -> IO (Maybe [Double])-getJoystickAxes js =- alloca $ \p'n -> do- p'axes <- c'glfwGetJoystickAxes (toC js) p'n- n <- fromC `fmap` peek p'n- if p'axes == nullPtr || n <= 0- then return Nothing- else (Just . map fromC) `fmap` peekArray n p'axes---- | Returns a list of all joystick button states for the specified joystick.--- See <http://www.glfw.org/docs/3.2/group__input.html#gace54cd930dcd502e118fe4021384ce1b glfwGetJoystickButtons>-getJoystickButtons :: Joystick -> IO (Maybe [JoystickButtonState])-getJoystickButtons js =- alloca $ \p'n -> do- p'buttons <- c'glfwGetJoystickButtons (toC js) p'n- n <- fromC `fmap` peek p'n- if p'buttons == nullPtr || n <= 0- then return Nothing- else (Just . map fromC) `fmap` peekArray n p'buttons---- | A human-readable name for a Joystick. Not guranteed to be unique.--- See <http://www.glfw.org/docs/3.2/group__input.html#gac8d7f6107e05cfd106cfba973ab51e19 glfwGetJoystickName>-getJoystickName :: Joystick -> IO (Maybe String)-getJoystickName js = do- p'name <- c'glfwGetJoystickName (toC js)- if p'name == nullPtr- then return Nothing- else Just `fmap` peekCString p'name---- | Sets a callback for when a joystick is connected or disconnected.--- See <http://www.glfw.org/docs/3.2/group__input.html#gab1dc8379f1b82bb660a6b9c9fa06ca07 glfwSetJoystickCallback>-setJoystickCallback :: Maybe JoystickCallback -> IO ()-setJoystickCallback = setCallback- mk'GLFWjoystickfun- (\cb a0 a1 -> schedule $ cb (fromC a0) (fromC a1))- c'glfwSetJoystickCallback- storedJoystickFun------------------------------------------------------------------------------------- Time---- | Returns the time (in seconds) of the GLFW timer.--- This is the amount of time since GLFW was initialized, unless 'setTime' was used.--- The exact resolution is system dependent.--- See <http://www.glfw.org/docs/3.2/group__input.html#gaa6cf4e7a77158a3b8fd00328b1720a4a glfwGetTime>-getTime :: IO (Maybe Double)-getTime = do- t <- fromC `fmap` c'glfwGetTime- return $ if t == 0- then Nothing- else Just t---- | Sets the GLFW timer to the specified value, which is measured in seconds, and must be positive.--- The value must also be less than ~584 years in seconds (18446744073.0).--- After this the timer begins to count upward at the normal rate.--- See <http://www.glfw.org/docs/3.2/group__input.html#gaf59589ef6e8b8c8b5ad184b25afd4dc0 glfwSetTime>-setTime :: Double -> IO ()-setTime = c'glfwSetTime . toC---- | Returns the current value of the raw timer, measured in 1 / frequency--- seconds. The frequency can be queried using getTimerFrequency.--- See <http://www.glfw.org/docs/3.2/input_guide.html#time Timer input>-getTimerValue :: IO Word64-getTimerValue = c'glfwGetTimerValue---- | Returns the frequency, in Hz, of the raw timer.--- See <http://www.glfw.org/docs/3.2/input_guide.html#time Timer input>-getTimerFrequency :: IO Word64-getTimerFrequency = c'glfwGetTimerFrequency------------------------------------------------------------------------------------- Context---- | Makes the context of the specified window the current one for the calling thread.--- A context can only be made current on a single thread at a time,--- and each thread can have only a single current context at a time.--- See <http://www.glfw.org/docs/3.2/group__context.html#ga1c04dc242268f827290fe40aa1c91157 glfwMakeContextCurrent>-makeContextCurrent :: Maybe Window -> IO ()-makeContextCurrent =- c'glfwMakeContextCurrent . maybe nullPtr toC---- | Obtains which window owns the current context of the calling thread.--- See <http://www.glfw.org/docs/3.2/group__context.html#gac84759b1f6c2d271a4fea8ae89ec980d glfwGetCurrentContext>-getCurrentContext :: IO (Maybe Window)-getCurrentContext = do- p'win <- c'glfwGetCurrentContext- return $ if p'win == nullPtr- then Nothing- else Just $ fromC p'win---- | Swaps the front and back buffers of the window.--- See <http://www.glfw.org/docs/3.2/group__window.html#ga15a5a1ee5b3c2ca6b15ca209a12efd14 glfwSwapBuffers>-swapBuffers :: Window -> IO ()-swapBuffers =- c'glfwSwapBuffers . toC---- | Sets the number of screen updates that the GPU should wait after 'swapBuffers' before actually swapping the buffers.--- Generates 'Error'NoCurrentContext' if no context is current.--- See <http://www.glfw.org/docs/3.2/group__context.html#ga6d4e0cdf151b5e579bd67f13202994ed glfwSwapInterval>-swapInterval :: Int -> IO ()-swapInterval =- c'glfwSwapInterval . toC---- | If the current OpenGL or OpenGL ES context supports the extension specified.--- Generates 'Error'NoCurrentContext' if no context is current.--- See <http://www.glfw.org/docs/3.2/group__context.html#ga87425065c011cef1ebd6aac75e059dfa glfwExtensionSupported>-extensionSupported :: String -> IO Bool-extensionSupported ext =- withCString ext $ \p'ext ->- fromC `fmap` c'glfwExtensionSupported p'ext------------------------------------------------------------------------------------- Clipboard--- http://www.glfw.org/docs/3.2/input.html#clipboard---- | The window that will own the clipboard contents, and also the clipboard string.--- See <http://www.glfw.org/docs/3.2/group__input.html#gaba1f022c5eb07dfac421df34cdcd31dd glfwSetClipboardString>-setClipboardString :: Window -> String -> IO ()-setClipboardString win s =- withCString s (c'glfwSetClipboardString (toC win))---- | Obtains the contents of the system keyboard, if possible.--- Generates 'Error'FormatUnavailable' if the system clipboard is empty or if it's not a UTF-8 string.--- See <http://www.glfw.org/docs/3.2/group__input.html#ga5aba1d704d9ab539282b1fbe9f18bb94 glfwGetClipboardString>-getClipboardString :: Window -> IO (Maybe String)-getClipboardString win = do- p's <- c'glfwGetClipboardString (toC win)- if p's == nullPtr- then return Nothing- else Just `fmap` peekCString p's------------------------------------------------------------------------------------- 3.1 additions (http://www.glfw.org/docs/3.1/news.html#news_31)------------------------------------------------------------------------------------- Cursor Objects--- http://www.glfw.org/docs/3.2/input.html#cursor_object---- | Creates a new cursor.-createCursor :: Image -- ^ The desired cursor image.- -> Int -- ^ The desired x-coordinate, in pixels, of the cursor- -- hotspot.- -> Int -- ^ The desired y-coordinate, in pixels, of the cursor- -- hotspot.- -> IO Cursor-createCursor img x y =- withGLFWImage img $ \p'img ->- Cursor `fmap` c'glfwCreateCursor p'img (toC x) (toC y)---- | Creates a cursor with a standard shape that can be set for a window with--- setCursor.-createStandardCursor :: StandardCursorShape -> IO Cursor-createStandardCursor = (fmap Cursor) . c'glfwCreateStandardCursor . toC---- | Sets the cursor image to be used when the cursor is over the client area--- of the specified window. The set cursor will only be visible when the cursor--- mode of the window is GLFW_CURSOR_NORMAL.---- On some platforms, the set cursor may not be visible unless the window also--- has input focus.-setCursor :: Window -> Cursor -> IO ()-setCursor (Window wptr) (Cursor cptr) = c'glfwSetCursor wptr cptr---- | Destroys a cursor previously created with `createCursor`. Any remaining--- cursors will be destroyed by `terminate`.-destroyCursor :: Cursor -> IO ()-destroyCursor = c'glfwDestroyCursor . unCursor---- | A callback that allows for drag and drop support.-type DropCallback = Window -- ^ The window that received the event.- -> [String] -- ^ The file and/or directory path names- -> IO ()---- | Sets the file drop callback of the specified window, which is called when--- one or more dragged files are dropped on the window.-setDropCallback :: Window -> Maybe DropCallback -> IO ()-setDropCallback win = setWindowCallback- mk'GLFWdropfun- (\cb w c fs -> do- let count = fromC c- fps <- flip mapM [0..count-1] $ \i -> do- let p = advancePtr fs i- p' <- peek p- peekCString p'- schedule $ cb (fromC w) fps)- (c'glfwSetDropCallback (toC win))- storedDropFun- win------------------------------------------------------------------------------------- Vulkan-related functions------------------------------------------------------------------------------------- | This function returns whether the Vulkan loader has been found.--- This check is performed by `init`.-vulkanSupported :: IO Bool-vulkanSupported = (c'GLFW_TRUE ==) <$> c'glfwVulkanSupported---- | Get required vulkan extensions;--- Pointer memory is managed by GLFW, destroyed by `terminate` call.------ The returned extension names are kept in `CString` type, because--- they are expected to be consumed by vulkan device initialization functions.-getRequiredInstanceExtensions :: IO [CString]-getRequiredInstanceExtensions = alloca $ \countPtr -> do- extsPtrPtr <- c'glfwGetRequiredInstanceExtensions countPtr- count <- fromIntegral <$> peek countPtr- peekArray count extsPtrPtr---- | Returns the address of the specified Vulkan instance function.-getInstanceProcAddress :: Ptr vkInstance- -- ^ VkInstance.- -- Note, the returned function must be used- -- with the same instance or its child.- -> String- -- ^ Function name- -> IO (FunPtr vkProc)-getInstanceProcAddress i procName- = withCString procName (c'glfwGetInstanceProcAddress i)---- | Returns whether the specified queue family can present images.-getPhysicalDevicePresentationSupport ::- Ptr vkInstance- -- ^ VkInstance- -> Ptr vkPhysicalDevice- -- ^ VkPhysicalDevice- -> Word32- -- ^ Index of a queue family to query.- -- This is an index in the array returned by- -- @vkGetPhysicalDeviceQueueFamilyProperties@ function.- -> IO Bool-getPhysicalDevicePresentationSupport inst dev i- = (c'GLFW_TRUE ==) <$> c'glfwGetPhysicalDevicePresentationSupport inst dev i---- | Creates a Vulkan surface for the specified window-createWindowSurface :: Enum vkResult- => Ptr vkInstance- -- ^ VkInstance- -> Window- -- ^ GLFWwindow *window- -> Ptr vkAllocationCallbacks- -- ^ const VkAllocationCallbacks *allocator- -> Ptr vkSurfaceKHR- -- ^ VkSurfaceKHR *surface- -> IO vkResult-createWindowSurface i win acs s- = toEnum . fromIntegral- <$> c'glfwCreateWindowSurface i (toC win) acs s------------------------------------------------------------------------------------- Native APIs------------------------------------------------------------------------------------- $nativeaccess--- The low level native-access bindings are exposed here via bindings-GLFW.--- These must be enabled with the 'ExposeNative' flag passed to bindings-GLFW.--- The return values of these functions are used as a best-guess and are not--- coupled with any other implementation. They should be used with caution--- and at your own risk.---- | See <http://www.glfw.org/docs/3.2/group__native.html#gac84f63a3f9db145b9435e5e0dbc4183d glfwGetWin32Adapter>-getWin32Adapter :: Window -> IO CString-getWin32Adapter = c'glfwGetWin32Adapter . toC---- | See <http://www.glfw.org/docs/3.2/group__native.html#gac408b09a330749402d5d1fa1f5894dd9 glfwGetWin32Monitor>-getWin32Monitor :: Window -> IO CString-getWin32Monitor = c'glfwGetWin32Monitor . toC---- | See <http://www.glfw.org/docs/3.2/group__native.html#gafe5079aa79038b0079fc09d5f0a8e667 glfwGetWin32Window>-getWin32Window :: Window -> IO (Ptr ())-getWin32Window = c'glfwGetWin32Window . toC---- | See <http://www.glfw.org/docs/3.2/group__native.html#gadc4010d91d9cc1134d040eeb1202a143 glfwGetWGLContext>-getWGLContext :: Window -> IO (Ptr ())-getWGLContext = c'glfwGetWGLContext . toC---- | See <http://www.glfw.org/docs/3.2/group__native.html#gaf22f429aec4b1aab316142d66d9be3e6 glfwGetCocoaMonitor>-getCocoaMonitor :: Window -> IO (Ptr Word32)-getCocoaMonitor = c'glfwGetCocoaMonitor . toC---- | See <http://www.glfw.org/docs/3.2/group__native.html#gac3ed9d495d0c2bb9652de5a50c648715 glfwGetCocoaWindow>-getCocoaWindow :: Window -> IO (Ptr ())-getCocoaWindow = c'glfwGetCocoaWindow . toC---- | See <http://www.glfw.org/docs/3.2/group__native.html#ga559e002e3cd63c979881770cd4dc63bc glfwGetNSGLContext>-getNSGLContext :: Window -> IO (Ptr ())-getNSGLContext = c'glfwGetNSGLContext . toC---- | See <http://www.glfw.org/docs/3.2/group__native.html#ga8519b66594ea3ef6eeafaa2e3ee37406 glfwGetX11Display>-getX11Display :: Window -> IO (Ptr display)-getX11Display = c'glfwGetX11Display . toC---- | See <http://www.glfw.org/docs/3.2/group__native.html#ga088fbfa80f50569402b41be71ad66e40 glfwGetX11Adapter>-getX11Adapter :: Window -> IO Word64-getX11Adapter = c'glfwGetX11Adapter . toC---- | See <http://www.glfw.org/docs/3.2/group__native.html#gab2f8cc043905e9fa9b12bfdbbcfe874c glfwGetX11Monitor>-getX11Monitor :: Window -> IO Word64-getX11Monitor = c'glfwGetX11Monitor . toC---- | See <http://www.glfw.org/docs/3.2/group__native.html#ga90ca676322740842db446999a1b1f21d glfwGetX11Window>-getX11Window :: Window -> IO Word64-getX11Window = c'glfwGetX11Window . toC---- | See <http://www.glfw.org/docs/3.2/group__native.html#ga62d884114b0abfcdc2930e89f20867e2 glfwGetGLXContext>-getGLXContext :: Window -> IO (Ptr ())-getGLXContext = c'glfwGetGLXContext . toC---- | See <http://www.glfw.org/docs/3.2/group__native.html#ga1ed27b8766e859a21381e8f8ce18d049 glfwGetGLXWindow>-getGLXWindow :: Window -> IO Word64-getGLXWindow = c'glfwGetGLXWindow . toC---- | See <http://www.glfw.org/docs/3.2/group__native.html#gaaf8118a3c877f3a6bc8e7a649519de5e glfwGetWaylandDisplay>-getWaylandDisplay :: IO (Ptr wl_display)-getWaylandDisplay = c'glfwGetWaylandDisplay---- | See <http://www.glfw.org/docs/3.2/group__native.html#gab10427a667b6cd91eec7709f7a906bd3 glfwGetWaylandMonitor>-getWaylandMonitor :: Window -> IO (Ptr wl_output)-getWaylandMonitor = c'glfwGetWaylandMonitor . toC---- | See <http://www.glfw.org/docs/3.2/group__native.html#ga4738d7aca4191363519a9a641c3ab64c glfwGetWaylandWindow>-getWaylandWindow :: Window -> IO (Ptr wl_surface)-getWaylandWindow = c'glfwGetWaylandWindow . toC---- | See <http://www.glfw.org/docs/3.2/group__native.html#ga40dd05325d9813fa67d61328c51d2930 glfwGetMirDisplay>-getMirDisplay :: IO (Ptr mir_connection)-getMirDisplay = c'glfwGetMirDisplay---- | See <http://www.glfw.org/docs/3.2/group__native.html#gae0941c11dc8f01aeb7cbb563f5cd930b glfwGetMirMonitor>-getMirMonitor :: Window -> IO Int-getMirMonitor = (fmap fromC) . c'glfwGetMirMonitor . toC---- | See <http://www.glfw.org/docs/3.2/group__native.html#ga964d52bb7932216c379762eef1ea9b05 glfwGetMirWindow>-getMirWindow :: Window -> IO (Ptr mir_surface)-getMirWindow = c'glfwGetMirWindow . toC---- | See <http://www.glfw.org/docs/3.2/group__native.html#ga1cd8d973f47aacb5532d368147cc3138 glfwGetEGLDisplay>-getEGLDisplay :: IO (Ptr ())-getEGLDisplay = c'glfwGetEGLDisplay---- | See <http://www.glfw.org/docs/3.2/group__native.html#ga671c5072becd085f4ab5771a9c8efcf1 glfwGetEGLContext>-getEGLContext :: Window -> IO (Ptr ())-getEGLContext = c'glfwGetEGLContext . toC---- | See <http://www.glfw.org/docs/3.2/group__native.html#ga2199b36117a6a695fec8441d8052eee6 glfwGetEGLSurface>-getEGLSurface :: Window -> IO (Ptr ())-getEGLSurface = c'glfwGetEGLSurface . toC+{-| + +Threading restrictions which apply to the C version of GLFW still apply when +writing @GLFW-b@ programs. See +<http://www.glfw.org/docs/3.2/intro.html#thread_safety GLFW thread safety documentation> +(applies here). + +Current context restructions which apply to the C version of GLFW still apply. +See <http://www.glfw.org/docs/3.2/context.html#context_current GLFW current context documentation> +(applies here). + +@GLFW-b@ wraps callbacks and schedules them to be run after 'pollEvents' and +'waitEvents' in the normal GHC runtime where they aren't subject to the usual +GLFW reentrancy restrictions. See +<http://www.glfw.org/docs/3.2/intro.html#reentrancy GLFW reentrancy documentation> +(does not apply here). + +-} +module Graphics.UI.GLFW + ( -- * Error handling + Error (..) + -- + , setErrorCallback, ErrorCallback + + -- * Initialization and version information + , Version (..) + -- + , init + , terminate + , getVersion + , getVersionString + + -- * Monitor handling + , Monitor + , MonitorState (..) + , VideoMode (..) + , GammaRamp (gammaRampRed, gammaRampGreen, gammaRampBlue) + , makeGammaRamp + -- + , getMonitors + , getPrimaryMonitor + , getMonitorPos + , getMonitorPhysicalSize + , getMonitorName + , setMonitorCallback, MonitorCallback + , getVideoModes + , getVideoMode + , setGamma + , getGammaRamp + , setGammaRamp + + -- * Window handling + , Window + , WindowHint (..) + , ContextRobustness (..) + , OpenGLProfile (..) + , ClientAPI (..) + , ContextCreationAPI (..) + , ContextReleaseBehavior (..) + -- + , defaultWindowHints + , windowHint + , createWindow + , destroyWindow + , windowShouldClose + , setWindowShouldClose + , setWindowTitle + , getWindowPos + , setWindowPos + , getWindowSize + , setWindowSize + , setWindowSizeLimits + , setWindowAspectRatio + , getWindowFrameSize + , getFramebufferSize + , setWindowIcon + , iconifyWindow + , restoreWindow + , focusWindow + , maximizeWindow + , showWindow + , hideWindow + , getWindowMonitor + , setCursorPos + , setFullscreen + , setWindowed + -- related to c'glfwGetWindowAttrib --. + , getWindowFocused -- | + , getWindowMaximized -- | + , getWindowFloating -- | + , getWindowIconified -- | + , getWindowResizable -- | + , getWindowDecorated -- | + , getWindowVisible -- | + , getWindowClientAPI -- | + , getWindowContextCreationAPI -- | + , getWindowContextVersionMajor -- | + , getWindowContextVersionMinor -- | + , getWindowContextVersionRevision -- | + , getWindowContextRobustness -- | + , getWindowContextReleaseBehavior -- | + , getWindowContextNoError -- | + , getWindowOpenGLForwardCompat -- | + , getWindowOpenGLDebugContext -- | + , getWindowOpenGLProfile --------------' + , setWindowPosCallback, WindowPosCallback + , setWindowSizeCallback, WindowSizeCallback + , setWindowCloseCallback, WindowCloseCallback + , setWindowRefreshCallback, WindowRefreshCallback + , setWindowFocusCallback, WindowFocusCallback + , setWindowIconifyCallback, WindowIconifyCallback + , setFramebufferSizeCallback, FramebufferSizeCallback + , pollEvents + , waitEvents + , waitEventsTimeout + , postEmptyEvent + + -- * Input handling + , Key (..) + , KeyState (..) + , Joystick (..) + , JoystickState (..) + , JoystickButtonState (..) + , MouseButton (..) + , MouseButtonState (..) + , CursorState (..) + , CursorInputMode (..) + , StickyKeysInputMode (..) + , StickyMouseButtonsInputMode (..) + , ModifierKeys (..) + , Image + , mkImage + , Cursor (..) + , StandardCursorShape (..) + -- + -- related to c'glfwSetInputMode ----. + , getCursorInputMode -- | + , setCursorInputMode -- | + , getStickyKeysInputMode -- | + , setStickyKeysInputMode -- | + , getStickyMouseButtonsInputMode -- | + , setStickyMouseButtonsInputMode -----' + , getKey + , getKeyName + , getMouseButton + , getCursorPos + , setKeyCallback, KeyCallback + , setCharCallback, CharCallback + , setCharModsCallback, CharModsCallback + , setMouseButtonCallback, MouseButtonCallback + , setCursorPosCallback, CursorPosCallback + , setCursorEnterCallback, CursorEnterCallback + , createCursor + , createStandardCursor + , setCursor + , destroyCursor + , setScrollCallback, ScrollCallback + , setDropCallback, DropCallback + , joystickPresent + , getJoystickAxes + , getJoystickButtons + , getJoystickName + , setJoystickCallback, JoystickCallback + + -- * Time + , getTime + , setTime + , getTimerValue + , getTimerFrequency + + -- * Context + , makeContextCurrent + , getCurrentContext + , swapBuffers + , swapInterval + , extensionSupported + + -- * Clipboard + , getClipboardString + , setClipboardString + + -- * Vulkan-related functions + , vulkanSupported + , getRequiredInstanceExtensions + , getInstanceProcAddress + , getPhysicalDevicePresentationSupport + , createWindowSurface + + -- * Native access functions + -- $nativeaccess + , getWin32Adapter + , getWin32Monitor + , getWin32Window + , getWGLContext + , getCocoaMonitor + , getCocoaWindow + , getNSGLContext + , getX11Display + , getX11Adapter + , getX11Monitor + , getX11Window + , getGLXContext + , getGLXWindow + , getWaylandDisplay + , getWaylandMonitor + , getWaylandWindow + , getMirDisplay + , getMirMonitor + , getMirWindow + , getEGLDisplay + , getEGLContext + , getEGLSurface + + ) where + +-------------------------------------------------------------------------------- + +import Prelude hiding (init) + +import Control.Monad (when, liftM) +import Data.IORef (IORef, atomicModifyIORef, newIORef, readIORef) +import Data.Word (Word32, Word64) +import Foreign.C.String (peekCString, withCString, CString) +import Foreign.C.Types (CUInt, CUShort) +import Foreign.Marshal.Alloc (alloca, allocaBytes) +import Foreign.Marshal.Array (advancePtr, allocaArray, peekArray, withArray) +import Foreign.Ptr (FunPtr, freeHaskellFunPtr, nullFunPtr, nullPtr + ,Ptr) +import Foreign.StablePtr +import Foreign.Storable (Storable (..)) +import System.IO.Unsafe (unsafePerformIO) + +import Graphics.UI.GLFW.C +import Graphics.UI.GLFW.Types + +import Bindings.GLFW + +-------------------------------------------------------------------------------- + +-- We store FunPtrs from mk'GLFW*fun in these stored*Fun IORefs. Initialized +-- with unsafePerformIO, they are basically mutable global variables. + +storedErrorFun :: IORef C'GLFWerrorfun +storedMonitorFun :: IORef C'GLFWmonitorfun +storedJoystickFun :: IORef C'GLFWjoystickfun + +storedErrorFun = unsafePerformIO $ newIORef nullFunPtr +storedMonitorFun = unsafePerformIO $ newIORef nullFunPtr +storedJoystickFun = unsafePerformIO $ newIORef nullFunPtr + +-- These NOINLINE pragmas are due to use of unsafePerformIO. +-- See http://hackage.haskell.org/packages/archive/base/latest/doc/html/System-IO-Unsafe.html#v:unsafePerformIO . + +{-# NOINLINE storedErrorFun #-} +{-# NOINLINE storedMonitorFun #-} +{-# NOINLINE storedJoystickFun #-} + +setWindowCallback + :: (c -> IO (FunPtr c)) -- wf wrapper function + -> (h -> c) -- af adapter function + -> (FunPtr c -> IO (FunPtr c)) -- gf c'glfwSet*Callback function + -> (WindowCallbacks -> IORef (FunPtr c)) -- ior accessor for storage location + -> Window -- win window + -> Maybe h -- mcb Haskell callback + -> IO () +setWindowCallback wr af gf ior win mcb = do + pcallbacks <- castPtrToStablePtr `liftM` c'glfwGetWindowUserPointer (unWindow win) + callbacks <- deRefStablePtr pcallbacks + setCallback wr af gf (ior callbacks) mcb + +setCallback + :: (c -> IO (FunPtr c)) -- wf wrapper function + -> (h -> c) -- af adapter function + -> (FunPtr c -> IO (FunPtr c)) -- gf c'glfwSet*Callback function + -> IORef (FunPtr c) -- ior storage location + -> Maybe h -- mcb Haskell callback + -> IO () +setCallback wf af gf ior mcb = do + -- If mcb is Just, make ccb the FunPtr of the adapted callback. Otherwise a + -- null FunPtr. + ccb <- maybe (return nullFunPtr) (wf . af) mcb + -- Call the GLFW callback-setting function. + _ <- gf ccb + -- Store it. + storeCallback ior ccb + +storeCallback :: IORef (FunPtr a) -> FunPtr a -> IO () +storeCallback ior new = do + -- Store the new FunPtr, retrieve the previous one. + prev <- atomicModifyIORef ior (\cur -> (new, cur)) + -- Free the old FunPtr if necessary. + when (prev /= nullFunPtr) $ freeHaskellFunPtr prev + +-------------------------------------------------------------------------------- + +-- | The error code and also a human-readable error message. +type ErrorCallback = Error -> String -> IO () +-- | Fires when the window position changes. +type WindowPosCallback = Window -> Int -> Int -> IO () +-- | Fires when the window is resized (in Screen Coordinates, which might not map 1:1 with pixels). +type WindowSizeCallback = Window -> Int -> Int -> IO () +-- | Fires when the user is attempting to close the window +type WindowCloseCallback = Window -> IO () +-- | Fires when the contents of the window are damaged and they must be refreshed. +type WindowRefreshCallback = Window -> IO () +-- | Fires when the window gains or loses input focus. +type WindowFocusCallback = Window -> Bool -> IO () +-- | Fires when the window is iconified (minimized) or not. +type WindowIconifyCallback = Window -> Bool -> IO () +-- | Fires when the size of the framebuffer for the window changes (in Pixels). +type FramebufferSizeCallback = Window -> Int -> Int -> IO () +-- | Fires whenever a mouse button is clicked. +type MouseButtonCallback = Window -> MouseButton -> MouseButtonState -> ModifierKeys -> IO () +-- | Fires every time the cursor position changes. Sub-pixel accuracy is used, when available. +type CursorPosCallback = Window -> Double -> Double -> IO () +-- | Fires when the cursor enters or exits the client area of the window. +type CursorEnterCallback = Window -> CursorState -> IO () +-- | Fires when the user scrolls the mouse wheel or via touch gesture. +type ScrollCallback = Window -> Double -> Double -> IO () +-- | Fires for each press or repeat of keyboard keys (regardless of if it has textual meaning or not, eg Shift) +type KeyCallback = Window -> Key -> Int -> KeyState -> ModifierKeys -> IO () +-- | Fires when a complete character codepoint is typed by the user, Shift then 'b' generates "B". +type CharCallback = Window -> Char -> IO () +-- | Similar to 'CharCallback', fires when a complete unicode codepoint is typed by the user. +type CharModsCallback = Window -> Char -> ModifierKeys -> IO () +-- | Fires when a monitor is connected or disconnected. +type MonitorCallback = Monitor -> MonitorState -> IO () +-- | Fires when a joystick is connected or disconnected. +type JoystickCallback = Joystick -> JoystickState -> IO () + +-- 3.1 additions + +-------------------------------------------------------------------------------- +-- CB scheduling + +data ScheduledCallbacks = ScheduledCallbacks + { _forward :: [IO ()] -- Execution iterates this list + , _backward :: [IO ()] -- New schedules prepend here + } + +storedScheduledCallbacks :: IORef ScheduledCallbacks +storedScheduledCallbacks = unsafePerformIO . newIORef $ ScheduledCallbacks [] [] + +-- This NOINLINE pragma is due to use of unsafePerformIO. +-- See http://hackage.haskell.org/packages/archive/base/latest/doc/html/System-IO-Unsafe.html#v:unsafePerformIO . + +{-# NOINLINE storedScheduledCallbacks #-} + +-- This is provided in newer "base" versions. To avoid depending on +-- it, it's reimplemented here. Should remove if/when compatibility +-- with older base is not an issue: +atomicModifyIORef' :: IORef a -> (a -> (a,b)) -> IO b +atomicModifyIORef' ref f = do + b <- atomicModifyIORef ref + (\x -> let (a, b) = f x + in (a, a `seq` b)) + b `seq` return b + +schedule :: IO () -> IO () +schedule act = + atomicModifyIORef' storedScheduledCallbacks $ + \(ScheduledCallbacks oldForward oldBackward) -> + (ScheduledCallbacks oldForward (act : oldBackward), ()) + +splitFirst :: [a] -> (Maybe a, [a]) +splitFirst [] = (Nothing, []) +splitFirst (x:xs) = (Just x, xs) + +getNextScheduled :: IO (Maybe (IO ())) +getNextScheduled = + atomicModifyIORef storedScheduledCallbacks $ + \(ScheduledCallbacks oldForward oldBackward) -> + case oldForward of + [] -> + let (mCb, newForward) = splitFirst (reverse oldBackward) + in (ScheduledCallbacks newForward [], mCb) + (cb:rest) -> -- Eat forward first + (ScheduledCallbacks rest oldBackward, Just cb) + +executeScheduled :: IO () +executeScheduled = do + mcb <- getNextScheduled + case mcb of + Nothing -> return () + Just cb -> cb >> executeScheduled + +-------------------------------------------------------------------------------- +-- Error handling + +-- | Can (and probably should) be used before GLFW initialization. +-- See <http://www.glfw.org/docs/3.2/group__init.html#gaa5d796c3cf7c1a7f02f845486333fb5f glfwSetErrorCallback> +setErrorCallback :: Maybe ErrorCallback -> IO () +setErrorCallback = setCallback + mk'GLFWerrorfun + (\cb a0 a1 -> do + s <- peekCString a1 + schedule $ cb (fromC a0) s) + c'glfwSetErrorCallback + storedErrorFun + +-------------------------------------------------------------------------------- +-- Image utility functions + +withGLFWImage :: Image -> (Ptr C'GLFWimage -> IO a) -> IO a +withGLFWImage (Image w h pxs) f = + alloca $ \p'img -> + withArray pxs $ \p'pxs -> do + poke p'img $ C'GLFWimage (toC w) (toC h) p'pxs + f p'img + +-------------------------------------------------------------------------------- +-- Initialization and version information + +-- | Attempts to initialize the GLFW library. When the library is not initialized, the only +-- allowed functions to call are 'getVersion', 'getVersionString', 'setErrorCallback', +-- 'init', and 'terminate'. Returns if the initialization was successful or not. +-- See <http://www.glfw.org/docs/3.2/group__init.html#ga317aac130a235ab08c6db0834907d85e glfwInit> +-- and <http://www.glfw.org/docs/3.2/intro.html#intro_init Initialization and Termination> +init :: IO Bool +init = + fromC `fmap` c'glfwInit + +-- | Cleans up GLFW and puts the library into an uninitialized state. +-- Once you call this, you must initilize the library again. +-- Warning: No window's context may be current in another thread when this is called. +-- See <http://www.glfw.org/docs/3.2/group__init.html#gaaae48c0a18607ea4a4ba951d939f0901 glfwTerminate> +-- and <http://www.glfw.org/docs/3.2/intro.html#intro_init Initialization and Termination>. This +-- function is not <https://www.glfw.org/docs/latest/intro.html#reentrancy reentrant>. +terminate :: IO () +terminate = do + c'glfwTerminate + -- Free all stored FunPtrs. + storeCallback storedErrorFun nullFunPtr + storeCallback storedMonitorFun nullFunPtr + storeCallback storedJoystickFun nullFunPtr + +-- | Gets the version of the GLFW library that's being used with the current program. +-- See <http://www.glfw.org/docs/3.2/group__init.html#ga9f8ffaacf3c269cc48eafbf8b9b71197 glfwGetVersion> +getVersion :: IO Version +getVersion = + allocaArray 3 $ \p -> do + let p0 = p + p1 = p `advancePtr` 1 + p2 = p `advancePtr` 2 + c'glfwGetVersion p0 p1 p2 + v0 <- fromC `fmap` peek p0 + v1 <- fromC `fmap` peek p1 + v2 <- fromC `fmap` peek p2 + return $ Version v0 v1 v2 + +-- | Gets the compile-time version string of the GLFW library binary. +-- Gives extra info like platform and compile time options used, but you should not +-- attempt to parse this to get the GLFW version number. Use 'getVersion' instead. +-- See <http://www.glfw.org/docs/3.2/group__init.html#ga23d47dc013fce2bf58036da66079a657 glfwGetVersionString> +getVersionString :: IO (Maybe String) +getVersionString = do + p'vs <- c'glfwGetVersionString + if p'vs /= nullPtr + then Just `fmap` peekCString p'vs + else return Nothing + +-------------------------------------------------------------------------------- +-- Monitor handling + +-- | Gets the list of available monitors, if possible. +-- See <http://www.glfw.org/docs/3.2/group__monitor.html#ga3fba51c8bd36491d4712aa5bd074a537 glfwGetMonitors> +getMonitors :: IO (Maybe [Monitor]) +getMonitors = + alloca $ \p'n -> do + p'mon <- c'glfwGetMonitors p'n + n <- fromC `fmap` peek p'n + if p'mon == nullPtr || n <= 0 + then return Nothing + else (Just . map fromC) `fmap` peekArray n p'mon + +-- | Gets the primary monitor. +-- See <http://www.glfw.org/docs/3.2/group__monitor.html#ga721867d84c6d18d6790d64d2847ca0b1 glfwGetPrimaryMonitor> +getPrimaryMonitor :: IO (Maybe Monitor) +getPrimaryMonitor = do + p'mon <- c'glfwGetPrimaryMonitor + return $ + if p'mon == nullPtr + then Nothing + else Just $ fromC p'mon + +-- | Gets the position of the specified monitor within the coordinate space. +-- See <http://www.glfw.org/docs/3.2/group__monitor.html#ga102f54e7acc9149edbcf0997152df8c9 glfwGetMonitorPos> +getMonitorPos :: Monitor -> IO (Int, Int) +getMonitorPos mon = + allocaArray 2 $ \p -> do + let p'x = p + p'y = p `advancePtr` 1 + c'glfwGetMonitorPos (toC mon) p'x p'y + x <- fromC `fmap` peek p'x + y <- fromC `fmap` peek p'y + return (x, y) + +-- | The physical width and height of the monitor. +-- See <http://www.glfw.org/docs/3.2/group__monitor.html#ga7d8bffc6c55539286a6bd20d32a8d7ea glfwGetMonitorPhysicalSize> +getMonitorPhysicalSize :: Monitor -> IO (Int, Int) +getMonitorPhysicalSize mon = + allocaArray 2 $ \p -> do + let p'w = p + p'h = p `advancePtr` 1 + c'glfwGetMonitorPhysicalSize (toC mon) p'w p'h + w <- fromC `fmap` peek p'w + h <- fromC `fmap` peek p'h + return (w, h) + +-- | A human-readable name for the monitor specified. +-- See <http://www.glfw.org/docs/3.2/group__monitor.html#ga79a34ee22ff080ca954a9663e4679daf getMonitorName> +getMonitorName :: Monitor -> IO (Maybe String) +getMonitorName mon = do + p'name <- c'glfwGetMonitorName (toC mon) + if p'name == nullPtr + then return Nothing + else Just `fmap` peekCString p'name + +-- | Sets a callback for when a monitor is connected or disconnected. +-- See <http://www.glfw.org/docs/3.2/group__monitor.html#gac3fe0f647f68b731f99756cd81897378 glfwSetMonitorCallback> +setMonitorCallback :: Maybe MonitorCallback -> IO () +setMonitorCallback = setCallback + mk'GLFWmonitorfun + (\cb a0 a1 -> schedule $ cb (fromC a0) (fromC a1)) + c'glfwSetMonitorCallback + storedMonitorFun + +-- | Obtains the possible video modes of the monitor. +-- See <http://www.glfw.org/docs/3.2/group__monitor.html#ga820b0ce9a5237d645ea7cbb4bd383458 glfwGetVideoModes> +getVideoModes :: Monitor -> IO (Maybe [VideoMode]) +getVideoModes mon = + alloca $ \p'n -> do + p'vms <- c'glfwGetVideoModes (toC mon) p'n + n <- fromC `fmap` peek p'n + if p'vms == nullPtr || n <= 0 + then return Nothing + else (Just . map fromC) `fmap` peekArray n p'vms + +-- | Gets the active video mode of the monitor. +-- See <http://www.glfw.org/docs/3.2/group__monitor.html#gafc1bb972a921ad5b3bd5d63a95fc2d52 glfwGetVideoMode> +getVideoMode :: Monitor -> IO (Maybe VideoMode) +getVideoMode mon = do + p'vm <- c'glfwGetVideoMode (toC mon) + if p'vm == nullPtr + then return Nothing + else (Just . fromC) `fmap` peek p'vm + +-- | Sets the gamma of a monitor. +-- See <http://www.glfw.org/docs/3.2/group__monitor.html#ga6ac582625c990220785ddd34efa3169a glfwSetGamma> +setGamma :: Monitor -> Double -> IO () +setGamma mon e = + c'glfwSetGamma (toC mon) (toC e) + +-- | Gets the gamma ramp in use with the monitor. +-- See <http://www.glfw.org/docs/3.2/group__monitor.html#gab7c41deb2219bde3e1eb756ddaa9ec80 glfwGetGammaRamp> +getGammaRamp :: Monitor -> IO (Maybe GammaRamp) +getGammaRamp m = do + p'ggr <- c'glfwGetGammaRamp (toC m) + if p'ggr == nullPtr + then return Nothing + else do + ggr <- peek p'ggr + let p'rs = c'GLFWgammaramp'red ggr + p'gs = c'GLFWgammaramp'green ggr + p'bs = c'GLFWgammaramp'blue ggr + cn = c'GLFWgammaramp'size ggr + n = fromC cn + if n == 0 || nullPtr `elem` [p'rs, p'gs, p'bs] + then return Nothing + else do + rs <- map fromC `fmap` peekArray n p'rs + gs <- map fromC `fmap` peekArray n p'gs + bs <- map fromC `fmap` peekArray n p'bs + return $ Just GammaRamp + { gammaRampRed = rs + , gammaRampGreen = gs + , gammaRampBlue = bs + } + +-- | Assigns a gamma ramp to use with the given monitor. +-- See <http://www.glfw.org/docs/3.2/group__monitor.html#ga583f0ffd0d29613d8cd172b996bbf0dd glfwSetGammaRamp> +setGammaRamp :: Monitor -> GammaRamp -> IO () +setGammaRamp mon gr = + let rs = map toC $ gammaRampRed gr :: [CUShort] + gs = map toC $ gammaRampGreen gr :: [CUShort] + bs = map toC $ gammaRampBlue gr :: [CUShort] + -- GammaRamp's smart constructor ensures that the RGB lists all have + -- equal length, so just use the number of reds. + cn = toC $ length rs :: CUInt + in alloca $ \p'ggr -> + withArray rs $ \p'rs -> + withArray gs $ \p'gs -> + withArray bs $ \p'bs -> do + let ggr = C'GLFWgammaramp + { c'GLFWgammaramp'red = p'rs + , c'GLFWgammaramp'green = p'gs + , c'GLFWgammaramp'blue = p'bs + , c'GLFWgammaramp'size = cn + } + poke p'ggr ggr + c'glfwSetGammaRamp (toC mon) p'ggr + +-------------------------------------------------------------------------------- +-- Window handling + +-- | Sets all the window hints to default. +-- See <http://www.glfw.org/docs/3.2/group__window.html#gaa77c4898dfb83344a6b4f76aa16b9a4a glfwDefaultWindowHints> +defaultWindowHints :: IO () +defaultWindowHints = + c'glfwDefaultWindowHints + +-- | Hints something to the GLFW windowing system. +-- See <http://www.glfw.org/docs/3.2/group__window.html#ga7d9c8c62384b1e2821c4dc48952d2033 glfwWindowHint> +windowHint :: WindowHint -> IO () +windowHint wh = + let (t, v) = unpack + in c'glfwWindowHint t v + where + unpack = case wh of + (WindowHint'Resizable x) -> (c'GLFW_RESIZABLE, toC x) + (WindowHint'Visible x) -> (c'GLFW_VISIBLE, toC x) + (WindowHint'Decorated x) -> (c'GLFW_DECORATED, toC x) + (WindowHint'RedBits x) -> (c'GLFW_RED_BITS, toC x) + (WindowHint'GreenBits x) -> (c'GLFW_GREEN_BITS, toC x) + (WindowHint'BlueBits x) -> (c'GLFW_BLUE_BITS, toC x) + (WindowHint'AlphaBits x) -> (c'GLFW_ALPHA_BITS, toC x) + (WindowHint'DepthBits x) -> (c'GLFW_DEPTH_BITS, toC x) + (WindowHint'StencilBits x) -> (c'GLFW_STENCIL_BITS, toC x) + (WindowHint'AccumRedBits x) -> (c'GLFW_ACCUM_RED_BITS, toC x) + (WindowHint'AccumGreenBits x) -> (c'GLFW_ACCUM_GREEN_BITS, toC x) + (WindowHint'AccumBlueBits x) -> (c'GLFW_ACCUM_BLUE_BITS, toC x) + (WindowHint'AccumAlphaBits x) -> (c'GLFW_ACCUM_ALPHA_BITS, toC x) + (WindowHint'AuxBuffers x) -> (c'GLFW_AUX_BUFFERS, toC x) + (WindowHint'Samples x) -> (c'GLFW_SAMPLES, toC x) + (WindowHint'RefreshRate x) -> (c'GLFW_REFRESH_RATE, toC x) + (WindowHint'DoubleBuffer x) -> (c'GLFW_DOUBLEBUFFER, toC x) + (WindowHint'Stereo x) -> (c'GLFW_STEREO, toC x) + (WindowHint'sRGBCapable x) -> (c'GLFW_SRGB_CAPABLE, toC x) + (WindowHint'Floating x) -> (c'GLFW_FLOATING, toC x) + (WindowHint'Focused x) -> (c'GLFW_FOCUSED, toC x) + (WindowHint'Maximized x) -> (c'GLFW_MAXIMIZED, toC x) + (WindowHint'AutoIconify x) -> (c'GLFW_AUTO_ICONIFY, toC x) + (WindowHint'ClientAPI x) -> (c'GLFW_CLIENT_API, toC x) + (WindowHint'ContextCreationAPI x) -> (c'GLFW_CONTEXT_CREATION_API, toC x) + (WindowHint'ContextVersionMajor x) -> (c'GLFW_CONTEXT_VERSION_MAJOR, toC x) + (WindowHint'ContextVersionMinor x) -> (c'GLFW_CONTEXT_VERSION_MINOR, toC x) + (WindowHint'ContextRobustness x) -> (c'GLFW_CONTEXT_ROBUSTNESS, toC x) + (WindowHint'ContextReleaseBehavior x) -> (c'GLFW_CONTEXT_RELEASE_BEHAVIOR, toC x) + (WindowHint'ContextNoError x) -> (c'GLFW_CONTEXT_NO_ERROR, toC x) + (WindowHint'OpenGLForwardCompat x) -> (c'GLFW_OPENGL_FORWARD_COMPAT, toC x) + (WindowHint'OpenGLDebugContext x) -> (c'GLFW_OPENGL_DEBUG_CONTEXT, toC x) + (WindowHint'OpenGLProfile x) -> (c'GLFW_OPENGL_PROFILE, toC x) + +-- | Creates a new window. +-- Note: If running in GHCI don't forget to `:set -fno-ghci-sandbox` or you +-- may run into an assertion failure, segfault or other nasty crash. +-- See <http://www.glfw.org/docs/3.2/group__window.html#ga5c336fddf2cbb5b92f65f10fb6043344 glfwCreateWindow> +createWindow :: Int -- ^ Desired width for the window. + -> Int -- ^ Desired height for the window. + -> String -- ^ Desired title for the window. + -> Maybe Monitor -- ^ Monitor to use in fullscreen mode. + -> Maybe Window -- ^ Window for context object sharing, see + -- <http://www.glfw.org/docs/3.2/context.html#context_sharing here>. + -> IO (Maybe Window) +createWindow w h title mmon mwin = + withCString title $ \ptitle -> do + charFun <- newIORef nullFunPtr + charModsFun <- newIORef nullFunPtr + cursorEnterFun <- newIORef nullFunPtr + cursorPosFun <- newIORef nullFunPtr + framebufferSizeFun <- newIORef nullFunPtr + keyFun <- newIORef nullFunPtr + mouseButtonFun <- newIORef nullFunPtr + scrollFun <- newIORef nullFunPtr + windowCloseFun <- newIORef nullFunPtr + windowFocusFun <- newIORef nullFunPtr + windowIconifyFun <- newIORef nullFunPtr + windowPosFun <- newIORef nullFunPtr + windowRefreshFun <- newIORef nullFunPtr + windowSizeFun <- newIORef nullFunPtr + dropFun <- newIORef nullFunPtr + let callbacks = WindowCallbacks + { storedCharFun = charFun + , storedCharModsFun = charModsFun + , storedCursorEnterFun = cursorEnterFun + , storedCursorPosFun = cursorPosFun + , storedFramebufferSizeFun = framebufferSizeFun + , storedKeyFun = keyFun + , storedMouseButtonFun = mouseButtonFun + , storedScrollFun = scrollFun + , storedWindowCloseFun = windowCloseFun + , storedWindowFocusFun = windowFocusFun + , storedWindowIconifyFun = windowIconifyFun + , storedWindowPosFun = windowPosFun + , storedWindowRefreshFun = windowRefreshFun + , storedWindowSizeFun = windowSizeFun + , storedDropFun = dropFun + } + p'win <- c'glfwCreateWindow + (toC w) + (toC h) + ptitle + (maybe nullPtr toC mmon) + (maybe nullPtr toC mwin) + if p'win == nullPtr + then return Nothing + else do callbackPtr <- newStablePtr callbacks + c'glfwSetWindowUserPointer p'win (castStablePtrToPtr callbackPtr) + return $ Just $ fromC p'win + +-- | Cleans up a window and all associated resources +-- See <http://www.glfw.org/docs/3.2/group__window.html#gacdf43e51376051d2c091662e9fe3d7b2 glfwDestroyWindow>. +-- This function is not <https://www.glfw.org/docs/latest/intro.html#reentrancy reentrant>. +destroyWindow :: Window -> IO () +destroyWindow win = do + pcb <- castPtrToStablePtr `liftM` c'glfwGetWindowUserPointer (toC win) + cbs <- deRefStablePtr pcb + c'glfwDestroyWindow (toC win) + + let free callback = do funptr <- readIORef (callback cbs) + when (funptr /= nullFunPtr) $ freeHaskellFunPtr funptr + free storedCharFun + free storedCharModsFun + free storedCursorEnterFun + free storedCursorPosFun + free storedFramebufferSizeFun + free storedKeyFun + free storedMouseButtonFun + free storedScrollFun + free storedWindowCloseFun + free storedWindowFocusFun + free storedWindowIconifyFun + free storedWindowPosFun + free storedWindowRefreshFun + free storedWindowSizeFun + freeStablePtr pcb + +-- | If the window should close or not. +-- See <http://www.glfw.org/docs/3.2/group__window.html#ga24e02fbfefbb81fc45320989f8140ab5 glfwWindowShouldClose> +windowShouldClose :: Window -> IO Bool +windowShouldClose win = + fromC `fmap` c'glfwWindowShouldClose (toC win) + +-- | Sets if the window should close or not. +-- See <http://www.glfw.org/docs/3.2/group__window.html#ga49c449dde2a6f87d996f4daaa09d6708 glfwSetWindowShouldClose> +setWindowShouldClose :: Window -> Bool -> IO () +setWindowShouldClose win b = + c'glfwSetWindowShouldClose (toC win) (toC b) + +-- | Sets the Title string of the window. +-- See <http://www.glfw.org/docs/3.2/group__window.html#ga5d877f09e968cef7a360b513306f17ff glfwSetWindowTitle> +setWindowTitle :: Window -> String -> IO () +setWindowTitle win title = + withCString title $ c'glfwSetWindowTitle (toC win) + +-- | Gets the window's position (in Screen Coordinates). +-- See <http://www.glfw.org/docs/3.2/group__window.html#ga73cb526c000876fd8ddf571570fdb634 glfwGetWindowPos> +getWindowPos :: Window -> IO (Int, Int) +getWindowPos win = + allocaArray 2 $ \p -> do + let p'x = p + p'y = p `advancePtr` 1 + c'glfwGetWindowPos (toC win) p'x p'y + x <- fromC `fmap` peek p'x + y <- fromC `fmap` peek p'y + return (x, y) + +-- | Sets the window's position (in Screen Coordinates). +-- See <http://www.glfw.org/docs/3.2/group__window.html#ga1abb6d690e8c88e0c8cd1751356dbca8 glfwSetWindowPos> +setWindowPos :: Window -> Int -> Int -> IO () +setWindowPos win x y = + c'glfwSetWindowPos (toC win) (toC x) (toC y) + +-- | Gets the size of the window (in Screen Coordinates). +-- See <http://www.glfw.org/docs/3.2/group__window.html#gaeea7cbc03373a41fb51cfbf9f2a5d4c6 glfwGetWindowSize> +getWindowSize :: Window -> IO (Int, Int) +getWindowSize win = + allocaArray 2 $ \p -> do + let p'w = p + p'h = p `advancePtr` 1 + c'glfwGetWindowSize (toC win) p'w p'h + w <- fromC `fmap` peek p'w + h <- fromC `fmap` peek p'h + return (w, h) + +-- | Gets the size of the frame around the window (in Screen Coordinates). This +-- size includes the title bar, if the window has one. Not to be confused with +-- 'getFramebufferSize', which gets the size of the rendering area. +-- See <http://www.glfw.org/docs/3.2/group__window.html#ga1a9fd382058c53101b21cf211898f1f1 glfwGetWindowFrameSize> +getWindowFrameSize :: Window -> IO (Int, Int, Int, Int) +getWindowFrameSize win = + allocaArray 4 $ \p -> do + let p'l = p + p't = p `advancePtr` 1 + p'r = p `advancePtr` 2 + p'b = p `advancePtr` 3 + c'glfwGetWindowFrameSize (toC win) p'l p't p'r p'b + l <- fromC `fmap` peek p'l + t <- fromC `fmap` peek p't + r <- fromC `fmap` peek p'r + b <- fromC `fmap` peek p'b + return (l, t, r, b) + +-- | Sets the size of the client area for the window (in Screen Coordinates). +-- See <http://www.glfw.org/docs/3.2/group__window.html#ga371911f12c74c504dd8d47d832d095cb glfwSetWindowSize> +setWindowSize :: Window -> Int -> Int -> IO () +setWindowSize win w h = + c'glfwSetWindowSize (toC win) (toC w) (toC h) + +-- | Sets the size limits of the client area of the specified window. If the +-- window is full screen, the size limits only take effect once it is made +-- windowed. If the window is not resizable this function does nothing. Pass +-- 'Nothing' in any argument to disable the limit. +-- See <http://www.glfw.org/docs/3.2/group__window.html#gac314fa6cec7d2d307be9963e2709cc90 glfwSetWindowSizeLimits> +setWindowSizeLimits :: Window + -> Maybe Int + -- ^ The minimum width, in screen coordinates, of the client + -- area. + -> Maybe Int + -- ^ The minimum height, in screen coordinates, of the + -- client area. + -> Maybe Int + -- ^ The maximum width, in screen coordinates, of the client + -- area. + -> Maybe Int + -- ^ The maximum height, in screen coordinates, of the + -- client area. + -> IO () +setWindowSizeLimits win min'w min'h max'w max'h = + c'glfwSetWindowSizeLimits (toC win) (toC min'w) (toC min'h) + (toC max'w) (toC max'h) + +-- | Sets the required aspect ratio of the client area of the specified window. +-- Pass Nothing to disable the limit. +-- See <http://www.glfw.org/docs/3.2/group__window.html#ga72ac8cb1ee2e312a878b55153d81b937 glfwSetWindowAspectRatio> +setWindowAspectRatio :: Window -> Maybe (Int, Int) -> IO () +setWindowAspectRatio win Nothing = + c'glfwSetWindowAspectRatio (toC win) c'GLFW_DONT_CARE c'GLFW_DONT_CARE +setWindowAspectRatio win (Just (w, h)) = + c'glfwSetWindowAspectRatio (toC win) (toC w) (toC h) + +-- | The size of the framebuffer (in Pixels) +-- See <http://www.glfw.org/docs/3.2/group__window.html#ga0e2637a4161afb283f5300c7f94785c9 glfwGetFramebufferSize> +getFramebufferSize :: Window -> IO (Int, Int) +getFramebufferSize win = + allocaArray 2 $ \p -> do + let p'w = p + p'h = p `advancePtr` 1 + c'glfwGetFramebufferSize (toC win) p'w p'h + w <- fromC `fmap` peek p'w + h <- fromC `fmap` peek p'h + return (w, h) + +-- | Sets the icon of the specified window. The system will try to find the +-- image with the dimensions closest to the ones required by the platform. This +-- image is then scaled and used as the icon for that size. Good sizes are +-- 16x16, 32x32, and 48x48. Pass the empty list to reset to the default icon. +-- Has no effect on OS X (See the <https://developer.apple.com/library/content/documentation/CoreFoundation/Conceptual/CFBundles/Introduction/Introduction.html Bundle Programming Guide>) +setWindowIcon :: Window -> [Image] -> IO () +setWindowIcon win [] = c'glfwSetWindowIcon (toC win) 0 nullPtr +setWindowIcon win imgs = + let arrSizeBytes = length imgs * sizeOf (undefined :: C'GLFWimage) + + addNextImage :: [Image] -> Int -> Ptr C'GLFWimage -> IO () + addNextImage [] numImages ptr = + c'glfwSetWindowIcon (toC win) (toC numImages) ptr + + addNextImage (img:rest) idx ptr = + withGLFWImage img $ \p'img -> do + c'img <- peek p'img + pokeElemOff ptr idx c'img + addNextImage rest (idx + 1) ptr + in allocaBytes arrSizeBytes $ addNextImage imgs 0 + +-- | Iconifies (minimizes) the window. +-- See <http://www.glfw.org/docs/3.2/group__window.html#ga1bb559c0ebaad63c5c05ad2a066779c4 glfwIconifyWindow> +iconifyWindow :: Window -> IO () +iconifyWindow = + c'glfwIconifyWindow . toC + +-- | Restores the window from an iconified/minimized state. +-- See <http://www.glfw.org/docs/3.2/group__window.html#ga52527a5904b47d802b6b4bb519cdebc7 glfwRestoreWindow> +restoreWindow :: Window -> IO () +restoreWindow = + c'glfwRestoreWindow . toC + +-- | Brings the specified window to front and sets input focus. The window +-- should already be visible and not iconified. +-- See <http://www.glfw.org/docs/latest/group__window.html#ga873780357abd3f3a081d71a40aae45a1 glfwFocusWindow> +focusWindow :: Window -> IO () +focusWindow = c'glfwFocusWindow . toC + +-- | Maximizes the specified window if it was not already maximized. +-- See <http://www.glfw.org/docs/3.2/group__window.html#ga3f541387449d911274324ae7f17ec56b glfwMaximizeWindow> +maximizeWindow :: Window -> IO () +maximizeWindow = c'glfwMaximizeWindow . toC + +-- | Shows the window. +-- See <http://www.glfw.org/docs/3.2/group__window.html#ga61be47917b72536a148300f46494fc66 glfwShowWindow> +showWindow :: Window -> IO () +showWindow = + c'glfwShowWindow . toC + +-- | Hides the window. +-- See <http://www.glfw.org/docs/3.2/group__window.html#ga49401f82a1ba5f15db5590728314d47c glfwHideWindow> +hideWindow :: Window -> IO () +hideWindow = + c'glfwHideWindow . toC + +-- | Gets the monitor that this window is running on, provided the window is +-- fullscreen. +-- See <http://www.glfw.org/docs/3.2/group__window.html#gaeac25e64789974ccbe0811766bd91a16 glfwGetWindowMonitor> +getWindowMonitor :: Window -> IO (Maybe Monitor) +getWindowMonitor win = do + p'mon <- c'glfwGetWindowMonitor (toC win) + return $ if p'mon == nullPtr + then Nothing + else Just $ fromC p'mon + +-- | Sets the position of the cursor within the window. +-- See <http://www.glfw.org/docs/3.2/group__input.html#ga04b03af936d906ca123c8f4ee08b39e7 glfwSetCursorPos> +setCursorPos :: Window -> Double -> Double -> IO () +setCursorPos win x y = + c'glfwSetCursorPos (toC win) (toC x) (toC y) + +-- | Makes a window fullscreen on the given monitor. The number of red, green, +-- and blue bits is ignored. Note, this shouldn't be used to update the +-- resolution of a fullscreen window. Use 'setWindowSize' instead. +-- See <http://www.glfw.org/docs/3.2/group__window.html#ga81c76c418af80a1cce7055bccb0ae0a7 glfwSetWindowMonitor> +setFullscreen :: Window -> Monitor -> VideoMode -> IO () +setFullscreen win mon (VideoMode width height _ _ _ refresh) = + c'glfwSetWindowMonitor (toC win) (toC mon) 0 0 (toC width) (toC height) (toC refresh) + +-- | Updates a window to be windowed instead of fullscreen. Note, this shouldn't +-- be used to update the position or size of a window. Use 'setWindowPos' and +-- 'setWindowSize' instead. +-- See <http://www.glfw.org/docs/3.2/group__window.html#ga81c76c418af80a1cce7055bccb0ae0a7 glfwSetWindowMonitor> +setWindowed :: Window + -> Int -- ^ The width of the client area + -> Int -- ^ The height of the client area + -> Int -- ^ The x position of the window + -> Int -- ^ The y position of the window + -> IO () +setWindowed win width height x y = + c'glfwSetWindowMonitor (toC win) nullPtr (toC x) (toC y) (toC width) (toC height) 0 + +-- start of functions related to c'glfwGetWindowAttrib + +-- | If the window has focus or not. +-- See <http://www.glfw.org/docs/3.2/group__window.html#gacccb29947ea4b16860ebef42c2cb9337 glfwGetWindowAttrib> +getWindowFocused :: Window -> IO Bool +getWindowFocused win = + fromC `fmap` c'glfwGetWindowAttrib (toC win) c'GLFW_FOCUSED + +-- | If the window is maximized or not. +-- See <http://www.glfw.org/docs/3.2/group__window.html#gacccb29947ea4b16860ebef42c2cb9337 glfwGetWindowAttrib> +getWindowMaximized :: Window -> IO Bool +getWindowMaximized win = + fromC `fmap` c'glfwGetWindowAttrib (toC win) c'GLFW_MAXIMIZED + +-- | If the window has been set to be 'always on top' or not. +-- See <http://www.glfw.org/docs/latest/group__window.html#gacccb29947ea4b16860ebef42c2cb9337 glfwGetWindowAttrib> +getWindowFloating :: Window -> IO Bool +getWindowFloating win = + fromC `fmap` c'glfwGetWindowAttrib (toC win) c'GLFW_FLOATING + +-- | If the window is iconified (minimized) or not. +-- See <http://www.glfw.org/docs/3.2/group__window.html#gacccb29947ea4b16860ebef42c2cb9337 glfwGetWindowAttrib> +getWindowIconified :: Window -> IO Bool +getWindowIconified win = + fromC `fmap` c'glfwGetWindowAttrib (toC win) c'GLFW_ICONIFIED + +-- | If the window is resizable or not. +-- See <http://www.glfw.org/docs/3.2/group__window.html#gacccb29947ea4b16860ebef42c2cb9337 glfwGetWindowAttrib> +getWindowResizable :: Window -> IO Bool +getWindowResizable win = + fromC `fmap` c'glfwGetWindowAttrib (toC win) c'GLFW_RESIZABLE + +-- | If the window is decorated or not. +-- See <http://www.glfw.org/docs/3.2/group__window.html#gacccb29947ea4b16860ebef42c2cb9337 glfwGetWindowAttrib> +getWindowDecorated :: Window -> IO Bool +getWindowDecorated win = + fromC `fmap` c'glfwGetWindowAttrib (toC win) c'GLFW_DECORATED + +-- | If the window is visible or not. +-- See <http://www.glfw.org/docs/3.2/group__window.html#gacccb29947ea4b16860ebef42c2cb9337 glfwGetWindowAttrib> +getWindowVisible :: Window -> IO Bool +getWindowVisible win = + fromC `fmap` c'glfwGetWindowAttrib (toC win) c'GLFW_VISIBLE + +-- | The client api for this window. +-- See <http://www.glfw.org/docs/3.2/group__window.html#gacccb29947ea4b16860ebef42c2cb9337 glfwGetWindowAttrib> +getWindowClientAPI :: Window -> IO ClientAPI +getWindowClientAPI win = + fromC `fmap` c'glfwGetWindowAttrib (toC win) c'GLFW_CLIENT_API + +-- | Returns the context creation API used to create the specified window. +-- See <http://www.glfw.org/docs/3.2/group__window.html#gacccb29947ea4b16860ebef42c2cb9337 glfwGetWindowAttrib> +getWindowContextCreationAPI :: Window -> IO ContextCreationAPI +getWindowContextCreationAPI win = + fromC `fmap` c'glfwGetWindowAttrib (toC win) c'GLFW_CONTEXT_CREATION_API + +-- | The context's "major" version, x.0.0 +-- See <http://www.glfw.org/docs/3.2/group__window.html#gacccb29947ea4b16860ebef42c2cb9337 glfwGetWindowAttrib> +getWindowContextVersionMajor :: Window -> IO Int +getWindowContextVersionMajor win = + fromC `fmap` c'glfwGetWindowAttrib (toC win) c'GLFW_CONTEXT_VERSION_MAJOR + +-- | The context's "minor" version, 0.y.0 +-- See <http://www.glfw.org/docs/3.2/group__window.html#gacccb29947ea4b16860ebef42c2cb9337 glfwGetWindowAttrib> +getWindowContextVersionMinor :: Window -> IO Int +getWindowContextVersionMinor win = + fromC `fmap` c'glfwGetWindowAttrib (toC win) c'GLFW_CONTEXT_VERSION_MINOR + +-- | The context's "revision" version, 0.0.z +-- See <http://www.glfw.org/docs/3.2/group__window.html#gacccb29947ea4b16860ebef42c2cb9337 glfwGetWindowAttrib> +getWindowContextVersionRevision :: Window -> IO Int +getWindowContextVersionRevision win = + fromC `fmap` c'glfwGetWindowAttrib (toC win) c'GLFW_CONTEXT_REVISION + +-- | The context robustness of this window. +-- See <http://www.glfw.org/docs/3.2/group__window.html#gacccb29947ea4b16860ebef42c2cb9337 glfwGetWindowAttrib> +getWindowContextRobustness :: Window -> IO ContextRobustness +getWindowContextRobustness win = + fromC `fmap` c'glfwGetWindowAttrib (toC win) c'GLFW_CONTEXT_ROBUSTNESS + +-- | Returns the context release behavior. +-- See <http://www.glfw.org/docs/3.2/group__window.html#gacccb29947ea4b16860ebef42c2cb9337 glfwGetWindowAttrib> +getWindowContextReleaseBehavior :: Window -> IO ContextReleaseBehavior +getWindowContextReleaseBehavior win = + fromC `fmap` c'glfwGetWindowAttrib (toC win) c'GLFW_CONTEXT_RELEASE_BEHAVIOR + +-- | Returns true if the window is set to NO_ERROR (see the +-- <https://www.khronos.org/registry/OpenGL/extensions/KHR/KHR_no_error.txt KHR_no_error> +-- extension. +getWindowContextNoError :: Window -> IO Bool +getWindowContextNoError win = + fromC `fmap` c'glfwGetWindowAttrib (toC win) c'GLFW_CONTEXT_NO_ERROR + +-- | If this window is set for opengl to be forward compatible. +-- See <http://www.glfw.org/docs/3.2/group__window.html#gacccb29947ea4b16860ebef42c2cb9337 glfwGetWindowAttrib> +getWindowOpenGLForwardCompat :: Window -> IO Bool +getWindowOpenGLForwardCompat win = + fromC `fmap` c'glfwGetWindowAttrib (toC win) c'GLFW_OPENGL_FORWARD_COMPAT + +-- | If the window has an opengl debug context +-- See <http://www.glfw.org/docs/3.2/group__window.html#gacccb29947ea4b16860ebef42c2cb9337 glfwGetWindowAttrib> +getWindowOpenGLDebugContext :: Window -> IO Bool +getWindowOpenGLDebugContext win = + fromC `fmap` c'glfwGetWindowAttrib (toC win) c'GLFW_OPENGL_DEBUG_CONTEXT + +-- | Obtains the current opengl profile. +-- See <http://www.glfw.org/docs/3.2/group__window.html#gacccb29947ea4b16860ebef42c2cb9337 glfwGetWindowAttrib> +getWindowOpenGLProfile :: Window -> IO OpenGLProfile +getWindowOpenGLProfile win = + fromC `fmap` c'glfwGetWindowAttrib (toC win) c'GLFW_OPENGL_PROFILE + +-- end of functions related to c'glfwGetWindowAttrib + +-- | Sets the callback to use when the window position changes. +-- See <http://www.glfw.org/docs/3.2/group__window.html#ga2837d4d240659feb4268fcb6530a6ba1 glfwSetWindowPosCallback> +setWindowPosCallback :: Window -> Maybe WindowPosCallback -> IO () +setWindowPosCallback win = setWindowCallback + mk'GLFWwindowposfun + (\cb a0 a1 a2 -> + schedule $ cb (fromC a0) (fromC a1) (fromC a2)) + (c'glfwSetWindowPosCallback (toC win)) + storedWindowPosFun + win + +-- | Sets the callback to use when the window's size changes. +-- See <http://www.glfw.org/docs/3.2/group__window.html#gaa40cd24840daa8c62f36cafc847c72b6 glfwSetWindowSizeCallback> +setWindowSizeCallback :: Window -> Maybe WindowSizeCallback -> IO () +setWindowSizeCallback win = setWindowCallback + mk'GLFWwindowsizefun + (\cb a0 a1 a2 -> + schedule $ cb (fromC a0) (fromC a1) (fromC a2)) + (c'glfwSetWindowSizeCallback (toC win)) + storedWindowSizeFun + win + +-- | Sets the callback to use when the user attempts to close the window. +-- See <http://www.glfw.org/docs/3.2/group__window.html#gaade9264e79fae52bdb78e2df11ee8d6a glfwSetWindowCloseCallback> +setWindowCloseCallback :: Window -> Maybe WindowCloseCallback -> IO () +setWindowCloseCallback win = setWindowCallback + mk'GLFWwindowclosefun + (. fromC) + (c'glfwSetWindowCloseCallback (toC win)) + storedWindowCloseFun + win + +-- | Sets the callback to use when the window's data is partly dead and it should refresh. +-- See <http://www.glfw.org/docs/3.2/group__window.html#ga4569b76e8ac87c55b53199e6becd97eb glfwSetWindowRefreshCallback> +setWindowRefreshCallback :: Window -> Maybe WindowRefreshCallback -> IO () +setWindowRefreshCallback win = setWindowCallback + mk'GLFWwindowrefreshfun + (. fromC) + (c'glfwSetWindowRefreshCallback (toC win)) + storedWindowRefreshFun + win + +-- | Sets the callback to use when the window gains or loses focus. +-- See <http://www.glfw.org/docs/3.2/group__window.html#ga25d1c584edb375d7711c5c3548ba711f glfwSetWindowFocusCallback> +setWindowFocusCallback :: Window -> Maybe WindowFocusCallback -> IO () +setWindowFocusCallback win = setWindowCallback + mk'GLFWwindowfocusfun + (\cb a0 a1 -> schedule $ cb (fromC a0) (fromC a1)) + (c'glfwSetWindowFocusCallback (toC win)) + storedWindowFocusFun + win + +-- | Sets the callback to use when the window is iconified or not (aka, minimized or not). +-- See <http://www.glfw.org/docs/3.2/group__window.html#gab1ea7263081c0e073b8d5b91d6ffd367 glfwSetWindowIconifyCallback> +setWindowIconifyCallback :: Window -> Maybe WindowIconifyCallback -> IO () +setWindowIconifyCallback win = setWindowCallback + mk'GLFWwindowiconifyfun + (\cb a0 a1 -> schedule $ cb (fromC a0) (fromC a1)) + (c'glfwSetWindowIconifyCallback (toC win)) + storedWindowIconifyFun + win + +-- | Sets the callback to use when the framebuffer's size changes. +-- See <http://www.glfw.org/docs/3.2/group__window.html#ga3203461a5303bf289f2e05f854b2f7cf glfwSetFramebufferSizeCallback> +setFramebufferSizeCallback :: Window -> Maybe FramebufferSizeCallback -> IO () +setFramebufferSizeCallback win = setWindowCallback + mk'GLFWframebuffersizefun + (\cb a0 a1 a2 -> schedule $ cb (fromC a0) (fromC a1) (fromC a2)) + (c'glfwSetFramebufferSizeCallback (toC win)) + storedFramebufferSizeFun + win + +-- | Checks for any pending events, processes them, and then immediately returns. +-- This is most useful for continual rendering, such as games. +-- See the <http://www.glfw.org/docs/3.2/input.html#events Event Processing Guide>. This +-- function is not <https://www.glfw.org/docs/latest/intro.html#reentrancy reentrant>. +pollEvents :: IO () +pollEvents = c'glfwPollEvents >> executeScheduled + +-- | Waits until at least one event is in the queue then processes the queue and returns. +-- Requires at least one window to be active for it to sleep. This saves a lot of CPU, and +-- is better if you're doing only periodic rendering, such as with an editor program. +-- See the <http://www.glfw.org/docs/3.2/input.html#events Event Processing Guide>. This +-- function is not <https://www.glfw.org/docs/latest/intro.html#reentrancy reentrant>. +waitEvents :: IO () +waitEvents = c'glfwWaitEvents >> executeScheduled + +-- | Same as 'waitEvents', with a timeout after which the function returns. +-- See the <http://www.glfw.org/docs/3.2/input.html#events Event Processing Guide>. This +-- function is not <https://www.glfw.org/docs/latest/intro.html#reentrancy reentrant>. +waitEventsTimeout :: Double -> IO () +waitEventsTimeout seconds = + c'glfwWaitEventsTimeout (toC seconds) >> executeScheduled + +-- | Creates an empty event within the event queue. Can be called from any +-- thread, so you can use this to wake up the main thread that's using +-- 'waitEvents' from a secondary thread. +-- See the <http://www.glfw.org/docs/3.2/input.html#events Event Processing Guide> +postEmptyEvent :: IO () +postEmptyEvent = c'glfwPostEmptyEvent + +-------------------------------------------------------------------------------- +-- Input handling + +-- start of glfw{GS}etInputMode-related functions + +-- | Gets the current cursor input mode. +-- See <http://www.glfw.org/docs/3.2/group__input.html#gaa92336e173da9c8834558b54ee80563b glfwSetInputMode> +getCursorInputMode :: Window -> IO CursorInputMode +getCursorInputMode win = + fromC `fmap` c'glfwGetInputMode (toC win) c'GLFW_CURSOR + +-- | Set the cursor input mode. +-- See <http://www.glfw.org/docs/3.2/group__input.html#gaa92336e173da9c8834558b54ee80563b glfwSetInputMode> +setCursorInputMode :: Window -> CursorInputMode -> IO () +setCursorInputMode win c = + c'glfwSetInputMode (toC win) c'GLFW_CURSOR (toC c) + +-- | Gets the current sticky keys mode. +-- See <http://www.glfw.org/docs/3.2/group__input.html#gaa92336e173da9c8834558b54ee80563b glfwSetInputMode> +getStickyKeysInputMode :: Window -> IO StickyKeysInputMode +getStickyKeysInputMode win = + fromC `fmap` c'glfwGetInputMode (toC win) c'GLFW_STICKY_KEYS + +-- | Sets if sticky keys should be used or not. +-- See <http://www.glfw.org/docs/3.2/group__input.html#gaa92336e173da9c8834558b54ee80563b glfwSetInputMode> +setStickyKeysInputMode :: Window -> StickyKeysInputMode -> IO () +setStickyKeysInputMode win sk = + c'glfwSetInputMode (toC win) c'GLFW_STICKY_KEYS (toC sk) + +-- | Gets if sticky mouse buttons are on or not. +-- See <http://www.glfw.org/docs/3.2/group__input.html#gaa92336e173da9c8834558b54ee80563b glfwSetInputMode> +getStickyMouseButtonsInputMode :: Window -> IO StickyMouseButtonsInputMode +getStickyMouseButtonsInputMode win = + fromC `fmap` c'glfwGetInputMode (toC win) c'GLFW_STICKY_MOUSE_BUTTONS + +-- | Sets if sticky mouse buttons should be used or not. +-- See <http://www.glfw.org/docs/3.2/group__input.html#gaa92336e173da9c8834558b54ee80563b glfwSetInputMode> +setStickyMouseButtonsInputMode :: Window -> StickyMouseButtonsInputMode -> IO () +setStickyMouseButtonsInputMode win smb = + c'glfwSetInputMode (toC win) c'GLFW_STICKY_MOUSE_BUTTONS (toC smb) + +-- end of glfw{GS}etInputMode-related functions + +-- | Gets the state of the specified key. If Stickey Keys isn't enabled then it's possible for +-- keyboard polling to miss individual key presses. Use the callback to avoid this. +-- See <http://www.glfw.org/docs/3.2/group__input.html#gadd341da06bc8d418b4dc3a3518af9ad2 glfwGetKey> +getKey :: Window -> Key -> IO KeyState +getKey win k = + fromC `fmap` c'glfwGetKey (toC win) (toC k) + +-- | Returns the localized name of the specified printable key. This is intended +-- for displaying key bindings to the user. The scancode is used if the provided +-- 'Key' isn't printable. If the scancode maps to a non-printable key as well, +-- then 'Nothing' is returned. +-- See <http://www.glfw.org/docs/3.2/group__input.html#ga237a182e5ec0b21ce64543f3b5e7e2be glfwGetKeyName> +getKeyName :: Key -> Int -> IO (Maybe String) +getKeyName k scancode = do + cstr <- c'glfwGetKeyName (toC k) (toC scancode) + if cstr == nullPtr + then return Nothing + else Just `fmap` peekCString cstr + +-- | Gets the state of a single specified mouse button. If sticky mouse button +-- mode isn't enabled it's possible for mouse polling to miss individual mouse events. Use +-- the call back to avoid this. +-- See <http://www.glfw.org/docs/3.2/group__input.html#gac1473feacb5996c01a7a5a33b5066704 glfwGetMouseButton> +getMouseButton :: Window -> MouseButton -> IO MouseButtonState +getMouseButton win b = + fromC `fmap` c'glfwGetMouseButton (toC win) (toC b) + +-- | Returns the position, in screen coodinates, relative to the upper left. +-- If the 'CursorInputMode' is "disabled", then results are unbounded by the window size. +-- See <http://www.glfw.org/docs/3.2/group__input.html#ga01d37b6c40133676b9cea60ca1d7c0cc glfwGetCursorPos> +getCursorPos :: Window -> IO (Double, Double) +getCursorPos win = + allocaArray 2 $ \p -> do + let p'x = p + p'y = p `advancePtr` 1 + c'glfwGetCursorPos (toC win) p'x p'y + x <- fromC `fmap` peek p'x + y <- fromC `fmap` peek p'y + return (x, y) + +-- | Assigns the given callback to use for all keyboard presses and repeats. +-- See <http://www.glfw.org/docs/3.2/group__input.html#ga7e496507126f35ea72f01b2e6ef6d155 glfwSetKeyCallback> +setKeyCallback :: Window -> Maybe KeyCallback -> IO () +setKeyCallback win = setWindowCallback + mk'GLFWkeyfun + (\cb a0 a1 a2 a3 a4 -> + schedule $ cb (fromC a0) (fromC a1) (fromC a2) (fromC a3) (fromC a4)) + (c'glfwSetKeyCallback (toC win)) + storedKeyFun + win + +-- | Sets the callback to use when the user types a character +-- See <http://www.glfw.org/docs/3.2/group__input.html#ga556239421c6a5a243c66fca28da9f742 glfwSetCharCallback> +setCharCallback :: Window -> Maybe CharCallback -> IO () +setCharCallback win = setWindowCallback + mk'GLFWcharfun + (\cb a0 a1 -> schedule $ cb (fromC a0) (fromC a1)) + (c'glfwSetCharCallback (toC win)) + storedCharFun + win + +-- | Sets the callback to use with Unicode characters regardless of what +-- modifier keys are used. +-- See <http://www.glfw.org/docs/3.2/group__input.html#ga3f55ef5dc03a374e567f068b13c94afc glfwSetCharModsCallback> +setCharModsCallback :: Window -> Maybe CharModsCallback -> IO () +setCharModsCallback win = setWindowCallback + mk'GLFWcharmodsfun + (\cb a0 a1 a2 -> schedule $ cb (fromC a0) (fromC a1) (fromC a2)) + (c'glfwSetCharModsCallback (toC win)) + storedCharModsFun + win + +-- | Assigns the callback to run whenver a mouse button is clicked. +-- See <http://www.glfw.org/docs/3.2/group__input.html#gaef49b72d84d615bca0a6ed65485e035d glfwSetMouseButtonCallback> +setMouseButtonCallback :: Window -> Maybe MouseButtonCallback -> IO () +setMouseButtonCallback win = setWindowCallback + mk'GLFWmousebuttonfun + (\cb a0 a1 a2 a3 -> schedule $ cb (fromC a0) (fromC a1) (fromC a2) (fromC a3)) + (c'glfwSetMouseButtonCallback (toC win)) + storedMouseButtonFun + win + +-- | Assigns the callback to run whenver the cursor position changes. +-- See <http://www.glfw.org/docs/3.2/group__input.html#ga7dad39486f2c7591af7fb25134a2501d glfwSetCursorPosCallback> +setCursorPosCallback :: Window -> Maybe CursorPosCallback -> IO () +setCursorPosCallback win = setWindowCallback + mk'GLFWcursorposfun + (\cb a0 a1 a2 -> schedule $ cb (fromC a0) (fromC a1) (fromC a2)) + (c'glfwSetCursorPosCallback (toC win)) + storedCursorPosFun + win + +-- | Sets the callback for when the cursor enters or leaves the client area. +-- See <http://www.glfw.org/docs/3.2/input.html#cursor_enter Cursor Enter/Leave Events> +setCursorEnterCallback :: Window -> Maybe CursorEnterCallback -> IO () +setCursorEnterCallback win = setWindowCallback + mk'GLFWcursorenterfun + (\cb a0 a1 -> schedule $ cb (fromC a0) (fromC a1)) + (c'glfwSetCursorEnterCallback (toC win)) + storedCursorEnterFun + win + +-- | Sets the callback to run when the user scrolls with the mouse wheel or a touch gesture. +-- See <http://www.glfw.org/docs/3.2/input.html#scrolling Scroll Input> +setScrollCallback :: Window -> Maybe ScrollCallback -> IO () +setScrollCallback win = setWindowCallback + mk'GLFWscrollfun + (\cb a0 a1 a2 -> schedule $ cb (fromC a0) (fromC a1) (fromC a2)) + (c'glfwSetScrollCallback (toC win)) + storedScrollFun + win + +-- | Tests if the joystick is present at all +-- See <http://www.glfw.org/docs/3.2/group__input.html#gaffcbd9ac8ee737fcdd25475123a3c790 glfwJoystickPresent> +joystickPresent :: Joystick -> IO Bool +joystickPresent js = + fromC `fmap` c'glfwJoystickPresent (toC js) + +-- | Returns the values of all axes of the specified joystick, normalized to between -1.0 and 1.0 +-- See <http://www.glfw.org/docs/3.2/group__input.html#ga6271d46a5901ec2c99601ccf4dd14731 glfwGetJoystickAxes> +getJoystickAxes :: Joystick -> IO (Maybe [Double]) +getJoystickAxes js = + alloca $ \p'n -> do + p'axes <- c'glfwGetJoystickAxes (toC js) p'n + n <- fromC `fmap` peek p'n + if p'axes == nullPtr || n <= 0 + then return Nothing + else (Just . map fromC) `fmap` peekArray n p'axes + +-- | Returns a list of all joystick button states for the specified joystick. +-- See <http://www.glfw.org/docs/3.2/group__input.html#gace54cd930dcd502e118fe4021384ce1b glfwGetJoystickButtons> +getJoystickButtons :: Joystick -> IO (Maybe [JoystickButtonState]) +getJoystickButtons js = + alloca $ \p'n -> do + p'buttons <- c'glfwGetJoystickButtons (toC js) p'n + n <- fromC `fmap` peek p'n + if p'buttons == nullPtr || n <= 0 + then return Nothing + else (Just . map fromC) `fmap` peekArray n p'buttons + +-- | A human-readable name for a Joystick. Not guranteed to be unique. +-- See <http://www.glfw.org/docs/3.2/group__input.html#gac8d7f6107e05cfd106cfba973ab51e19 glfwGetJoystickName> +getJoystickName :: Joystick -> IO (Maybe String) +getJoystickName js = do + p'name <- c'glfwGetJoystickName (toC js) + if p'name == nullPtr + then return Nothing + else Just `fmap` peekCString p'name + +-- | Sets a callback for when a joystick is connected or disconnected. +-- See <http://www.glfw.org/docs/3.2/group__input.html#gab1dc8379f1b82bb660a6b9c9fa06ca07 glfwSetJoystickCallback> +setJoystickCallback :: Maybe JoystickCallback -> IO () +setJoystickCallback = setCallback + mk'GLFWjoystickfun + (\cb a0 a1 -> schedule $ cb (fromC a0) (fromC a1)) + c'glfwSetJoystickCallback + storedJoystickFun + +-------------------------------------------------------------------------------- +-- Time + +-- | Returns the time (in seconds) of the GLFW timer. +-- This is the amount of time since GLFW was initialized, unless 'setTime' was used. +-- The exact resolution is system dependent. +-- See <http://www.glfw.org/docs/3.2/group__input.html#gaa6cf4e7a77158a3b8fd00328b1720a4a glfwGetTime> +getTime :: IO (Maybe Double) +getTime = do + t <- fromC `fmap` c'glfwGetTime + return $ if t == 0 + then Nothing + else Just t + +-- | Sets the GLFW timer to the specified value, which is measured in seconds, and must be positive. +-- The value must also be less than ~584 years in seconds (18446744073.0). +-- After this the timer begins to count upward at the normal rate. +-- See <http://www.glfw.org/docs/3.2/group__input.html#gaf59589ef6e8b8c8b5ad184b25afd4dc0 glfwSetTime> +setTime :: Double -> IO () +setTime = c'glfwSetTime . toC + +-- | Returns the current value of the raw timer, measured in 1 / frequency +-- seconds. The frequency can be queried using getTimerFrequency. +-- See <http://www.glfw.org/docs/3.2/input_guide.html#time Timer input> +getTimerValue :: IO Word64 +getTimerValue = c'glfwGetTimerValue + +-- | Returns the frequency, in Hz, of the raw timer. +-- See <http://www.glfw.org/docs/3.2/input_guide.html#time Timer input> +getTimerFrequency :: IO Word64 +getTimerFrequency = c'glfwGetTimerFrequency + +-------------------------------------------------------------------------------- +-- Context + +-- | Makes the context of the specified window the current one for the calling thread. +-- A context can only be made current on a single thread at a time, +-- and each thread can have only a single current context at a time. +-- See <http://www.glfw.org/docs/3.2/group__context.html#ga1c04dc242268f827290fe40aa1c91157 glfwMakeContextCurrent> +makeContextCurrent :: Maybe Window -> IO () +makeContextCurrent = + c'glfwMakeContextCurrent . maybe nullPtr toC + +-- | Obtains which window owns the current context of the calling thread. +-- See <http://www.glfw.org/docs/3.2/group__context.html#gac84759b1f6c2d271a4fea8ae89ec980d glfwGetCurrentContext> +getCurrentContext :: IO (Maybe Window) +getCurrentContext = do + p'win <- c'glfwGetCurrentContext + return $ if p'win == nullPtr + then Nothing + else Just $ fromC p'win + +-- | Swaps the front and back buffers of the window. +-- See <http://www.glfw.org/docs/3.2/group__window.html#ga15a5a1ee5b3c2ca6b15ca209a12efd14 glfwSwapBuffers> +swapBuffers :: Window -> IO () +swapBuffers = + c'glfwSwapBuffers . toC + +-- | Sets the number of screen updates that the GPU should wait after 'swapBuffers' before actually swapping the buffers. +-- Generates 'Error'NoCurrentContext' if no context is current. +-- See <http://www.glfw.org/docs/3.2/group__context.html#ga6d4e0cdf151b5e579bd67f13202994ed glfwSwapInterval> +swapInterval :: Int -> IO () +swapInterval = + c'glfwSwapInterval . toC + +-- | If the current OpenGL or OpenGL ES context supports the extension specified. +-- Generates 'Error'NoCurrentContext' if no context is current. +-- See <http://www.glfw.org/docs/3.2/group__context.html#ga87425065c011cef1ebd6aac75e059dfa glfwExtensionSupported> +extensionSupported :: String -> IO Bool +extensionSupported ext = + withCString ext $ \p'ext -> + fromC `fmap` c'glfwExtensionSupported p'ext + +-------------------------------------------------------------------------------- +-- Clipboard +-- http://www.glfw.org/docs/3.2/input.html#clipboard + +-- | The window that will own the clipboard contents, and also the clipboard string. +-- See <http://www.glfw.org/docs/3.2/group__input.html#gaba1f022c5eb07dfac421df34cdcd31dd glfwSetClipboardString> +setClipboardString :: Window -> String -> IO () +setClipboardString win s = + withCString s (c'glfwSetClipboardString (toC win)) + +-- | Obtains the contents of the system keyboard, if possible. +-- Generates 'Error'FormatUnavailable' if the system clipboard is empty or if it's not a UTF-8 string. +-- See <http://www.glfw.org/docs/3.2/group__input.html#ga5aba1d704d9ab539282b1fbe9f18bb94 glfwGetClipboardString> +getClipboardString :: Window -> IO (Maybe String) +getClipboardString win = do + p's <- c'glfwGetClipboardString (toC win) + if p's == nullPtr + then return Nothing + else Just `fmap` peekCString p's + +-------------------------------------------------------------------------------- +-- 3.1 additions (http://www.glfw.org/docs/3.1/news.html#news_31) +-------------------------------------------------------------------------------- + +-- Cursor Objects +-- http://www.glfw.org/docs/3.2/input.html#cursor_object + +-- | Creates a new cursor. +createCursor :: Image -- ^ The desired cursor image. + -> Int -- ^ The desired x-coordinate, in pixels, of the cursor + -- hotspot. + -> Int -- ^ The desired y-coordinate, in pixels, of the cursor + -- hotspot. + -> IO Cursor +createCursor img x y = + withGLFWImage img $ \p'img -> + Cursor `fmap` c'glfwCreateCursor p'img (toC x) (toC y) + +-- | Creates a cursor with a standard shape that can be set for a window with +-- setCursor. +createStandardCursor :: StandardCursorShape -> IO Cursor +createStandardCursor = (fmap Cursor) . c'glfwCreateStandardCursor . toC + +-- | Sets the cursor image to be used when the cursor is over the client area +-- of the specified window. The set cursor will only be visible when the cursor +-- mode of the window is GLFW_CURSOR_NORMAL. + +-- On some platforms, the set cursor may not be visible unless the window also +-- has input focus. +setCursor :: Window -> Cursor -> IO () +setCursor (Window wptr) (Cursor cptr) = c'glfwSetCursor wptr cptr + +-- | Destroys a cursor previously created with `createCursor`. Any remaining +-- cursors will be destroyed by `terminate`. This function is not +-- <https://www.glfw.org/docs/latest/intro.html#reentrancy reentrant>. +destroyCursor :: Cursor -> IO () +destroyCursor = c'glfwDestroyCursor . unCursor + +-- | A callback that allows for drag and drop support. +type DropCallback = Window -- ^ The window that received the event. + -> [String] -- ^ The file and/or directory path names + -> IO () + +-- | Sets the file drop callback of the specified window, which is called when +-- one or more dragged files are dropped on the window. +setDropCallback :: Window -> Maybe DropCallback -> IO () +setDropCallback win = setWindowCallback + mk'GLFWdropfun + (\cb w c fs -> do + let count = fromC c + fps <- flip mapM [0..count-1] $ \i -> do + let p = advancePtr fs i + p' <- peek p + peekCString p' + schedule $ cb (fromC w) fps) + (c'glfwSetDropCallback (toC win)) + storedDropFun + win + +-------------------------------------------------------------------------------- +-- Vulkan-related functions +-------------------------------------------------------------------------------- + +-- | This function returns whether the Vulkan loader has been found. +-- This check is performed by `init`. +vulkanSupported :: IO Bool +vulkanSupported = (c'GLFW_TRUE ==) <$> c'glfwVulkanSupported + +-- | Get required vulkan extensions; +-- Pointer memory is managed by GLFW, destroyed by `terminate` call. +-- +-- The returned extension names are kept in `CString` type, because +-- they are expected to be consumed by vulkan device initialization functions. +getRequiredInstanceExtensions :: IO [CString] +getRequiredInstanceExtensions = alloca $ \countPtr -> do + extsPtrPtr <- c'glfwGetRequiredInstanceExtensions countPtr + count <- fromIntegral <$> peek countPtr + peekArray count extsPtrPtr + +-- | Returns the address of the specified Vulkan instance function. +getInstanceProcAddress :: Ptr vkInstance + -- ^ VkInstance. + -- Note, the returned function must be used + -- with the same instance or its child. + -> String + -- ^ Function name + -> IO (FunPtr vkProc) +getInstanceProcAddress i procName + = withCString procName (c'glfwGetInstanceProcAddress i) + +-- | Returns whether the specified queue family can present images. +getPhysicalDevicePresentationSupport :: + Ptr vkInstance + -- ^ VkInstance + -> Ptr vkPhysicalDevice + -- ^ VkPhysicalDevice + -> Word32 + -- ^ Index of a queue family to query. + -- This is an index in the array returned by + -- @vkGetPhysicalDeviceQueueFamilyProperties@ function. + -> IO Bool +getPhysicalDevicePresentationSupport inst dev i + = (c'GLFW_TRUE ==) <$> c'glfwGetPhysicalDevicePresentationSupport inst dev i + +-- | Creates a Vulkan surface for the specified window +createWindowSurface :: Enum vkResult + => Ptr vkInstance + -- ^ VkInstance + -> Window + -- ^ GLFWwindow *window + -> Ptr vkAllocationCallbacks + -- ^ const VkAllocationCallbacks *allocator + -> Ptr vkSurfaceKHR + -- ^ VkSurfaceKHR *surface + -> IO vkResult +createWindowSurface i win acs s + = toEnum . fromIntegral + <$> c'glfwCreateWindowSurface i (toC win) acs s + +-------------------------------------------------------------------------------- +-- Native APIs +-------------------------------------------------------------------------------- + +-- $nativeaccess +-- The low level native-access bindings are exposed here via bindings-GLFW. +-- These must be enabled with the 'ExposeNative' flag passed to bindings-GLFW. +-- The return values of these functions are used as a best-guess and are not +-- coupled with any other implementation. They should be used with caution +-- and at your own risk. + +-- | See <http://www.glfw.org/docs/3.2/group__native.html#gac84f63a3f9db145b9435e5e0dbc4183d glfwGetWin32Adapter> +getWin32Adapter :: Window -> IO CString +getWin32Adapter = c'glfwGetWin32Adapter . toC + +-- | See <http://www.glfw.org/docs/3.2/group__native.html#gac408b09a330749402d5d1fa1f5894dd9 glfwGetWin32Monitor> +getWin32Monitor :: Window -> IO CString +getWin32Monitor = c'glfwGetWin32Monitor . toC + +-- | See <http://www.glfw.org/docs/3.2/group__native.html#gafe5079aa79038b0079fc09d5f0a8e667 glfwGetWin32Window> +getWin32Window :: Window -> IO (Ptr ()) +getWin32Window = c'glfwGetWin32Window . toC + +-- | See <http://www.glfw.org/docs/3.2/group__native.html#gadc4010d91d9cc1134d040eeb1202a143 glfwGetWGLContext> +getWGLContext :: Window -> IO (Ptr ()) +getWGLContext = c'glfwGetWGLContext . toC + +-- | See <http://www.glfw.org/docs/3.2/group__native.html#gaf22f429aec4b1aab316142d66d9be3e6 glfwGetCocoaMonitor> +getCocoaMonitor :: Window -> IO (Ptr Word32) +getCocoaMonitor = c'glfwGetCocoaMonitor . toC + +-- | See <http://www.glfw.org/docs/3.2/group__native.html#gac3ed9d495d0c2bb9652de5a50c648715 glfwGetCocoaWindow> +getCocoaWindow :: Window -> IO (Ptr ()) +getCocoaWindow = c'glfwGetCocoaWindow . toC + +-- | See <http://www.glfw.org/docs/3.2/group__native.html#ga559e002e3cd63c979881770cd4dc63bc glfwGetNSGLContext> +getNSGLContext :: Window -> IO (Ptr ()) +getNSGLContext = c'glfwGetNSGLContext . toC + +-- | See <http://www.glfw.org/docs/3.2/group__native.html#ga8519b66594ea3ef6eeafaa2e3ee37406 glfwGetX11Display> +getX11Display :: Window -> IO (Ptr display) +getX11Display = c'glfwGetX11Display . toC + +-- | See <http://www.glfw.org/docs/3.2/group__native.html#ga088fbfa80f50569402b41be71ad66e40 glfwGetX11Adapter> +getX11Adapter :: Window -> IO Word64 +getX11Adapter = c'glfwGetX11Adapter . toC + +-- | See <http://www.glfw.org/docs/3.2/group__native.html#gab2f8cc043905e9fa9b12bfdbbcfe874c glfwGetX11Monitor> +getX11Monitor :: Window -> IO Word64 +getX11Monitor = c'glfwGetX11Monitor . toC + +-- | See <http://www.glfw.org/docs/3.2/group__native.html#ga90ca676322740842db446999a1b1f21d glfwGetX11Window> +getX11Window :: Window -> IO Word64 +getX11Window = c'glfwGetX11Window . toC + +-- | See <http://www.glfw.org/docs/3.2/group__native.html#ga62d884114b0abfcdc2930e89f20867e2 glfwGetGLXContext> +getGLXContext :: Window -> IO (Ptr ()) +getGLXContext = c'glfwGetGLXContext . toC + +-- | See <http://www.glfw.org/docs/3.2/group__native.html#ga1ed27b8766e859a21381e8f8ce18d049 glfwGetGLXWindow> +getGLXWindow :: Window -> IO Word64 +getGLXWindow = c'glfwGetGLXWindow . toC + +-- | See <http://www.glfw.org/docs/3.2/group__native.html#gaaf8118a3c877f3a6bc8e7a649519de5e glfwGetWaylandDisplay> +getWaylandDisplay :: IO (Ptr wl_display) +getWaylandDisplay = c'glfwGetWaylandDisplay + +-- | See <http://www.glfw.org/docs/3.2/group__native.html#gab10427a667b6cd91eec7709f7a906bd3 glfwGetWaylandMonitor> +getWaylandMonitor :: Window -> IO (Ptr wl_output) +getWaylandMonitor = c'glfwGetWaylandMonitor . toC + +-- | See <http://www.glfw.org/docs/3.2/group__native.html#ga4738d7aca4191363519a9a641c3ab64c glfwGetWaylandWindow> +getWaylandWindow :: Window -> IO (Ptr wl_surface) +getWaylandWindow = c'glfwGetWaylandWindow . toC + +-- | See <http://www.glfw.org/docs/3.2/group__native.html#ga40dd05325d9813fa67d61328c51d2930 glfwGetMirDisplay> +getMirDisplay :: IO (Ptr mir_connection) +getMirDisplay = c'glfwGetMirDisplay + +-- | See <http://www.glfw.org/docs/3.2/group__native.html#gae0941c11dc8f01aeb7cbb563f5cd930b glfwGetMirMonitor> +getMirMonitor :: Window -> IO Int +getMirMonitor = (fmap fromC) . c'glfwGetMirMonitor . toC + +-- | See <http://www.glfw.org/docs/3.2/group__native.html#ga964d52bb7932216c379762eef1ea9b05 glfwGetMirWindow> +getMirWindow :: Window -> IO (Ptr mir_surface) +getMirWindow = c'glfwGetMirWindow . toC + +-- | See <http://www.glfw.org/docs/3.2/group__native.html#ga1cd8d973f47aacb5532d368147cc3138 glfwGetEGLDisplay> +getEGLDisplay :: IO (Ptr ()) +getEGLDisplay = c'glfwGetEGLDisplay + +-- | See <http://www.glfw.org/docs/3.2/group__native.html#ga671c5072becd085f4ab5771a9c8efcf1 glfwGetEGLContext> +getEGLContext :: Window -> IO (Ptr ()) +getEGLContext = c'glfwGetEGLContext . toC + +-- | See <http://www.glfw.org/docs/3.2/group__native.html#ga2199b36117a6a695fec8441d8052eee6 glfwGetEGLSurface> +getEGLSurface :: Window -> IO (Ptr ()) +getEGLSurface = c'glfwGetEGLSurface . toC
Graphics/UI/GLFW/C.hs view
@@ -1,568 +1,568 @@-{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses, FlexibleContexts #-}-------------------------------------------------------------------------------------- This code is generated by util/genC.hs.------------------------------------------------------------------------------------module Graphics.UI.GLFW.C where------------------------------------------------------------------------------------import Data.Bits ((.&.))-import Data.Char (chr, ord)-import Foreign.C.Types (CDouble, CFloat, CInt, CUChar, CUInt, CUShort)-import Foreign.Ptr (Ptr)--import Bindings.GLFW-import Graphics.UI.GLFW.Types------------------------------------------------------------------------------------class C c h where- fromC :: c -> h- toC :: h -> c------------------------------------------------------------------------------------instance (C CInt b) => C CInt (Maybe b) where- fromC i | i == c'GLFW_DONT_CARE = Nothing- | otherwise = Just $ fromC i- toC = maybe c'GLFW_DONT_CARE toC------------------------------------------------------------------------------------instance C CInt Char where- fromC = chr . fromIntegral- toC = fromIntegral . ord--instance C CUInt Char where- fromC = chr . fromIntegral- toC = fromIntegral . ord--instance C CDouble Double where- fromC = realToFrac- toC = realToFrac--instance C CInt Int where- fromC = fromIntegral- toC = fromIntegral--instance C CUInt Int where- fromC = fromIntegral- toC = fromIntegral--instance C CUShort Int where- fromC = fromIntegral- toC = fromIntegral--instance C CFloat Double where- fromC = realToFrac- toC = realToFrac--instance C (Ptr C'GLFWmonitor) Monitor where- fromC = Monitor- toC = unMonitor--instance C (Ptr C'GLFWwindow) Window where- fromC = Window- toC = unWindow--instance C CInt ModifierKeys where- fromC v = ModifierKeys- { modifierKeysShift = (v .&. c'GLFW_MOD_SHIFT) /= 0- , modifierKeysControl = (v .&. c'GLFW_MOD_CONTROL) /= 0- , modifierKeysAlt = (v .&. c'GLFW_MOD_ALT) /= 0- , modifierKeysSuper = (v .&. c'GLFW_MOD_SUPER) /= 0- }- toC = undefined--instance C C'GLFWvidmode VideoMode where- fromC gvm = VideoMode- { videoModeWidth = fromIntegral $ c'GLFWvidmode'width gvm- , videoModeHeight = fromIntegral $ c'GLFWvidmode'height gvm- , videoModeRedBits = fromIntegral $ c'GLFWvidmode'redBits gvm- , videoModeGreenBits = fromIntegral $ c'GLFWvidmode'greenBits gvm- , videoModeBlueBits = fromIntegral $ c'GLFWvidmode'blueBits gvm- , videoModeRefreshRate = fromIntegral $ c'GLFWvidmode'refreshRate gvm- }- toC = undefined--instance C CInt StandardCursorShape where- fromC v- | v == c'GLFW_ARROW_CURSOR = StandardCursorShape'Arrow- | v == c'GLFW_IBEAM_CURSOR = StandardCursorShape'IBeam- | v == c'GLFW_CROSSHAIR_CURSOR = StandardCursorShape'Crosshair- | v == c'GLFW_HAND_CURSOR = StandardCursorShape'Hand- | v == c'GLFW_HRESIZE_CURSOR = StandardCursorShape'HResize- | v == c'GLFW_VRESIZE_CURSOR = StandardCursorShape'VResize- | otherwise = error $ "C CInt StandardCursorShape fromC: " ++ show v- toC StandardCursorShape'Arrow = c'GLFW_ARROW_CURSOR- toC StandardCursorShape'IBeam = c'GLFW_IBEAM_CURSOR- toC StandardCursorShape'Crosshair = c'GLFW_CROSSHAIR_CURSOR- toC StandardCursorShape'Hand = c'GLFW_HAND_CURSOR- toC StandardCursorShape'HResize = c'GLFW_HRESIZE_CURSOR- toC StandardCursorShape'VResize = c'GLFW_VRESIZE_CURSOR------------------------------------------------------------------------------------instance C CInt Bool where- fromC v- | v == c'GLFW_FALSE = False- | v == c'GLFW_TRUE = True- | otherwise = error $ "C CInt Bool fromC: " ++ show v- toC False = c'GLFW_FALSE- toC True = c'GLFW_TRUE--instance C CInt Error where- fromC v- | v == c'GLFW_NOT_INITIALIZED = Error'NotInitialized- | v == c'GLFW_NO_CURRENT_CONTEXT = Error'NoCurrentContext- | v == c'GLFW_INVALID_ENUM = Error'InvalidEnum- | v == c'GLFW_INVALID_VALUE = Error'InvalidValue- | v == c'GLFW_OUT_OF_MEMORY = Error'OutOfMemory- | v == c'GLFW_API_UNAVAILABLE = Error'ApiUnavailable- | v == c'GLFW_VERSION_UNAVAILABLE = Error'VersionUnavailable- | v == c'GLFW_PLATFORM_ERROR = Error'PlatformError- | v == c'GLFW_FORMAT_UNAVAILABLE = Error'FormatUnavailable- | otherwise = error $ "C CInt Error fromC: " ++ show v- toC Error'NotInitialized = c'GLFW_NOT_INITIALIZED- toC Error'NoCurrentContext = c'GLFW_NO_CURRENT_CONTEXT- toC Error'InvalidEnum = c'GLFW_INVALID_ENUM- toC Error'InvalidValue = c'GLFW_INVALID_VALUE- toC Error'OutOfMemory = c'GLFW_OUT_OF_MEMORY- toC Error'ApiUnavailable = c'GLFW_API_UNAVAILABLE- toC Error'VersionUnavailable = c'GLFW_VERSION_UNAVAILABLE- toC Error'PlatformError = c'GLFW_PLATFORM_ERROR- toC Error'FormatUnavailable = c'GLFW_FORMAT_UNAVAILABLE--instance C CInt MonitorState where- fromC v- | v == c'GLFW_CONNECTED = MonitorState'Connected- | v == c'GLFW_DISCONNECTED = MonitorState'Disconnected- | otherwise = error $ "C CInt MonitorState fromC: " ++ show v- toC MonitorState'Connected = c'GLFW_CONNECTED- toC MonitorState'Disconnected = c'GLFW_DISCONNECTED--instance C CInt ContextRobustness where- fromC v- | v == c'GLFW_NO_ROBUSTNESS = ContextRobustness'NoRobustness- | v == c'GLFW_NO_RESET_NOTIFICATION = ContextRobustness'NoResetNotification- | v == c'GLFW_LOSE_CONTEXT_ON_RESET = ContextRobustness'LoseContextOnReset- | otherwise = error $ "C CInt ContextRobustness fromC: " ++ show v- toC ContextRobustness'NoRobustness = c'GLFW_NO_ROBUSTNESS- toC ContextRobustness'NoResetNotification = c'GLFW_NO_RESET_NOTIFICATION- toC ContextRobustness'LoseContextOnReset = c'GLFW_LOSE_CONTEXT_ON_RESET--instance C CInt ContextReleaseBehavior where- fromC v- | v == c'GLFW_ANY_RELEASE_BEHAVIOR = ContextReleaseBehavior'Any- | v == c'GLFW_RELEASE_BEHAVIOR_NONE = ContextReleaseBehavior'None- | v == c'GLFW_RELEASE_BEHAVIOR_FLUSH = ContextReleaseBehavior'Flush- | otherwise = error $ "C CInt ContextReleaseBehavior fromC: " ++ show v- toC ContextReleaseBehavior'Any = c'GLFW_ANY_RELEASE_BEHAVIOR- toC ContextReleaseBehavior'None = c'GLFW_RELEASE_BEHAVIOR_NONE- toC ContextReleaseBehavior'Flush = c'GLFW_RELEASE_BEHAVIOR_FLUSH--instance C CInt OpenGLProfile where- fromC v- | v == c'GLFW_OPENGL_ANY_PROFILE = OpenGLProfile'Any- | v == c'GLFW_OPENGL_COMPAT_PROFILE = OpenGLProfile'Compat- | v == c'GLFW_OPENGL_CORE_PROFILE = OpenGLProfile'Core- | otherwise = error $ "C CInt OpenGLProfile fromC: " ++ show v- toC OpenGLProfile'Any = c'GLFW_OPENGL_ANY_PROFILE- toC OpenGLProfile'Compat = c'GLFW_OPENGL_COMPAT_PROFILE- toC OpenGLProfile'Core = c'GLFW_OPENGL_CORE_PROFILE--instance C CInt ClientAPI where- fromC v- | v == c'GLFW_NO_API = ClientAPI'NoAPI- | v == c'GLFW_OPENGL_API = ClientAPI'OpenGL- | v == c'GLFW_OPENGL_ES_API = ClientAPI'OpenGLES- | otherwise = error $ "C CInt ClientAPI fromC: " ++ show v- toC ClientAPI'NoAPI = c'GLFW_NO_API- toC ClientAPI'OpenGL = c'GLFW_OPENGL_API- toC ClientAPI'OpenGLES = c'GLFW_OPENGL_ES_API--instance C CInt ContextCreationAPI where- fromC v- | v == c'GLFW_NATIVE_CONTEXT_API = ContextCreationAPI'Native- | v == c'GLFW_EGL_CONTEXT_API = ContextCreationAPI'EGL- | otherwise = error $ "C CInt ContextCreationAPI fromC: " ++ show v- toC ContextCreationAPI'Native = c'GLFW_NATIVE_CONTEXT_API- toC ContextCreationAPI'EGL = c'GLFW_EGL_CONTEXT_API--instance C CInt Key where- fromC v- | v == c'GLFW_KEY_UNKNOWN = Key'Unknown- | v == c'GLFW_KEY_SPACE = Key'Space- | v == c'GLFW_KEY_APOSTROPHE = Key'Apostrophe- | v == c'GLFW_KEY_COMMA = Key'Comma- | v == c'GLFW_KEY_MINUS = Key'Minus- | v == c'GLFW_KEY_PERIOD = Key'Period- | v == c'GLFW_KEY_SLASH = Key'Slash- | v == c'GLFW_KEY_0 = Key'0- | v == c'GLFW_KEY_1 = Key'1- | v == c'GLFW_KEY_2 = Key'2- | v == c'GLFW_KEY_3 = Key'3- | v == c'GLFW_KEY_4 = Key'4- | v == c'GLFW_KEY_5 = Key'5- | v == c'GLFW_KEY_6 = Key'6- | v == c'GLFW_KEY_7 = Key'7- | v == c'GLFW_KEY_8 = Key'8- | v == c'GLFW_KEY_9 = Key'9- | v == c'GLFW_KEY_SEMICOLON = Key'Semicolon- | v == c'GLFW_KEY_EQUAL = Key'Equal- | v == c'GLFW_KEY_A = Key'A- | v == c'GLFW_KEY_B = Key'B- | v == c'GLFW_KEY_C = Key'C- | v == c'GLFW_KEY_D = Key'D- | v == c'GLFW_KEY_E = Key'E- | v == c'GLFW_KEY_F = Key'F- | v == c'GLFW_KEY_G = Key'G- | v == c'GLFW_KEY_H = Key'H- | v == c'GLFW_KEY_I = Key'I- | v == c'GLFW_KEY_J = Key'J- | v == c'GLFW_KEY_K = Key'K- | v == c'GLFW_KEY_L = Key'L- | v == c'GLFW_KEY_M = Key'M- | v == c'GLFW_KEY_N = Key'N- | v == c'GLFW_KEY_O = Key'O- | v == c'GLFW_KEY_P = Key'P- | v == c'GLFW_KEY_Q = Key'Q- | v == c'GLFW_KEY_R = Key'R- | v == c'GLFW_KEY_S = Key'S- | v == c'GLFW_KEY_T = Key'T- | v == c'GLFW_KEY_U = Key'U- | v == c'GLFW_KEY_V = Key'V- | v == c'GLFW_KEY_W = Key'W- | v == c'GLFW_KEY_X = Key'X- | v == c'GLFW_KEY_Y = Key'Y- | v == c'GLFW_KEY_Z = Key'Z- | v == c'GLFW_KEY_LEFT_BRACKET = Key'LeftBracket- | v == c'GLFW_KEY_BACKSLASH = Key'Backslash- | v == c'GLFW_KEY_RIGHT_BRACKET = Key'RightBracket- | v == c'GLFW_KEY_GRAVE_ACCENT = Key'GraveAccent- | v == c'GLFW_KEY_WORLD_1 = Key'World1- | v == c'GLFW_KEY_WORLD_2 = Key'World2- | v == c'GLFW_KEY_ESCAPE = Key'Escape- | v == c'GLFW_KEY_ENTER = Key'Enter- | v == c'GLFW_KEY_TAB = Key'Tab- | v == c'GLFW_KEY_BACKSPACE = Key'Backspace- | v == c'GLFW_KEY_INSERT = Key'Insert- | v == c'GLFW_KEY_DELETE = Key'Delete- | v == c'GLFW_KEY_RIGHT = Key'Right- | v == c'GLFW_KEY_LEFT = Key'Left- | v == c'GLFW_KEY_DOWN = Key'Down- | v == c'GLFW_KEY_UP = Key'Up- | v == c'GLFW_KEY_PAGE_UP = Key'PageUp- | v == c'GLFW_KEY_PAGE_DOWN = Key'PageDown- | v == c'GLFW_KEY_HOME = Key'Home- | v == c'GLFW_KEY_END = Key'End- | v == c'GLFW_KEY_CAPS_LOCK = Key'CapsLock- | v == c'GLFW_KEY_SCROLL_LOCK = Key'ScrollLock- | v == c'GLFW_KEY_NUM_LOCK = Key'NumLock- | v == c'GLFW_KEY_PRINT_SCREEN = Key'PrintScreen- | v == c'GLFW_KEY_PAUSE = Key'Pause- | v == c'GLFW_KEY_F1 = Key'F1- | v == c'GLFW_KEY_F2 = Key'F2- | v == c'GLFW_KEY_F3 = Key'F3- | v == c'GLFW_KEY_F4 = Key'F4- | v == c'GLFW_KEY_F5 = Key'F5- | v == c'GLFW_KEY_F6 = Key'F6- | v == c'GLFW_KEY_F7 = Key'F7- | v == c'GLFW_KEY_F8 = Key'F8- | v == c'GLFW_KEY_F9 = Key'F9- | v == c'GLFW_KEY_F10 = Key'F10- | v == c'GLFW_KEY_F11 = Key'F11- | v == c'GLFW_KEY_F12 = Key'F12- | v == c'GLFW_KEY_F13 = Key'F13- | v == c'GLFW_KEY_F14 = Key'F14- | v == c'GLFW_KEY_F15 = Key'F15- | v == c'GLFW_KEY_F16 = Key'F16- | v == c'GLFW_KEY_F17 = Key'F17- | v == c'GLFW_KEY_F18 = Key'F18- | v == c'GLFW_KEY_F19 = Key'F19- | v == c'GLFW_KEY_F20 = Key'F20- | v == c'GLFW_KEY_F21 = Key'F21- | v == c'GLFW_KEY_F22 = Key'F22- | v == c'GLFW_KEY_F23 = Key'F23- | v == c'GLFW_KEY_F24 = Key'F24- | v == c'GLFW_KEY_F25 = Key'F25- | v == c'GLFW_KEY_KP_0 = Key'Pad0- | v == c'GLFW_KEY_KP_1 = Key'Pad1- | v == c'GLFW_KEY_KP_2 = Key'Pad2- | v == c'GLFW_KEY_KP_3 = Key'Pad3- | v == c'GLFW_KEY_KP_4 = Key'Pad4- | v == c'GLFW_KEY_KP_5 = Key'Pad5- | v == c'GLFW_KEY_KP_6 = Key'Pad6- | v == c'GLFW_KEY_KP_7 = Key'Pad7- | v == c'GLFW_KEY_KP_8 = Key'Pad8- | v == c'GLFW_KEY_KP_9 = Key'Pad9- | v == c'GLFW_KEY_KP_DECIMAL = Key'PadDecimal- | v == c'GLFW_KEY_KP_DIVIDE = Key'PadDivide- | v == c'GLFW_KEY_KP_MULTIPLY = Key'PadMultiply- | v == c'GLFW_KEY_KP_SUBTRACT = Key'PadSubtract- | v == c'GLFW_KEY_KP_ADD = Key'PadAdd- | v == c'GLFW_KEY_KP_ENTER = Key'PadEnter- | v == c'GLFW_KEY_KP_EQUAL = Key'PadEqual- | v == c'GLFW_KEY_LEFT_SHIFT = Key'LeftShift- | v == c'GLFW_KEY_LEFT_CONTROL = Key'LeftControl- | v == c'GLFW_KEY_LEFT_ALT = Key'LeftAlt- | v == c'GLFW_KEY_LEFT_SUPER = Key'LeftSuper- | v == c'GLFW_KEY_RIGHT_SHIFT = Key'RightShift- | v == c'GLFW_KEY_RIGHT_CONTROL = Key'RightControl- | v == c'GLFW_KEY_RIGHT_ALT = Key'RightAlt- | v == c'GLFW_KEY_RIGHT_SUPER = Key'RightSuper- | v == c'GLFW_KEY_MENU = Key'Menu- | otherwise = error $ "C CInt Key fromC: " ++ show v- toC Key'Unknown = c'GLFW_KEY_UNKNOWN- toC Key'Space = c'GLFW_KEY_SPACE- toC Key'Apostrophe = c'GLFW_KEY_APOSTROPHE- toC Key'Comma = c'GLFW_KEY_COMMA- toC Key'Minus = c'GLFW_KEY_MINUS- toC Key'Period = c'GLFW_KEY_PERIOD- toC Key'Slash = c'GLFW_KEY_SLASH- toC Key'0 = c'GLFW_KEY_0- toC Key'1 = c'GLFW_KEY_1- toC Key'2 = c'GLFW_KEY_2- toC Key'3 = c'GLFW_KEY_3- toC Key'4 = c'GLFW_KEY_4- toC Key'5 = c'GLFW_KEY_5- toC Key'6 = c'GLFW_KEY_6- toC Key'7 = c'GLFW_KEY_7- toC Key'8 = c'GLFW_KEY_8- toC Key'9 = c'GLFW_KEY_9- toC Key'Semicolon = c'GLFW_KEY_SEMICOLON- toC Key'Equal = c'GLFW_KEY_EQUAL- toC Key'A = c'GLFW_KEY_A- toC Key'B = c'GLFW_KEY_B- toC Key'C = c'GLFW_KEY_C- toC Key'D = c'GLFW_KEY_D- toC Key'E = c'GLFW_KEY_E- toC Key'F = c'GLFW_KEY_F- toC Key'G = c'GLFW_KEY_G- toC Key'H = c'GLFW_KEY_H- toC Key'I = c'GLFW_KEY_I- toC Key'J = c'GLFW_KEY_J- toC Key'K = c'GLFW_KEY_K- toC Key'L = c'GLFW_KEY_L- toC Key'M = c'GLFW_KEY_M- toC Key'N = c'GLFW_KEY_N- toC Key'O = c'GLFW_KEY_O- toC Key'P = c'GLFW_KEY_P- toC Key'Q = c'GLFW_KEY_Q- toC Key'R = c'GLFW_KEY_R- toC Key'S = c'GLFW_KEY_S- toC Key'T = c'GLFW_KEY_T- toC Key'U = c'GLFW_KEY_U- toC Key'V = c'GLFW_KEY_V- toC Key'W = c'GLFW_KEY_W- toC Key'X = c'GLFW_KEY_X- toC Key'Y = c'GLFW_KEY_Y- toC Key'Z = c'GLFW_KEY_Z- toC Key'LeftBracket = c'GLFW_KEY_LEFT_BRACKET- toC Key'Backslash = c'GLFW_KEY_BACKSLASH- toC Key'RightBracket = c'GLFW_KEY_RIGHT_BRACKET- toC Key'GraveAccent = c'GLFW_KEY_GRAVE_ACCENT- toC Key'World1 = c'GLFW_KEY_WORLD_1- toC Key'World2 = c'GLFW_KEY_WORLD_2- toC Key'Escape = c'GLFW_KEY_ESCAPE- toC Key'Enter = c'GLFW_KEY_ENTER- toC Key'Tab = c'GLFW_KEY_TAB- toC Key'Backspace = c'GLFW_KEY_BACKSPACE- toC Key'Insert = c'GLFW_KEY_INSERT- toC Key'Delete = c'GLFW_KEY_DELETE- toC Key'Right = c'GLFW_KEY_RIGHT- toC Key'Left = c'GLFW_KEY_LEFT- toC Key'Down = c'GLFW_KEY_DOWN- toC Key'Up = c'GLFW_KEY_UP- toC Key'PageUp = c'GLFW_KEY_PAGE_UP- toC Key'PageDown = c'GLFW_KEY_PAGE_DOWN- toC Key'Home = c'GLFW_KEY_HOME- toC Key'End = c'GLFW_KEY_END- toC Key'CapsLock = c'GLFW_KEY_CAPS_LOCK- toC Key'ScrollLock = c'GLFW_KEY_SCROLL_LOCK- toC Key'NumLock = c'GLFW_KEY_NUM_LOCK- toC Key'PrintScreen = c'GLFW_KEY_PRINT_SCREEN- toC Key'Pause = c'GLFW_KEY_PAUSE- toC Key'F1 = c'GLFW_KEY_F1- toC Key'F2 = c'GLFW_KEY_F2- toC Key'F3 = c'GLFW_KEY_F3- toC Key'F4 = c'GLFW_KEY_F4- toC Key'F5 = c'GLFW_KEY_F5- toC Key'F6 = c'GLFW_KEY_F6- toC Key'F7 = c'GLFW_KEY_F7- toC Key'F8 = c'GLFW_KEY_F8- toC Key'F9 = c'GLFW_KEY_F9- toC Key'F10 = c'GLFW_KEY_F10- toC Key'F11 = c'GLFW_KEY_F11- toC Key'F12 = c'GLFW_KEY_F12- toC Key'F13 = c'GLFW_KEY_F13- toC Key'F14 = c'GLFW_KEY_F14- toC Key'F15 = c'GLFW_KEY_F15- toC Key'F16 = c'GLFW_KEY_F16- toC Key'F17 = c'GLFW_KEY_F17- toC Key'F18 = c'GLFW_KEY_F18- toC Key'F19 = c'GLFW_KEY_F19- toC Key'F20 = c'GLFW_KEY_F20- toC Key'F21 = c'GLFW_KEY_F21- toC Key'F22 = c'GLFW_KEY_F22- toC Key'F23 = c'GLFW_KEY_F23- toC Key'F24 = c'GLFW_KEY_F24- toC Key'F25 = c'GLFW_KEY_F25- toC Key'Pad0 = c'GLFW_KEY_KP_0- toC Key'Pad1 = c'GLFW_KEY_KP_1- toC Key'Pad2 = c'GLFW_KEY_KP_2- toC Key'Pad3 = c'GLFW_KEY_KP_3- toC Key'Pad4 = c'GLFW_KEY_KP_4- toC Key'Pad5 = c'GLFW_KEY_KP_5- toC Key'Pad6 = c'GLFW_KEY_KP_6- toC Key'Pad7 = c'GLFW_KEY_KP_7- toC Key'Pad8 = c'GLFW_KEY_KP_8- toC Key'Pad9 = c'GLFW_KEY_KP_9- toC Key'PadDecimal = c'GLFW_KEY_KP_DECIMAL- toC Key'PadDivide = c'GLFW_KEY_KP_DIVIDE- toC Key'PadMultiply = c'GLFW_KEY_KP_MULTIPLY- toC Key'PadSubtract = c'GLFW_KEY_KP_SUBTRACT- toC Key'PadAdd = c'GLFW_KEY_KP_ADD- toC Key'PadEnter = c'GLFW_KEY_KP_ENTER- toC Key'PadEqual = c'GLFW_KEY_KP_EQUAL- toC Key'LeftShift = c'GLFW_KEY_LEFT_SHIFT- toC Key'LeftControl = c'GLFW_KEY_LEFT_CONTROL- toC Key'LeftAlt = c'GLFW_KEY_LEFT_ALT- toC Key'LeftSuper = c'GLFW_KEY_LEFT_SUPER- toC Key'RightShift = c'GLFW_KEY_RIGHT_SHIFT- toC Key'RightControl = c'GLFW_KEY_RIGHT_CONTROL- toC Key'RightAlt = c'GLFW_KEY_RIGHT_ALT- toC Key'RightSuper = c'GLFW_KEY_RIGHT_SUPER- toC Key'Menu = c'GLFW_KEY_MENU--instance C CInt KeyState where- fromC v- | v == c'GLFW_PRESS = KeyState'Pressed- | v == c'GLFW_RELEASE = KeyState'Released- | v == c'GLFW_REPEAT = KeyState'Repeating- | otherwise = error $ "C CInt KeyState fromC: " ++ show v- toC KeyState'Pressed = c'GLFW_PRESS- toC KeyState'Released = c'GLFW_RELEASE- toC KeyState'Repeating = c'GLFW_REPEAT--instance C CInt Joystick where- fromC v- | v == c'GLFW_JOYSTICK_1 = Joystick'1- | v == c'GLFW_JOYSTICK_2 = Joystick'2- | v == c'GLFW_JOYSTICK_3 = Joystick'3- | v == c'GLFW_JOYSTICK_4 = Joystick'4- | v == c'GLFW_JOYSTICK_5 = Joystick'5- | v == c'GLFW_JOYSTICK_6 = Joystick'6- | v == c'GLFW_JOYSTICK_7 = Joystick'7- | v == c'GLFW_JOYSTICK_8 = Joystick'8- | v == c'GLFW_JOYSTICK_9 = Joystick'9- | v == c'GLFW_JOYSTICK_10 = Joystick'10- | v == c'GLFW_JOYSTICK_11 = Joystick'11- | v == c'GLFW_JOYSTICK_12 = Joystick'12- | v == c'GLFW_JOYSTICK_13 = Joystick'13- | v == c'GLFW_JOYSTICK_14 = Joystick'14- | v == c'GLFW_JOYSTICK_15 = Joystick'15- | v == c'GLFW_JOYSTICK_16 = Joystick'16- | otherwise = error $ "C CInt Joystick fromC: " ++ show v- toC Joystick'1 = c'GLFW_JOYSTICK_1- toC Joystick'2 = c'GLFW_JOYSTICK_2- toC Joystick'3 = c'GLFW_JOYSTICK_3- toC Joystick'4 = c'GLFW_JOYSTICK_4- toC Joystick'5 = c'GLFW_JOYSTICK_5- toC Joystick'6 = c'GLFW_JOYSTICK_6- toC Joystick'7 = c'GLFW_JOYSTICK_7- toC Joystick'8 = c'GLFW_JOYSTICK_8- toC Joystick'9 = c'GLFW_JOYSTICK_9- toC Joystick'10 = c'GLFW_JOYSTICK_10- toC Joystick'11 = c'GLFW_JOYSTICK_11- toC Joystick'12 = c'GLFW_JOYSTICK_12- toC Joystick'13 = c'GLFW_JOYSTICK_13- toC Joystick'14 = c'GLFW_JOYSTICK_14- toC Joystick'15 = c'GLFW_JOYSTICK_15- toC Joystick'16 = c'GLFW_JOYSTICK_16--instance C CUChar JoystickButtonState where- fromC v- | v == c'GLFW_PRESS = JoystickButtonState'Pressed- | v == c'GLFW_RELEASE = JoystickButtonState'Released- | otherwise = error $ "C CUChar JoystickButtonState fromC: " ++ show v- toC JoystickButtonState'Pressed = c'GLFW_PRESS- toC JoystickButtonState'Released = c'GLFW_RELEASE--instance C CInt JoystickState where- fromC v- | v == c'GLFW_CONNECTED = JoystickState'Connected- | v == c'GLFW_DISCONNECTED = JoystickState'Disconnected- | otherwise = error $ "C CInt JoystickState fromC: " ++ show v- toC JoystickState'Connected = c'GLFW_CONNECTED- toC JoystickState'Disconnected = c'GLFW_DISCONNECTED--instance C CInt MouseButton where- fromC v- | v == c'GLFW_MOUSE_BUTTON_1 = MouseButton'1- | v == c'GLFW_MOUSE_BUTTON_2 = MouseButton'2- | v == c'GLFW_MOUSE_BUTTON_3 = MouseButton'3- | v == c'GLFW_MOUSE_BUTTON_4 = MouseButton'4- | v == c'GLFW_MOUSE_BUTTON_5 = MouseButton'5- | v == c'GLFW_MOUSE_BUTTON_6 = MouseButton'6- | v == c'GLFW_MOUSE_BUTTON_7 = MouseButton'7- | v == c'GLFW_MOUSE_BUTTON_8 = MouseButton'8- | otherwise = error $ "C CInt MouseButton fromC: " ++ show v- toC MouseButton'1 = c'GLFW_MOUSE_BUTTON_1- toC MouseButton'2 = c'GLFW_MOUSE_BUTTON_2- toC MouseButton'3 = c'GLFW_MOUSE_BUTTON_3- toC MouseButton'4 = c'GLFW_MOUSE_BUTTON_4- toC MouseButton'5 = c'GLFW_MOUSE_BUTTON_5- toC MouseButton'6 = c'GLFW_MOUSE_BUTTON_6- toC MouseButton'7 = c'GLFW_MOUSE_BUTTON_7- toC MouseButton'8 = c'GLFW_MOUSE_BUTTON_8--instance C CInt MouseButtonState where- fromC v- | v == c'GLFW_PRESS = MouseButtonState'Pressed- | v == c'GLFW_RELEASE = MouseButtonState'Released- | otherwise = error $ "C CInt MouseButtonState fromC: " ++ show v- toC MouseButtonState'Pressed = c'GLFW_PRESS- toC MouseButtonState'Released = c'GLFW_RELEASE--instance C CInt CursorState where- fromC v- | v == c'GLFW_TRUE = CursorState'InWindow- | v == c'GLFW_FALSE = CursorState'NotInWindow- | otherwise = error $ "C CInt CursorState fromC: " ++ show v- toC CursorState'InWindow = c'GLFW_TRUE- toC CursorState'NotInWindow = c'GLFW_FALSE--instance C CInt CursorInputMode where- fromC v- | v == c'GLFW_CURSOR_NORMAL = CursorInputMode'Normal- | v == c'GLFW_CURSOR_HIDDEN = CursorInputMode'Hidden- | v == c'GLFW_CURSOR_DISABLED = CursorInputMode'Disabled- | otherwise = error $ "C CInt CursorInputMode fromC: " ++ show v- toC CursorInputMode'Normal = c'GLFW_CURSOR_NORMAL- toC CursorInputMode'Hidden = c'GLFW_CURSOR_HIDDEN- toC CursorInputMode'Disabled = c'GLFW_CURSOR_DISABLED--instance C CInt StickyKeysInputMode where- fromC v- | v == c'GLFW_TRUE = StickyKeysInputMode'Enabled- | v == c'GLFW_FALSE = StickyKeysInputMode'Disabled- | otherwise = error $ "C CInt StickyKeysInputMode fromC: " ++ show v- toC StickyKeysInputMode'Enabled = c'GLFW_TRUE- toC StickyKeysInputMode'Disabled = c'GLFW_FALSE--instance C CInt StickyMouseButtonsInputMode where- fromC v- | v == c'GLFW_TRUE = StickyMouseButtonsInputMode'Enabled- | v == c'GLFW_FALSE = StickyMouseButtonsInputMode'Disabled- | otherwise = error $ "C CInt StickyMouseButtonsInputMode fromC: " ++ show v- toC StickyMouseButtonsInputMode'Enabled = c'GLFW_TRUE- toC StickyMouseButtonsInputMode'Disabled = c'GLFW_FALSE-----------------------------------------------------------------------------------+{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses, FlexibleContexts #-} + +-------------------------------------------------------------------------------- + +-- This code is generated by util/genC.hs. + +-------------------------------------------------------------------------------- + +module Graphics.UI.GLFW.C where + +-------------------------------------------------------------------------------- + +import Data.Bits ((.&.)) +import Data.Char (chr, ord) +import Foreign.C.Types (CDouble, CFloat, CInt, CUChar, CUInt, CUShort) +import Foreign.Ptr (Ptr) + +import Bindings.GLFW +import Graphics.UI.GLFW.Types + +-------------------------------------------------------------------------------- + +class C c h where + fromC :: c -> h + toC :: h -> c + +-------------------------------------------------------------------------------- + +instance (C CInt b) => C CInt (Maybe b) where + fromC i | i == c'GLFW_DONT_CARE = Nothing + | otherwise = Just $ fromC i + toC = maybe c'GLFW_DONT_CARE toC + +-------------------------------------------------------------------------------- + +instance C CInt Char where + fromC = chr . fromIntegral + toC = fromIntegral . ord + +instance C CUInt Char where + fromC = chr . fromIntegral + toC = fromIntegral . ord + +instance C CDouble Double where + fromC = realToFrac + toC = realToFrac + +instance C CInt Int where + fromC = fromIntegral + toC = fromIntegral + +instance C CUInt Int where + fromC = fromIntegral + toC = fromIntegral + +instance C CUShort Int where + fromC = fromIntegral + toC = fromIntegral + +instance C CFloat Double where + fromC = realToFrac + toC = realToFrac + +instance C (Ptr C'GLFWmonitor) Monitor where + fromC = Monitor + toC = unMonitor + +instance C (Ptr C'GLFWwindow) Window where + fromC = Window + toC = unWindow + +instance C CInt ModifierKeys where + fromC v = ModifierKeys + { modifierKeysShift = (v .&. c'GLFW_MOD_SHIFT) /= 0 + , modifierKeysControl = (v .&. c'GLFW_MOD_CONTROL) /= 0 + , modifierKeysAlt = (v .&. c'GLFW_MOD_ALT) /= 0 + , modifierKeysSuper = (v .&. c'GLFW_MOD_SUPER) /= 0 + } + toC = undefined + +instance C C'GLFWvidmode VideoMode where + fromC gvm = VideoMode + { videoModeWidth = fromIntegral $ c'GLFWvidmode'width gvm + , videoModeHeight = fromIntegral $ c'GLFWvidmode'height gvm + , videoModeRedBits = fromIntegral $ c'GLFWvidmode'redBits gvm + , videoModeGreenBits = fromIntegral $ c'GLFWvidmode'greenBits gvm + , videoModeBlueBits = fromIntegral $ c'GLFWvidmode'blueBits gvm + , videoModeRefreshRate = fromIntegral $ c'GLFWvidmode'refreshRate gvm + } + toC = undefined + +instance C CInt StandardCursorShape where + fromC v + | v == c'GLFW_ARROW_CURSOR = StandardCursorShape'Arrow + | v == c'GLFW_IBEAM_CURSOR = StandardCursorShape'IBeam + | v == c'GLFW_CROSSHAIR_CURSOR = StandardCursorShape'Crosshair + | v == c'GLFW_HAND_CURSOR = StandardCursorShape'Hand + | v == c'GLFW_HRESIZE_CURSOR = StandardCursorShape'HResize + | v == c'GLFW_VRESIZE_CURSOR = StandardCursorShape'VResize + | otherwise = error $ "C CInt StandardCursorShape fromC: " ++ show v + toC StandardCursorShape'Arrow = c'GLFW_ARROW_CURSOR + toC StandardCursorShape'IBeam = c'GLFW_IBEAM_CURSOR + toC StandardCursorShape'Crosshair = c'GLFW_CROSSHAIR_CURSOR + toC StandardCursorShape'Hand = c'GLFW_HAND_CURSOR + toC StandardCursorShape'HResize = c'GLFW_HRESIZE_CURSOR + toC StandardCursorShape'VResize = c'GLFW_VRESIZE_CURSOR + +-------------------------------------------------------------------------------- + +instance C CInt Bool where + fromC v + | v == c'GLFW_FALSE = False + | v == c'GLFW_TRUE = True + | otherwise = error $ "C CInt Bool fromC: " ++ show v + toC False = c'GLFW_FALSE + toC True = c'GLFW_TRUE + +instance C CInt Error where + fromC v + | v == c'GLFW_NOT_INITIALIZED = Error'NotInitialized + | v == c'GLFW_NO_CURRENT_CONTEXT = Error'NoCurrentContext + | v == c'GLFW_INVALID_ENUM = Error'InvalidEnum + | v == c'GLFW_INVALID_VALUE = Error'InvalidValue + | v == c'GLFW_OUT_OF_MEMORY = Error'OutOfMemory + | v == c'GLFW_API_UNAVAILABLE = Error'ApiUnavailable + | v == c'GLFW_VERSION_UNAVAILABLE = Error'VersionUnavailable + | v == c'GLFW_PLATFORM_ERROR = Error'PlatformError + | v == c'GLFW_FORMAT_UNAVAILABLE = Error'FormatUnavailable + | otherwise = error $ "C CInt Error fromC: " ++ show v + toC Error'NotInitialized = c'GLFW_NOT_INITIALIZED + toC Error'NoCurrentContext = c'GLFW_NO_CURRENT_CONTEXT + toC Error'InvalidEnum = c'GLFW_INVALID_ENUM + toC Error'InvalidValue = c'GLFW_INVALID_VALUE + toC Error'OutOfMemory = c'GLFW_OUT_OF_MEMORY + toC Error'ApiUnavailable = c'GLFW_API_UNAVAILABLE + toC Error'VersionUnavailable = c'GLFW_VERSION_UNAVAILABLE + toC Error'PlatformError = c'GLFW_PLATFORM_ERROR + toC Error'FormatUnavailable = c'GLFW_FORMAT_UNAVAILABLE + +instance C CInt MonitorState where + fromC v + | v == c'GLFW_CONNECTED = MonitorState'Connected + | v == c'GLFW_DISCONNECTED = MonitorState'Disconnected + | otherwise = error $ "C CInt MonitorState fromC: " ++ show v + toC MonitorState'Connected = c'GLFW_CONNECTED + toC MonitorState'Disconnected = c'GLFW_DISCONNECTED + +instance C CInt ContextRobustness where + fromC v + | v == c'GLFW_NO_ROBUSTNESS = ContextRobustness'NoRobustness + | v == c'GLFW_NO_RESET_NOTIFICATION = ContextRobustness'NoResetNotification + | v == c'GLFW_LOSE_CONTEXT_ON_RESET = ContextRobustness'LoseContextOnReset + | otherwise = error $ "C CInt ContextRobustness fromC: " ++ show v + toC ContextRobustness'NoRobustness = c'GLFW_NO_ROBUSTNESS + toC ContextRobustness'NoResetNotification = c'GLFW_NO_RESET_NOTIFICATION + toC ContextRobustness'LoseContextOnReset = c'GLFW_LOSE_CONTEXT_ON_RESET + +instance C CInt ContextReleaseBehavior where + fromC v + | v == c'GLFW_ANY_RELEASE_BEHAVIOR = ContextReleaseBehavior'Any + | v == c'GLFW_RELEASE_BEHAVIOR_NONE = ContextReleaseBehavior'None + | v == c'GLFW_RELEASE_BEHAVIOR_FLUSH = ContextReleaseBehavior'Flush + | otherwise = error $ "C CInt ContextReleaseBehavior fromC: " ++ show v + toC ContextReleaseBehavior'Any = c'GLFW_ANY_RELEASE_BEHAVIOR + toC ContextReleaseBehavior'None = c'GLFW_RELEASE_BEHAVIOR_NONE + toC ContextReleaseBehavior'Flush = c'GLFW_RELEASE_BEHAVIOR_FLUSH + +instance C CInt OpenGLProfile where + fromC v + | v == c'GLFW_OPENGL_ANY_PROFILE = OpenGLProfile'Any + | v == c'GLFW_OPENGL_COMPAT_PROFILE = OpenGLProfile'Compat + | v == c'GLFW_OPENGL_CORE_PROFILE = OpenGLProfile'Core + | otherwise = error $ "C CInt OpenGLProfile fromC: " ++ show v + toC OpenGLProfile'Any = c'GLFW_OPENGL_ANY_PROFILE + toC OpenGLProfile'Compat = c'GLFW_OPENGL_COMPAT_PROFILE + toC OpenGLProfile'Core = c'GLFW_OPENGL_CORE_PROFILE + +instance C CInt ClientAPI where + fromC v + | v == c'GLFW_NO_API = ClientAPI'NoAPI + | v == c'GLFW_OPENGL_API = ClientAPI'OpenGL + | v == c'GLFW_OPENGL_ES_API = ClientAPI'OpenGLES + | otherwise = error $ "C CInt ClientAPI fromC: " ++ show v + toC ClientAPI'NoAPI = c'GLFW_NO_API + toC ClientAPI'OpenGL = c'GLFW_OPENGL_API + toC ClientAPI'OpenGLES = c'GLFW_OPENGL_ES_API + +instance C CInt ContextCreationAPI where + fromC v + | v == c'GLFW_NATIVE_CONTEXT_API = ContextCreationAPI'Native + | v == c'GLFW_EGL_CONTEXT_API = ContextCreationAPI'EGL + | otherwise = error $ "C CInt ContextCreationAPI fromC: " ++ show v + toC ContextCreationAPI'Native = c'GLFW_NATIVE_CONTEXT_API + toC ContextCreationAPI'EGL = c'GLFW_EGL_CONTEXT_API + +instance C CInt Key where + fromC v + | v == c'GLFW_KEY_UNKNOWN = Key'Unknown + | v == c'GLFW_KEY_SPACE = Key'Space + | v == c'GLFW_KEY_APOSTROPHE = Key'Apostrophe + | v == c'GLFW_KEY_COMMA = Key'Comma + | v == c'GLFW_KEY_MINUS = Key'Minus + | v == c'GLFW_KEY_PERIOD = Key'Period + | v == c'GLFW_KEY_SLASH = Key'Slash + | v == c'GLFW_KEY_0 = Key'0 + | v == c'GLFW_KEY_1 = Key'1 + | v == c'GLFW_KEY_2 = Key'2 + | v == c'GLFW_KEY_3 = Key'3 + | v == c'GLFW_KEY_4 = Key'4 + | v == c'GLFW_KEY_5 = Key'5 + | v == c'GLFW_KEY_6 = Key'6 + | v == c'GLFW_KEY_7 = Key'7 + | v == c'GLFW_KEY_8 = Key'8 + | v == c'GLFW_KEY_9 = Key'9 + | v == c'GLFW_KEY_SEMICOLON = Key'Semicolon + | v == c'GLFW_KEY_EQUAL = Key'Equal + | v == c'GLFW_KEY_A = Key'A + | v == c'GLFW_KEY_B = Key'B + | v == c'GLFW_KEY_C = Key'C + | v == c'GLFW_KEY_D = Key'D + | v == c'GLFW_KEY_E = Key'E + | v == c'GLFW_KEY_F = Key'F + | v == c'GLFW_KEY_G = Key'G + | v == c'GLFW_KEY_H = Key'H + | v == c'GLFW_KEY_I = Key'I + | v == c'GLFW_KEY_J = Key'J + | v == c'GLFW_KEY_K = Key'K + | v == c'GLFW_KEY_L = Key'L + | v == c'GLFW_KEY_M = Key'M + | v == c'GLFW_KEY_N = Key'N + | v == c'GLFW_KEY_O = Key'O + | v == c'GLFW_KEY_P = Key'P + | v == c'GLFW_KEY_Q = Key'Q + | v == c'GLFW_KEY_R = Key'R + | v == c'GLFW_KEY_S = Key'S + | v == c'GLFW_KEY_T = Key'T + | v == c'GLFW_KEY_U = Key'U + | v == c'GLFW_KEY_V = Key'V + | v == c'GLFW_KEY_W = Key'W + | v == c'GLFW_KEY_X = Key'X + | v == c'GLFW_KEY_Y = Key'Y + | v == c'GLFW_KEY_Z = Key'Z + | v == c'GLFW_KEY_LEFT_BRACKET = Key'LeftBracket + | v == c'GLFW_KEY_BACKSLASH = Key'Backslash + | v == c'GLFW_KEY_RIGHT_BRACKET = Key'RightBracket + | v == c'GLFW_KEY_GRAVE_ACCENT = Key'GraveAccent + | v == c'GLFW_KEY_WORLD_1 = Key'World1 + | v == c'GLFW_KEY_WORLD_2 = Key'World2 + | v == c'GLFW_KEY_ESCAPE = Key'Escape + | v == c'GLFW_KEY_ENTER = Key'Enter + | v == c'GLFW_KEY_TAB = Key'Tab + | v == c'GLFW_KEY_BACKSPACE = Key'Backspace + | v == c'GLFW_KEY_INSERT = Key'Insert + | v == c'GLFW_KEY_DELETE = Key'Delete + | v == c'GLFW_KEY_RIGHT = Key'Right + | v == c'GLFW_KEY_LEFT = Key'Left + | v == c'GLFW_KEY_DOWN = Key'Down + | v == c'GLFW_KEY_UP = Key'Up + | v == c'GLFW_KEY_PAGE_UP = Key'PageUp + | v == c'GLFW_KEY_PAGE_DOWN = Key'PageDown + | v == c'GLFW_KEY_HOME = Key'Home + | v == c'GLFW_KEY_END = Key'End + | v == c'GLFW_KEY_CAPS_LOCK = Key'CapsLock + | v == c'GLFW_KEY_SCROLL_LOCK = Key'ScrollLock + | v == c'GLFW_KEY_NUM_LOCK = Key'NumLock + | v == c'GLFW_KEY_PRINT_SCREEN = Key'PrintScreen + | v == c'GLFW_KEY_PAUSE = Key'Pause + | v == c'GLFW_KEY_F1 = Key'F1 + | v == c'GLFW_KEY_F2 = Key'F2 + | v == c'GLFW_KEY_F3 = Key'F3 + | v == c'GLFW_KEY_F4 = Key'F4 + | v == c'GLFW_KEY_F5 = Key'F5 + | v == c'GLFW_KEY_F6 = Key'F6 + | v == c'GLFW_KEY_F7 = Key'F7 + | v == c'GLFW_KEY_F8 = Key'F8 + | v == c'GLFW_KEY_F9 = Key'F9 + | v == c'GLFW_KEY_F10 = Key'F10 + | v == c'GLFW_KEY_F11 = Key'F11 + | v == c'GLFW_KEY_F12 = Key'F12 + | v == c'GLFW_KEY_F13 = Key'F13 + | v == c'GLFW_KEY_F14 = Key'F14 + | v == c'GLFW_KEY_F15 = Key'F15 + | v == c'GLFW_KEY_F16 = Key'F16 + | v == c'GLFW_KEY_F17 = Key'F17 + | v == c'GLFW_KEY_F18 = Key'F18 + | v == c'GLFW_KEY_F19 = Key'F19 + | v == c'GLFW_KEY_F20 = Key'F20 + | v == c'GLFW_KEY_F21 = Key'F21 + | v == c'GLFW_KEY_F22 = Key'F22 + | v == c'GLFW_KEY_F23 = Key'F23 + | v == c'GLFW_KEY_F24 = Key'F24 + | v == c'GLFW_KEY_F25 = Key'F25 + | v == c'GLFW_KEY_KP_0 = Key'Pad0 + | v == c'GLFW_KEY_KP_1 = Key'Pad1 + | v == c'GLFW_KEY_KP_2 = Key'Pad2 + | v == c'GLFW_KEY_KP_3 = Key'Pad3 + | v == c'GLFW_KEY_KP_4 = Key'Pad4 + | v == c'GLFW_KEY_KP_5 = Key'Pad5 + | v == c'GLFW_KEY_KP_6 = Key'Pad6 + | v == c'GLFW_KEY_KP_7 = Key'Pad7 + | v == c'GLFW_KEY_KP_8 = Key'Pad8 + | v == c'GLFW_KEY_KP_9 = Key'Pad9 + | v == c'GLFW_KEY_KP_DECIMAL = Key'PadDecimal + | v == c'GLFW_KEY_KP_DIVIDE = Key'PadDivide + | v == c'GLFW_KEY_KP_MULTIPLY = Key'PadMultiply + | v == c'GLFW_KEY_KP_SUBTRACT = Key'PadSubtract + | v == c'GLFW_KEY_KP_ADD = Key'PadAdd + | v == c'GLFW_KEY_KP_ENTER = Key'PadEnter + | v == c'GLFW_KEY_KP_EQUAL = Key'PadEqual + | v == c'GLFW_KEY_LEFT_SHIFT = Key'LeftShift + | v == c'GLFW_KEY_LEFT_CONTROL = Key'LeftControl + | v == c'GLFW_KEY_LEFT_ALT = Key'LeftAlt + | v == c'GLFW_KEY_LEFT_SUPER = Key'LeftSuper + | v == c'GLFW_KEY_RIGHT_SHIFT = Key'RightShift + | v == c'GLFW_KEY_RIGHT_CONTROL = Key'RightControl + | v == c'GLFW_KEY_RIGHT_ALT = Key'RightAlt + | v == c'GLFW_KEY_RIGHT_SUPER = Key'RightSuper + | v == c'GLFW_KEY_MENU = Key'Menu + | otherwise = error $ "C CInt Key fromC: " ++ show v + toC Key'Unknown = c'GLFW_KEY_UNKNOWN + toC Key'Space = c'GLFW_KEY_SPACE + toC Key'Apostrophe = c'GLFW_KEY_APOSTROPHE + toC Key'Comma = c'GLFW_KEY_COMMA + toC Key'Minus = c'GLFW_KEY_MINUS + toC Key'Period = c'GLFW_KEY_PERIOD + toC Key'Slash = c'GLFW_KEY_SLASH + toC Key'0 = c'GLFW_KEY_0 + toC Key'1 = c'GLFW_KEY_1 + toC Key'2 = c'GLFW_KEY_2 + toC Key'3 = c'GLFW_KEY_3 + toC Key'4 = c'GLFW_KEY_4 + toC Key'5 = c'GLFW_KEY_5 + toC Key'6 = c'GLFW_KEY_6 + toC Key'7 = c'GLFW_KEY_7 + toC Key'8 = c'GLFW_KEY_8 + toC Key'9 = c'GLFW_KEY_9 + toC Key'Semicolon = c'GLFW_KEY_SEMICOLON + toC Key'Equal = c'GLFW_KEY_EQUAL + toC Key'A = c'GLFW_KEY_A + toC Key'B = c'GLFW_KEY_B + toC Key'C = c'GLFW_KEY_C + toC Key'D = c'GLFW_KEY_D + toC Key'E = c'GLFW_KEY_E + toC Key'F = c'GLFW_KEY_F + toC Key'G = c'GLFW_KEY_G + toC Key'H = c'GLFW_KEY_H + toC Key'I = c'GLFW_KEY_I + toC Key'J = c'GLFW_KEY_J + toC Key'K = c'GLFW_KEY_K + toC Key'L = c'GLFW_KEY_L + toC Key'M = c'GLFW_KEY_M + toC Key'N = c'GLFW_KEY_N + toC Key'O = c'GLFW_KEY_O + toC Key'P = c'GLFW_KEY_P + toC Key'Q = c'GLFW_KEY_Q + toC Key'R = c'GLFW_KEY_R + toC Key'S = c'GLFW_KEY_S + toC Key'T = c'GLFW_KEY_T + toC Key'U = c'GLFW_KEY_U + toC Key'V = c'GLFW_KEY_V + toC Key'W = c'GLFW_KEY_W + toC Key'X = c'GLFW_KEY_X + toC Key'Y = c'GLFW_KEY_Y + toC Key'Z = c'GLFW_KEY_Z + toC Key'LeftBracket = c'GLFW_KEY_LEFT_BRACKET + toC Key'Backslash = c'GLFW_KEY_BACKSLASH + toC Key'RightBracket = c'GLFW_KEY_RIGHT_BRACKET + toC Key'GraveAccent = c'GLFW_KEY_GRAVE_ACCENT + toC Key'World1 = c'GLFW_KEY_WORLD_1 + toC Key'World2 = c'GLFW_KEY_WORLD_2 + toC Key'Escape = c'GLFW_KEY_ESCAPE + toC Key'Enter = c'GLFW_KEY_ENTER + toC Key'Tab = c'GLFW_KEY_TAB + toC Key'Backspace = c'GLFW_KEY_BACKSPACE + toC Key'Insert = c'GLFW_KEY_INSERT + toC Key'Delete = c'GLFW_KEY_DELETE + toC Key'Right = c'GLFW_KEY_RIGHT + toC Key'Left = c'GLFW_KEY_LEFT + toC Key'Down = c'GLFW_KEY_DOWN + toC Key'Up = c'GLFW_KEY_UP + toC Key'PageUp = c'GLFW_KEY_PAGE_UP + toC Key'PageDown = c'GLFW_KEY_PAGE_DOWN + toC Key'Home = c'GLFW_KEY_HOME + toC Key'End = c'GLFW_KEY_END + toC Key'CapsLock = c'GLFW_KEY_CAPS_LOCK + toC Key'ScrollLock = c'GLFW_KEY_SCROLL_LOCK + toC Key'NumLock = c'GLFW_KEY_NUM_LOCK + toC Key'PrintScreen = c'GLFW_KEY_PRINT_SCREEN + toC Key'Pause = c'GLFW_KEY_PAUSE + toC Key'F1 = c'GLFW_KEY_F1 + toC Key'F2 = c'GLFW_KEY_F2 + toC Key'F3 = c'GLFW_KEY_F3 + toC Key'F4 = c'GLFW_KEY_F4 + toC Key'F5 = c'GLFW_KEY_F5 + toC Key'F6 = c'GLFW_KEY_F6 + toC Key'F7 = c'GLFW_KEY_F7 + toC Key'F8 = c'GLFW_KEY_F8 + toC Key'F9 = c'GLFW_KEY_F9 + toC Key'F10 = c'GLFW_KEY_F10 + toC Key'F11 = c'GLFW_KEY_F11 + toC Key'F12 = c'GLFW_KEY_F12 + toC Key'F13 = c'GLFW_KEY_F13 + toC Key'F14 = c'GLFW_KEY_F14 + toC Key'F15 = c'GLFW_KEY_F15 + toC Key'F16 = c'GLFW_KEY_F16 + toC Key'F17 = c'GLFW_KEY_F17 + toC Key'F18 = c'GLFW_KEY_F18 + toC Key'F19 = c'GLFW_KEY_F19 + toC Key'F20 = c'GLFW_KEY_F20 + toC Key'F21 = c'GLFW_KEY_F21 + toC Key'F22 = c'GLFW_KEY_F22 + toC Key'F23 = c'GLFW_KEY_F23 + toC Key'F24 = c'GLFW_KEY_F24 + toC Key'F25 = c'GLFW_KEY_F25 + toC Key'Pad0 = c'GLFW_KEY_KP_0 + toC Key'Pad1 = c'GLFW_KEY_KP_1 + toC Key'Pad2 = c'GLFW_KEY_KP_2 + toC Key'Pad3 = c'GLFW_KEY_KP_3 + toC Key'Pad4 = c'GLFW_KEY_KP_4 + toC Key'Pad5 = c'GLFW_KEY_KP_5 + toC Key'Pad6 = c'GLFW_KEY_KP_6 + toC Key'Pad7 = c'GLFW_KEY_KP_7 + toC Key'Pad8 = c'GLFW_KEY_KP_8 + toC Key'Pad9 = c'GLFW_KEY_KP_9 + toC Key'PadDecimal = c'GLFW_KEY_KP_DECIMAL + toC Key'PadDivide = c'GLFW_KEY_KP_DIVIDE + toC Key'PadMultiply = c'GLFW_KEY_KP_MULTIPLY + toC Key'PadSubtract = c'GLFW_KEY_KP_SUBTRACT + toC Key'PadAdd = c'GLFW_KEY_KP_ADD + toC Key'PadEnter = c'GLFW_KEY_KP_ENTER + toC Key'PadEqual = c'GLFW_KEY_KP_EQUAL + toC Key'LeftShift = c'GLFW_KEY_LEFT_SHIFT + toC Key'LeftControl = c'GLFW_KEY_LEFT_CONTROL + toC Key'LeftAlt = c'GLFW_KEY_LEFT_ALT + toC Key'LeftSuper = c'GLFW_KEY_LEFT_SUPER + toC Key'RightShift = c'GLFW_KEY_RIGHT_SHIFT + toC Key'RightControl = c'GLFW_KEY_RIGHT_CONTROL + toC Key'RightAlt = c'GLFW_KEY_RIGHT_ALT + toC Key'RightSuper = c'GLFW_KEY_RIGHT_SUPER + toC Key'Menu = c'GLFW_KEY_MENU + +instance C CInt KeyState where + fromC v + | v == c'GLFW_PRESS = KeyState'Pressed + | v == c'GLFW_RELEASE = KeyState'Released + | v == c'GLFW_REPEAT = KeyState'Repeating + | otherwise = error $ "C CInt KeyState fromC: " ++ show v + toC KeyState'Pressed = c'GLFW_PRESS + toC KeyState'Released = c'GLFW_RELEASE + toC KeyState'Repeating = c'GLFW_REPEAT + +instance C CInt Joystick where + fromC v + | v == c'GLFW_JOYSTICK_1 = Joystick'1 + | v == c'GLFW_JOYSTICK_2 = Joystick'2 + | v == c'GLFW_JOYSTICK_3 = Joystick'3 + | v == c'GLFW_JOYSTICK_4 = Joystick'4 + | v == c'GLFW_JOYSTICK_5 = Joystick'5 + | v == c'GLFW_JOYSTICK_6 = Joystick'6 + | v == c'GLFW_JOYSTICK_7 = Joystick'7 + | v == c'GLFW_JOYSTICK_8 = Joystick'8 + | v == c'GLFW_JOYSTICK_9 = Joystick'9 + | v == c'GLFW_JOYSTICK_10 = Joystick'10 + | v == c'GLFW_JOYSTICK_11 = Joystick'11 + | v == c'GLFW_JOYSTICK_12 = Joystick'12 + | v == c'GLFW_JOYSTICK_13 = Joystick'13 + | v == c'GLFW_JOYSTICK_14 = Joystick'14 + | v == c'GLFW_JOYSTICK_15 = Joystick'15 + | v == c'GLFW_JOYSTICK_16 = Joystick'16 + | otherwise = error $ "C CInt Joystick fromC: " ++ show v + toC Joystick'1 = c'GLFW_JOYSTICK_1 + toC Joystick'2 = c'GLFW_JOYSTICK_2 + toC Joystick'3 = c'GLFW_JOYSTICK_3 + toC Joystick'4 = c'GLFW_JOYSTICK_4 + toC Joystick'5 = c'GLFW_JOYSTICK_5 + toC Joystick'6 = c'GLFW_JOYSTICK_6 + toC Joystick'7 = c'GLFW_JOYSTICK_7 + toC Joystick'8 = c'GLFW_JOYSTICK_8 + toC Joystick'9 = c'GLFW_JOYSTICK_9 + toC Joystick'10 = c'GLFW_JOYSTICK_10 + toC Joystick'11 = c'GLFW_JOYSTICK_11 + toC Joystick'12 = c'GLFW_JOYSTICK_12 + toC Joystick'13 = c'GLFW_JOYSTICK_13 + toC Joystick'14 = c'GLFW_JOYSTICK_14 + toC Joystick'15 = c'GLFW_JOYSTICK_15 + toC Joystick'16 = c'GLFW_JOYSTICK_16 + +instance C CUChar JoystickButtonState where + fromC v + | v == c'GLFW_PRESS = JoystickButtonState'Pressed + | v == c'GLFW_RELEASE = JoystickButtonState'Released + | otherwise = error $ "C CUChar JoystickButtonState fromC: " ++ show v + toC JoystickButtonState'Pressed = c'GLFW_PRESS + toC JoystickButtonState'Released = c'GLFW_RELEASE + +instance C CInt JoystickState where + fromC v + | v == c'GLFW_CONNECTED = JoystickState'Connected + | v == c'GLFW_DISCONNECTED = JoystickState'Disconnected + | otherwise = error $ "C CInt JoystickState fromC: " ++ show v + toC JoystickState'Connected = c'GLFW_CONNECTED + toC JoystickState'Disconnected = c'GLFW_DISCONNECTED + +instance C CInt MouseButton where + fromC v + | v == c'GLFW_MOUSE_BUTTON_1 = MouseButton'1 + | v == c'GLFW_MOUSE_BUTTON_2 = MouseButton'2 + | v == c'GLFW_MOUSE_BUTTON_3 = MouseButton'3 + | v == c'GLFW_MOUSE_BUTTON_4 = MouseButton'4 + | v == c'GLFW_MOUSE_BUTTON_5 = MouseButton'5 + | v == c'GLFW_MOUSE_BUTTON_6 = MouseButton'6 + | v == c'GLFW_MOUSE_BUTTON_7 = MouseButton'7 + | v == c'GLFW_MOUSE_BUTTON_8 = MouseButton'8 + | otherwise = error $ "C CInt MouseButton fromC: " ++ show v + toC MouseButton'1 = c'GLFW_MOUSE_BUTTON_1 + toC MouseButton'2 = c'GLFW_MOUSE_BUTTON_2 + toC MouseButton'3 = c'GLFW_MOUSE_BUTTON_3 + toC MouseButton'4 = c'GLFW_MOUSE_BUTTON_4 + toC MouseButton'5 = c'GLFW_MOUSE_BUTTON_5 + toC MouseButton'6 = c'GLFW_MOUSE_BUTTON_6 + toC MouseButton'7 = c'GLFW_MOUSE_BUTTON_7 + toC MouseButton'8 = c'GLFW_MOUSE_BUTTON_8 + +instance C CInt MouseButtonState where + fromC v + | v == c'GLFW_PRESS = MouseButtonState'Pressed + | v == c'GLFW_RELEASE = MouseButtonState'Released + | otherwise = error $ "C CInt MouseButtonState fromC: " ++ show v + toC MouseButtonState'Pressed = c'GLFW_PRESS + toC MouseButtonState'Released = c'GLFW_RELEASE + +instance C CInt CursorState where + fromC v + | v == c'GLFW_TRUE = CursorState'InWindow + | v == c'GLFW_FALSE = CursorState'NotInWindow + | otherwise = error $ "C CInt CursorState fromC: " ++ show v + toC CursorState'InWindow = c'GLFW_TRUE + toC CursorState'NotInWindow = c'GLFW_FALSE + +instance C CInt CursorInputMode where + fromC v + | v == c'GLFW_CURSOR_NORMAL = CursorInputMode'Normal + | v == c'GLFW_CURSOR_HIDDEN = CursorInputMode'Hidden + | v == c'GLFW_CURSOR_DISABLED = CursorInputMode'Disabled + | otherwise = error $ "C CInt CursorInputMode fromC: " ++ show v + toC CursorInputMode'Normal = c'GLFW_CURSOR_NORMAL + toC CursorInputMode'Hidden = c'GLFW_CURSOR_HIDDEN + toC CursorInputMode'Disabled = c'GLFW_CURSOR_DISABLED + +instance C CInt StickyKeysInputMode where + fromC v + | v == c'GLFW_TRUE = StickyKeysInputMode'Enabled + | v == c'GLFW_FALSE = StickyKeysInputMode'Disabled + | otherwise = error $ "C CInt StickyKeysInputMode fromC: " ++ show v + toC StickyKeysInputMode'Enabled = c'GLFW_TRUE + toC StickyKeysInputMode'Disabled = c'GLFW_FALSE + +instance C CInt StickyMouseButtonsInputMode where + fromC v + | v == c'GLFW_TRUE = StickyMouseButtonsInputMode'Enabled + | v == c'GLFW_FALSE = StickyMouseButtonsInputMode'Disabled + | otherwise = error $ "C CInt StickyMouseButtonsInputMode fromC: " ++ show v + toC StickyMouseButtonsInputMode'Enabled = c'GLFW_TRUE + toC StickyMouseButtonsInputMode'Disabled = c'GLFW_FALSE + +-------------------------------------------------------------------------------- + {-# ANN module "HLint: ignore Use camelCase" #-}
Graphics/UI/GLFW/Types.hs view
@@ -1,530 +1,530 @@-{-# LANGUAGE DeriveDataTypeable #-}-{-# LANGUAGE DeriveGeneric #-}-{-# LANGUAGE StandaloneDeriving #-}-{-# OPTIONS_GHC -fno-warn-orphans #-}---- | The types of the package. This module is considered "internal", and the--- types are re-exported from Graphics.UI.GLFW as necessary.-module Graphics.UI.GLFW.Types where------------------------------------------------------------------------------------import Control.DeepSeq (NFData)-import Data.Data (Data)-import Data.IORef (IORef)-import Data.Typeable (Typeable)-import Data.Word (Word8)-import Foreign.Ptr (Ptr)-import Foreign.C.Types (CUChar(..))-import GHC.Generics--import Bindings.GLFW------------------------------------------------------------------------------------- Error handling---- | An enum for one of the <http://www.glfw.org/docs/3.2/group__errors.html#ga196e125ef261d94184e2b55c05762f14 GLFW error codes>.-data Error =- Error'NotInitialized -- ^ <http://www.glfw.org/docs/3.2/group__errors.html#ga2374ee02c177f12e1fa76ff3ed15e14a doc>- | Error'NoCurrentContext -- ^ <http://www.glfw.org/docs/3.2/group__errors.html#gaa8290386e9528ccb9e42a3a4e16fc0d0 doc>- | Error'InvalidEnum -- ^ <http://www.glfw.org/docs/3.2/group__errors.html#ga76f6bb9c4eea73db675f096b404593ce doc>- | Error'InvalidValue -- ^ <http://www.glfw.org/docs/3.2/group__errors.html#gaaf2ef9aa8202c2b82ac2d921e554c687 doc>- | Error'OutOfMemory -- ^ <http://www.glfw.org/docs/3.2/group__errors.html#ga9023953a2bcb98c2906afd071d21ee7f doc>- | Error'ApiUnavailable -- ^ <http://www.glfw.org/docs/3.2/group__errors.html#ga56882b290db23261cc6c053c40c2d08e doc>- | Error'VersionUnavailable -- ^ <http://www.glfw.org/docs/3.2/group__errors.html#gad16c5565b4a69f9c2a9ac2c0dbc89462 doc>- | Error'PlatformError -- ^ <http://www.glfw.org/docs/3.2/group__errors.html#gad44162d78100ea5e87cdd38426b8c7a1 doc>- | Error'FormatUnavailable -- ^ <http://www.glfw.org/docs/3.2/group__errors.html#ga196e125ef261d94184e2b55c05762f14 doc>- deriving (Bounded, Data, Enum, Eq, Ord, Read, Show, Typeable, Generic)--instance NFData Error------------------------------------------------------------------------------------- Initialization and version information---- | The library version of the GLFW implementation in use.--- See <http://www.glfw.org/docs/3.2/intro.html#intro_version Version Management>-data Version = Version- { versionMajor :: Int- , versionMinor :: Int- , versionRevision :: Int- } deriving (Data, Eq, Ord, Read, Show, Typeable, Generic)--instance NFData Version------------------------------------------------------------------------------------- Monitor handling---- | Represents a physical monitor that's currently connected.--- See the <http://www.glfw.org/docs/3.2/monitor.html Monitor Guide>-newtype Monitor = Monitor- { unMonitor :: Ptr C'GLFWmonitor- } deriving (Data, Eq, Ord, Show, Typeable, Generic)---- | Part of the 'MonitorCallback', for when a monitor gets connected or disconnected.-data MonitorState =- MonitorState'Connected- | MonitorState'Disconnected- deriving (Data, Eq, Ord, Read, Show, Typeable, Generic)--instance NFData MonitorState---- | See <http://www.glfw.org/docs/3.2/monitor.html#monitor_modes Video Modes>-data VideoMode = VideoMode- { videoModeWidth :: Int- , videoModeHeight :: Int- , videoModeRedBits :: Int- , videoModeGreenBits :: Int- , videoModeBlueBits :: Int- , videoModeRefreshRate :: Int- } deriving (Data, Eq, Ord, Read, Show, Typeable, Generic)--instance NFData VideoMode---- | Lets you adjust the gamma of a monitor. To ensure that only valid values are created, use 'makeGammaRamp'.--- See <http://www.glfw.org/docs/3.2/monitor.html#monitor_gamma Gamma Ramp>.-data GammaRamp = GammaRamp- -- NOTE: It would be bad to give clients a way to construct invalid gamma ramps- -- with lists of unequal length, so this constructor should not be exported.- { gammaRampRed :: [Int]- , gammaRampGreen :: [Int]- , gammaRampBlue :: [Int]- } deriving (Data, Eq, Ord, Read, Show, Typeable, Generic)--instance NFData GammaRamp---- | Smart constructor for a 'GammaRamp'.-makeGammaRamp :: [Int] -> [Int] -> [Int] -> Maybe GammaRamp-makeGammaRamp rs gs bs- | lengthsEqual = Just $ GammaRamp rs gs bs- | otherwise = Nothing- where- lengthsEqual =- let rsl = length rs- gsl = length gs- bsl = length bs- in rsl == gsl && gsl == bsl------------------------------------------------------------------------------------- Window handling---- | Collects all the callbacks that can be associated with a Window into a single place.-data WindowCallbacks = WindowCallbacks- { storedCharFun :: IORef C'GLFWcharfun- , storedCharModsFun :: IORef C'GLFWcharmodsfun- , storedCursorEnterFun :: IORef C'GLFWcursorenterfun- , storedCursorPosFun :: IORef C'GLFWcursorposfun- , storedFramebufferSizeFun :: IORef C'GLFWframebuffersizefun- , storedKeyFun :: IORef C'GLFWkeyfun- , storedMouseButtonFun :: IORef C'GLFWmousebuttonfun- , storedScrollFun :: IORef C'GLFWscrollfun- , storedWindowCloseFun :: IORef C'GLFWwindowclosefun- , storedWindowFocusFun :: IORef C'GLFWwindowfocusfun- , storedWindowIconifyFun :: IORef C'GLFWwindowiconifyfun- , storedWindowPosFun :: IORef C'GLFWwindowposfun- , storedWindowRefreshFun :: IORef C'GLFWwindowrefreshfun- , storedWindowSizeFun :: IORef C'GLFWwindowsizefun- , storedDropFun :: IORef C'GLFWdropfun- }---- | Reprisents a GLFW window value.--- See the <http://www.glfw.org/docs/3.2/window.html Window Guide>-newtype Window = Window- { unWindow :: Ptr C'GLFWwindow- } deriving (Data, Eq, Ord, Show, Typeable, Generic)---- | Lets you set various window hints before creating a 'Window'.--- See <http://www.glfw.org/docs/3.2/window.html#window_hints Window Hints>,--- particularly <http://www.glfw.org/docs/3.2/window.html#window_hints_values Supported and Default Values>.-data WindowHint =- WindowHint'Resizable Bool- | WindowHint'Visible Bool- | WindowHint'Decorated Bool- | WindowHint'RedBits (Maybe Int)- | WindowHint'GreenBits (Maybe Int)- | WindowHint'BlueBits (Maybe Int)- | WindowHint'AlphaBits (Maybe Int)- | WindowHint'DepthBits (Maybe Int)- | WindowHint'StencilBits (Maybe Int)- | WindowHint'AccumRedBits (Maybe Int)- | WindowHint'AccumGreenBits (Maybe Int)- | WindowHint'AccumBlueBits (Maybe Int)- | WindowHint'AccumAlphaBits (Maybe Int)- | WindowHint'AuxBuffers (Maybe Int)- | WindowHint'Samples (Maybe Int)- | WindowHint'RefreshRate (Maybe Int)- | WindowHint'DoubleBuffer Bool- | WindowHint'Stereo Bool- | WindowHint'sRGBCapable Bool- | WindowHint'Floating Bool- | WindowHint'Focused Bool- | WindowHint'Maximized Bool- | WindowHint'AutoIconify Bool- | WindowHint'ClientAPI ClientAPI- | WindowHint'ContextCreationAPI ContextCreationAPI- | WindowHint'ContextVersionMajor Int- | WindowHint'ContextVersionMinor Int- | WindowHint'ContextRobustness ContextRobustness- | WindowHint'ContextReleaseBehavior ContextReleaseBehavior- | WindowHint'ContextNoError Bool- | WindowHint'OpenGLForwardCompat Bool- | WindowHint'OpenGLDebugContext Bool- | WindowHint'OpenGLProfile OpenGLProfile- deriving (Data, Eq, Ord, Read, Show, Typeable, Generic)--instance NFData WindowHint---- | The OpenGL robustness strategy.-data ContextRobustness =- ContextRobustness'NoRobustness- | ContextRobustness'NoResetNotification- | ContextRobustness'LoseContextOnReset- deriving (Bounded, Data, Enum, Eq, Ord, Read, Show, Typeable, Generic)--instance NFData ContextRobustness---- | The OpenGL profile.-data OpenGLProfile =- OpenGLProfile'Any- | OpenGLProfile'Compat- | OpenGLProfile'Core- deriving (Bounded, Data, Enum, Eq, Ord, Read, Show, Typeable, Generic)--instance NFData OpenGLProfile---- | The type of OpenGL to create a context for.-data ClientAPI =- ClientAPI'NoAPI- | ClientAPI'OpenGL- | ClientAPI'OpenGLES- deriving (Bounded, Data, Enum, Eq, Ord, Read, Show, Typeable, Generic)--instance NFData ClientAPI---- | The type of API to use for context creation.--- See the <http://www.glfw.org/docs/latest/window_guide.html Window Guide> for--- more information.------ This is a hard constraint. If no client API is requested, this hint is--- ignored. Best practice is to stick to one API or the other, otherwise may--- segfault on Linux. OS X does not support the EGL API and will fail if this--- hint is used.-data ContextCreationAPI- = ContextCreationAPI'Native- | ContextCreationAPI'EGL- deriving (Bounded, Data, Enum, Eq, Ord, Read, Show, Typeable, Generic)--instance NFData ContextCreationAPI---- | The context release behavior.--- See the <http://www.glfw.org/docs/latest/window_guide.html Window Guide> for--- more information.------ Context release behaviors are described in detail by the--- <https://www.khronos.org/registry/OpenGL/extensions/KHR/KHR_context_flush_control.txt KHR_context_flush_control>--- extension.-data ContextReleaseBehavior- = ContextReleaseBehavior'Any- | ContextReleaseBehavior'None- | ContextReleaseBehavior'Flush- deriving (Bounded, Data, Enum, Eq, Ord, Read, Show, Typeable, Generic)--instance NFData ContextReleaseBehavior------------------------------------------------------------------------------------- Input handling---- | Part of the <http://www.glfw.org/docs/3.2/input.html#input_keyboard Keyboard Input> system.-data Key =- Key'Unknown- | Key'Space- | Key'Apostrophe- | Key'Comma- | Key'Minus- | Key'Period- | Key'Slash- | Key'0- | Key'1- | Key'2- | Key'3- | Key'4- | Key'5- | Key'6- | Key'7- | Key'8- | Key'9- | Key'Semicolon- | Key'Equal- | Key'A- | Key'B- | Key'C- | Key'D- | Key'E- | Key'F- | Key'G- | Key'H- | Key'I- | Key'J- | Key'K- | Key'L- | Key'M- | Key'N- | Key'O- | Key'P- | Key'Q- | Key'R- | Key'S- | Key'T- | Key'U- | Key'V- | Key'W- | Key'X- | Key'Y- | Key'Z- | Key'LeftBracket- | Key'Backslash- | Key'RightBracket- | Key'GraveAccent- | Key'World1- | Key'World2- | Key'Escape- | Key'Enter- | Key'Tab- | Key'Backspace- | Key'Insert- | Key'Delete- | Key'Right- | Key'Left- | Key'Down- | Key'Up- | Key'PageUp- | Key'PageDown- | Key'Home- | Key'End- | Key'CapsLock- | Key'ScrollLock- | Key'NumLock- | Key'PrintScreen- | Key'Pause- | Key'F1- | Key'F2- | Key'F3- | Key'F4- | Key'F5- | Key'F6- | Key'F7- | Key'F8- | Key'F9- | Key'F10- | Key'F11- | Key'F12- | Key'F13- | Key'F14- | Key'F15- | Key'F16- | Key'F17- | Key'F18- | Key'F19- | Key'F20- | Key'F21- | Key'F22- | Key'F23- | Key'F24- | Key'F25- | Key'Pad0- | Key'Pad1- | Key'Pad2- | Key'Pad3- | Key'Pad4- | Key'Pad5- | Key'Pad6- | Key'Pad7- | Key'Pad8- | Key'Pad9- | Key'PadDecimal- | Key'PadDivide- | Key'PadMultiply- | Key'PadSubtract- | Key'PadAdd- | Key'PadEnter- | Key'PadEqual- | Key'LeftShift- | Key'LeftControl- | Key'LeftAlt- | Key'LeftSuper- | Key'RightShift- | Key'RightControl- | Key'RightAlt- | Key'RightSuper- | Key'Menu- deriving (Bounded, Data, Enum, Eq, Ord, Read, Show, Typeable, Generic)--instance NFData Key---- | The state of an individual key when 'getKey' is called.-data KeyState =- KeyState'Pressed- | KeyState'Released- | KeyState'Repeating- deriving (Bounded, Data, Enum, Eq, Ord, Read, Show, Typeable, Generic)--instance NFData KeyState---- | For use with the <http://www.glfw.org/docs/3.2/input.html#joystick Joystick Input> system.-data Joystick =- Joystick'1- | Joystick'2- | Joystick'3- | Joystick'4- | Joystick'5- | Joystick'6- | Joystick'7- | Joystick'8- | Joystick'9- | Joystick'10- | Joystick'11- | Joystick'12- | Joystick'13- | Joystick'14- | Joystick'15- | Joystick'16- deriving (Bounded, Data, Enum, Eq, Ord, Read, Show, Typeable, Generic)--instance NFData Joystick---- | If a given joystick button is pressed or not when 'getJoystickButtons' is called.-data JoystickButtonState =- JoystickButtonState'Pressed- | JoystickButtonState'Released- deriving (Bounded, Data, Enum, Eq, Ord, Read, Show, Typeable, Generic)--instance NFData JoystickButtonState---- | Part of the 'JoystickCallback', for when a monitor gets connected or disconnected.-data JoystickState- = JoystickState'Connected- | JoystickState'Disconnected- deriving (Bounded, Data, Enum, Eq, Ord, Read, Show, Typeable, Generic)--instance NFData JoystickState---- | Part of the <http://www.glfw.org/docs/3.2/input.html#input_mouse Mouse Input> system.-data MouseButton =- MouseButton'1- | MouseButton'2- | MouseButton'3- | MouseButton'4- | MouseButton'5- | MouseButton'6- | MouseButton'7- | MouseButton'8- deriving (Bounded, Data, Enum, Eq, Ord, Read, Show, Typeable, Generic)--instance NFData MouseButton---- | If the mouse button is pressed or not when 'getMouseButton' is called.-data MouseButtonState =- MouseButtonState'Pressed- | MouseButtonState'Released- deriving (Bounded, Data, Enum, Eq, Ord, Read, Show, Typeable, Generic)--instance NFData MouseButtonState---- | If the mouse's cursor is in the window or not.-data CursorState =- CursorState'InWindow- | CursorState'NotInWindow- deriving (Bounded, Data, Enum, Eq, Ord, Read, Show, Typeable, Generic)--instance NFData CursorState---- | Allows for special forms of mouse input.--- See <http://www.glfw.org/docs/3.2/input.html#cursor_mode Cursor Modes>-data CursorInputMode =- CursorInputMode'Normal- | CursorInputMode'Hidden- | CursorInputMode'Disabled- deriving (Bounded, Data, Enum, Eq, Ord, Read, Show, Typeable, Generic)--instance NFData CursorInputMode---- | When sticky keys is enabled, once a key is pressed it will remain pressed--- at least until the state is polled with 'getKey'. After that, if the key has--- been released it will switch back to released. This helps prevent problems--- with low-resolution polling missing key pressed. Note that use of the--- callbacks to avoid this problem the the recommended route, and this is just--- for a fallback.-data StickyKeysInputMode =- StickyKeysInputMode'Enabled- | StickyKeysInputMode'Disabled- deriving (Bounded, Data, Enum, Eq, Ord, Read, Show, Typeable, Generic)--instance NFData StickyKeysInputMode---- | This is the mouse version of "StickyKeysInputMode".-data StickyMouseButtonsInputMode =- StickyMouseButtonsInputMode'Enabled- | StickyMouseButtonsInputMode'Disabled- deriving (Bounded, Data, Enum, Eq, Ord, Read, Show, Typeable, Generic)--instance NFData StickyMouseButtonsInputMode---- | Modifier keys that were pressed as part of another keypress event.-data ModifierKeys = ModifierKeys- { modifierKeysShift :: Bool- , modifierKeysControl :: Bool- , modifierKeysAlt :: Bool- , modifierKeysSuper :: Bool- } deriving (Data, Eq, Ord, Read, Show, Typeable, Generic)--instance NFData ModifierKeys------------------------------------------------------------------------------------- 3.1 Additions-----------------------------------------------------------------------------------deriving instance Data CUChar---- | GLFW image data, for setting up custom mouse cursor appearnaces.-data Image = Image- { imageWidth :: Int- , imageHeight :: Int- , imagePixels :: [CUChar]- } deriving (Data, Eq, Ord, Read, Show, Typeable, Generic)---- | Create an image given the function to generate 8-bit RGBA values based on--- the pixel location.-mkImage :: Int -> Int -> (Int -> Int -> (Word8, Word8, Word8, Word8)) -> Image-mkImage width height gen = Image- { imageWidth = width- , imageHeight = height- , imagePixels = [ CUChar channel | y <- [0..(height - 1)]- , x <- [0..(width - 1)]- , (r, g, b, a) <- [gen x y]- , channel <- [r, g, b, a]- ]- }--instance NFData Image---- | Reprisents a GLFW cursor.-newtype Cursor = Cursor- { unCursor :: Ptr C'GLFWcursor- } deriving (Data, Eq, Ord, Show, Typeable, Generic)---- | Lets you use one of the standard cursor appearnaces that the local--- system theme provides for.--- See <http://www.glfw.org/docs/3.2/input.html#cursor_standard Standard Cursor Creation>.-data StandardCursorShape =- StandardCursorShape'Arrow- | StandardCursorShape'IBeam- | StandardCursorShape'Crosshair- | StandardCursorShape'Hand- | StandardCursorShape'HResize- | StandardCursorShape'VResize- deriving (Bounded, Data, Enum, Eq, Ord, Read, Show, Typeable, Generic)--instance NFData StandardCursorShape------------------------------------------------------------------------------------{-# ANN module "HLint: ignore Use camelCase" #-}+{-# LANGUAGE DeriveDataTypeable #-} +{-# LANGUAGE DeriveGeneric #-} +{-# LANGUAGE StandaloneDeriving #-} +{-# OPTIONS_GHC -fno-warn-orphans #-} + +-- | The types of the package. This module is considered "internal", and the +-- types are re-exported from Graphics.UI.GLFW as necessary. +module Graphics.UI.GLFW.Types where + +-------------------------------------------------------------------------------- + +import Control.DeepSeq (NFData) +import Data.Data (Data) +import Data.IORef (IORef) +import Data.Typeable (Typeable) +import Data.Word (Word8) +import Foreign.Ptr (Ptr) +import Foreign.C.Types (CUChar(..)) +import GHC.Generics + +import Bindings.GLFW + +-------------------------------------------------------------------------------- +-- Error handling + +-- | An enum for one of the <http://www.glfw.org/docs/3.2/group__errors.html#ga196e125ef261d94184e2b55c05762f14 GLFW error codes>. +data Error = + Error'NotInitialized -- ^ <http://www.glfw.org/docs/3.2/group__errors.html#ga2374ee02c177f12e1fa76ff3ed15e14a doc> + | Error'NoCurrentContext -- ^ <http://www.glfw.org/docs/3.2/group__errors.html#gaa8290386e9528ccb9e42a3a4e16fc0d0 doc> + | Error'InvalidEnum -- ^ <http://www.glfw.org/docs/3.2/group__errors.html#ga76f6bb9c4eea73db675f096b404593ce doc> + | Error'InvalidValue -- ^ <http://www.glfw.org/docs/3.2/group__errors.html#gaaf2ef9aa8202c2b82ac2d921e554c687 doc> + | Error'OutOfMemory -- ^ <http://www.glfw.org/docs/3.2/group__errors.html#ga9023953a2bcb98c2906afd071d21ee7f doc> + | Error'ApiUnavailable -- ^ <http://www.glfw.org/docs/3.2/group__errors.html#ga56882b290db23261cc6c053c40c2d08e doc> + | Error'VersionUnavailable -- ^ <http://www.glfw.org/docs/3.2/group__errors.html#gad16c5565b4a69f9c2a9ac2c0dbc89462 doc> + | Error'PlatformError -- ^ <http://www.glfw.org/docs/3.2/group__errors.html#gad44162d78100ea5e87cdd38426b8c7a1 doc> + | Error'FormatUnavailable -- ^ <http://www.glfw.org/docs/3.2/group__errors.html#ga196e125ef261d94184e2b55c05762f14 doc> + deriving (Bounded, Data, Enum, Eq, Ord, Read, Show, Typeable, Generic) + +instance NFData Error + +-------------------------------------------------------------------------------- +-- Initialization and version information + +-- | The library version of the GLFW implementation in use. +-- See <http://www.glfw.org/docs/3.2/intro.html#intro_version Version Management> +data Version = Version + { versionMajor :: {-# UNPACK #-} !Int + , versionMinor :: {-# UNPACK #-} !Int + , versionRevision :: {-# UNPACK #-} !Int + } deriving (Data, Eq, Ord, Read, Show, Typeable, Generic) + +instance NFData Version + +-------------------------------------------------------------------------------- +-- Monitor handling + +-- | Represents a physical monitor that's currently connected. +-- See the <http://www.glfw.org/docs/3.2/monitor.html Monitor Guide> +newtype Monitor = Monitor + { unMonitor :: Ptr C'GLFWmonitor + } deriving (Data, Eq, Ord, Show, Typeable, Generic) + +-- | Part of the 'MonitorCallback', for when a monitor gets connected or disconnected. +data MonitorState = + MonitorState'Connected + | MonitorState'Disconnected + deriving (Data, Eq, Ord, Read, Show, Typeable, Generic) + +instance NFData MonitorState + +-- | See <http://www.glfw.org/docs/3.2/monitor.html#monitor_modes Video Modes> +data VideoMode = VideoMode + { videoModeWidth :: {-# UNPACK #-} !Int + , videoModeHeight :: {-# UNPACK #-} !Int + , videoModeRedBits :: {-# UNPACK #-} !Int + , videoModeGreenBits :: {-# UNPACK #-} !Int + , videoModeBlueBits :: {-# UNPACK #-} !Int + , videoModeRefreshRate :: {-# UNPACK #-} !Int + } deriving (Data, Eq, Ord, Read, Show, Typeable, Generic) + +instance NFData VideoMode + +-- | Lets you adjust the gamma of a monitor. To ensure that only valid values are created, use 'makeGammaRamp'. +-- See <http://www.glfw.org/docs/3.2/monitor.html#monitor_gamma Gamma Ramp>. +data GammaRamp = GammaRamp + -- NOTE: It would be bad to give clients a way to construct invalid gamma ramps + -- with lists of unequal length, so this constructor should not be exported. + { gammaRampRed :: [Int] + , gammaRampGreen :: [Int] + , gammaRampBlue :: [Int] + } deriving (Data, Eq, Ord, Read, Show, Typeable, Generic) + +instance NFData GammaRamp + +-- | Smart constructor for a 'GammaRamp'. +makeGammaRamp :: [Int] -> [Int] -> [Int] -> Maybe GammaRamp +makeGammaRamp rs gs bs + | lengthsEqual = Just $ GammaRamp rs gs bs + | otherwise = Nothing + where + lengthsEqual = + let rsl = length rs + gsl = length gs + bsl = length bs + in rsl == gsl && gsl == bsl + +-------------------------------------------------------------------------------- +-- Window handling + +-- | Collects all the callbacks that can be associated with a Window into a single place. +data WindowCallbacks = WindowCallbacks + { storedCharFun :: !(IORef C'GLFWcharfun) + , storedCharModsFun :: !(IORef C'GLFWcharmodsfun) + , storedCursorEnterFun :: !(IORef C'GLFWcursorenterfun) + , storedCursorPosFun :: !(IORef C'GLFWcursorposfun) + , storedFramebufferSizeFun :: !(IORef C'GLFWframebuffersizefun) + , storedKeyFun :: !(IORef C'GLFWkeyfun) + , storedMouseButtonFun :: !(IORef C'GLFWmousebuttonfun) + , storedScrollFun :: !(IORef C'GLFWscrollfun) + , storedWindowCloseFun :: !(IORef C'GLFWwindowclosefun) + , storedWindowFocusFun :: !(IORef C'GLFWwindowfocusfun) + , storedWindowIconifyFun :: !(IORef C'GLFWwindowiconifyfun) + , storedWindowPosFun :: !(IORef C'GLFWwindowposfun) + , storedWindowRefreshFun :: !(IORef C'GLFWwindowrefreshfun) + , storedWindowSizeFun :: !(IORef C'GLFWwindowsizefun) + , storedDropFun :: !(IORef C'GLFWdropfun) + } + +-- | Reprisents a GLFW window value. +-- See the <http://www.glfw.org/docs/3.2/window.html Window Guide> +newtype Window = Window + { unWindow :: Ptr C'GLFWwindow + } deriving (Data, Eq, Ord, Show, Typeable, Generic) + +-- | Lets you set various window hints before creating a 'Window'. +-- See <http://www.glfw.org/docs/3.2/window.html#window_hints Window Hints>, +-- particularly <http://www.glfw.org/docs/3.2/window.html#window_hints_values Supported and Default Values>. +data WindowHint = + WindowHint'Resizable !Bool + | WindowHint'Visible !Bool + | WindowHint'Decorated !Bool + | WindowHint'RedBits !(Maybe Int) + | WindowHint'GreenBits !(Maybe Int) + | WindowHint'BlueBits !(Maybe Int) + | WindowHint'AlphaBits !(Maybe Int) + | WindowHint'DepthBits !(Maybe Int) + | WindowHint'StencilBits !(Maybe Int) + | WindowHint'AccumRedBits !(Maybe Int) + | WindowHint'AccumGreenBits !(Maybe Int) + | WindowHint'AccumBlueBits !(Maybe Int) + | WindowHint'AccumAlphaBits !(Maybe Int) + | WindowHint'AuxBuffers !(Maybe Int) + | WindowHint'Samples !(Maybe Int) + | WindowHint'RefreshRate !(Maybe Int) + | WindowHint'DoubleBuffer !Bool + | WindowHint'Stereo !Bool + | WindowHint'sRGBCapable !Bool + | WindowHint'Floating !Bool + | WindowHint'Focused !Bool + | WindowHint'Maximized !Bool + | WindowHint'AutoIconify !Bool + | WindowHint'ClientAPI !ClientAPI + | WindowHint'ContextCreationAPI !ContextCreationAPI + | WindowHint'ContextVersionMajor {-# UNPACK #-} !Int + | WindowHint'ContextVersionMinor {-# UNPACK #-} !Int + | WindowHint'ContextRobustness !ContextRobustness + | WindowHint'ContextReleaseBehavior !ContextReleaseBehavior + | WindowHint'ContextNoError !Bool + | WindowHint'OpenGLForwardCompat !Bool + | WindowHint'OpenGLDebugContext !Bool + | WindowHint'OpenGLProfile !OpenGLProfile + deriving (Data, Eq, Ord, Read, Show, Typeable, Generic) + +instance NFData WindowHint + +-- | The OpenGL robustness strategy. +data ContextRobustness = + ContextRobustness'NoRobustness + | ContextRobustness'NoResetNotification + | ContextRobustness'LoseContextOnReset + deriving (Bounded, Data, Enum, Eq, Ord, Read, Show, Typeable, Generic) + +instance NFData ContextRobustness + +-- | The OpenGL profile. +data OpenGLProfile = + OpenGLProfile'Any + | OpenGLProfile'Compat + | OpenGLProfile'Core + deriving (Bounded, Data, Enum, Eq, Ord, Read, Show, Typeable, Generic) + +instance NFData OpenGLProfile + +-- | The type of OpenGL to create a context for. +data ClientAPI = + ClientAPI'NoAPI + | ClientAPI'OpenGL + | ClientAPI'OpenGLES + deriving (Bounded, Data, Enum, Eq, Ord, Read, Show, Typeable, Generic) + +instance NFData ClientAPI + +-- | The type of API to use for context creation. +-- See the <http://www.glfw.org/docs/latest/window_guide.html Window Guide> for +-- more information. +-- +-- This is a hard constraint. If no client API is requested, this hint is +-- ignored. Best practice is to stick to one API or the other, otherwise may +-- segfault on Linux. OS X does not support the EGL API and will fail if this +-- hint is used. +data ContextCreationAPI + = ContextCreationAPI'Native + | ContextCreationAPI'EGL + deriving (Bounded, Data, Enum, Eq, Ord, Read, Show, Typeable, Generic) + +instance NFData ContextCreationAPI + +-- | The context release behavior. +-- See the <http://www.glfw.org/docs/latest/window_guide.html Window Guide> for +-- more information. +-- +-- Context release behaviors are described in detail by the +-- <https://www.khronos.org/registry/OpenGL/extensions/KHR/KHR_context_flush_control.txt KHR_context_flush_control> +-- extension. +data ContextReleaseBehavior + = ContextReleaseBehavior'Any + | ContextReleaseBehavior'None + | ContextReleaseBehavior'Flush + deriving (Bounded, Data, Enum, Eq, Ord, Read, Show, Typeable, Generic) + +instance NFData ContextReleaseBehavior + +-------------------------------------------------------------------------------- +-- Input handling + +-- | Part of the <http://www.glfw.org/docs/3.2/input.html#input_keyboard Keyboard Input> system. +data Key = + Key'Unknown + | Key'Space + | Key'Apostrophe + | Key'Comma + | Key'Minus + | Key'Period + | Key'Slash + | Key'0 + | Key'1 + | Key'2 + | Key'3 + | Key'4 + | Key'5 + | Key'6 + | Key'7 + | Key'8 + | Key'9 + | Key'Semicolon + | Key'Equal + | Key'A + | Key'B + | Key'C + | Key'D + | Key'E + | Key'F + | Key'G + | Key'H + | Key'I + | Key'J + | Key'K + | Key'L + | Key'M + | Key'N + | Key'O + | Key'P + | Key'Q + | Key'R + | Key'S + | Key'T + | Key'U + | Key'V + | Key'W + | Key'X + | Key'Y + | Key'Z + | Key'LeftBracket + | Key'Backslash + | Key'RightBracket + | Key'GraveAccent + | Key'World1 + | Key'World2 + | Key'Escape + | Key'Enter + | Key'Tab + | Key'Backspace + | Key'Insert + | Key'Delete + | Key'Right + | Key'Left + | Key'Down + | Key'Up + | Key'PageUp + | Key'PageDown + | Key'Home + | Key'End + | Key'CapsLock + | Key'ScrollLock + | Key'NumLock + | Key'PrintScreen + | Key'Pause + | Key'F1 + | Key'F2 + | Key'F3 + | Key'F4 + | Key'F5 + | Key'F6 + | Key'F7 + | Key'F8 + | Key'F9 + | Key'F10 + | Key'F11 + | Key'F12 + | Key'F13 + | Key'F14 + | Key'F15 + | Key'F16 + | Key'F17 + | Key'F18 + | Key'F19 + | Key'F20 + | Key'F21 + | Key'F22 + | Key'F23 + | Key'F24 + | Key'F25 + | Key'Pad0 + | Key'Pad1 + | Key'Pad2 + | Key'Pad3 + | Key'Pad4 + | Key'Pad5 + | Key'Pad6 + | Key'Pad7 + | Key'Pad8 + | Key'Pad9 + | Key'PadDecimal + | Key'PadDivide + | Key'PadMultiply + | Key'PadSubtract + | Key'PadAdd + | Key'PadEnter + | Key'PadEqual + | Key'LeftShift + | Key'LeftControl + | Key'LeftAlt + | Key'LeftSuper + | Key'RightShift + | Key'RightControl + | Key'RightAlt + | Key'RightSuper + | Key'Menu + deriving (Bounded, Data, Enum, Eq, Ord, Read, Show, Typeable, Generic) + +instance NFData Key + +-- | The state of an individual key when 'getKey' is called. +data KeyState = + KeyState'Pressed + | KeyState'Released + | KeyState'Repeating + deriving (Bounded, Data, Enum, Eq, Ord, Read, Show, Typeable, Generic) + +instance NFData KeyState + +-- | For use with the <http://www.glfw.org/docs/3.2/input.html#joystick Joystick Input> system. +data Joystick = + Joystick'1 + | Joystick'2 + | Joystick'3 + | Joystick'4 + | Joystick'5 + | Joystick'6 + | Joystick'7 + | Joystick'8 + | Joystick'9 + | Joystick'10 + | Joystick'11 + | Joystick'12 + | Joystick'13 + | Joystick'14 + | Joystick'15 + | Joystick'16 + deriving (Bounded, Data, Enum, Eq, Ord, Read, Show, Typeable, Generic) + +instance NFData Joystick + +-- | If a given joystick button is pressed or not when 'getJoystickButtons' is called. +data JoystickButtonState = + JoystickButtonState'Pressed + | JoystickButtonState'Released + deriving (Bounded, Data, Enum, Eq, Ord, Read, Show, Typeable, Generic) + +instance NFData JoystickButtonState + +-- | Part of the 'JoystickCallback', for when a monitor gets connected or disconnected. +data JoystickState + = JoystickState'Connected + | JoystickState'Disconnected + deriving (Bounded, Data, Enum, Eq, Ord, Read, Show, Typeable, Generic) + +instance NFData JoystickState + +-- | Part of the <http://www.glfw.org/docs/3.2/input.html#input_mouse Mouse Input> system. +data MouseButton = + MouseButton'1 + | MouseButton'2 + | MouseButton'3 + | MouseButton'4 + | MouseButton'5 + | MouseButton'6 + | MouseButton'7 + | MouseButton'8 + deriving (Bounded, Data, Enum, Eq, Ord, Read, Show, Typeable, Generic) + +instance NFData MouseButton + +-- | If the mouse button is pressed or not when 'getMouseButton' is called. +data MouseButtonState = + MouseButtonState'Pressed + | MouseButtonState'Released + deriving (Bounded, Data, Enum, Eq, Ord, Read, Show, Typeable, Generic) + +instance NFData MouseButtonState + +-- | If the mouse's cursor is in the window or not. +data CursorState = + CursorState'InWindow + | CursorState'NotInWindow + deriving (Bounded, Data, Enum, Eq, Ord, Read, Show, Typeable, Generic) + +instance NFData CursorState + +-- | Allows for special forms of mouse input. +-- See <http://www.glfw.org/docs/3.2/input.html#cursor_mode Cursor Modes> +data CursorInputMode = + CursorInputMode'Normal + | CursorInputMode'Hidden + | CursorInputMode'Disabled + deriving (Bounded, Data, Enum, Eq, Ord, Read, Show, Typeable, Generic) + +instance NFData CursorInputMode + +-- | When sticky keys is enabled, once a key is pressed it will remain pressed +-- at least until the state is polled with 'getKey'. After that, if the key has +-- been released it will switch back to released. This helps prevent problems +-- with low-resolution polling missing key pressed. Note that use of the +-- callbacks to avoid this problem the the recommended route, and this is just +-- for a fallback. +data StickyKeysInputMode = + StickyKeysInputMode'Enabled + | StickyKeysInputMode'Disabled + deriving (Bounded, Data, Enum, Eq, Ord, Read, Show, Typeable, Generic) + +instance NFData StickyKeysInputMode + +-- | This is the mouse version of "StickyKeysInputMode". +data StickyMouseButtonsInputMode = + StickyMouseButtonsInputMode'Enabled + | StickyMouseButtonsInputMode'Disabled + deriving (Bounded, Data, Enum, Eq, Ord, Read, Show, Typeable, Generic) + +instance NFData StickyMouseButtonsInputMode + +-- | Modifier keys that were pressed as part of another keypress event. +data ModifierKeys = ModifierKeys + { modifierKeysShift :: !Bool + , modifierKeysControl :: !Bool + , modifierKeysAlt :: !Bool + , modifierKeysSuper :: !Bool + } deriving (Data, Eq, Ord, Read, Show, Typeable, Generic) + +instance NFData ModifierKeys + +-------------------------------------------------------------------------------- +-- 3.1 Additions +-------------------------------------------------------------------------------- + +deriving instance Data CUChar + +-- | GLFW image data, for setting up custom mouse cursor appearnaces. +data Image = Image + { imageWidth :: {-# UNPACK #-} !Int + , imageHeight :: {-# UNPACK #-} !Int + , imagePixels :: [CUChar] + } deriving (Data, Eq, Ord, Read, Show, Typeable, Generic) + +-- | Create an image given the function to generate 8-bit RGBA values based on +-- the pixel location. +mkImage :: Int -> Int -> (Int -> Int -> (Word8, Word8, Word8, Word8)) -> Image +mkImage width height gen = Image + { imageWidth = width + , imageHeight = height + , imagePixels = [ CUChar channel | y <- [0..(height - 1)] + , x <- [0..(width - 1)] + , (r, g, b, a) <- [gen x y] + , channel <- [r, g, b, a] + ] + } + +instance NFData Image + +-- | Reprisents a GLFW cursor. +newtype Cursor = Cursor + { unCursor :: Ptr C'GLFWcursor + } deriving (Data, Eq, Ord, Show, Typeable, Generic) + +-- | Lets you use one of the standard cursor appearnaces that the local +-- system theme provides for. +-- See <http://www.glfw.org/docs/3.2/input.html#cursor_standard Standard Cursor Creation>. +data StandardCursorShape = + StandardCursorShape'Arrow + | StandardCursorShape'IBeam + | StandardCursorShape'Crosshair + | StandardCursorShape'Hand + | StandardCursorShape'HResize + | StandardCursorShape'VResize + deriving (Bounded, Data, Enum, Eq, Ord, Read, Show, Typeable, Generic) + +instance NFData StandardCursorShape + +-------------------------------------------------------------------------------- + +{-# ANN module "HLint: ignore Use camelCase" #-}
README.md view
@@ -8,7 +8,7 @@ creating windows with OpenGL contexts and managing input and events. GLFW-b depends on [bindings-GLFW][3], which, as of the time of this writing,-binds to GLFW 3.1, [released 2015-01-18][4].+binds to GLFW 3.2.1, [released 2016-08-18][4]. For a demonstration of GLFW-b, see [GLFW-b-demo][5]. @@ -39,6 +39,6 @@ [1]: http://www.haskell.org/ [2]: http://www.glfw.org/ [3]: https://github.com/bsl/bindings-GLFW-[4]: http://www.glfw.org/Version-3.1-released.html+[4]: http://www.glfw.org/Version-3.2.1-released.html [5]: https://github.com/bsl/GLFW-b-demo [6]: http://nvie.com/posts/a-successful-git-branching-model/
Test.hs view
@@ -1,614 +1,614 @@--- base-import Control.Concurrent (threadDelay)-import Control.Monad (forM_)-import Data.Char (isAscii)-import Data.Bits (xor)-import Data.List (intercalate, isPrefixOf)---- HUnit-import Test.HUnit ((@?=), assertBool, assertFailure)---- test-framework-import Test.Framework (Test, defaultMain, testGroup)---- test-framework-hunit-import Test.Framework.Providers.HUnit (testCase)---- GLFW-b-import qualified Graphics.UI.GLFW as GLFW------------------------------------------------------------------------------------main :: IO ()-main = do- GLFW.setErrorCallback $ Just $ \e s ->- putStrLn $ unwords ["###", show e, show s]-- True <- GLFW.init-- Just mon <- GLFW.getPrimaryMonitor-- GLFW.windowHint $ GLFW.WindowHint'Visible False- mwin@(Just win) <- GLFW.createWindow 100 100 "GLFW-b test" Nothing Nothing- GLFW.makeContextCurrent mwin-- -- Mostly check for compiling- GLFW.setJoystickCallback $ Just $ \j c -> putStrLn $ concat- [ show j, " changed state: ", show c ]-- defaultMain $ tests mon win-- -- TODO because of how defaultMain works, this code is not reached- GLFW.destroyWindow win- GLFW.terminate------------------------------------------------------------------------------------versionMajor, versionMinor, versionRevision :: Int-versionMajor = 3-versionMinor = 2-versionRevision = 1--giveItTime :: IO ()-giveItTime = threadDelay 500000--joysticks :: [GLFW.Joystick]-joysticks =- [ GLFW.Joystick'1- , GLFW.Joystick'2- , GLFW.Joystick'3- , GLFW.Joystick'4- , GLFW.Joystick'5- , GLFW.Joystick'6- , GLFW.Joystick'7- , GLFW.Joystick'8- , GLFW.Joystick'9- , GLFW.Joystick'10- , GLFW.Joystick'11- , GLFW.Joystick'12- , GLFW.Joystick'13- , GLFW.Joystick'14- , GLFW.Joystick'15- , GLFW.Joystick'16- ]--between :: Ord a => a -> (a,a) -> Bool-between n (l,h) = n >= l && n <= h--videoModeLooksValid :: GLFW.VideoMode -> Bool-videoModeLooksValid vm = and- [ GLFW.videoModeWidth vm `between` (0,4000)- , GLFW.videoModeHeight vm `between` (0,3000)- , GLFW.videoModeRedBits vm `between` (0, 32)- , GLFW.videoModeGreenBits vm `between` (0, 32)- , GLFW.videoModeBlueBits vm `between` (0, 32)- , GLFW.videoModeRefreshRate vm `between` (0, 120)- ]------------------------------------------------------------------------------------tests :: GLFW.Monitor -> GLFW.Window -> [Test]-tests mon win =- [ testGroup "Initialization and version information"- [ testCase "getVersion" test_getVersion- , testCase "getVersionString" test_getVersionString- ]- , testGroup "Monitor handling"- [ testCase "getMonitors" test_getMonitors- , testCase "getPrimaryMonitor" test_getPrimaryMonitor- , testCase "getMonitorPos" $ test_getMonitorPos mon- , testCase "getMonitorPhysicalSize" $ test_getMonitorPhysicalSize mon- , testCase "getMonitorName" $ test_getMonitorName mon- , testCase "getVideoModes" $ test_getVideoModes mon- , testCase "getVideoMode" $ test_getVideoMode mon- , testCase "getGamma" $ test_getGammaRamp mon- ]- , testGroup "Window handling"- [ testCase "defaultWindowHints" test_defaultWindowHints-- -- Test window attributes- , testCase "getWindowFocused" $ test_getWindowFocused win- , testCase "getWindowResizable" $ test_getWindowResizable win- , testCase "getWindowDecorated" $ test_getWindowDecorated win- , testCase "getWindowClientAPI" $ test_getWindowClientAPI win- , testCase "window context version" $ test_window_context_version win- , testCase "getWindowContextRobustness" $ test_getWindowContextRobustness win- , testCase "getWindowOpenGLForwardCompat" $ test_getWindowOpenGLForwardCompat win- , testCase "getWindowOpenGLDebugContext" $ test_getWindowOpenGLDebugContext win- , testCase "getWindowOpenGLProfile" $ test_getWindowOpenGLProfile win- , testCase "window close flag" $ test_window_close_flag win- , testCase "setWindowTitle" $ test_setWindowTitle win- , testCase "window pos" $ test_window_pos win- , testCase "window size" $ test_window_size win- , testCase "getWindowFrameSize" $ test_getWindowFrameSize win- , testCase "getFramebufferSize" $ test_getFramebufferSize win- , testCase "iconification" $ test_iconification win- -- , testCase "show/hide" $ test_show_hide win- , testCase "getWindowMonitor" $ test_getWindowMonitor win mon- , testCase "setWindowed" $ test_setWindowed win- , testCase "setWindowIcon" $ test_setWindowIcon win- , testCase "maximizeWindow" $ test_maximizeWindow win- , testCase "setWindowSizeLimits" $ test_setWindowSizeLimits win- , testCase "setWindowAspectRatio" $ test_setWindowAspectRatio win- , testCase "focusWindow" $ test_focusWindow win- , testCase "cursor pos" $ test_cursor_pos win- , testCase "pollEvents" test_pollEvents- , testCase "waitEvents" test_waitEvents- , testCase "waitEventsTimeout" test_waitEventsTimeout- ]- , testGroup "Input handling"- [ testCase "cursor input mode" $ test_cursor_input_mode win- , testCase "sticky keys input mode" $ test_sticky_keys_input_mode win- , testCase "sticky mouse buttons input mode" $ test_sticky_mouse_buttons_input_mode win- , testCase "joystickPresent" test_joystickPresent- , testCase "getJoystickAxes" test_getJoystickAxes- , testCase "getJoystickButtons" test_getJoystickButtons- , testCase "getJoystickName" test_getJoystickName- , testCase "getKeyName" test_getKeyName- ]- , testGroup "Time"- [ testCase "getTime" test_getTime- , testCase "setTime" test_setTime- , testCase "getTimerValue" test_getTimerValue- , testCase "getTimerFrequency" test_getTimerFrequency- ]- , testGroup "Context"- [ testCase "getCurrentContext" $ test_getCurrentContext win- , testCase "swapBuffers" $ test_swapBuffers win- , testCase "swapInterval" test_swapInterval- , testCase "extensionSupported" test_extensionSupported- ]- , testGroup "Clipboard"- [ testCase "clipboard" $ test_clipboard win- ]- ]------------------------------------------------------------------------------------test_getVersion :: IO ()-test_getVersion = do- v <- GLFW.getVersion- GLFW.versionMajor v @?= versionMajor- GLFW.versionMinor v @?= versionMinor- GLFW.versionRevision v @?= versionRevision--test_getVersionString :: IO ()-test_getVersionString = do- mvs <- GLFW.getVersionString- case mvs of- Just vs -> assertBool "" $ v `isPrefixOf` vs- Nothing -> assertFailure ""- where- v = intercalate "." $ map show [versionMajor, versionMinor]--test_getMonitors :: IO ()-test_getMonitors = do- r <- GLFW.getMonitors- case r of- Just ms -> assertBool "" $ (not . null) ms- Nothing -> assertFailure ""--test_getPrimaryMonitor :: IO ()-test_getPrimaryMonitor = do- r <- GLFW.getPrimaryMonitor- case r of- Just _ -> return ()- Nothing -> assertFailure ""--test_getMonitorPos :: GLFW.Monitor -> IO ()-test_getMonitorPos mon = do- (x, y) <- GLFW.getMonitorPos mon- assertBool "" $ x >= 0- assertBool "" $ y >= 0--test_getMonitorPhysicalSize :: GLFW.Monitor -> IO ()-test_getMonitorPhysicalSize mon = do- (w, h) <- GLFW.getMonitorPhysicalSize mon- assertBool "" $ w `between` (0, 1000)- assertBool "" $ h `between` (0, 500)--test_getMonitorName :: GLFW.Monitor -> IO ()-test_getMonitorName mon = do- mname <- GLFW.getMonitorName mon- case mname of- Nothing -> assertFailure ""- Just name -> do- assertBool "" $ length name `between` (0, 20)- assertBool "" $ all isAscii name--test_getVideoModes :: GLFW.Monitor -> IO ()-test_getVideoModes mon = do- mvms <- GLFW.getVideoModes mon- case mvms of- Nothing -> assertFailure ""- Just vms -> assertBool "" $ all videoModeLooksValid vms--test_getVideoMode :: GLFW.Monitor -> IO ()-test_getVideoMode mon = do- mvm <- GLFW.getVideoMode mon- case mvm of- Just vm -> assertBool "" $ videoModeLooksValid vm- Nothing -> assertFailure ""--test_getGammaRamp :: GLFW.Monitor -> IO ()-test_getGammaRamp mon = do- mgr <- GLFW.getGammaRamp mon- case mgr of- Nothing -> assertFailure ""- Just gr -> assertBool "" $- let rsl = length $ GLFW.gammaRampRed gr- gsl = length $ GLFW.gammaRampGreen gr- bsl = length $ GLFW.gammaRampBlue gr- in rsl > 0 && rsl == gsl && gsl == bsl------------------------------------------------------------------------------------test_defaultWindowHints :: IO ()-test_defaultWindowHints =- GLFW.defaultWindowHints--test_window_close_flag :: GLFW.Window -> IO ()-test_window_close_flag win = do- r0 <- GLFW.windowShouldClose win- r0 @?= False-- GLFW.setWindowShouldClose win True- r1 <- GLFW.windowShouldClose win- r1 @?= True-- GLFW.setWindowShouldClose win False- r2 <- GLFW.windowShouldClose win- r2 @?= False--test_setWindowTitle :: GLFW.Window -> IO ()-test_setWindowTitle win =- GLFW.setWindowTitle win "some new title"---- This is a little strange. Depending on your window manager, etc, after--- setting the window position to (x,y), the actual new window position might--- be (x+5,y+5) due to borders. So we just check for consistency.-test_window_pos :: GLFW.Window -> IO ()-test_window_pos win = do- let x = 17- y = 37- xoff = 53- yoff = 149- (x0, y0, dx0, dy0) <- setGet x y- (x1, y1, dx1, dy1) <- setGet (x+xoff) (y+yoff)- dx0 @?= dx1- dy0 @?= dy1- x1 - x0 @?= xoff- y1 - y0 @?= yoff- where- setGet x0 y0 = do- GLFW.setWindowPos win x0 y0- giveItTime- (x1, y1) <- GLFW.getWindowPos win- let (dx, dy) = (x0-x1, y0-y1)- return (x1, y1, dx, dy)--test_window_size :: GLFW.Window -> IO ()-test_window_size win = do- let w = 170- h = 370- GLFW.setWindowSize win w h- giveItTime- (w', h') <- GLFW.getWindowSize win- w' @?= w- h' @?= h--test_getWindowFrameSize :: GLFW.Window -> IO ()-test_getWindowFrameSize win = do- -- The frame size is pretty dependent on the window manager. We can only- -- really expect that the window has a title bar, so the top frame won't be- -- zero...- (_, t, _, _) <- GLFW.getWindowFrameSize win- assertBool "Window has no frame width up top!" $ t > 0--test_getFramebufferSize :: GLFW.Window -> IO ()-test_getFramebufferSize win = do- (w, h) <- GLFW.getWindowSize win- (fw, fh) <- GLFW.getFramebufferSize win- -- Window size and framebuffer size are not always equal, an example are- -- retina screens. But maybe it's safe to assume they'll always be scaled- -- equally in both dimensions?- let ww = ( fromIntegral fw / fromIntegral w ) :: Double- hh = ( fromIntegral fh / fromIntegral h ) :: Double- ww @?= hh- assertBool "" $ fw /= 0- assertBool "" $ fh /= 0--test_iconification :: GLFW.Window -> IO ()-test_iconification win = do- GLFW.showWindow win- is0 <- GLFW.getWindowIconified win- is0 @?= False-- GLFW.iconifyWindow win- giveItTime- is1 <- GLFW.getWindowIconified win- is1 @?= True-- GLFW.restoreWindow win- GLFW.hideWindow win---- test_show_hide :: GLFW.Window -> IO ()--- test_show_hide win = do--- v0 <- GLFW.getWindowVisible win--- v0 @?= True---- GLFW.hideWindow win--- giveItTime--- v1 <- GLFW.getWindowVisible win--- v1 @?= False---- GLFW.showWindow win--- giveItTime--- v2 <- GLFW.getWindowVisible win--- v2 @?= True--test_getWindowMonitor :: GLFW.Window -> GLFW.Monitor -> IO ()-test_getWindowMonitor win _ = do- m <- GLFW.getWindowMonitor win- m @?= Nothing--test_setWindowed :: GLFW.Window -> IO ()-test_setWindowed win = GLFW.setWindowed win 100 100 0 0--test_setWindowIcon :: GLFW.Window -> IO ()-test_setWindowIcon win = let- icon1 = GLFW.mkImage 32 32 $ \x y ->- case even ((x `div` 8) `xor` (y `div` 8)) of- True -> (255, 0, 0, 255)- False -> (0, 255, 0, 255)-- icon2 = GLFW.mkImage 16 16 $ \x y ->- case even ((x `div` 8) `xor` (y `div` 8)) of- True -> (255, 255, 255, 255)- False -> (0, 0, 0, 255)-- in GLFW.setWindowIcon win [icon1, icon2]--test_maximizeWindow :: GLFW.Window -> IO ()-test_maximizeWindow win = do- GLFW.showWindow win- startsMaximized <- GLFW.getWindowMaximized win- startsMaximized @?= False-- GLFW.maximizeWindow win- giveItTime-- isMaximized <- GLFW.getWindowMaximized win- isMaximized @?= True- GLFW.hideWindow win--test_setWindowSizeLimits :: GLFW.Window -> IO ()-test_setWindowSizeLimits win = do- GLFW.setWindowSizeLimits win (Just 640) (Just 480) (Just 1024) (Just 768)--test_setWindowAspectRatio :: GLFW.Window -> IO ()-test_setWindowAspectRatio win = do- GLFW.setWindowAspectRatio win Nothing--test_focusWindow :: GLFW.Window -> IO ()-test_focusWindow = GLFW.focusWindow--test_cursor_pos :: GLFW.Window -> IO ()-test_cursor_pos win = do- GLFW.showWindow win- (w, h) <- GLFW.getWindowSize win-- -- Make sure we use integral coordinates here so that we don't run into- -- platform-dependent differences.- let cx :: Double- cy :: Double- (cx, cy) = (fromIntegral $ w `div` 2, fromIntegral $ h `div` 2)-- -- !HACK! Poll events seems to be necessary on OS X,- -- before /and/ after glfwSetCursorPos, otherwise, the- -- windowing system likely never receives the cursor update. This is- -- reflected in the C version of GLFW as well, we just call it here in- -- order to have a more robust test.-- GLFW.pollEvents- GLFW.setCursorPos win cx cy- GLFW.pollEvents -- !HACK! see comment above-- (cx', cy') <- GLFW.getCursorPos win- cx' @?= cx- cy' @?= cy- GLFW.hideWindow win--test_getWindowFocused :: GLFW.Window -> IO ()-test_getWindowFocused win = do- fs <- GLFW.getWindowFocused win- fs @?= False--test_getWindowResizable :: GLFW.Window -> IO ()-test_getWindowResizable win = do- b <- GLFW.getWindowResizable win- b @?= True--test_getWindowDecorated :: GLFW.Window -> IO ()-test_getWindowDecorated win = do- b <- GLFW.getWindowDecorated win- b @?= True--test_getWindowClientAPI :: GLFW.Window -> IO ()-test_getWindowClientAPI win = do- a <- GLFW.getWindowClientAPI win- a @?= GLFW.ClientAPI'OpenGL--test_window_context_version :: GLFW.Window -> IO ()-test_window_context_version win = do- v0 <- GLFW.getWindowContextVersionMajor win- v1 <- GLFW.getWindowContextVersionMinor win- assertBool "" $ all (`between` (0, 20)) [v0, v1]--test_getWindowContextRobustness :: GLFW.Window -> IO ()-test_getWindowContextRobustness win = do- _ <- GLFW.getWindowContextRobustness win- return ()--test_getWindowOpenGLForwardCompat :: GLFW.Window -> IO ()-test_getWindowOpenGLForwardCompat win = do- _ <- GLFW.getWindowOpenGLForwardCompat win- return ()--test_getWindowOpenGLDebugContext :: GLFW.Window -> IO ()-test_getWindowOpenGLDebugContext win = do- _ <- GLFW.getWindowOpenGLDebugContext win- return ()--test_getWindowOpenGLProfile :: GLFW.Window -> IO ()-test_getWindowOpenGLProfile win = do- _ <- GLFW.getWindowOpenGLProfile win- return ()--test_pollEvents :: IO ()-test_pollEvents =- GLFW.pollEvents--test_waitEvents :: IO ()-test_waitEvents = GLFW.postEmptyEvent >> GLFW.waitEvents--test_waitEventsTimeout :: IO ()-test_waitEventsTimeout =- -- to not slow down the test too much we set the timeout to 0.001 second :- GLFW.waitEventsTimeout 0.001------------------------------------------------------------------------------------test_cursor_input_mode :: GLFW.Window -> IO ()-test_cursor_input_mode win = do- modes' <- mapM setGet modes- modes' @?= modes- where- modes =- [ GLFW.CursorInputMode'Disabled- , GLFW.CursorInputMode'Hidden- , GLFW.CursorInputMode'Normal- ]- setGet m = do- GLFW.setCursorInputMode win m- GLFW.getCursorInputMode win--test_sticky_keys_input_mode :: GLFW.Window -> IO ()-test_sticky_keys_input_mode win = do- modes' <- mapM setGet modes- modes' @?= modes- where- modes =- [ GLFW.StickyKeysInputMode'Enabled- , GLFW.StickyKeysInputMode'Disabled- ]- setGet m = do- GLFW.setStickyKeysInputMode win m- GLFW.getStickyKeysInputMode win--test_sticky_mouse_buttons_input_mode :: GLFW.Window -> IO ()-test_sticky_mouse_buttons_input_mode win = do- modes' <- mapM setGet modes- modes' @?= modes- where- modes =- [ GLFW.StickyMouseButtonsInputMode'Enabled- , GLFW.StickyMouseButtonsInputMode'Disabled- ]- setGet m = do- GLFW.setStickyMouseButtonsInputMode win m- GLFW.getStickyMouseButtonsInputMode win--test_joystickPresent :: IO ()-test_joystickPresent = do- _ <- GLFW.joystickPresent GLFW.Joystick'1- r <- GLFW.joystickPresent GLFW.Joystick'16- assertBool "" $ not r--test_getJoystickAxes :: IO ()-test_getJoystickAxes =- mapM_ GLFW.getJoystickAxes joysticks--test_getJoystickButtons :: IO ()-test_getJoystickButtons =- mapM_ GLFW.getJoystickButtons joysticks--test_getJoystickName :: IO ()-test_getJoystickName =- mapM_ GLFW.getJoystickName joysticks--test_getKeyName :: IO ()-test_getKeyName =- forM_ (zip [GLFW.Key'Slash, GLFW.Key'Period] ["/", "."]) $ \(k, n) -> do- name <- GLFW.getKeyName k 0- case name of- Nothing -> return ()- Just s -> s @?= n------------------------------------------------------------------------------------test_getTime :: IO ()-test_getTime = do- mt <- GLFW.getTime- case mt of- Nothing -> assertFailure ""- Just t -> assertBool "" $ t `between` (0, 10)--test_setTime :: IO ()-test_setTime = do- let t = 37- GLFW.setTime t- mt <- GLFW.getTime- case mt of- Just t' -> assertBool "" $ t' `between` (t, t+10)- Nothing -> assertFailure ""--test_getTimerValue :: IO ()-test_getTimerValue = GLFW.getTimerValue >>= assertBool "" . (> 0)--test_getTimerFrequency :: IO ()-test_getTimerFrequency = GLFW.getTimerFrequency >>= assertBool "" . (> 0)------------------------------------------------------------------------------------test_getCurrentContext :: GLFW.Window -> IO ()-test_getCurrentContext win = do- mwin <- GLFW.getCurrentContext- case mwin of- Nothing -> assertFailure ""- Just win' -> win' @?= win--test_swapBuffers :: GLFW.Window -> IO ()-test_swapBuffers =- GLFW.swapBuffers--test_swapInterval :: IO ()-test_swapInterval =- GLFW.swapInterval 1--test_extensionSupported :: IO ()-test_extensionSupported = do- b0 <- GLFW.extensionSupported "GL_ARB_multisample"- b0 @?= True- b1 <- GLFW.extensionSupported "bogus"- b1 @?= False------------------------------------------------------------------------------------test_clipboard :: GLFW.Window -> IO ()-test_clipboard win = do- rs <- mapM setGet ss- rs @?= map Just ss- where- ss =- [ "abc 123 ???"- , "xyz 456 !!!"- ]- setGet s = do- GLFW.setClipboardString win s- giveItTime- GLFW.getClipboardString win------------------------------------------------------------------------------------{-# ANN module "HLint: ignore Use camelCase" #-}+-- base +import Control.Concurrent (threadDelay) +import Control.Monad (forM_) +import Data.Char (isAscii) +import Data.Bits (xor) +import Data.List (intercalate, isPrefixOf) + +-- HUnit +import Test.HUnit ((@?=), assertBool, assertFailure) + +-- test-framework +import Test.Framework (Test, defaultMain, testGroup) + +-- test-framework-hunit +import Test.Framework.Providers.HUnit (testCase) + +-- GLFW-b +import qualified Graphics.UI.GLFW as GLFW + +-------------------------------------------------------------------------------- + +main :: IO () +main = do + GLFW.setErrorCallback $ Just $ \e s -> + putStrLn $ unwords ["###", show e, show s] + + True <- GLFW.init + + Just mon <- GLFW.getPrimaryMonitor + + GLFW.windowHint $ GLFW.WindowHint'Visible False + mwin@(Just win) <- GLFW.createWindow 100 100 "GLFW-b test" Nothing Nothing + GLFW.makeContextCurrent mwin + + -- Mostly check for compiling + GLFW.setJoystickCallback $ Just $ \j c -> putStrLn $ concat + [ show j, " changed state: ", show c ] + + defaultMain $ tests mon win + + -- TODO because of how defaultMain works, this code is not reached + GLFW.destroyWindow win + GLFW.terminate + +-------------------------------------------------------------------------------- + +versionMajor, versionMinor, versionRevision :: Int +versionMajor = 3 +versionMinor = 2 +versionRevision = 1 + +giveItTime :: IO () +giveItTime = threadDelay 500000 + +joysticks :: [GLFW.Joystick] +joysticks = + [ GLFW.Joystick'1 + , GLFW.Joystick'2 + , GLFW.Joystick'3 + , GLFW.Joystick'4 + , GLFW.Joystick'5 + , GLFW.Joystick'6 + , GLFW.Joystick'7 + , GLFW.Joystick'8 + , GLFW.Joystick'9 + , GLFW.Joystick'10 + , GLFW.Joystick'11 + , GLFW.Joystick'12 + , GLFW.Joystick'13 + , GLFW.Joystick'14 + , GLFW.Joystick'15 + , GLFW.Joystick'16 + ] + +between :: Ord a => a -> (a,a) -> Bool +between n (l,h) = n >= l && n <= h + +videoModeLooksValid :: GLFW.VideoMode -> Bool +videoModeLooksValid vm = and + [ GLFW.videoModeWidth vm `between` (0,4000) + , GLFW.videoModeHeight vm `between` (0,3000) + , GLFW.videoModeRedBits vm `between` (0, 32) + , GLFW.videoModeGreenBits vm `between` (0, 32) + , GLFW.videoModeBlueBits vm `between` (0, 32) + , GLFW.videoModeRefreshRate vm `between` (0, 120) + ] + +-------------------------------------------------------------------------------- + +tests :: GLFW.Monitor -> GLFW.Window -> [Test] +tests mon win = + [ testGroup "Initialization and version information" + [ testCase "getVersion" test_getVersion + , testCase "getVersionString" test_getVersionString + ] + , testGroup "Monitor handling" + [ testCase "getMonitors" test_getMonitors + , testCase "getPrimaryMonitor" test_getPrimaryMonitor + , testCase "getMonitorPos" $ test_getMonitorPos mon + , testCase "getMonitorPhysicalSize" $ test_getMonitorPhysicalSize mon + , testCase "getMonitorName" $ test_getMonitorName mon + , testCase "getVideoModes" $ test_getVideoModes mon + , testCase "getVideoMode" $ test_getVideoMode mon + , testCase "getGamma" $ test_getGammaRamp mon + ] + , testGroup "Window handling" + [ testCase "defaultWindowHints" test_defaultWindowHints + + -- Test window attributes + , testCase "getWindowFocused" $ test_getWindowFocused win + , testCase "getWindowResizable" $ test_getWindowResizable win + , testCase "getWindowDecorated" $ test_getWindowDecorated win + , testCase "getWindowClientAPI" $ test_getWindowClientAPI win + , testCase "window context version" $ test_window_context_version win + , testCase "getWindowContextRobustness" $ test_getWindowContextRobustness win + , testCase "getWindowOpenGLForwardCompat" $ test_getWindowOpenGLForwardCompat win + , testCase "getWindowOpenGLDebugContext" $ test_getWindowOpenGLDebugContext win + , testCase "getWindowOpenGLProfile" $ test_getWindowOpenGLProfile win + , testCase "window close flag" $ test_window_close_flag win + , testCase "setWindowTitle" $ test_setWindowTitle win + , testCase "window pos" $ test_window_pos win + , testCase "window size" $ test_window_size win + , testCase "getWindowFrameSize" $ test_getWindowFrameSize win + , testCase "getFramebufferSize" $ test_getFramebufferSize win + , testCase "iconification" $ test_iconification win + -- , testCase "show/hide" $ test_show_hide win + , testCase "getWindowMonitor" $ test_getWindowMonitor win mon + , testCase "setWindowed" $ test_setWindowed win + , testCase "setWindowIcon" $ test_setWindowIcon win + , testCase "maximizeWindow" $ test_maximizeWindow win + , testCase "setWindowSizeLimits" $ test_setWindowSizeLimits win + , testCase "setWindowAspectRatio" $ test_setWindowAspectRatio win + , testCase "focusWindow" $ test_focusWindow win + , testCase "cursor pos" $ test_cursor_pos win + , testCase "pollEvents" test_pollEvents + , testCase "waitEvents" test_waitEvents + , testCase "waitEventsTimeout" test_waitEventsTimeout + ] + , testGroup "Input handling" + [ testCase "cursor input mode" $ test_cursor_input_mode win + , testCase "sticky keys input mode" $ test_sticky_keys_input_mode win + , testCase "sticky mouse buttons input mode" $ test_sticky_mouse_buttons_input_mode win + , testCase "joystickPresent" test_joystickPresent + , testCase "getJoystickAxes" test_getJoystickAxes + , testCase "getJoystickButtons" test_getJoystickButtons + , testCase "getJoystickName" test_getJoystickName + , testCase "getKeyName" test_getKeyName + ] + , testGroup "Time" + [ testCase "getTime" test_getTime + , testCase "setTime" test_setTime + , testCase "getTimerValue" test_getTimerValue + , testCase "getTimerFrequency" test_getTimerFrequency + ] + , testGroup "Context" + [ testCase "getCurrentContext" $ test_getCurrentContext win + , testCase "swapBuffers" $ test_swapBuffers win + , testCase "swapInterval" test_swapInterval + , testCase "extensionSupported" test_extensionSupported + ] + , testGroup "Clipboard" + [ testCase "clipboard" $ test_clipboard win + ] + ] + +-------------------------------------------------------------------------------- + +test_getVersion :: IO () +test_getVersion = do + v <- GLFW.getVersion + GLFW.versionMajor v @?= versionMajor + GLFW.versionMinor v @?= versionMinor + GLFW.versionRevision v @?= versionRevision + +test_getVersionString :: IO () +test_getVersionString = do + mvs <- GLFW.getVersionString + case mvs of + Just vs -> assertBool "" $ v `isPrefixOf` vs + Nothing -> assertFailure "" + where + v = intercalate "." $ map show [versionMajor, versionMinor] + +test_getMonitors :: IO () +test_getMonitors = do + r <- GLFW.getMonitors + case r of + Just ms -> assertBool "" $ (not . null) ms + Nothing -> assertFailure "" + +test_getPrimaryMonitor :: IO () +test_getPrimaryMonitor = do + r <- GLFW.getPrimaryMonitor + case r of + Just _ -> return () + Nothing -> assertFailure "" + +test_getMonitorPos :: GLFW.Monitor -> IO () +test_getMonitorPos mon = do + (x, y) <- GLFW.getMonitorPos mon + assertBool "" $ x >= 0 + assertBool "" $ y >= 0 + +test_getMonitorPhysicalSize :: GLFW.Monitor -> IO () +test_getMonitorPhysicalSize mon = do + (w, h) <- GLFW.getMonitorPhysicalSize mon + assertBool "" $ w `between` (0, 1000) + assertBool "" $ h `between` (0, 500) + +test_getMonitorName :: GLFW.Monitor -> IO () +test_getMonitorName mon = do + mname <- GLFW.getMonitorName mon + case mname of + Nothing -> assertFailure "" + Just name -> do + assertBool "" $ length name `between` (0, 20) + assertBool "" $ all isAscii name + +test_getVideoModes :: GLFW.Monitor -> IO () +test_getVideoModes mon = do + mvms <- GLFW.getVideoModes mon + case mvms of + Nothing -> assertFailure "" + Just vms -> assertBool "" $ all videoModeLooksValid vms + +test_getVideoMode :: GLFW.Monitor -> IO () +test_getVideoMode mon = do + mvm <- GLFW.getVideoMode mon + case mvm of + Just vm -> assertBool "" $ videoModeLooksValid vm + Nothing -> assertFailure "" + +test_getGammaRamp :: GLFW.Monitor -> IO () +test_getGammaRamp mon = do + mgr <- GLFW.getGammaRamp mon + case mgr of + Nothing -> assertFailure "" + Just gr -> assertBool "" $ + let rsl = length $ GLFW.gammaRampRed gr + gsl = length $ GLFW.gammaRampGreen gr + bsl = length $ GLFW.gammaRampBlue gr + in rsl > 0 && rsl == gsl && gsl == bsl + +-------------------------------------------------------------------------------- + +test_defaultWindowHints :: IO () +test_defaultWindowHints = + GLFW.defaultWindowHints + +test_window_close_flag :: GLFW.Window -> IO () +test_window_close_flag win = do + r0 <- GLFW.windowShouldClose win + r0 @?= False + + GLFW.setWindowShouldClose win True + r1 <- GLFW.windowShouldClose win + r1 @?= True + + GLFW.setWindowShouldClose win False + r2 <- GLFW.windowShouldClose win + r2 @?= False + +test_setWindowTitle :: GLFW.Window -> IO () +test_setWindowTitle win = + GLFW.setWindowTitle win "some new title" + +-- This is a little strange. Depending on your window manager, etc, after +-- setting the window position to (x,y), the actual new window position might +-- be (x+5,y+5) due to borders. So we just check for consistency. +test_window_pos :: GLFW.Window -> IO () +test_window_pos win = do + let x = 17 + y = 37 + xoff = 53 + yoff = 149 + (x0, y0, dx0, dy0) <- setGet x y + (x1, y1, dx1, dy1) <- setGet (x+xoff) (y+yoff) + dx0 @?= dx1 + dy0 @?= dy1 + x1 - x0 @?= xoff + y1 - y0 @?= yoff + where + setGet x0 y0 = do + GLFW.setWindowPos win x0 y0 + giveItTime + (x1, y1) <- GLFW.getWindowPos win + let (dx, dy) = (x0-x1, y0-y1) + return (x1, y1, dx, dy) + +test_window_size :: GLFW.Window -> IO () +test_window_size win = do + let w = 170 + h = 370 + GLFW.setWindowSize win w h + giveItTime + (w', h') <- GLFW.getWindowSize win + w' @?= w + h' @?= h + +test_getWindowFrameSize :: GLFW.Window -> IO () +test_getWindowFrameSize win = do + -- The frame size is pretty dependent on the window manager. We can only + -- really expect that the window has a title bar, so the top frame won't be + -- zero... + (_, t, _, _) <- GLFW.getWindowFrameSize win + assertBool "Window has no frame width up top!" $ t > 0 + +test_getFramebufferSize :: GLFW.Window -> IO () +test_getFramebufferSize win = do + (w, h) <- GLFW.getWindowSize win + (fw, fh) <- GLFW.getFramebufferSize win + -- Window size and framebuffer size are not always equal, an example are + -- retina screens. But maybe it's safe to assume they'll always be scaled + -- equally in both dimensions? + let ww = ( fromIntegral fw / fromIntegral w ) :: Double + hh = ( fromIntegral fh / fromIntegral h ) :: Double + ww @?= hh + assertBool "" $ fw /= 0 + assertBool "" $ fh /= 0 + +test_iconification :: GLFW.Window -> IO () +test_iconification win = do + GLFW.showWindow win + is0 <- GLFW.getWindowIconified win + is0 @?= False + + GLFW.iconifyWindow win + giveItTime + is1 <- GLFW.getWindowIconified win + is1 @?= True + + GLFW.restoreWindow win + GLFW.hideWindow win + +-- test_show_hide :: GLFW.Window -> IO () +-- test_show_hide win = do +-- v0 <- GLFW.getWindowVisible win +-- v0 @?= True + +-- GLFW.hideWindow win +-- giveItTime +-- v1 <- GLFW.getWindowVisible win +-- v1 @?= False + +-- GLFW.showWindow win +-- giveItTime +-- v2 <- GLFW.getWindowVisible win +-- v2 @?= True + +test_getWindowMonitor :: GLFW.Window -> GLFW.Monitor -> IO () +test_getWindowMonitor win _ = do + m <- GLFW.getWindowMonitor win + m @?= Nothing + +test_setWindowed :: GLFW.Window -> IO () +test_setWindowed win = GLFW.setWindowed win 100 100 0 0 + +test_setWindowIcon :: GLFW.Window -> IO () +test_setWindowIcon win = let + icon1 = GLFW.mkImage 32 32 $ \x y -> + case even ((x `div` 8) `xor` (y `div` 8)) of + True -> (255, 0, 0, 255) + False -> (0, 255, 0, 255) + + icon2 = GLFW.mkImage 16 16 $ \x y -> + case even ((x `div` 8) `xor` (y `div` 8)) of + True -> (255, 255, 255, 255) + False -> (0, 0, 0, 255) + + in GLFW.setWindowIcon win [icon1, icon2] + +test_maximizeWindow :: GLFW.Window -> IO () +test_maximizeWindow win = do + GLFW.showWindow win + startsMaximized <- GLFW.getWindowMaximized win + startsMaximized @?= False + + GLFW.maximizeWindow win + giveItTime + + isMaximized <- GLFW.getWindowMaximized win + isMaximized @?= True + GLFW.hideWindow win + +test_setWindowSizeLimits :: GLFW.Window -> IO () +test_setWindowSizeLimits win = do + GLFW.setWindowSizeLimits win (Just 640) (Just 480) (Just 1024) (Just 768) + +test_setWindowAspectRatio :: GLFW.Window -> IO () +test_setWindowAspectRatio win = do + GLFW.setWindowAspectRatio win Nothing + +test_focusWindow :: GLFW.Window -> IO () +test_focusWindow = GLFW.focusWindow + +test_cursor_pos :: GLFW.Window -> IO () +test_cursor_pos win = do + GLFW.showWindow win + (w, h) <- GLFW.getWindowSize win + + -- Make sure we use integral coordinates here so that we don't run into + -- platform-dependent differences. + let cx :: Double + cy :: Double + (cx, cy) = (fromIntegral $ w `div` 2, fromIntegral $ h `div` 2) + + -- !HACK! Poll events seems to be necessary on OS X, + -- before /and/ after glfwSetCursorPos, otherwise, the + -- windowing system likely never receives the cursor update. This is + -- reflected in the C version of GLFW as well, we just call it here in + -- order to have a more robust test. + + GLFW.pollEvents + GLFW.setCursorPos win cx cy + GLFW.pollEvents -- !HACK! see comment above + + (cx', cy') <- GLFW.getCursorPos win + cx' @?= cx + cy' @?= cy + GLFW.hideWindow win + +test_getWindowFocused :: GLFW.Window -> IO () +test_getWindowFocused win = do + fs <- GLFW.getWindowFocused win + fs @?= False + +test_getWindowResizable :: GLFW.Window -> IO () +test_getWindowResizable win = do + b <- GLFW.getWindowResizable win + b @?= True + +test_getWindowDecorated :: GLFW.Window -> IO () +test_getWindowDecorated win = do + b <- GLFW.getWindowDecorated win + b @?= True + +test_getWindowClientAPI :: GLFW.Window -> IO () +test_getWindowClientAPI win = do + a <- GLFW.getWindowClientAPI win + a @?= GLFW.ClientAPI'OpenGL + +test_window_context_version :: GLFW.Window -> IO () +test_window_context_version win = do + v0 <- GLFW.getWindowContextVersionMajor win + v1 <- GLFW.getWindowContextVersionMinor win + assertBool "" $ all (`between` (0, 20)) [v0, v1] + +test_getWindowContextRobustness :: GLFW.Window -> IO () +test_getWindowContextRobustness win = do + _ <- GLFW.getWindowContextRobustness win + return () + +test_getWindowOpenGLForwardCompat :: GLFW.Window -> IO () +test_getWindowOpenGLForwardCompat win = do + _ <- GLFW.getWindowOpenGLForwardCompat win + return () + +test_getWindowOpenGLDebugContext :: GLFW.Window -> IO () +test_getWindowOpenGLDebugContext win = do + _ <- GLFW.getWindowOpenGLDebugContext win + return () + +test_getWindowOpenGLProfile :: GLFW.Window -> IO () +test_getWindowOpenGLProfile win = do + _ <- GLFW.getWindowOpenGLProfile win + return () + +test_pollEvents :: IO () +test_pollEvents = + GLFW.pollEvents + +test_waitEvents :: IO () +test_waitEvents = GLFW.postEmptyEvent >> GLFW.waitEvents + +test_waitEventsTimeout :: IO () +test_waitEventsTimeout = + -- to not slow down the test too much we set the timeout to 0.001 second : + GLFW.waitEventsTimeout 0.001 + +-------------------------------------------------------------------------------- + +test_cursor_input_mode :: GLFW.Window -> IO () +test_cursor_input_mode win = do + modes' <- mapM setGet modes + modes' @?= modes + where + modes = + [ GLFW.CursorInputMode'Disabled + , GLFW.CursorInputMode'Hidden + , GLFW.CursorInputMode'Normal + ] + setGet m = do + GLFW.setCursorInputMode win m + GLFW.getCursorInputMode win + +test_sticky_keys_input_mode :: GLFW.Window -> IO () +test_sticky_keys_input_mode win = do + modes' <- mapM setGet modes + modes' @?= modes + where + modes = + [ GLFW.StickyKeysInputMode'Enabled + , GLFW.StickyKeysInputMode'Disabled + ] + setGet m = do + GLFW.setStickyKeysInputMode win m + GLFW.getStickyKeysInputMode win + +test_sticky_mouse_buttons_input_mode :: GLFW.Window -> IO () +test_sticky_mouse_buttons_input_mode win = do + modes' <- mapM setGet modes + modes' @?= modes + where + modes = + [ GLFW.StickyMouseButtonsInputMode'Enabled + , GLFW.StickyMouseButtonsInputMode'Disabled + ] + setGet m = do + GLFW.setStickyMouseButtonsInputMode win m + GLFW.getStickyMouseButtonsInputMode win + +test_joystickPresent :: IO () +test_joystickPresent = do + _ <- GLFW.joystickPresent GLFW.Joystick'1 + r <- GLFW.joystickPresent GLFW.Joystick'16 + assertBool "" $ not r + +test_getJoystickAxes :: IO () +test_getJoystickAxes = + mapM_ GLFW.getJoystickAxes joysticks + +test_getJoystickButtons :: IO () +test_getJoystickButtons = + mapM_ GLFW.getJoystickButtons joysticks + +test_getJoystickName :: IO () +test_getJoystickName = + mapM_ GLFW.getJoystickName joysticks + +test_getKeyName :: IO () +test_getKeyName = + forM_ (zip [GLFW.Key'Slash, GLFW.Key'Period] ["/", "."]) $ \(k, n) -> do + name <- GLFW.getKeyName k 0 + case name of + Nothing -> return () + Just s -> s @?= n + +-------------------------------------------------------------------------------- + +test_getTime :: IO () +test_getTime = do + mt <- GLFW.getTime + case mt of + Nothing -> assertFailure "" + Just t -> assertBool "" $ t `between` (0, 10) + +test_setTime :: IO () +test_setTime = do + let t = 37 + GLFW.setTime t + mt <- GLFW.getTime + case mt of + Just t' -> assertBool "" $ t' `between` (t, t+10) + Nothing -> assertFailure "" + +test_getTimerValue :: IO () +test_getTimerValue = GLFW.getTimerValue >>= assertBool "" . (> 0) + +test_getTimerFrequency :: IO () +test_getTimerFrequency = GLFW.getTimerFrequency >>= assertBool "" . (> 0) + +-------------------------------------------------------------------------------- + +test_getCurrentContext :: GLFW.Window -> IO () +test_getCurrentContext win = do + mwin <- GLFW.getCurrentContext + case mwin of + Nothing -> assertFailure "" + Just win' -> win' @?= win + +test_swapBuffers :: GLFW.Window -> IO () +test_swapBuffers = + GLFW.swapBuffers + +test_swapInterval :: IO () +test_swapInterval = + GLFW.swapInterval 1 + +test_extensionSupported :: IO () +test_extensionSupported = do + b0 <- GLFW.extensionSupported "GL_ARB_multisample" + b0 @?= True + b1 <- GLFW.extensionSupported "bogus" + b1 @?= False + +-------------------------------------------------------------------------------- + +test_clipboard :: GLFW.Window -> IO () +test_clipboard win = do + rs <- mapM setGet ss + rs @?= map Just ss + where + ss = + [ "abc 123 ???" + , "xyz 456 !!!" + ] + setGet s = do + GLFW.setClipboardString win s + giveItTime + GLFW.getClipboardString win + +-------------------------------------------------------------------------------- + +{-# ANN module "HLint: ignore Use camelCase" #-}