GLFW-b 3.3.0.0 → 3.3.9.0
raw patch · 6 files changed
+4215/−4218 lines, 6 filesdep ~bindings-GLFWPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
Dependency ranges changed: bindings-GLFW
API changes (from Hackage documentation)
+ Graphics.UI.GLFW.C: class C c h
+ Graphics.UI.GLFW.C: fromC :: C c h => c -> h
+ Graphics.UI.GLFW.C: instance Graphics.UI.GLFW.C.C (GHC.Ptr.Ptr Bindings.GLFW.C'GLFWmonitor) Graphics.UI.GLFW.Types.Monitor
+ Graphics.UI.GLFW.C: instance Graphics.UI.GLFW.C.C (GHC.Ptr.Ptr Bindings.GLFW.C'GLFWwindow) Graphics.UI.GLFW.Types.Window
+ Graphics.UI.GLFW.C: instance Graphics.UI.GLFW.C.C Bindings.GLFW.C'GLFWvidmode Graphics.UI.GLFW.Types.VideoMode
+ Graphics.UI.GLFW.C: instance Graphics.UI.GLFW.C.C Foreign.C.Types.CDouble GHC.Types.Double
+ Graphics.UI.GLFW.C: instance Graphics.UI.GLFW.C.C Foreign.C.Types.CFloat GHC.Types.Double
+ Graphics.UI.GLFW.C: instance Graphics.UI.GLFW.C.C Foreign.C.Types.CInt GHC.Types.Bool
+ Graphics.UI.GLFW.C: instance Graphics.UI.GLFW.C.C Foreign.C.Types.CInt GHC.Types.Char
+ Graphics.UI.GLFW.C: instance Graphics.UI.GLFW.C.C Foreign.C.Types.CInt GHC.Types.Int
+ Graphics.UI.GLFW.C: instance Graphics.UI.GLFW.C.C Foreign.C.Types.CInt Graphics.UI.GLFW.Types.ClientAPI
+ Graphics.UI.GLFW.C: instance Graphics.UI.GLFW.C.C Foreign.C.Types.CInt Graphics.UI.GLFW.Types.ContextCreationAPI
+ Graphics.UI.GLFW.C: instance Graphics.UI.GLFW.C.C Foreign.C.Types.CInt Graphics.UI.GLFW.Types.ContextReleaseBehavior
+ Graphics.UI.GLFW.C: instance Graphics.UI.GLFW.C.C Foreign.C.Types.CInt Graphics.UI.GLFW.Types.ContextRobustness
+ Graphics.UI.GLFW.C: instance Graphics.UI.GLFW.C.C Foreign.C.Types.CInt Graphics.UI.GLFW.Types.CursorInputMode
+ Graphics.UI.GLFW.C: instance Graphics.UI.GLFW.C.C Foreign.C.Types.CInt Graphics.UI.GLFW.Types.CursorState
+ Graphics.UI.GLFW.C: instance Graphics.UI.GLFW.C.C Foreign.C.Types.CInt Graphics.UI.GLFW.Types.Error
+ Graphics.UI.GLFW.C: instance Graphics.UI.GLFW.C.C Foreign.C.Types.CInt Graphics.UI.GLFW.Types.GamepadAxis
+ Graphics.UI.GLFW.C: instance Graphics.UI.GLFW.C.C Foreign.C.Types.CInt Graphics.UI.GLFW.Types.GamepadButton
+ Graphics.UI.GLFW.C: instance Graphics.UI.GLFW.C.C Foreign.C.Types.CInt Graphics.UI.GLFW.Types.InitHint
+ Graphics.UI.GLFW.C: instance Graphics.UI.GLFW.C.C Foreign.C.Types.CInt Graphics.UI.GLFW.Types.Joystick
+ Graphics.UI.GLFW.C: instance Graphics.UI.GLFW.C.C Foreign.C.Types.CInt Graphics.UI.GLFW.Types.JoystickState
+ Graphics.UI.GLFW.C: instance Graphics.UI.GLFW.C.C Foreign.C.Types.CInt Graphics.UI.GLFW.Types.Key
+ Graphics.UI.GLFW.C: instance Graphics.UI.GLFW.C.C Foreign.C.Types.CInt Graphics.UI.GLFW.Types.KeyState
+ Graphics.UI.GLFW.C: instance Graphics.UI.GLFW.C.C Foreign.C.Types.CInt Graphics.UI.GLFW.Types.ModifierKeys
+ Graphics.UI.GLFW.C: instance Graphics.UI.GLFW.C.C Foreign.C.Types.CInt Graphics.UI.GLFW.Types.MonitorState
+ Graphics.UI.GLFW.C: instance Graphics.UI.GLFW.C.C Foreign.C.Types.CInt Graphics.UI.GLFW.Types.MouseButton
+ Graphics.UI.GLFW.C: instance Graphics.UI.GLFW.C.C Foreign.C.Types.CInt Graphics.UI.GLFW.Types.MouseButtonState
+ Graphics.UI.GLFW.C: instance Graphics.UI.GLFW.C.C Foreign.C.Types.CInt Graphics.UI.GLFW.Types.OpenGLProfile
+ Graphics.UI.GLFW.C: instance Graphics.UI.GLFW.C.C Foreign.C.Types.CInt Graphics.UI.GLFW.Types.StandardCursorShape
+ Graphics.UI.GLFW.C: instance Graphics.UI.GLFW.C.C Foreign.C.Types.CInt Graphics.UI.GLFW.Types.StickyKeysInputMode
+ Graphics.UI.GLFW.C: instance Graphics.UI.GLFW.C.C Foreign.C.Types.CInt Graphics.UI.GLFW.Types.StickyMouseButtonsInputMode
+ Graphics.UI.GLFW.C: instance Graphics.UI.GLFW.C.C Foreign.C.Types.CInt Graphics.UI.GLFW.Types.WindowAttrib
+ Graphics.UI.GLFW.C: instance Graphics.UI.GLFW.C.C Foreign.C.Types.CInt b => Graphics.UI.GLFW.C.C Foreign.C.Types.CInt (GHC.Maybe.Maybe b)
+ Graphics.UI.GLFW.C: instance Graphics.UI.GLFW.C.C Foreign.C.Types.CUChar Graphics.UI.GLFW.Types.GamepadButtonState
+ Graphics.UI.GLFW.C: instance Graphics.UI.GLFW.C.C Foreign.C.Types.CUChar Graphics.UI.GLFW.Types.JoystickButtonState
+ Graphics.UI.GLFW.C: instance Graphics.UI.GLFW.C.C Foreign.C.Types.CUChar Graphics.UI.GLFW.Types.JoystickHatState
+ Graphics.UI.GLFW.C: instance Graphics.UI.GLFW.C.C Foreign.C.Types.CUInt GHC.Types.Char
+ Graphics.UI.GLFW.C: instance Graphics.UI.GLFW.C.C Foreign.C.Types.CUInt GHC.Types.Int
+ Graphics.UI.GLFW.C: instance Graphics.UI.GLFW.C.C Foreign.C.Types.CUShort GHC.Types.Int
+ Graphics.UI.GLFW.C: toC :: C c h => h -> c
- Graphics.UI.GLFW: type DropCallback = Window " The window that received the event.
" -> [String] " The file and/or directory path names
" -> IO ()
+ Graphics.UI.GLFW: type DropCallback = -- | The window that received the event. Window -> -- | The file and/or directory path names [String] -> IO ()
Files
- GLFW-b.cabal +90/−91
- Graphics/UI/GLFW.hs +2066/−2066
- Graphics/UI/GLFW/C.hs +685/−685
- Graphics/UI/GLFW/Types.hs +647/−647
- README.md +44/−44
- Test.hs +683/−685
GLFW-b.cabal view
@@ -1,91 +1,90 @@-name: GLFW-b -version: 3.3.0.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.3.0, released 2019-04-15 - (<http://www.glfw.org/Version-3.3.0-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 - , array >= 0.5.3.0 - , bindings-GLFW >= 3.3.0.0 - --------------------------------------------------------------------------------- - -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: - GLFW-b - , HUnit >= 1.3 && < 1.7 - , base < 5 - , array >= 0.5.3.0 - , bindings-GLFW >= 3.3.0.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.3.9.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.3.9, released 2023-12-13+ (<http://www.glfw.org/Version-3.3.0-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+ Graphics.UI.GLFW.C++ other-modules:+ Graphics.UI.GLFW.Types++ build-depends:+ base < 5+ , deepseq >= 1.1.0.0+ , array >= 0.5.3.0+ , bindings-GLFW >= 3.3.9.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.Types++ build-depends:+ GLFW-b+ , HUnit >= 1.3 && < 1.7+ , base < 5+ , array >= 0.5.3.0+ , bindings-GLFW >= 3.3.9.1+ , 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,2067 +1,2067 @@-{-# LANGUAGE ScopedTypeVariables #-} -{-| - -Threading restrictions which apply to the C version of GLFW still apply when -writing @GLFW-b@ programs. See -<http://www.glfw.org/docs/3.3/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.3/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.3/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 - , InitHint(..) - , initHint - , terminate - , getVersion - , getVersionString - , getError - , clearError - , rawMouseMotionSupported - - -- * Monitor handling - , Monitor - , MonitorState (..) - , VideoMode (..) - , GammaRamp (gammaRampRed, gammaRampGreen, gammaRampBlue) - , makeGammaRamp - -- - , getMonitors - , getPrimaryMonitor - , getMonitorPos - , getMonitorPhysicalSize - , getMonitorContentScale - , getMonitorWorkarea - , getMonitorName - , setMonitorCallback, MonitorCallback - , getVideoModes - , getVideoMode - , setGamma - , getGammaRamp - , setGammaRamp - - -- * Window handling - , Window - , WindowHint (..) - , WindowAttrib (..) - , ContextRobustness (..) - , OpenGLProfile (..) - , ClientAPI (..) - , ContextCreationAPI (..) - , ContextReleaseBehavior (..) - -- - , defaultWindowHints - , windowHint - , setWindowAttrib - , getWindowAttrib - , createWindow - , destroyWindow - , windowShouldClose - , setWindowShouldClose - , getWindowOpacity - , setWindowOpacity - , setWindowTitle - , getWindowPos - , setWindowPos - , getWindowSize - , setWindowSize - , setWindowSizeLimits - , setWindowAspectRatio - , getWindowFrameSize - , getWindowContentScale - , getFramebufferSize - , setWindowIcon - , iconifyWindow - , restoreWindow - , focusWindow - , maximizeWindow - , showWindow - , hideWindow - , requestWindowAttention - , 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 - , setWindowContentScaleCallback, WindowContentScaleCallback - , setWindowMaximizeCallback, WindowMaximizeCallback - , pollEvents - , waitEvents - , waitEventsTimeout - , postEmptyEvent - - -- * Input handling - , Key (..) - , KeyState (..) - , Joystick (..) - , JoystickState (..) - , JoystickButtonState (..) - , MouseButton (..) - , MouseButtonState (..) - , CursorState (..) - , CursorInputMode (..) - , StickyKeysInputMode (..) - , StickyMouseButtonsInputMode (..) - , ModifierKeys (..) - , GamepadButton (..) - , GamepadAxis (..) - , GamepadButtonState (..) - , GamepadState (..) - , Image - , mkImage - , Cursor (..) - , StandardCursorShape (..) - -- - -- related to c'glfwSetInputMode ----. - , getCursorInputMode -- | - , setCursorInputMode -- | - , getRawMouseMotion -- | - , setRawMouseMotion -- | - , getStickyKeysInputMode -- | - , setStickyKeysInputMode -- | - , getStickyMouseButtonsInputMode -- | - , setStickyMouseButtonsInputMode -----' - , getKey - , getKeyName - , getKeyScancode - , getMouseButton - , getCursorPos - , setKeyCallback, KeyCallback - , setCharCallback, CharCallback - , setCharModsCallback, CharModsCallback - , setMouseButtonCallback, MouseButtonCallback - , setCursorPosCallback, CursorPosCallback - , setCursorEnterCallback, CursorEnterCallback - , createCursor - , createStandardCursor - , setCursor - , destroyCursor - , setScrollCallback, ScrollCallback - , setDropCallback, DropCallback - , joystickPresent - , joystickIsGamepad - , getJoystickAxes - , getJoystickButtons - , getJoystickHats, JoystickHatState(..) - , getJoystickName - , getJoystickGUID - , setJoystickCallback, JoystickCallback - , getGamepadName - , getGamepadState - , updateGamepadMappings - - -- * 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 - , getX11SelectionString - , setX11SelectionString - , getGLXContext - , getGLXWindow - , getWaylandDisplay - , getWaylandMonitor - , getWaylandWindow - , getEGLDisplay - , getEGLContext - , getEGLSurface - , getOSMesaContext - , getOSMesaColorBuffer, OSMesaColorBuffer, OSMesaRGBA - , getOSMesaDepthBuffer, OSMesaDepthBuffer - ) where - --------------------------------------------------------------------------------- - -import Prelude hiding (init) - -import Control.Monad (when, liftM, forM) -import Data.Array.IArray (Array, array) -import Data.Bits (shiftR, shiftL, (.&.), (.|.)) -import Data.IORef (IORef, atomicModifyIORef, newIORef, readIORef) -import Data.List (foldl') -import Data.Word (Word8, Word16, Word32, Word64) -import Foreign.C.String (peekCString, withCString, CString) -import Foreign.C.Types (CUInt, CInt, CUShort, CFloat(..)) -import Foreign.Marshal.Alloc (alloca, allocaBytes) -import Foreign.Marshal.Array (advancePtr, allocaArray, peekArray, withArray) -import Foreign.Ptr ( FunPtr, freeHaskellFunPtr, nullFunPtr, nullPtr - , Ptr, castPtr, plusPtr) -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 - --------------------------------------------------------------------------------- --- Helper functions - --- C to haskell float. -hFloat :: CFloat -> Float -hFloat (CFloat f) = f - --------------------------------------------------------------------------------- - --- 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 () --- | Fires when a window is rescaled -type WindowContentScaleCallback = Window -> Float -> Float -> IO () --- | Fires when a window is maximized or restored. Returns True if the window --- was maximized and False if the window was restored. -type WindowMaximizeCallback = Window -> Bool -> IO () --------------------------------------------------------------------------------- --- 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.3/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.3/group__init.html#ga317aac130a235ab08c6db0834907d85e glfwInit> --- and <http://www.glfw.org/docs/3.3/intro.html#intro_init Initialization and Termination> -init :: IO Bool -init = fromC `fmap` c'glfwInit - --- | This function sets hints for the next initialization of GLFW. See --- <https://www.glfw.org/docs/3.3/group__init.html#ga110fd1d3f0412822b4f1908c026f724a glfwInitHint> -initHint :: InitHint -> Bool -> IO () -initHint hint val = c'glfwInitHint (toC hint) (toC val) - --- | 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.3/group__init.html#gaaae48c0a18607ea4a4ba951d939f0901 glfwTerminate> --- and <http://www.glfw.org/docs/3.3/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.3/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.3/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 - --- | Returns and clears the error code of the last error that occurred on the --- calling thread and a UTF-8 encoded human-readable description of it. If no --- error has occurred since the last call, it returns Nothing. -getError :: IO (Maybe (Error, String)) -getError = alloca $ \errStr -> do - err <- c'glfwGetError errStr - if err == c'GLFW_NO_ERROR - then return Nothing - else peek errStr - >>= peekCString - >>= (\s -> return $ Just (fromC err, s)) - --- | Clears the last error as would be retreived by 'getError'. -clearError :: IO () -clearError = c'glfwGetError nullPtr >> pure () - --- | Returns true if raw mouse motion is supported on the current system. --- See <https://www.glfw.org/docs/3.3/group__input.html#gae4ee0dbd0d256183e1ea4026d897e1c2 glfwRawMouseMotionSupported> -rawMouseMotionSupported :: IO Bool -rawMouseMotionSupported = fromC <$> c'glfwRawMouseMotionSupported - --------------------------------------------------------------------------------- --- Monitor handling - --- | Gets the list of available monitors, if possible. --- See <http://www.glfw.org/docs/3.3/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.3/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.3/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.3/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.3/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.3/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.3/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.3/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.3/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.3/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.3/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 - --- | This function retrieves the content scale for the specified monitor. The --- content scale is the ratio between the current DPI and the platform's default --- DPI. --- See <https://www.glfw.org/docs/3.3/group__monitor.html#gad3152e84465fa620b601265ebfcdb21b glfwGetMonitorContentScale> -getMonitorContentScale :: Monitor -> IO (Float, Float) -getMonitorContentScale mon = - alloca $ \p'x -> - alloca $ \p'y -> do - c'glfwGetMonitorContentScale (toC mon) p'x p'y - CFloat x <- peek p'x - CFloat y <- peek p'y - return (x, y) - --- | This function returns the position, in screen coordinates, of the --- upper-left corner of the work area of the specified monitor along with the --- work area size in screen coordinates. Returned tuple is: --- (xPos, yPos, width, height) --- See <https://www.glfw.org/docs/3.3/group__monitor.html#ga7387a3bdb64bfe8ebf2b9e54f5b6c9d0 glfwGetMonitorWorkarea> -getMonitorWorkarea :: Monitor -> IO (Int, Int, Int, Int) -getMonitorWorkarea mon = - alloca $ \p'x -> - alloca $ \p'y -> - alloca $ \p'w -> - alloca $ \p'h -> do - c'glfwGetMonitorWorkarea (toC mon) p'x p'y p'w p'h - x <- fromC <$> peek p'x - y <- fromC <$> peek p'y - w <- fromC <$> peek p'w - h <- fromC <$> peek p'h - return (x, y, w, h) - --------------------------------------------------------------------------------- --- Window handling - --- | Sets all the window hints to default. --- See <http://www.glfw.org/docs/3.3/group__window.html#gaa77c4898dfb83344a6b4f76aa16b9a4a glfwDefaultWindowHints> -defaultWindowHints :: IO () -defaultWindowHints = - c'glfwDefaultWindowHints - -setStringHint :: CInt -> String -> IO () -setStringHint hint = flip withCString (c'glfwWindowHintString hint) - --- | Hints something to the GLFW windowing system. --- See --- <http://www.glfw.org/docs/3.3/group__window.html#ga7d9c8c62384b1e2821c4dc48952d2033 glfwWindowHint> --- and --- <https://www.glfw.org/docs/3.3/group__window.html#ga8cb2782861c9d997bcf2dea97f363e5f glfwWindowHintString> -windowHint :: WindowHint -> IO () -windowHint (WindowHint'Resizable x) = - c'glfwWindowHint c'GLFW_RESIZABLE (toC x) -windowHint (WindowHint'Visible x) = - c'glfwWindowHint c'GLFW_VISIBLE (toC x) -windowHint (WindowHint'Decorated x) = - c'glfwWindowHint c'GLFW_DECORATED (toC x) -windowHint (WindowHint'RedBits x) = - c'glfwWindowHint c'GLFW_RED_BITS (toC x) -windowHint (WindowHint'GreenBits x) = - c'glfwWindowHint c'GLFW_GREEN_BITS (toC x) -windowHint (WindowHint'BlueBits x) = - c'glfwWindowHint c'GLFW_BLUE_BITS (toC x) -windowHint (WindowHint'AlphaBits x) = - c'glfwWindowHint c'GLFW_ALPHA_BITS (toC x) -windowHint (WindowHint'DepthBits x) = - c'glfwWindowHint c'GLFW_DEPTH_BITS (toC x) -windowHint (WindowHint'StencilBits x) = - c'glfwWindowHint c'GLFW_STENCIL_BITS (toC x) -windowHint (WindowHint'AccumRedBits x) = - c'glfwWindowHint c'GLFW_ACCUM_RED_BITS (toC x) -windowHint (WindowHint'AccumGreenBits x) = - c'glfwWindowHint c'GLFW_ACCUM_GREEN_BITS (toC x) -windowHint (WindowHint'AccumBlueBits x) = - c'glfwWindowHint c'GLFW_ACCUM_BLUE_BITS (toC x) -windowHint (WindowHint'AccumAlphaBits x) = - c'glfwWindowHint c'GLFW_ACCUM_ALPHA_BITS (toC x) -windowHint (WindowHint'AuxBuffers x) = - c'glfwWindowHint c'GLFW_AUX_BUFFERS (toC x) -windowHint (WindowHint'Samples x) = - c'glfwWindowHint c'GLFW_SAMPLES (toC x) -windowHint (WindowHint'RefreshRate x) = - c'glfwWindowHint c'GLFW_REFRESH_RATE (toC x) -windowHint (WindowHint'DoubleBuffer x) = - c'glfwWindowHint c'GLFW_DOUBLEBUFFER (toC x) -windowHint (WindowHint'Stereo x) = - c'glfwWindowHint c'GLFW_STEREO (toC x) -windowHint (WindowHint'sRGBCapable x) = - c'glfwWindowHint c'GLFW_SRGB_CAPABLE (toC x) -windowHint (WindowHint'Floating x) = - c'glfwWindowHint c'GLFW_FLOATING (toC x) -windowHint (WindowHint'Focused x) = - c'glfwWindowHint c'GLFW_FOCUSED (toC x) -windowHint (WindowHint'Maximized x) = - c'glfwWindowHint c'GLFW_MAXIMIZED (toC x) -windowHint (WindowHint'AutoIconify x) = - c'glfwWindowHint c'GLFW_AUTO_ICONIFY (toC x) -windowHint (WindowHint'ClientAPI x) = - c'glfwWindowHint c'GLFW_CLIENT_API (toC x) -windowHint (WindowHint'ContextCreationAPI x) = - c'glfwWindowHint c'GLFW_CONTEXT_CREATION_API (toC x) -windowHint (WindowHint'ContextVersionMajor x) = - c'glfwWindowHint c'GLFW_CONTEXT_VERSION_MAJOR (toC x) -windowHint (WindowHint'ContextVersionMinor x) = - c'glfwWindowHint c'GLFW_CONTEXT_VERSION_MINOR (toC x) -windowHint (WindowHint'ContextRobustness x) = - c'glfwWindowHint c'GLFW_CONTEXT_ROBUSTNESS (toC x) -windowHint (WindowHint'ContextReleaseBehavior x) = - c'glfwWindowHint c'GLFW_CONTEXT_RELEASE_BEHAVIOR (toC x) -windowHint (WindowHint'ContextNoError x) = - c'glfwWindowHint c'GLFW_CONTEXT_NO_ERROR (toC x) -windowHint (WindowHint'OpenGLForwardCompat x) = - c'glfwWindowHint c'GLFW_OPENGL_FORWARD_COMPAT (toC x) -windowHint (WindowHint'OpenGLDebugContext x) = - c'glfwWindowHint c'GLFW_OPENGL_DEBUG_CONTEXT (toC x) -windowHint (WindowHint'OpenGLProfile x) = - c'glfwWindowHint c'GLFW_OPENGL_PROFILE (toC x) -windowHint (WindowHint'TransparentFramebuffer x) = - c'glfwWindowHint c'GLFW_TRANSPARENT_FRAMEBUFFER (toC x) -windowHint (WindowHint'CenterCursor x) = - c'glfwWindowHint c'GLFW_CENTER_CURSOR (toC x) -windowHint (WindowHint'FocusOnShow x) = - c'glfwWindowHint c'GLFW_FOCUS_ON_SHOW (toC x) -windowHint (WindowHint'ScaleToMonitor x) = - c'glfwWindowHint c'GLFW_SCALE_TO_MONITOR (toC x) -windowHint (WindowHint'CocoaRetinaFramebuffer x) = - c'glfwWindowHint c'GLFW_COCOA_RETINA_FRAMEBUFFER (toC x) -windowHint (WindowHint'CocoaGraphicsSwitching x) = - c'glfwWindowHint c'GLFW_COCOA_GRAPHICS_SWITCHING (toC x) -windowHint (WindowHint'CocoaFrameName x) = setStringHint c'GLFW_COCOA_FRAME_NAME x -windowHint (WindowHint'X11ClassName x) = setStringHint c'GLFW_X11_CLASS_NAME x -windowHint (WindowHint'X11InstanceName x) = setStringHint c'GLFW_X11_INSTANCE_NAME x - --- | Creates c'a new window. (toC x) --- 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.3/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.3/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 - windowContentScaleFun <- newIORef nullFunPtr - windowMaximizeFun <- 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 - , storedWindowContentScaleFun = windowContentScaleFun - , storedWindowMaximizeFun = windowMaximizeFun - , 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) - -- Not sure why this isn't the default... - c'glfwSetInputMode p'win c'GLFW_LOCK_KEY_MODS (toC True) - return $ Just $ fromC p'win - --- | Cleans up a window and all associated resources --- See <http://www.glfw.org/docs/3.3/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 - --- | Returns the value of an attribute of the specified window or its OpenGL or --- OpenGL ES context. --- See <https://www.glfw.org/docs/3.3/group__window.html#gacccb29947ea4b16860ebef42c2cb9337 glfwGetWindowAttrib> -getWindowAttrib :: Window -> WindowAttrib -> IO Bool -getWindowAttrib win attrib = - fromC <$> c'glfwGetWindowAttrib (toC win) (toC attrib) - --- | Sets the value of an attribute of the specified window. --- See <https://www.glfw.org/docs/3.3/group__window.html#gace2afda29b4116ec012e410a6819033e glfwSetWindowAttrib> -setWindowAttrib :: Window -> WindowAttrib -> Bool -> IO () -setWindowAttrib win attrib = c'glfwSetWindowAttrib (toC win) (toC attrib) . toC - --- | If the window should close or not. --- See <http://www.glfw.org/docs/3.3/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.3/group__window.html#ga49c449dde2a6f87d996f4daaa09d6708 glfwSetWindowShouldClose> -setWindowShouldClose :: Window -> Bool -> IO () -setWindowShouldClose win b = - c'glfwSetWindowShouldClose (toC win) (toC b) - --- | Returns the opacity of the window, including any decorations. --- See <https://www.glfw.org/docs/3.3/group__window.html#gad09f0bd7a6307c4533b7061828480a84 glfwGetWindowOpacity -getWindowOpacity :: Window -> IO Float -getWindowOpacity = fmap hFloat . c'glfwGetWindowOpacity . toC - --- | Sets the opacity of the window, including any decorations --- See <https://www.glfw.org/docs/3.3/group__window.html#gac31caeb3d1088831b13d2c8a156802e9 glfwSetWindowOpacity> -setWindowOpacity :: Window -> Float -> IO () -setWindowOpacity win op = c'glfwSetWindowOpacity (toC win) (CFloat op) - --- | Sets the Title string of the window. --- See <http://www.glfw.org/docs/3.3/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.3/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.3/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.3/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.3/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.3/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.3/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.3/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) - --- | This function retrieves the content scale for the specified window. The --- content scale is the ratio between the current DPI and the platform's --- default DPI. --- See <https://www.glfw.org/docs/3.3/group__window.html#gaf5d31de9c19c4f994facea64d2b3106c glfwGetWindowContentScale> -getWindowContentScale :: Window -> IO (Float, Float) -getWindowContentScale win = - alloca $ \p'x -> - alloca $ \p'y -> do - c'glfwGetWindowContentScale (toC win) p'x p'y - CFloat x <- peek p'x - CFloat y <- peek p'y - return (x, y) - --- | The size of the framebuffer (in Pixels) --- See <http://www.glfw.org/docs/3.3/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.3/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.3/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.3/group__window.html#ga3f541387449d911274324ae7f17ec56b glfwMaximizeWindow> -maximizeWindow :: Window -> IO () -maximizeWindow = c'glfwMaximizeWindow . toC - --- | Shows the window. --- See <http://www.glfw.org/docs/3.3/group__window.html#ga61be47917b72536a148300f46494fc66 glfwShowWindow> -showWindow :: Window -> IO () -showWindow = c'glfwShowWindow . toC - --- | Hides the window. --- See <http://www.glfw.org/docs/3.3/group__window.html#ga49401f82a1ba5f15db5590728314d47c glfwHideWindow> -hideWindow :: Window -> IO () -hideWindow = c'glfwHideWindow . toC - --- | Requests user attention to the specified window. --- See <https://www.glfw.org/docs/3.3/group__window.html#ga2f8d59323fc4692c1d54ba08c863a703 glfwRequestWindowAttention> -requestWindowAttention :: Window -> IO () -requestWindowAttention = c'glfwRequestWindowAttention . toC - --- | Gets the monitor that this window is running on, provided the window is --- fullscreen. --- See <http://www.glfw.org/docs/3.3/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.3/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.3/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.3/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.3/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.3/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.3/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.3/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.3/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.3/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.3/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.3/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.3/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.3/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.3/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.3/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.3/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.3/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.3/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.3/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.3/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.3/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.3/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.3/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.3/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.3/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 for when the content scale of the window changes. --- See <https://www.glfw.org/docs/3.3/window_guide.html#window_scale Window Content Scale> -setWindowContentScaleCallback :: Window -> Maybe WindowContentScaleCallback -> IO () -setWindowContentScaleCallback win = setWindowCallback - mk'GLFWwindowcontentscalefun - (\cb w (CFloat f1) (CFloat f2) -> schedule $ cb (fromC w) f1 f2) - (c'glfwSetWindowContentScaleCallback (toC win)) - storedWindowContentScaleFun - win - --- | Sets the maximization callback of the specified window, which is called --- when the window is maximized or restored. --- See <https://www.glfw.org/docs/3.3/window_guide.html#window_maximize Window maximization> -setWindowMaximizeCallback :: Window -> Maybe WindowMaximizeCallback -> IO () -setWindowMaximizeCallback win = setWindowCallback - mk'GLFWwindowmaximizefun - (\cb w x -> schedule $ cb (fromC w) (fromC x)) - (c'glfwSetWindowMaximizeCallback (toC win)) - storedWindowMaximizeFun - win - --- | Sets the callback to use when the framebuffer's size changes. --- See <http://www.glfw.org/docs/3.3/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.3/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.3/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.3/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.3/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.3/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.3/group__input.html#gaa92336e173da9c8834558b54ee80563b glfwSetInputMode> -setCursorInputMode :: Window -> CursorInputMode -> IO () -setCursorInputMode win c = - c'glfwSetInputMode (toC win) c'GLFW_CURSOR (toC c) - --- | Sets the cursor to receive raw input, if available (See --- rawMouseMotionSupported and --- <https://www.glfw.org/docs/3.3/input_guide.html#raw_mouse_motion Raw Mouse Motion> -setRawMouseMotion :: Window -> Bool -> IO () -setRawMouseMotion win toggle = do - supported <- rawMouseMotionSupported - if not supported - then putStrLn "WARNING -- Asked to set raw mouse motion but is unsupported" - else c'glfwSetInputMode (toC win) c'GLFW_RAW_MOUSE_MOTION (toC toggle) - --- | Returns whether or not we've currently enabled raw mouse motion. --- See <https://www.glfw.org/docs/3.3/input_guide.html#raw_mouse_motion Raw Mouse Motion> -getRawMouseMotion :: Window -> IO Bool -getRawMouseMotion win = - fromC <$> c'glfwGetInputMode (toC win) c'GLFW_RAW_MOUSE_MOTION - --- | Gets the current sticky keys mode. --- See <http://www.glfw.org/docs/3.3/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.3/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.3/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.3/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.3/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.3/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 - --- | This function returns the platform-specific scancode of the specified key. --- See <https://www.glfw.org/docs/3.3/group__input.html#ga67ddd1b7dcbbaff03e4a76c0ea67103a glfwGetKeyScancode> -getKeyScancode :: Key -> IO Int -getKeyScancode = fmap fromC . c'glfwGetKeyScancode . toC - --- | 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.3/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.3/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.3/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.3/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.3/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.3/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.3/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.3/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.3/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.3/group__input.html#gaffcbd9ac8ee737fcdd25475123a3c790 glfwJoystickPresent> -joystickPresent :: Joystick -> IO Bool -joystickPresent = fmap fromC . c'glfwJoystickPresent . toC - --- | 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.3/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 <$> peek p'n - if p'axes == nullPtr || n <= 0 - then return Nothing - else (Just . map fromC) <$> peekArray n p'axes - --- | Returns a list of all joystick button states for the specified joystick. --- See <http://www.glfw.org/docs/3.3/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 <$> peek p'n - if p'buttons == nullPtr || n <= 0 - then return Nothing - else (Just . map fromC) <$> peekArray n p'buttons - --- | Returns a list of all hats of the specified joystick. --- See <https://www.glfw.org/docs/3.3/group__input.html#ga2d8d0634bb81c180899aeb07477a67ea glfwGetJoystickHats> -getJoystickHats :: Joystick -> IO (Maybe [JoystickHatState]) -getJoystickHats js = alloca $ \p'n -> do - p'hats <- c'glfwGetJoystickHats (toC js) p'n - n <- fromC <$> peek p'n - if p'hats == nullPtr || n <= 0 - then return Nothing - else (Just . map fromC) <$> peekArray n p'hats - --- | A human-readable name for a Joystick. Not guranteed to be unique. --- See <http://www.glfw.org/docs/3.3/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 <$> peekCString p'name - --- | Sets a callback for when a joystick is connected or disconnected. --- See <http://www.glfw.org/docs/3.3/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 - --- | Adds the specified SDL_GameControllerDB gamepad mappings. --- See <https://www.glfw.org/docs/3.3/group__input.html#gaed5104612f2fa8e66aa6e846652ad00f glfwUpdateGamepadMappings> -updateGamepadMappings :: String -> IO Bool -updateGamepadMappings = - flip withCString $ \s -> fromC <$> c'glfwUpdateGamepadMappings s - --- | This function returns whether the specified joystick is both present and --- has a gamepad mapping. --- See <https://www.glfw.org/docs/3.3/group__input.html#gad0f676860f329d80f7e47e9f06a96f00 glfwJoystickIsGamepad> -joystickIsGamepad :: Joystick -> IO Bool -joystickIsGamepad = fmap (== c'GLFW_TRUE) . c'glfwJoystickIsGamepad . toC - --- | This function returns the SDL compatible GUID of the specified joystick. --- See <https://www.glfw.org/docs/3.3/group__input.html#gae168c2c0b8cf2a1cb67c6b3c00bdd543 glfwGetJoystickGUID> -getJoystickGUID :: Joystick -> IO (Maybe String) -getJoystickGUID js = do - p'guid <- c'glfwGetJoystickGUID (toC js) - if p'guid == nullPtr - then return Nothing - else Just <$> peekCString p'guid - --- | This function returns the human-readable name of the gamepad from the --- gamepad mapping assigned to the specified joystick. --- See <https://www.glfw.org/docs/3.3/group__input.html#ga5c71e3533b2d384db9317fcd7661b210 glfwGetGamepadName> -getGamepadName :: Joystick -> IO (Maybe String) -getGamepadName js = do - p'name <- c'glfwGetGamepadName (toC js) - if p'name == nullPtr - then return Nothing - else Just <$> peekCString p'name - --- | This function retrives the state of the specified joystick remapped to an --- Xbox-like gamepad. --- See <https://www.glfw.org/docs/3.3/group__input.html#gadccddea8bce6113fa459de379ddaf051 glfwGetGamepadState> -getGamepadState :: Joystick -> IO (Maybe GamepadState) -getGamepadState js = alloca $ \p'gps -> do - hasGamepad <- fromC <$> c'glfwGetGamepadState (toC js) p'gps - if hasGamepad - then do - gps <- peek p'gps - return $ Just GamepadState - { getButtonState = fromC . (c'GLFWgamepadstate'buttons gps !!) - . (fromIntegral :: CInt -> Int) - . toC - , getAxisState = hFloat - . (c'GLFWgamepadstate'axes gps !!) - . (fromIntegral :: CInt -> Int) - . toC - } - else return Nothing - --------------------------------------------------------------------------------- --- 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.3/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.3/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.3/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.3/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.3/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.3/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.3/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.3/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.3/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.3/input.html#clipboard - --- | The window that will own the clipboard contents, and also the clipboard string. --- See <http://www.glfw.org/docs/3.3/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.3/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.3/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.3/group__native.html#gac84f63a3f9db145b9435e5e0dbc4183d glfwGetWin32Adapter> -getWin32Adapter :: Window -> IO CString -getWin32Adapter = c'glfwGetWin32Adapter . toC - --- | See <http://www.glfw.org/docs/3.3/group__native.html#gac408b09a330749402d5d1fa1f5894dd9 glfwGetWin32Monitor> -getWin32Monitor :: Window -> IO CString -getWin32Monitor = c'glfwGetWin32Monitor . toC - --- | See <http://www.glfw.org/docs/3.3/group__native.html#gafe5079aa79038b0079fc09d5f0a8e667 glfwGetWin32Window> -getWin32Window :: Window -> IO (Ptr ()) -getWin32Window = c'glfwGetWin32Window . toC - --- | See <http://www.glfw.org/docs/3.3/group__native.html#gadc4010d91d9cc1134d040eeb1202a143 glfwGetWGLContext> -getWGLContext :: Window -> IO (Ptr ()) -getWGLContext = c'glfwGetWGLContext . toC - --- | See <http://www.glfw.org/docs/3.3/group__native.html#gaf22f429aec4b1aab316142d66d9be3e6 glfwGetCocoaMonitor> -getCocoaMonitor :: Window -> IO (Ptr Word32) -getCocoaMonitor = c'glfwGetCocoaMonitor . toC - --- | See <http://www.glfw.org/docs/3.3/group__native.html#gac3ed9d495d0c2bb9652de5a50c648715 glfwGetCocoaWindow> -getCocoaWindow :: Window -> IO (Ptr ()) -getCocoaWindow = c'glfwGetCocoaWindow . toC - --- | See <http://www.glfw.org/docs/3.3/group__native.html#ga559e002e3cd63c979881770cd4dc63bc glfwGetNSGLContext> -getNSGLContext :: Window -> IO (Ptr ()) -getNSGLContext = c'glfwGetNSGLContext . toC - --- | See <http://www.glfw.org/docs/3.3/group__native.html#ga8519b66594ea3ef6eeafaa2e3ee37406 glfwGetX11Display> -getX11Display :: Window -> IO (Ptr display) -getX11Display = c'glfwGetX11Display . toC - --- | See <http://www.glfw.org/docs/3.3/group__native.html#ga088fbfa80f50569402b41be71ad66e40 glfwGetX11Adapter> -getX11Adapter :: Window -> IO Word64 -getX11Adapter = c'glfwGetX11Adapter . toC - --- | See <http://www.glfw.org/docs/3.3/group__native.html#gab2f8cc043905e9fa9b12bfdbbcfe874c glfwGetX11Monitor> -getX11Monitor :: Window -> IO Word64 -getX11Monitor = c'glfwGetX11Monitor . toC - --- | See <http://www.glfw.org/docs/3.3/group__native.html#ga90ca676322740842db446999a1b1f21d glfwGetX11Window> -getX11Window :: Window -> IO Word64 -getX11Window = c'glfwGetX11Window . toC - --- | See <https://www.glfw.org/docs/3.3/group__native.html#ga72f23e3980b83788c70aa854eca31430 glfwGetX11SelectionString> -getX11SelectionString :: IO String -getX11SelectionString = c'glfwGetX11SelectionString >>= peekCString - --- | See <https://www.glfw.org/docs/3.3/group__native.html#ga55f879ab02d93367f966186b6f0133f7 glfwSetX11SelectionString> -setX11SelectionString :: String -> IO () -setX11SelectionString = flip withCString c'glfwSetX11SelectionString - --- | See <http://www.glfw.org/docs/3.3/group__native.html#ga62d884114b0abfcdc2930e89f20867e2 glfwGetGLXContext> -getGLXContext :: Window -> IO (Ptr ()) -getGLXContext = c'glfwGetGLXContext . toC - --- | See <http://www.glfw.org/docs/3.3/group__native.html#ga1ed27b8766e859a21381e8f8ce18d049 glfwGetGLXWindow> -getGLXWindow :: Window -> IO Word64 -getGLXWindow = c'glfwGetGLXWindow . toC - --- | See <http://www.glfw.org/docs/3.3/group__native.html#gaaf8118a3c877f3a6bc8e7a649519de5e glfwGetWaylandDisplay> -getWaylandDisplay :: IO (Ptr wl_display) -getWaylandDisplay = c'glfwGetWaylandDisplay - --- | See <http://www.glfw.org/docs/3.3/group__native.html#gab10427a667b6cd91eec7709f7a906bd3 glfwGetWaylandMonitor> -getWaylandMonitor :: Window -> IO (Ptr wl_output) -getWaylandMonitor = c'glfwGetWaylandMonitor . toC - --- | See <http://www.glfw.org/docs/3.3/group__native.html#ga4738d7aca4191363519a9a641c3ab64c glfwGetWaylandWindow> -getWaylandWindow :: Window -> IO (Ptr wl_surface) -getWaylandWindow = c'glfwGetWaylandWindow . toC - --- | See <http://www.glfw.org/docs/3.3/group__native.html#ga1cd8d973f47aacb5532d368147cc3138 glfwGetEGLDisplay> -getEGLDisplay :: IO (Ptr ()) -getEGLDisplay = c'glfwGetEGLDisplay - --- | See <http://www.glfw.org/docs/3.3/group__native.html#ga671c5072becd085f4ab5771a9c8efcf1 glfwGetEGLContext> -getEGLContext :: Window -> IO (Ptr ()) -getEGLContext = c'glfwGetEGLContext . toC - --- | See <http://www.glfw.org/docs/3.3/group__native.html#ga2199b36117a6a695fec8441d8052eee6 glfwGetEGLSurface> -getEGLSurface :: Window -> IO (Ptr ()) -getEGLSurface = c'glfwGetEGLSurface . toC - --- | See <https://www.glfw.org/docs/3.3/group__native.html#ga9e47700080094eb569cb053afaa88773 glfwGetOSMesaContext> -getOSMesaContext :: Window -> IO (Ptr ()) -getOSMesaContext = c'glfwGetOSMesaContext . toC - --- | An RGBA type is a low-dynamic range representation of a color, represented --- by a 32-bit value. The channels here are in order: R, G, B, A -type OSMesaRGBA = (Word8, Word8, Word8, Word8) - --- | A color buffer is a two dimensional array of RGBA values. The first --- dimension is width, and the second is height. --- --- TODO: It's a shame this is an Array and not a UArray. -type OSMesaColorBuffer = Array (Int, Int) OSMesaRGBA - --- | A depth buffer is a two dimensional array of depth values. The range is --- usually determined by a parameter returned from the query function. -type OSMesaDepthBuffer = Array (Int, Int) Word32 - --- | Returns the color buffer of the offscreen context provided by OSMesa. The --- color buffer is returned as an array whose integers are unsigned and --- represent the (R, G, B, A) values. For formats that do not have alpha, A --- will always be 255. -getOSMesaColorBuffer :: Window -> IO (Maybe OSMesaColorBuffer) -getOSMesaColorBuffer win = - alloca $ \p'width -> - alloca $ \p'height -> - alloca $ \p'format -> - alloca $ \p'buf -> do - result <- fromC <$> c'glfwGetOSMesaColorBuffer (toC win) - p'width p'height p'format p'buf - if not result then return Nothing else do - w <- fromIntegral <$> peek p'width - h <- fromIntegral <$> peek p'height - format <- peek p'format - buf <- peek p'buf - Just . array ((0, 0), (w, h)) <$> sequence - [ fmap (\rgba -> ((x, y), rgba)) $ - mkRGBA format (castPtr buf) (y * w + x) - | x <- [0..w] - , y <- [0..h] - ] - where - getByte :: Int -> Word32 -> Word8 - getByte i x = fromIntegral $ (x `shiftR` (i * 8)) .&. 0xFF - - mkRGBA :: CInt -> Ptr Word8 -> Int -> IO OSMesaRGBA - mkRGBA 0x1908 buf offset = do - -- OSMESA_RGBA - (rgba :: Word32) <- peekElemOff (castPtr buf) offset - return (getByte 0 rgba, getByte 1 rgba, getByte 2 rgba, getByte 3 rgba) - mkRGBA 0x1 buf offset = do - -- OSMESA_BGRA - (bgra :: Word32) <- peekElemOff (castPtr buf) offset - return (getByte 2 bgra, getByte 1 bgra, getByte 0 bgra, getByte 3 bgra) - mkRGBA 0x2 buf offset = do - -- OSMESA_ARGB - (argb :: Word32) <- peekElemOff (castPtr buf) offset - return (getByte 1 argb, getByte 2 argb, getByte 3 argb, getByte 0 argb) - mkRGBA 0x1907 buf offset = do - -- OSMESA_RGB - r <- peek (buf `plusPtr` (offset * 3 + 0)) - g <- peek (buf `plusPtr` (offset * 3 + 1)) - b <- peek (buf `plusPtr` (offset * 3 + 2)) - return (r, g, b, 255) - mkRGBA 0x4 buf offset = do - -- OSMESA_BGR - b <- peek (buf `plusPtr` (offset * 3 + 0)) - g <- peek (buf `plusPtr` (offset * 3 + 1)) - r <- peek (buf `plusPtr` (offset * 3 + 2)) - return (r, g, b, 255) - mkRGBA 0x5 buf offset = do - -- OSMESA_RGB_565 - (rgb :: Word16) <- peekElemOff (castPtr buf) offset - return ( - fromIntegral $ rgb .&. 0x1F, - fromIntegral $ (rgb `shiftR` 5) .&. 0x3F, - fromIntegral $ (rgb `shiftR` 11) .&. 0x1F, - 255) - mkRGBA fmt _ _ = error $ "Unrecognized OSMESA_FORMAT: " ++ show fmt - --- | Returns the depth buffer and maximum depth value of the offscreen render --- target that's provided by OSMesa. -getOSMesaDepthBuffer :: Window -> IO (Maybe (OSMesaDepthBuffer, Word32)) -getOSMesaDepthBuffer win = - alloca $ \p'width -> - alloca $ \p'height -> - alloca $ \p'bytesPerVal -> - alloca $ \p'buf -> do - result <- fromC <$> c'glfwGetOSMesaDepthBuffer (toC win) - p'width p'height p'bytesPerVal p'buf - if not result then return Nothing else do - w <- fromIntegral <$> peek p'width - h <- fromIntegral <$> peek p'height - bytesPerVal <- fromIntegral <$> peek p'bytesPerVal - buf <- peek p'buf - depthBuffer <- array ((0, 0), (w, h)) <$> sequence - [ fmap (\d -> ((x, y), d)) $ - mkDepth bytesPerVal (castPtr buf) (y * w + x) - | x <- [0..w] - , y <- [0..h] - ] - return (Just (depthBuffer, (1 `shiftL` (8 * bytesPerVal)) - 1)) - where - mkDepth :: Int -> Ptr Word8 -> Int -> IO Word32 - mkDepth bpv ptr offset = do - -- Assumes little-endian? - bytes <- forM [0..(bpv - 1)] $ \i -> peekElemOff ptr (offset * bpv + i) - return $ foldl' (\d -> ((d `shiftL` 8) .|.) . fromIntegral) 0 bytes +{-# LANGUAGE ScopedTypeVariables #-}+{-|++Threading restrictions which apply to the C version of GLFW still apply when+writing @GLFW-b@ programs. See+<http://www.glfw.org/docs/3.3/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.3/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.3/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+ , InitHint(..)+ , initHint+ , terminate+ , getVersion+ , getVersionString+ , getError+ , clearError+ , rawMouseMotionSupported++ -- * Monitor handling+ , Monitor+ , MonitorState (..)+ , VideoMode (..)+ , GammaRamp (gammaRampRed, gammaRampGreen, gammaRampBlue)+ , makeGammaRamp+ --+ , getMonitors+ , getPrimaryMonitor+ , getMonitorPos+ , getMonitorPhysicalSize+ , getMonitorContentScale+ , getMonitorWorkarea+ , getMonitorName+ , setMonitorCallback, MonitorCallback+ , getVideoModes+ , getVideoMode+ , setGamma+ , getGammaRamp+ , setGammaRamp++ -- * Window handling+ , Window+ , WindowHint (..)+ , WindowAttrib (..)+ , ContextRobustness (..)+ , OpenGLProfile (..)+ , ClientAPI (..)+ , ContextCreationAPI (..)+ , ContextReleaseBehavior (..)+ --+ , defaultWindowHints+ , windowHint+ , setWindowAttrib+ , getWindowAttrib+ , createWindow+ , destroyWindow+ , windowShouldClose+ , setWindowShouldClose+ , getWindowOpacity+ , setWindowOpacity+ , setWindowTitle+ , getWindowPos+ , setWindowPos+ , getWindowSize+ , setWindowSize+ , setWindowSizeLimits+ , setWindowAspectRatio+ , getWindowFrameSize+ , getWindowContentScale+ , getFramebufferSize+ , setWindowIcon+ , iconifyWindow+ , restoreWindow+ , focusWindow+ , maximizeWindow+ , showWindow+ , hideWindow+ , requestWindowAttention+ , 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+ , setWindowContentScaleCallback, WindowContentScaleCallback+ , setWindowMaximizeCallback, WindowMaximizeCallback+ , pollEvents+ , waitEvents+ , waitEventsTimeout+ , postEmptyEvent++ -- * Input handling+ , Key (..)+ , KeyState (..)+ , Joystick (..)+ , JoystickState (..)+ , JoystickButtonState (..)+ , MouseButton (..)+ , MouseButtonState (..)+ , CursorState (..)+ , CursorInputMode (..)+ , StickyKeysInputMode (..)+ , StickyMouseButtonsInputMode (..)+ , ModifierKeys (..)+ , GamepadButton (..)+ , GamepadAxis (..)+ , GamepadButtonState (..)+ , GamepadState (..)+ , Image+ , mkImage+ , Cursor (..)+ , StandardCursorShape (..)+ --+ -- related to c'glfwSetInputMode ----.+ , getCursorInputMode -- |+ , setCursorInputMode -- |+ , getRawMouseMotion -- |+ , setRawMouseMotion -- |+ , getStickyKeysInputMode -- |+ , setStickyKeysInputMode -- |+ , getStickyMouseButtonsInputMode -- |+ , setStickyMouseButtonsInputMode -----'+ , getKey+ , getKeyName+ , getKeyScancode+ , getMouseButton+ , getCursorPos+ , setKeyCallback, KeyCallback+ , setCharCallback, CharCallback+ , setCharModsCallback, CharModsCallback+ , setMouseButtonCallback, MouseButtonCallback+ , setCursorPosCallback, CursorPosCallback+ , setCursorEnterCallback, CursorEnterCallback+ , createCursor+ , createStandardCursor+ , setCursor+ , destroyCursor+ , setScrollCallback, ScrollCallback+ , setDropCallback, DropCallback+ , joystickPresent+ , joystickIsGamepad+ , getJoystickAxes+ , getJoystickButtons+ , getJoystickHats, JoystickHatState(..)+ , getJoystickName+ , getJoystickGUID+ , setJoystickCallback, JoystickCallback+ , getGamepadName+ , getGamepadState+ , updateGamepadMappings++ -- * 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+ , getX11SelectionString+ , setX11SelectionString+ , getGLXContext+ , getGLXWindow+ , getWaylandDisplay+ , getWaylandMonitor+ , getWaylandWindow+ , getEGLDisplay+ , getEGLContext+ , getEGLSurface+ , getOSMesaContext+ , getOSMesaColorBuffer, OSMesaColorBuffer, OSMesaRGBA+ , getOSMesaDepthBuffer, OSMesaDepthBuffer+ ) where++--------------------------------------------------------------------------------++import Prelude hiding (init)++import Control.Monad (when, liftM, forM)+import Data.Array.IArray (Array, array)+import Data.Bits (shiftR, shiftL, (.&.), (.|.))+import Data.IORef (IORef, atomicModifyIORef, newIORef, readIORef)+import Data.List (foldl')+import Data.Word (Word8, Word16, Word32, Word64)+import Foreign.C.String (peekCString, withCString, CString)+import Foreign.C.Types (CUInt, CInt, CUShort, CFloat(..))+import Foreign.Marshal.Alloc (alloca, allocaBytes)+import Foreign.Marshal.Array (advancePtr, allocaArray, peekArray, withArray)+import Foreign.Ptr ( FunPtr, freeHaskellFunPtr, nullFunPtr, nullPtr+ , Ptr, castPtr, plusPtr)+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++--------------------------------------------------------------------------------+-- Helper functions++-- C to haskell float.+hFloat :: CFloat -> Float+hFloat (CFloat f) = f++--------------------------------------------------------------------------------++-- 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 ()+-- | Fires when a window is rescaled+type WindowContentScaleCallback = Window -> Float -> Float -> IO ()+-- | Fires when a window is maximized or restored. Returns True if the window+-- was maximized and False if the window was restored.+type WindowMaximizeCallback = Window -> Bool -> IO ()+--------------------------------------------------------------------------------+-- 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.3/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.3/group__init.html#ga317aac130a235ab08c6db0834907d85e glfwInit>+-- and <http://www.glfw.org/docs/3.3/intro.html#intro_init Initialization and Termination>+init :: IO Bool+init = fromC `fmap` c'glfwInit++-- | This function sets hints for the next initialization of GLFW. See+-- <https://www.glfw.org/docs/3.3/group__init.html#ga110fd1d3f0412822b4f1908c026f724a glfwInitHint>+initHint :: InitHint -> Bool -> IO ()+initHint hint val = c'glfwInitHint (toC hint) (toC val)++-- | 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.3/group__init.html#gaaae48c0a18607ea4a4ba951d939f0901 glfwTerminate>+-- and <http://www.glfw.org/docs/3.3/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.3/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.3/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++-- | Returns and clears the error code of the last error that occurred on the+-- calling thread and a UTF-8 encoded human-readable description of it. If no+-- error has occurred since the last call, it returns Nothing.+getError :: IO (Maybe (Error, String))+getError = alloca $ \errStr -> do+ err <- c'glfwGetError errStr+ if err == c'GLFW_NO_ERROR+ then return Nothing+ else peek errStr+ >>= peekCString+ >>= (\s -> return $ Just (fromC err, s))++-- | Clears the last error as would be retreived by 'getError'.+clearError :: IO ()+clearError = c'glfwGetError nullPtr >> pure ()++-- | Returns true if raw mouse motion is supported on the current system.+-- See <https://www.glfw.org/docs/3.3/group__input.html#gae4ee0dbd0d256183e1ea4026d897e1c2 glfwRawMouseMotionSupported>+rawMouseMotionSupported :: IO Bool+rawMouseMotionSupported = fromC <$> c'glfwRawMouseMotionSupported++--------------------------------------------------------------------------------+-- Monitor handling++-- | Gets the list of available monitors, if possible.+-- See <http://www.glfw.org/docs/3.3/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.3/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.3/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.3/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.3/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.3/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.3/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.3/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.3/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.3/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.3/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++-- | This function retrieves the content scale for the specified monitor. The+-- content scale is the ratio between the current DPI and the platform's default+-- DPI.+-- See <https://www.glfw.org/docs/3.3/group__monitor.html#gad3152e84465fa620b601265ebfcdb21b glfwGetMonitorContentScale>+getMonitorContentScale :: Monitor -> IO (Float, Float)+getMonitorContentScale mon =+ alloca $ \p'x ->+ alloca $ \p'y -> do+ c'glfwGetMonitorContentScale (toC mon) p'x p'y+ CFloat x <- peek p'x+ CFloat y <- peek p'y+ return (x, y)++-- | This function returns the position, in screen coordinates, of the+-- upper-left corner of the work area of the specified monitor along with the+-- work area size in screen coordinates. Returned tuple is:+-- (xPos, yPos, width, height)+-- See <https://www.glfw.org/docs/3.3/group__monitor.html#ga7387a3bdb64bfe8ebf2b9e54f5b6c9d0 glfwGetMonitorWorkarea>+getMonitorWorkarea :: Monitor -> IO (Int, Int, Int, Int)+getMonitorWorkarea mon =+ alloca $ \p'x ->+ alloca $ \p'y ->+ alloca $ \p'w ->+ alloca $ \p'h -> do+ c'glfwGetMonitorWorkarea (toC mon) p'x p'y p'w p'h+ x <- fromC <$> peek p'x+ y <- fromC <$> peek p'y+ w <- fromC <$> peek p'w+ h <- fromC <$> peek p'h+ return (x, y, w, h)++--------------------------------------------------------------------------------+-- Window handling++-- | Sets all the window hints to default.+-- See <http://www.glfw.org/docs/3.3/group__window.html#gaa77c4898dfb83344a6b4f76aa16b9a4a glfwDefaultWindowHints>+defaultWindowHints :: IO ()+defaultWindowHints =+ c'glfwDefaultWindowHints++setStringHint :: CInt -> String -> IO ()+setStringHint hint = flip withCString (c'glfwWindowHintString hint)++-- | Hints something to the GLFW windowing system.+-- See+-- <http://www.glfw.org/docs/3.3/group__window.html#ga7d9c8c62384b1e2821c4dc48952d2033 glfwWindowHint>+-- and+-- <https://www.glfw.org/docs/3.3/group__window.html#ga8cb2782861c9d997bcf2dea97f363e5f glfwWindowHintString>+windowHint :: WindowHint -> IO ()+windowHint (WindowHint'Resizable x) =+ c'glfwWindowHint c'GLFW_RESIZABLE (toC x)+windowHint (WindowHint'Visible x) =+ c'glfwWindowHint c'GLFW_VISIBLE (toC x)+windowHint (WindowHint'Decorated x) =+ c'glfwWindowHint c'GLFW_DECORATED (toC x)+windowHint (WindowHint'RedBits x) =+ c'glfwWindowHint c'GLFW_RED_BITS (toC x)+windowHint (WindowHint'GreenBits x) =+ c'glfwWindowHint c'GLFW_GREEN_BITS (toC x)+windowHint (WindowHint'BlueBits x) =+ c'glfwWindowHint c'GLFW_BLUE_BITS (toC x)+windowHint (WindowHint'AlphaBits x) =+ c'glfwWindowHint c'GLFW_ALPHA_BITS (toC x)+windowHint (WindowHint'DepthBits x) =+ c'glfwWindowHint c'GLFW_DEPTH_BITS (toC x)+windowHint (WindowHint'StencilBits x) =+ c'glfwWindowHint c'GLFW_STENCIL_BITS (toC x)+windowHint (WindowHint'AccumRedBits x) =+ c'glfwWindowHint c'GLFW_ACCUM_RED_BITS (toC x)+windowHint (WindowHint'AccumGreenBits x) =+ c'glfwWindowHint c'GLFW_ACCUM_GREEN_BITS (toC x)+windowHint (WindowHint'AccumBlueBits x) =+ c'glfwWindowHint c'GLFW_ACCUM_BLUE_BITS (toC x)+windowHint (WindowHint'AccumAlphaBits x) =+ c'glfwWindowHint c'GLFW_ACCUM_ALPHA_BITS (toC x)+windowHint (WindowHint'AuxBuffers x) =+ c'glfwWindowHint c'GLFW_AUX_BUFFERS (toC x)+windowHint (WindowHint'Samples x) =+ c'glfwWindowHint c'GLFW_SAMPLES (toC x)+windowHint (WindowHint'RefreshRate x) =+ c'glfwWindowHint c'GLFW_REFRESH_RATE (toC x)+windowHint (WindowHint'DoubleBuffer x) =+ c'glfwWindowHint c'GLFW_DOUBLEBUFFER (toC x)+windowHint (WindowHint'Stereo x) =+ c'glfwWindowHint c'GLFW_STEREO (toC x)+windowHint (WindowHint'sRGBCapable x) =+ c'glfwWindowHint c'GLFW_SRGB_CAPABLE (toC x)+windowHint (WindowHint'Floating x) =+ c'glfwWindowHint c'GLFW_FLOATING (toC x)+windowHint (WindowHint'Focused x) =+ c'glfwWindowHint c'GLFW_FOCUSED (toC x)+windowHint (WindowHint'Maximized x) =+ c'glfwWindowHint c'GLFW_MAXIMIZED (toC x)+windowHint (WindowHint'AutoIconify x) =+ c'glfwWindowHint c'GLFW_AUTO_ICONIFY (toC x)+windowHint (WindowHint'ClientAPI x) =+ c'glfwWindowHint c'GLFW_CLIENT_API (toC x)+windowHint (WindowHint'ContextCreationAPI x) =+ c'glfwWindowHint c'GLFW_CONTEXT_CREATION_API (toC x)+windowHint (WindowHint'ContextVersionMajor x) =+ c'glfwWindowHint c'GLFW_CONTEXT_VERSION_MAJOR (toC x)+windowHint (WindowHint'ContextVersionMinor x) =+ c'glfwWindowHint c'GLFW_CONTEXT_VERSION_MINOR (toC x)+windowHint (WindowHint'ContextRobustness x) =+ c'glfwWindowHint c'GLFW_CONTEXT_ROBUSTNESS (toC x)+windowHint (WindowHint'ContextReleaseBehavior x) =+ c'glfwWindowHint c'GLFW_CONTEXT_RELEASE_BEHAVIOR (toC x)+windowHint (WindowHint'ContextNoError x) =+ c'glfwWindowHint c'GLFW_CONTEXT_NO_ERROR (toC x)+windowHint (WindowHint'OpenGLForwardCompat x) =+ c'glfwWindowHint c'GLFW_OPENGL_FORWARD_COMPAT (toC x)+windowHint (WindowHint'OpenGLDebugContext x) =+ c'glfwWindowHint c'GLFW_OPENGL_DEBUG_CONTEXT (toC x)+windowHint (WindowHint'OpenGLProfile x) =+ c'glfwWindowHint c'GLFW_OPENGL_PROFILE (toC x)+windowHint (WindowHint'TransparentFramebuffer x) =+ c'glfwWindowHint c'GLFW_TRANSPARENT_FRAMEBUFFER (toC x)+windowHint (WindowHint'CenterCursor x) =+ c'glfwWindowHint c'GLFW_CENTER_CURSOR (toC x)+windowHint (WindowHint'FocusOnShow x) =+ c'glfwWindowHint c'GLFW_FOCUS_ON_SHOW (toC x)+windowHint (WindowHint'ScaleToMonitor x) =+ c'glfwWindowHint c'GLFW_SCALE_TO_MONITOR (toC x)+windowHint (WindowHint'CocoaRetinaFramebuffer x) =+ c'glfwWindowHint c'GLFW_COCOA_RETINA_FRAMEBUFFER (toC x)+windowHint (WindowHint'CocoaGraphicsSwitching x) =+ c'glfwWindowHint c'GLFW_COCOA_GRAPHICS_SWITCHING (toC x)+windowHint (WindowHint'CocoaFrameName x) = setStringHint c'GLFW_COCOA_FRAME_NAME x+windowHint (WindowHint'X11ClassName x) = setStringHint c'GLFW_X11_CLASS_NAME x+windowHint (WindowHint'X11InstanceName x) = setStringHint c'GLFW_X11_INSTANCE_NAME 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.3/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.3/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+ windowContentScaleFun <- newIORef nullFunPtr+ windowMaximizeFun <- 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+ , storedWindowContentScaleFun = windowContentScaleFun+ , storedWindowMaximizeFun = windowMaximizeFun+ , 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)+ -- Not sure why this isn't the default...+ c'glfwSetInputMode p'win c'GLFW_LOCK_KEY_MODS (toC True)+ return $ Just $ fromC p'win++-- | Cleans up a window and all associated resources+-- See <http://www.glfw.org/docs/3.3/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++-- | Returns the value of an attribute of the specified window or its OpenGL or+-- OpenGL ES context.+-- See <https://www.glfw.org/docs/3.3/group__window.html#gacccb29947ea4b16860ebef42c2cb9337 glfwGetWindowAttrib>+getWindowAttrib :: Window -> WindowAttrib -> IO Bool+getWindowAttrib win attrib =+ fromC <$> c'glfwGetWindowAttrib (toC win) (toC attrib)++-- | Sets the value of an attribute of the specified window.+-- See <https://www.glfw.org/docs/3.3/group__window.html#gace2afda29b4116ec012e410a6819033e glfwSetWindowAttrib>+setWindowAttrib :: Window -> WindowAttrib -> Bool -> IO ()+setWindowAttrib win attrib = c'glfwSetWindowAttrib (toC win) (toC attrib) . toC++-- | If the window should close or not.+-- See <http://www.glfw.org/docs/3.3/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.3/group__window.html#ga49c449dde2a6f87d996f4daaa09d6708 glfwSetWindowShouldClose>+setWindowShouldClose :: Window -> Bool -> IO ()+setWindowShouldClose win b =+ c'glfwSetWindowShouldClose (toC win) (toC b)++-- | Returns the opacity of the window, including any decorations.+-- See <https://www.glfw.org/docs/3.3/group__window.html#gad09f0bd7a6307c4533b7061828480a84 glfwGetWindowOpacity+getWindowOpacity :: Window -> IO Float+getWindowOpacity = fmap hFloat . c'glfwGetWindowOpacity . toC++-- | Sets the opacity of the window, including any decorations+-- See <https://www.glfw.org/docs/3.3/group__window.html#gac31caeb3d1088831b13d2c8a156802e9 glfwSetWindowOpacity>+setWindowOpacity :: Window -> Float -> IO ()+setWindowOpacity win op = c'glfwSetWindowOpacity (toC win) (CFloat op)++-- | Sets the Title string of the window.+-- See <http://www.glfw.org/docs/3.3/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.3/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.3/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.3/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.3/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.3/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.3/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.3/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)++-- | This function retrieves the content scale for the specified window. The+-- content scale is the ratio between the current DPI and the platform's+-- default DPI.+-- See <https://www.glfw.org/docs/3.3/group__window.html#gaf5d31de9c19c4f994facea64d2b3106c glfwGetWindowContentScale>+getWindowContentScale :: Window -> IO (Float, Float)+getWindowContentScale win =+ alloca $ \p'x ->+ alloca $ \p'y -> do+ c'glfwGetWindowContentScale (toC win) p'x p'y+ CFloat x <- peek p'x+ CFloat y <- peek p'y+ return (x, y)++-- | The size of the framebuffer (in Pixels)+-- See <http://www.glfw.org/docs/3.3/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.3/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.3/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.3/group__window.html#ga3f541387449d911274324ae7f17ec56b glfwMaximizeWindow>+maximizeWindow :: Window -> IO ()+maximizeWindow = c'glfwMaximizeWindow . toC++-- | Shows the window.+-- See <http://www.glfw.org/docs/3.3/group__window.html#ga61be47917b72536a148300f46494fc66 glfwShowWindow>+showWindow :: Window -> IO ()+showWindow = c'glfwShowWindow . toC++-- | Hides the window.+-- See <http://www.glfw.org/docs/3.3/group__window.html#ga49401f82a1ba5f15db5590728314d47c glfwHideWindow>+hideWindow :: Window -> IO ()+hideWindow = c'glfwHideWindow . toC++-- | Requests user attention to the specified window.+-- See <https://www.glfw.org/docs/3.3/group__window.html#ga2f8d59323fc4692c1d54ba08c863a703 glfwRequestWindowAttention>+requestWindowAttention :: Window -> IO ()+requestWindowAttention = c'glfwRequestWindowAttention . toC++-- | Gets the monitor that this window is running on, provided the window is+-- fullscreen.+-- See <http://www.glfw.org/docs/3.3/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.3/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.3/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.3/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.3/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.3/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.3/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.3/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.3/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.3/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.3/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.3/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.3/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.3/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.3/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.3/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.3/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.3/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.3/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.3/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.3/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.3/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.3/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.3/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.3/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.3/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 for when the content scale of the window changes.+-- See <https://www.glfw.org/docs/3.3/window_guide.html#window_scale Window Content Scale>+setWindowContentScaleCallback :: Window -> Maybe WindowContentScaleCallback -> IO ()+setWindowContentScaleCallback win = setWindowCallback+ mk'GLFWwindowcontentscalefun+ (\cb w (CFloat f1) (CFloat f2) -> schedule $ cb (fromC w) f1 f2)+ (c'glfwSetWindowContentScaleCallback (toC win))+ storedWindowContentScaleFun+ win++-- | Sets the maximization callback of the specified window, which is called+-- when the window is maximized or restored.+-- See <https://www.glfw.org/docs/3.3/window_guide.html#window_maximize Window maximization>+setWindowMaximizeCallback :: Window -> Maybe WindowMaximizeCallback -> IO ()+setWindowMaximizeCallback win = setWindowCallback+ mk'GLFWwindowmaximizefun+ (\cb w x -> schedule $ cb (fromC w) (fromC x))+ (c'glfwSetWindowMaximizeCallback (toC win))+ storedWindowMaximizeFun+ win++-- | Sets the callback to use when the framebuffer's size changes.+-- See <http://www.glfw.org/docs/3.3/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.3/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.3/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.3/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.3/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.3/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.3/group__input.html#gaa92336e173da9c8834558b54ee80563b glfwSetInputMode>+setCursorInputMode :: Window -> CursorInputMode -> IO ()+setCursorInputMode win c =+ c'glfwSetInputMode (toC win) c'GLFW_CURSOR (toC c)++-- | Sets the cursor to receive raw input, if available (See+-- rawMouseMotionSupported and+-- <https://www.glfw.org/docs/3.3/input_guide.html#raw_mouse_motion Raw Mouse Motion>+setRawMouseMotion :: Window -> Bool -> IO ()+setRawMouseMotion win toggle = do+ supported <- rawMouseMotionSupported+ if not supported+ then putStrLn "WARNING -- Asked to set raw mouse motion but is unsupported"+ else c'glfwSetInputMode (toC win) c'GLFW_RAW_MOUSE_MOTION (toC toggle)++-- | Returns whether or not we've currently enabled raw mouse motion.+-- See <https://www.glfw.org/docs/3.3/input_guide.html#raw_mouse_motion Raw Mouse Motion>+getRawMouseMotion :: Window -> IO Bool+getRawMouseMotion win =+ fromC <$> c'glfwGetInputMode (toC win) c'GLFW_RAW_MOUSE_MOTION++-- | Gets the current sticky keys mode.+-- See <http://www.glfw.org/docs/3.3/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.3/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.3/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.3/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.3/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.3/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++-- | This function returns the platform-specific scancode of the specified key.+-- See <https://www.glfw.org/docs/3.3/group__input.html#ga67ddd1b7dcbbaff03e4a76c0ea67103a glfwGetKeyScancode>+getKeyScancode :: Key -> IO Int+getKeyScancode = fmap fromC . c'glfwGetKeyScancode . toC++-- | 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.3/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.3/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.3/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.3/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.3/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.3/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.3/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.3/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.3/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.3/group__input.html#gaffcbd9ac8ee737fcdd25475123a3c790 glfwJoystickPresent>+joystickPresent :: Joystick -> IO Bool+joystickPresent = fmap fromC . c'glfwJoystickPresent . toC++-- | 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.3/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 <$> peek p'n+ if p'axes == nullPtr || n <= 0+ then return Nothing+ else (Just . map fromC) <$> peekArray n p'axes++-- | Returns a list of all joystick button states for the specified joystick.+-- See <http://www.glfw.org/docs/3.3/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 <$> peek p'n+ if p'buttons == nullPtr || n <= 0+ then return Nothing+ else (Just . map fromC) <$> peekArray n p'buttons++-- | Returns a list of all hats of the specified joystick.+-- See <https://www.glfw.org/docs/3.3/group__input.html#ga2d8d0634bb81c180899aeb07477a67ea glfwGetJoystickHats>+getJoystickHats :: Joystick -> IO (Maybe [JoystickHatState])+getJoystickHats js = alloca $ \p'n -> do+ p'hats <- c'glfwGetJoystickHats (toC js) p'n+ n <- fromC <$> peek p'n+ if p'hats == nullPtr || n <= 0+ then return Nothing+ else (Just . map fromC) <$> peekArray n p'hats++-- | A human-readable name for a Joystick. Not guranteed to be unique.+-- See <http://www.glfw.org/docs/3.3/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 <$> peekCString p'name++-- | Sets a callback for when a joystick is connected or disconnected.+-- See <http://www.glfw.org/docs/3.3/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++-- | Adds the specified SDL_GameControllerDB gamepad mappings.+-- See <https://www.glfw.org/docs/3.3/group__input.html#gaed5104612f2fa8e66aa6e846652ad00f glfwUpdateGamepadMappings>+updateGamepadMappings :: String -> IO Bool+updateGamepadMappings =+ flip withCString $ \s -> fromC <$> c'glfwUpdateGamepadMappings s++-- | This function returns whether the specified joystick is both present and+-- has a gamepad mapping.+-- See <https://www.glfw.org/docs/3.3/group__input.html#gad0f676860f329d80f7e47e9f06a96f00 glfwJoystickIsGamepad>+joystickIsGamepad :: Joystick -> IO Bool+joystickIsGamepad = fmap (== c'GLFW_TRUE) . c'glfwJoystickIsGamepad . toC++-- | This function returns the SDL compatible GUID of the specified joystick.+-- See <https://www.glfw.org/docs/3.3/group__input.html#gae168c2c0b8cf2a1cb67c6b3c00bdd543 glfwGetJoystickGUID>+getJoystickGUID :: Joystick -> IO (Maybe String)+getJoystickGUID js = do+ p'guid <- c'glfwGetJoystickGUID (toC js)+ if p'guid == nullPtr+ then return Nothing+ else Just <$> peekCString p'guid++-- | This function returns the human-readable name of the gamepad from the+-- gamepad mapping assigned to the specified joystick.+-- See <https://www.glfw.org/docs/3.3/group__input.html#ga5c71e3533b2d384db9317fcd7661b210 glfwGetGamepadName>+getGamepadName :: Joystick -> IO (Maybe String)+getGamepadName js = do+ p'name <- c'glfwGetGamepadName (toC js)+ if p'name == nullPtr+ then return Nothing+ else Just <$> peekCString p'name++-- | This function retrives the state of the specified joystick remapped to an+-- Xbox-like gamepad.+-- See <https://www.glfw.org/docs/3.3/group__input.html#gadccddea8bce6113fa459de379ddaf051 glfwGetGamepadState>+getGamepadState :: Joystick -> IO (Maybe GamepadState)+getGamepadState js = alloca $ \p'gps -> do+ hasGamepad <- fromC <$> c'glfwGetGamepadState (toC js) p'gps+ if hasGamepad+ then do+ gps <- peek p'gps+ return $ Just GamepadState+ { getButtonState = fromC . (c'GLFWgamepadstate'buttons gps !!)+ . (fromIntegral :: CInt -> Int)+ . toC+ , getAxisState = hFloat+ . (c'GLFWgamepadstate'axes gps !!)+ . (fromIntegral :: CInt -> Int)+ . toC+ }+ else return Nothing++--------------------------------------------------------------------------------+-- 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.3/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.3/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.3/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.3/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.3/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.3/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.3/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.3/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.3/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.3/input.html#clipboard++-- | The window that will own the clipboard contents, and also the clipboard string.+-- See <http://www.glfw.org/docs/3.3/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.3/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.3/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.3/group__native.html#gac84f63a3f9db145b9435e5e0dbc4183d glfwGetWin32Adapter>+getWin32Adapter :: Window -> IO CString+getWin32Adapter = c'glfwGetWin32Adapter . toC++-- | See <http://www.glfw.org/docs/3.3/group__native.html#gac408b09a330749402d5d1fa1f5894dd9 glfwGetWin32Monitor>+getWin32Monitor :: Window -> IO CString+getWin32Monitor = c'glfwGetWin32Monitor . toC++-- | See <http://www.glfw.org/docs/3.3/group__native.html#gafe5079aa79038b0079fc09d5f0a8e667 glfwGetWin32Window>+getWin32Window :: Window -> IO (Ptr ())+getWin32Window = c'glfwGetWin32Window . toC++-- | See <http://www.glfw.org/docs/3.3/group__native.html#gadc4010d91d9cc1134d040eeb1202a143 glfwGetWGLContext>+getWGLContext :: Window -> IO (Ptr ())+getWGLContext = c'glfwGetWGLContext . toC++-- | See <http://www.glfw.org/docs/3.3/group__native.html#gaf22f429aec4b1aab316142d66d9be3e6 glfwGetCocoaMonitor>+getCocoaMonitor :: Window -> IO (Ptr Word32)+getCocoaMonitor = c'glfwGetCocoaMonitor . toC++-- | See <http://www.glfw.org/docs/3.3/group__native.html#gac3ed9d495d0c2bb9652de5a50c648715 glfwGetCocoaWindow>+getCocoaWindow :: Window -> IO (Ptr ())+getCocoaWindow = c'glfwGetCocoaWindow . toC++-- | See <http://www.glfw.org/docs/3.3/group__native.html#ga559e002e3cd63c979881770cd4dc63bc glfwGetNSGLContext>+getNSGLContext :: Window -> IO (Ptr ())+getNSGLContext = c'glfwGetNSGLContext . toC++-- | See <http://www.glfw.org/docs/3.3/group__native.html#ga8519b66594ea3ef6eeafaa2e3ee37406 glfwGetX11Display>+getX11Display :: Window -> IO (Ptr display)+getX11Display = c'glfwGetX11Display . toC++-- | See <http://www.glfw.org/docs/3.3/group__native.html#ga088fbfa80f50569402b41be71ad66e40 glfwGetX11Adapter>+getX11Adapter :: Window -> IO Word64+getX11Adapter = c'glfwGetX11Adapter . toC++-- | See <http://www.glfw.org/docs/3.3/group__native.html#gab2f8cc043905e9fa9b12bfdbbcfe874c glfwGetX11Monitor>+getX11Monitor :: Window -> IO Word64+getX11Monitor = c'glfwGetX11Monitor . toC++-- | See <http://www.glfw.org/docs/3.3/group__native.html#ga90ca676322740842db446999a1b1f21d glfwGetX11Window>+getX11Window :: Window -> IO Word64+getX11Window = c'glfwGetX11Window . toC++-- | See <https://www.glfw.org/docs/3.3/group__native.html#ga72f23e3980b83788c70aa854eca31430 glfwGetX11SelectionString>+getX11SelectionString :: IO String+getX11SelectionString = c'glfwGetX11SelectionString >>= peekCString++-- | See <https://www.glfw.org/docs/3.3/group__native.html#ga55f879ab02d93367f966186b6f0133f7 glfwSetX11SelectionString>+setX11SelectionString :: String -> IO ()+setX11SelectionString = flip withCString c'glfwSetX11SelectionString++-- | See <http://www.glfw.org/docs/3.3/group__native.html#ga62d884114b0abfcdc2930e89f20867e2 glfwGetGLXContext>+getGLXContext :: Window -> IO (Ptr ())+getGLXContext = c'glfwGetGLXContext . toC++-- | See <http://www.glfw.org/docs/3.3/group__native.html#ga1ed27b8766e859a21381e8f8ce18d049 glfwGetGLXWindow>+getGLXWindow :: Window -> IO Word64+getGLXWindow = c'glfwGetGLXWindow . toC++-- | See <http://www.glfw.org/docs/3.3/group__native.html#gaaf8118a3c877f3a6bc8e7a649519de5e glfwGetWaylandDisplay>+getWaylandDisplay :: IO (Ptr wl_display)+getWaylandDisplay = c'glfwGetWaylandDisplay++-- | See <http://www.glfw.org/docs/3.3/group__native.html#gab10427a667b6cd91eec7709f7a906bd3 glfwGetWaylandMonitor>+getWaylandMonitor :: Window -> IO (Ptr wl_output)+getWaylandMonitor = c'glfwGetWaylandMonitor . toC++-- | See <http://www.glfw.org/docs/3.3/group__native.html#ga4738d7aca4191363519a9a641c3ab64c glfwGetWaylandWindow>+getWaylandWindow :: Window -> IO (Ptr wl_surface)+getWaylandWindow = c'glfwGetWaylandWindow . toC++-- | See <http://www.glfw.org/docs/3.3/group__native.html#ga1cd8d973f47aacb5532d368147cc3138 glfwGetEGLDisplay>+getEGLDisplay :: IO (Ptr ())+getEGLDisplay = c'glfwGetEGLDisplay++-- | See <http://www.glfw.org/docs/3.3/group__native.html#ga671c5072becd085f4ab5771a9c8efcf1 glfwGetEGLContext>+getEGLContext :: Window -> IO (Ptr ())+getEGLContext = c'glfwGetEGLContext . toC++-- | See <http://www.glfw.org/docs/3.3/group__native.html#ga2199b36117a6a695fec8441d8052eee6 glfwGetEGLSurface>+getEGLSurface :: Window -> IO (Ptr ())+getEGLSurface = c'glfwGetEGLSurface . toC++-- | See <https://www.glfw.org/docs/3.3/group__native.html#ga9e47700080094eb569cb053afaa88773 glfwGetOSMesaContext>+getOSMesaContext :: Window -> IO (Ptr ())+getOSMesaContext = c'glfwGetOSMesaContext . toC++-- | An RGBA type is a low-dynamic range representation of a color, represented+-- by a 32-bit value. The channels here are in order: R, G, B, A+type OSMesaRGBA = (Word8, Word8, Word8, Word8)++-- | A color buffer is a two dimensional array of RGBA values. The first+-- dimension is width, and the second is height.+--+-- TODO: It's a shame this is an Array and not a UArray.+type OSMesaColorBuffer = Array (Int, Int) OSMesaRGBA++-- | A depth buffer is a two dimensional array of depth values. The range is+-- usually determined by a parameter returned from the query function.+type OSMesaDepthBuffer = Array (Int, Int) Word32++-- | Returns the color buffer of the offscreen context provided by OSMesa. The+-- color buffer is returned as an array whose integers are unsigned and+-- represent the (R, G, B, A) values. For formats that do not have alpha, A+-- will always be 255.+getOSMesaColorBuffer :: Window -> IO (Maybe OSMesaColorBuffer)+getOSMesaColorBuffer win =+ alloca $ \p'width ->+ alloca $ \p'height ->+ alloca $ \p'format ->+ alloca $ \p'buf -> do+ result <- fromC <$> c'glfwGetOSMesaColorBuffer (toC win)+ p'width p'height p'format p'buf+ if not result then return Nothing else do+ w <- fromIntegral <$> peek p'width+ h <- fromIntegral <$> peek p'height+ format <- peek p'format+ buf <- peek p'buf+ Just . array ((0, 0), (w, h)) <$> sequence+ [ fmap (\rgba -> ((x, y), rgba)) $+ mkRGBA format (castPtr buf) (y * w + x)+ | x <- [0..w]+ , y <- [0..h]+ ]+ where+ getByte :: Int -> Word32 -> Word8+ getByte i x = fromIntegral $ (x `shiftR` (i * 8)) .&. 0xFF++ mkRGBA :: CInt -> Ptr Word8 -> Int -> IO OSMesaRGBA+ mkRGBA 0x1908 buf offset = do+ -- OSMESA_RGBA+ (rgba :: Word32) <- peekElemOff (castPtr buf) offset+ return (getByte 0 rgba, getByte 1 rgba, getByte 2 rgba, getByte 3 rgba)+ mkRGBA 0x1 buf offset = do+ -- OSMESA_BGRA+ (bgra :: Word32) <- peekElemOff (castPtr buf) offset+ return (getByte 2 bgra, getByte 1 bgra, getByte 0 bgra, getByte 3 bgra)+ mkRGBA 0x2 buf offset = do+ -- OSMESA_ARGB+ (argb :: Word32) <- peekElemOff (castPtr buf) offset+ return (getByte 1 argb, getByte 2 argb, getByte 3 argb, getByte 0 argb)+ mkRGBA 0x1907 buf offset = do+ -- OSMESA_RGB+ r <- peek (buf `plusPtr` (offset * 3 + 0))+ g <- peek (buf `plusPtr` (offset * 3 + 1))+ b <- peek (buf `plusPtr` (offset * 3 + 2))+ return (r, g, b, 255)+ mkRGBA 0x4 buf offset = do+ -- OSMESA_BGR+ b <- peek (buf `plusPtr` (offset * 3 + 0))+ g <- peek (buf `plusPtr` (offset * 3 + 1))+ r <- peek (buf `plusPtr` (offset * 3 + 2))+ return (r, g, b, 255)+ mkRGBA 0x5 buf offset = do+ -- OSMESA_RGB_565+ (rgb :: Word16) <- peekElemOff (castPtr buf) offset+ return (+ fromIntegral $ rgb .&. 0x1F,+ fromIntegral $ (rgb `shiftR` 5) .&. 0x3F,+ fromIntegral $ (rgb `shiftR` 11) .&. 0x1F,+ 255)+ mkRGBA fmt _ _ = error $ "Unrecognized OSMESA_FORMAT: " ++ show fmt++-- | Returns the depth buffer and maximum depth value of the offscreen render+-- target that's provided by OSMesa.+getOSMesaDepthBuffer :: Window -> IO (Maybe (OSMesaDepthBuffer, Word32))+getOSMesaDepthBuffer win =+ alloca $ \p'width ->+ alloca $ \p'height ->+ alloca $ \p'bytesPerVal ->+ alloca $ \p'buf -> do+ result <- fromC <$> c'glfwGetOSMesaDepthBuffer (toC win)+ p'width p'height p'bytesPerVal p'buf+ if not result then return Nothing else do+ w <- fromIntegral <$> peek p'width+ h <- fromIntegral <$> peek p'height+ bytesPerVal <- fromIntegral <$> peek p'bytesPerVal+ buf <- peek p'buf+ depthBuffer <- array ((0, 0), (w, h)) <$> sequence+ [ fmap (\d -> ((x, y), d)) $+ mkDepth bytesPerVal (castPtr buf) (y * w + x)+ | x <- [0..w]+ , y <- [0..h]+ ]+ return (Just (depthBuffer, (1 `shiftL` (8 * bytesPerVal)) - 1))+ where+ mkDepth :: Int -> Ptr Word8 -> Int -> IO Word32+ mkDepth bpv ptr offset = do+ -- Assumes little-endian?+ bytes <- forM [0..(bpv - 1)] $ \i -> peekElemOff ptr (offset * bpv + i)+ return $ foldl' (\d -> ((d `shiftL` 8) .|.) . fromIntegral) 0 bytes
Graphics/UI/GLFW/C.hs view
@@ -1,686 +1,686 @@-{-# 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 - , modifierKeysCapsLock = (v .&. c'GLFW_MOD_CAPS_LOCK) /= 0 - , modifierKeysNumLock = (v .&. c'GLFW_MOD_NUM_LOCK) /= 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 InitHint where - fromC v - | v == c'GLFW_JOYSTICK_HAT_BUTTONS = InitHint'JoystickHatButtons - | v == c'GLFW_COCOA_CHDIR_RESOURCES = InitHint'CocoaChdirResources - | v == c'GLFW_COCOA_MENUBAR = InitHint'CocoaMenubar - | otherwise = error $ "C CInt InitHint fromC: " ++ show v - toC InitHint'JoystickHatButtons = c'GLFW_JOYSTICK_HAT_BUTTONS - toC InitHint'CocoaChdirResources = c'GLFW_COCOA_CHDIR_RESOURCES - toC InitHint'CocoaMenubar = c'GLFW_COCOA_MENUBAR - -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 - | v == c'GLFW_OSMESA_CONTEXT_API = ContextCreationAPI'OSMesa - | otherwise = error $ "C CInt ContextCreationAPI fromC: " ++ show v - toC ContextCreationAPI'Native = c'GLFW_NATIVE_CONTEXT_API - toC ContextCreationAPI'EGL = c'GLFW_EGL_CONTEXT_API - toC ContextCreationAPI'OSMesa = c'GLFW_OSMESA_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 JoystickHatState where - fromC v - | v == c'GLFW_HAT_CENTERED = JoystickHatState'Centered - | v == c'GLFW_HAT_UP = JoystickHatState'Up - | v == c'GLFW_HAT_RIGHT = JoystickHatState'Right - | v == c'GLFW_HAT_DOWN = JoystickHatState'Down - | v == c'GLFW_HAT_LEFT = JoystickHatState'Left - | v == c'GLFW_HAT_RIGHT_UP = JoystickHatState'RightUp - | v == c'GLFW_HAT_RIGHT_DOWN = JoystickHatState'RightDown - | v == c'GLFW_HAT_LEFT_UP = JoystickHatState'LeftUp - | v == c'GLFW_HAT_LEFT_DOWN = JoystickHatState'LeftDown - | otherwise = error $ "C CUChar JoystickHatState fromC: " ++ show v - toC JoystickHatState'Centered = c'GLFW_HAT_CENTERED - toC JoystickHatState'Up = c'GLFW_HAT_UP - toC JoystickHatState'Right = c'GLFW_HAT_RIGHT - toC JoystickHatState'Down = c'GLFW_HAT_DOWN - toC JoystickHatState'Left = c'GLFW_HAT_LEFT - toC JoystickHatState'RightUp = c'GLFW_HAT_RIGHT_UP - toC JoystickHatState'RightDown = c'GLFW_HAT_RIGHT_DOWN - toC JoystickHatState'LeftUp = c'GLFW_HAT_LEFT_UP - toC JoystickHatState'LeftDown = c'GLFW_HAT_LEFT_DOWN - -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 GamepadButton where - fromC v - | v == c'GLFW_GAMEPAD_BUTTON_A = GamepadButton'A - | v == c'GLFW_GAMEPAD_BUTTON_B = GamepadButton'B - | v == c'GLFW_GAMEPAD_BUTTON_X = GamepadButton'X - | v == c'GLFW_GAMEPAD_BUTTON_Y = GamepadButton'Y - | v == c'GLFW_GAMEPAD_BUTTON_LEFT_BUMPER = GamepadButton'LeftBumper - | v == c'GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER = GamepadButton'RightBumper - | v == c'GLFW_GAMEPAD_BUTTON_BACK = GamepadButton'Back - | v == c'GLFW_GAMEPAD_BUTTON_START = GamepadButton'Start - | v == c'GLFW_GAMEPAD_BUTTON_GUIDE = GamepadButton'Guide - | v == c'GLFW_GAMEPAD_BUTTON_LEFT_THUMB = GamepadButton'LeftThumb - | v == c'GLFW_GAMEPAD_BUTTON_RIGHT_THUMB = GamepadButton'RightThumb - | v == c'GLFW_GAMEPAD_BUTTON_DPAD_UP = GamepadButton'DpadUp - | v == c'GLFW_GAMEPAD_BUTTON_DPAD_RIGHT = GamepadButton'DpadRight - | v == c'GLFW_GAMEPAD_BUTTON_DPAD_DOWN = GamepadButton'DpadDown - | v == c'GLFW_GAMEPAD_BUTTON_DPAD_LEFT = GamepadButton'DpadLeft - | v == c'GLFW_GAMEPAD_BUTTON_CROSS = GamepadButton'Cross - | v == c'GLFW_GAMEPAD_BUTTON_CIRCLE = GamepadButton'Circle - | v == c'GLFW_GAMEPAD_BUTTON_SQUARE = GamepadButton'Square - | v == c'GLFW_GAMEPAD_BUTTON_TRIANGLE = GamepadButton'Triangle - | otherwise = error $ "C CInt GamepadButton fromC: " ++ show v - toC GamepadButton'A = c'GLFW_GAMEPAD_BUTTON_A - toC GamepadButton'B = c'GLFW_GAMEPAD_BUTTON_B - toC GamepadButton'X = c'GLFW_GAMEPAD_BUTTON_X - toC GamepadButton'Y = c'GLFW_GAMEPAD_BUTTON_Y - toC GamepadButton'LeftBumper = c'GLFW_GAMEPAD_BUTTON_LEFT_BUMPER - toC GamepadButton'RightBumper = c'GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER - toC GamepadButton'Back = c'GLFW_GAMEPAD_BUTTON_BACK - toC GamepadButton'Start = c'GLFW_GAMEPAD_BUTTON_START - toC GamepadButton'Guide = c'GLFW_GAMEPAD_BUTTON_GUIDE - toC GamepadButton'LeftThumb = c'GLFW_GAMEPAD_BUTTON_LEFT_THUMB - toC GamepadButton'RightThumb = c'GLFW_GAMEPAD_BUTTON_RIGHT_THUMB - toC GamepadButton'DpadUp = c'GLFW_GAMEPAD_BUTTON_DPAD_UP - toC GamepadButton'DpadRight = c'GLFW_GAMEPAD_BUTTON_DPAD_RIGHT - toC GamepadButton'DpadDown = c'GLFW_GAMEPAD_BUTTON_DPAD_DOWN - toC GamepadButton'DpadLeft = c'GLFW_GAMEPAD_BUTTON_DPAD_LEFT - toC GamepadButton'Cross = c'GLFW_GAMEPAD_BUTTON_CROSS - toC GamepadButton'Circle = c'GLFW_GAMEPAD_BUTTON_CIRCLE - toC GamepadButton'Square = c'GLFW_GAMEPAD_BUTTON_SQUARE - toC GamepadButton'Triangle = c'GLFW_GAMEPAD_BUTTON_TRIANGLE - -instance C CUChar GamepadButtonState where - fromC v - | v == c'GLFW_PRESS = GamepadButtonState'Pressed - | v == c'GLFW_RELEASE = GamepadButtonState'Released - | otherwise = error $ "C CUChar GamepadButtonState fromC: " ++ show v - toC GamepadButtonState'Pressed = c'GLFW_PRESS - toC GamepadButtonState'Released = c'GLFW_RELEASE - -instance C CInt GamepadAxis where - fromC v - | v == c'GLFW_GAMEPAD_AXIS_LEFT_X = GamepadAxis'LeftX - | v == c'GLFW_GAMEPAD_AXIS_RIGHT_X = GamepadAxis'RightX - | v == c'GLFW_GAMEPAD_AXIS_LEFT_Y = GamepadAxis'LeftY - | v == c'GLFW_GAMEPAD_AXIS_RIGHT_Y = GamepadAxis'RightY - | v == c'GLFW_GAMEPAD_AXIS_LEFT_TRIGGER = GamepadAxis'LeftTrigger - | v == c'GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER = GamepadAxis'RightTrigger - | otherwise = error $ "C CInt GamepadAxis fromC: " ++ show v - toC GamepadAxis'LeftX = c'GLFW_GAMEPAD_AXIS_LEFT_X - toC GamepadAxis'RightX = c'GLFW_GAMEPAD_AXIS_RIGHT_X - toC GamepadAxis'LeftY = c'GLFW_GAMEPAD_AXIS_LEFT_Y - toC GamepadAxis'RightY = c'GLFW_GAMEPAD_AXIS_RIGHT_Y - toC GamepadAxis'LeftTrigger = c'GLFW_GAMEPAD_AXIS_LEFT_TRIGGER - toC GamepadAxis'RightTrigger = c'GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER - -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 - -instance C CInt WindowAttrib where - fromC v - | v == c'GLFW_DECORATED = WindowAttrib'Decorated - | v == c'GLFW_RESIZABLE = WindowAttrib'Resizable - | v == c'GLFW_FLOATING = WindowAttrib'Floating - | v == c'GLFW_AUTO_ICONIFY = WindowAttrib'AutoIconify - | v == c'GLFW_FOCUS_ON_SHOW = WindowAttrib'FocusOnShow - | v == c'GLFW_HOVERED = WindowAttrib'Hovered - | otherwise = error $ "C CInt WindowAttrib fromC: " ++ show v - toC WindowAttrib'Decorated = c'GLFW_DECORATED - toC WindowAttrib'Resizable = c'GLFW_RESIZABLE - toC WindowAttrib'Floating = c'GLFW_FLOATING - toC WindowAttrib'AutoIconify = c'GLFW_AUTO_ICONIFY - toC WindowAttrib'FocusOnShow = c'GLFW_FOCUS_ON_SHOW - toC WindowAttrib'Hovered = c'GLFW_HOVERED - --------------------------------------------------------------------------------- - +{-# 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+ , modifierKeysCapsLock = (v .&. c'GLFW_MOD_CAPS_LOCK) /= 0+ , modifierKeysNumLock = (v .&. c'GLFW_MOD_NUM_LOCK) /= 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 InitHint where+ fromC v+ | v == c'GLFW_JOYSTICK_HAT_BUTTONS = InitHint'JoystickHatButtons+ | v == c'GLFW_COCOA_CHDIR_RESOURCES = InitHint'CocoaChdirResources+ | v == c'GLFW_COCOA_MENUBAR = InitHint'CocoaMenubar+ | otherwise = error $ "C CInt InitHint fromC: " ++ show v+ toC InitHint'JoystickHatButtons = c'GLFW_JOYSTICK_HAT_BUTTONS+ toC InitHint'CocoaChdirResources = c'GLFW_COCOA_CHDIR_RESOURCES+ toC InitHint'CocoaMenubar = c'GLFW_COCOA_MENUBAR++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+ | v == c'GLFW_OSMESA_CONTEXT_API = ContextCreationAPI'OSMesa+ | otherwise = error $ "C CInt ContextCreationAPI fromC: " ++ show v+ toC ContextCreationAPI'Native = c'GLFW_NATIVE_CONTEXT_API+ toC ContextCreationAPI'EGL = c'GLFW_EGL_CONTEXT_API+ toC ContextCreationAPI'OSMesa = c'GLFW_OSMESA_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 JoystickHatState where+ fromC v+ | v == c'GLFW_HAT_CENTERED = JoystickHatState'Centered+ | v == c'GLFW_HAT_UP = JoystickHatState'Up+ | v == c'GLFW_HAT_RIGHT = JoystickHatState'Right+ | v == c'GLFW_HAT_DOWN = JoystickHatState'Down+ | v == c'GLFW_HAT_LEFT = JoystickHatState'Left+ | v == c'GLFW_HAT_RIGHT_UP = JoystickHatState'RightUp+ | v == c'GLFW_HAT_RIGHT_DOWN = JoystickHatState'RightDown+ | v == c'GLFW_HAT_LEFT_UP = JoystickHatState'LeftUp+ | v == c'GLFW_HAT_LEFT_DOWN = JoystickHatState'LeftDown+ | otherwise = error $ "C CUChar JoystickHatState fromC: " ++ show v+ toC JoystickHatState'Centered = c'GLFW_HAT_CENTERED+ toC JoystickHatState'Up = c'GLFW_HAT_UP+ toC JoystickHatState'Right = c'GLFW_HAT_RIGHT+ toC JoystickHatState'Down = c'GLFW_HAT_DOWN+ toC JoystickHatState'Left = c'GLFW_HAT_LEFT+ toC JoystickHatState'RightUp = c'GLFW_HAT_RIGHT_UP+ toC JoystickHatState'RightDown = c'GLFW_HAT_RIGHT_DOWN+ toC JoystickHatState'LeftUp = c'GLFW_HAT_LEFT_UP+ toC JoystickHatState'LeftDown = c'GLFW_HAT_LEFT_DOWN++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 GamepadButton where+ fromC v+ | v == c'GLFW_GAMEPAD_BUTTON_A = GamepadButton'A+ | v == c'GLFW_GAMEPAD_BUTTON_B = GamepadButton'B+ | v == c'GLFW_GAMEPAD_BUTTON_X = GamepadButton'X+ | v == c'GLFW_GAMEPAD_BUTTON_Y = GamepadButton'Y+ | v == c'GLFW_GAMEPAD_BUTTON_LEFT_BUMPER = GamepadButton'LeftBumper+ | v == c'GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER = GamepadButton'RightBumper+ | v == c'GLFW_GAMEPAD_BUTTON_BACK = GamepadButton'Back+ | v == c'GLFW_GAMEPAD_BUTTON_START = GamepadButton'Start+ | v == c'GLFW_GAMEPAD_BUTTON_GUIDE = GamepadButton'Guide+ | v == c'GLFW_GAMEPAD_BUTTON_LEFT_THUMB = GamepadButton'LeftThumb+ | v == c'GLFW_GAMEPAD_BUTTON_RIGHT_THUMB = GamepadButton'RightThumb+ | v == c'GLFW_GAMEPAD_BUTTON_DPAD_UP = GamepadButton'DpadUp+ | v == c'GLFW_GAMEPAD_BUTTON_DPAD_RIGHT = GamepadButton'DpadRight+ | v == c'GLFW_GAMEPAD_BUTTON_DPAD_DOWN = GamepadButton'DpadDown+ | v == c'GLFW_GAMEPAD_BUTTON_DPAD_LEFT = GamepadButton'DpadLeft+ | v == c'GLFW_GAMEPAD_BUTTON_CROSS = GamepadButton'Cross+ | v == c'GLFW_GAMEPAD_BUTTON_CIRCLE = GamepadButton'Circle+ | v == c'GLFW_GAMEPAD_BUTTON_SQUARE = GamepadButton'Square+ | v == c'GLFW_GAMEPAD_BUTTON_TRIANGLE = GamepadButton'Triangle+ | otherwise = error $ "C CInt GamepadButton fromC: " ++ show v+ toC GamepadButton'A = c'GLFW_GAMEPAD_BUTTON_A+ toC GamepadButton'B = c'GLFW_GAMEPAD_BUTTON_B+ toC GamepadButton'X = c'GLFW_GAMEPAD_BUTTON_X+ toC GamepadButton'Y = c'GLFW_GAMEPAD_BUTTON_Y+ toC GamepadButton'LeftBumper = c'GLFW_GAMEPAD_BUTTON_LEFT_BUMPER+ toC GamepadButton'RightBumper = c'GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER+ toC GamepadButton'Back = c'GLFW_GAMEPAD_BUTTON_BACK+ toC GamepadButton'Start = c'GLFW_GAMEPAD_BUTTON_START+ toC GamepadButton'Guide = c'GLFW_GAMEPAD_BUTTON_GUIDE+ toC GamepadButton'LeftThumb = c'GLFW_GAMEPAD_BUTTON_LEFT_THUMB+ toC GamepadButton'RightThumb = c'GLFW_GAMEPAD_BUTTON_RIGHT_THUMB+ toC GamepadButton'DpadUp = c'GLFW_GAMEPAD_BUTTON_DPAD_UP+ toC GamepadButton'DpadRight = c'GLFW_GAMEPAD_BUTTON_DPAD_RIGHT+ toC GamepadButton'DpadDown = c'GLFW_GAMEPAD_BUTTON_DPAD_DOWN+ toC GamepadButton'DpadLeft = c'GLFW_GAMEPAD_BUTTON_DPAD_LEFT+ toC GamepadButton'Cross = c'GLFW_GAMEPAD_BUTTON_CROSS+ toC GamepadButton'Circle = c'GLFW_GAMEPAD_BUTTON_CIRCLE+ toC GamepadButton'Square = c'GLFW_GAMEPAD_BUTTON_SQUARE+ toC GamepadButton'Triangle = c'GLFW_GAMEPAD_BUTTON_TRIANGLE++instance C CUChar GamepadButtonState where+ fromC v+ | v == c'GLFW_PRESS = GamepadButtonState'Pressed+ | v == c'GLFW_RELEASE = GamepadButtonState'Released+ | otherwise = error $ "C CUChar GamepadButtonState fromC: " ++ show v+ toC GamepadButtonState'Pressed = c'GLFW_PRESS+ toC GamepadButtonState'Released = c'GLFW_RELEASE++instance C CInt GamepadAxis where+ fromC v+ | v == c'GLFW_GAMEPAD_AXIS_LEFT_X = GamepadAxis'LeftX+ | v == c'GLFW_GAMEPAD_AXIS_RIGHT_X = GamepadAxis'RightX+ | v == c'GLFW_GAMEPAD_AXIS_LEFT_Y = GamepadAxis'LeftY+ | v == c'GLFW_GAMEPAD_AXIS_RIGHT_Y = GamepadAxis'RightY+ | v == c'GLFW_GAMEPAD_AXIS_LEFT_TRIGGER = GamepadAxis'LeftTrigger+ | v == c'GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER = GamepadAxis'RightTrigger+ | otherwise = error $ "C CInt GamepadAxis fromC: " ++ show v+ toC GamepadAxis'LeftX = c'GLFW_GAMEPAD_AXIS_LEFT_X+ toC GamepadAxis'RightX = c'GLFW_GAMEPAD_AXIS_RIGHT_X+ toC GamepadAxis'LeftY = c'GLFW_GAMEPAD_AXIS_LEFT_Y+ toC GamepadAxis'RightY = c'GLFW_GAMEPAD_AXIS_RIGHT_Y+ toC GamepadAxis'LeftTrigger = c'GLFW_GAMEPAD_AXIS_LEFT_TRIGGER+ toC GamepadAxis'RightTrigger = c'GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER++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++instance C CInt WindowAttrib where+ fromC v+ | v == c'GLFW_DECORATED = WindowAttrib'Decorated+ | v == c'GLFW_RESIZABLE = WindowAttrib'Resizable+ | v == c'GLFW_FLOATING = WindowAttrib'Floating+ | v == c'GLFW_AUTO_ICONIFY = WindowAttrib'AutoIconify+ | v == c'GLFW_FOCUS_ON_SHOW = WindowAttrib'FocusOnShow+ | v == c'GLFW_HOVERED = WindowAttrib'Hovered+ | otherwise = error $ "C CInt WindowAttrib fromC: " ++ show v+ toC WindowAttrib'Decorated = c'GLFW_DECORATED+ toC WindowAttrib'Resizable = c'GLFW_RESIZABLE+ toC WindowAttrib'Floating = c'GLFW_FLOATING+ toC WindowAttrib'AutoIconify = c'GLFW_AUTO_ICONIFY+ toC WindowAttrib'FocusOnShow = c'GLFW_FOCUS_ON_SHOW+ toC WindowAttrib'Hovered = c'GLFW_HOVERED++--------------------------------------------------------------------------------+ {-# ANN module "HLint: ignore Use camelCase" #-}
Graphics/UI/GLFW/Types.hs view
@@ -1,647 +1,647 @@-{-# 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.3/group__errors.html#ga196e125ef261d94184e2b55c05762f14 GLFW error codes>. -data Error = - Error'NotInitialized -- ^ <http://www.glfw.org/docs/3.3/group__errors.html#ga2374ee02c177f12e1fa76ff3ed15e14a doc> - | Error'NoCurrentContext -- ^ <http://www.glfw.org/docs/3.3/group__errors.html#gaa8290386e9528ccb9e42a3a4e16fc0d0 doc> - | Error'InvalidEnum -- ^ <http://www.glfw.org/docs/3.3/group__errors.html#ga76f6bb9c4eea73db675f096b404593ce doc> - | Error'InvalidValue -- ^ <http://www.glfw.org/docs/3.3/group__errors.html#gaaf2ef9aa8202c2b82ac2d921e554c687 doc> - | Error'OutOfMemory -- ^ <http://www.glfw.org/docs/3.3/group__errors.html#ga9023953a2bcb98c2906afd071d21ee7f doc> - | Error'ApiUnavailable -- ^ <http://www.glfw.org/docs/3.3/group__errors.html#ga56882b290db23261cc6c053c40c2d08e doc> - | Error'VersionUnavailable -- ^ <http://www.glfw.org/docs/3.3/group__errors.html#gad16c5565b4a69f9c2a9ac2c0dbc89462 doc> - | Error'PlatformError -- ^ <http://www.glfw.org/docs/3.3/group__errors.html#gad44162d78100ea5e87cdd38426b8c7a1 doc> - | Error'FormatUnavailable -- ^ <http://www.glfw.org/docs/3.3/group__errors.html#ga196e125ef261d94184e2b55c05762f14 doc> - deriving (Bounded, Data, Enum, Eq, Ord, Read, Show, Typeable, Generic) - -instance NFData Error - --------------------------------------------------------------------------------- --- Initialization and version information - --- | Initialization hints are set before glfwInit and affect how the library --- behaves until termination. Hints are set with glfwInitHint. See --- <https://www.glfw.org/docs/3.3/intro_guide.html#init_hints Init Hints> -data InitHint - = InitHint'JoystickHatButtons - | InitHint'CocoaChdirResources - | InitHint'CocoaMenubar - deriving (Bounded, Data, Enum, Eq, Ord, Read, Show, Typeable, Generic) - -instance NFData InitHint - --- | The library version of the GLFW implementation in use. --- See <http://www.glfw.org/docs/3.3/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.3/monitor.html Monitor Guide> -newtype Monitor = Monitor - { unMonitor :: Ptr C'GLFWmonitor - } deriving (Data, Eq, Ord, Show, Typeable, Generic) - --- | Part of the t'Graphics.UI.GLFW.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.3/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.3/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) - , storedWindowContentScaleFun :: !(IORef C'GLFWwindowcontentscalefun) - , storedWindowMaximizeFun :: !(IORef C'GLFWwindowmaximizefun) - , storedDropFun :: !(IORef C'GLFWdropfun) - } - --- | Reprisents a GLFW window value. --- See the <http://www.glfw.org/docs/3.3/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.3/window.html#window_hints Window Hints>, --- particularly <http://www.glfw.org/docs/3.3/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 - | WindowHint'TransparentFramebuffer !Bool - | WindowHint'CenterCursor !Bool - | WindowHint'FocusOnShow !Bool - | WindowHint'ScaleToMonitor !Bool - | WindowHint'CocoaRetinaFramebuffer !Bool - | WindowHint'CocoaGraphicsSwitching !Bool - | WindowHint'CocoaFrameName !String - | WindowHint'X11ClassName !String - | WindowHint'X11InstanceName !String - deriving (Data, Eq, Ord, Read, Show, Typeable, Generic) - -instance NFData WindowHint - --- | A window-specific attribute. --- See <https://www.glfw.org/docs/3.3/window_guide.html#window_attribs Window Attributes> -data WindowAttrib - = WindowAttrib'Decorated - | WindowAttrib'Resizable - | WindowAttrib'Floating - | WindowAttrib'AutoIconify - | WindowAttrib'FocusOnShow - | WindowAttrib'Hovered - deriving (Bounded, Data, Enum, Eq, Ord, Read, Show, Typeable, Generic) - -instance NFData WindowAttrib - --- | 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 - | ContextCreationAPI'OSMesa - 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.3/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 'Graphics.UI.GLFW.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.3/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 --- 'Graphics.UI.GLFW.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 t'Graphics.UI.GLFW.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 - --- | The valid hat states of a joystick. Part of the --- <https://www.glfw.org/docs/3.3/input_guide.html#joystick_hat joystick hat> --- system. -data JoystickHatState - = JoystickHatState'Centered - | JoystickHatState'Up - | JoystickHatState'Right - | JoystickHatState'Down - | JoystickHatState'Left - | JoystickHatState'RightUp - | JoystickHatState'RightDown - | JoystickHatState'LeftUp - | JoystickHatState'LeftDown - deriving (Bounded, Data, Enum, Eq, Ord, Read, Show, Typeable, Generic) - -instance NFData JoystickHatState - --- | Part of the <http://www.Graphics.UI.GLFW.org/docs/3.3/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 'Graphics.UI.GLFW.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.3/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 'Graphics.UI.GLFW.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 - , modifierKeysCapsLock :: !Bool - , modifierKeysNumLock :: !Bool - } deriving (Data, Eq, Ord, Read, Show, Typeable, Generic) - -instance NFData ModifierKeys - --- | The different types of buttons we can find on a Gamepad. -data GamepadButton - = GamepadButton'A - | GamepadButton'B - | GamepadButton'X - | GamepadButton'Y - | GamepadButton'LeftBumper - | GamepadButton'RightBumper - | GamepadButton'Back - | GamepadButton'Start - | GamepadButton'Guide - | GamepadButton'LeftThumb - | GamepadButton'RightThumb - | GamepadButton'DpadUp - | GamepadButton'DpadRight - | GamepadButton'DpadDown - | GamepadButton'DpadLeft - | GamepadButton'Cross - | GamepadButton'Circle - | GamepadButton'Square - | GamepadButton'Triangle - deriving (Bounded, Data, Enum, Eq, Ord, Read, Show, Typeable, Generic) - -instance NFData GamepadButton - --- | The states in which the gamepad buttons are found -data GamepadButtonState - = GamepadButtonState'Pressed - | GamepadButtonState'Released - deriving (Bounded, Data, Enum, Eq, Ord, Read, Show, Typeable, Generic) - -instance NFData GamepadButtonState - --- | The different axes along which we can measure continuous input on a Gamepad -data GamepadAxis - = GamepadAxis'LeftX - | GamepadAxis'LeftY - | GamepadAxis'RightX - | GamepadAxis'RightY - | GamepadAxis'LeftTrigger - | GamepadAxis'RightTrigger - deriving (Bounded, Data, Enum, Eq, Ord, Read, Show, Typeable, Generic) - -instance NFData GamepadAxis - --- | This describes the input state of a gamepad -data GamepadState = GamepadState - { getButtonState :: GamepadButton -> GamepadButtonState - -- ^ Returns the current state of the given button - , getAxisState :: GamepadAxis -> Float - -- ^ Returns a value in the range [-1.0, 1.0] for the - -- given game axis - } deriving (Typeable, Generic) - -instance Eq GamepadState where - a == b = - let compareSt f x = (&& (f a x == f b x)) - in foldr (compareSt getButtonState) True [minBound..maxBound] && - foldr (compareSt getAxisState) True [minBound..maxBound] - -instance NFData GamepadState - -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)] - , let (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.3/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.3/group__errors.html#ga196e125ef261d94184e2b55c05762f14 GLFW error codes>.+data Error =+ Error'NotInitialized -- ^ <http://www.glfw.org/docs/3.3/group__errors.html#ga2374ee02c177f12e1fa76ff3ed15e14a doc>+ | Error'NoCurrentContext -- ^ <http://www.glfw.org/docs/3.3/group__errors.html#gaa8290386e9528ccb9e42a3a4e16fc0d0 doc>+ | Error'InvalidEnum -- ^ <http://www.glfw.org/docs/3.3/group__errors.html#ga76f6bb9c4eea73db675f096b404593ce doc>+ | Error'InvalidValue -- ^ <http://www.glfw.org/docs/3.3/group__errors.html#gaaf2ef9aa8202c2b82ac2d921e554c687 doc>+ | Error'OutOfMemory -- ^ <http://www.glfw.org/docs/3.3/group__errors.html#ga9023953a2bcb98c2906afd071d21ee7f doc>+ | Error'ApiUnavailable -- ^ <http://www.glfw.org/docs/3.3/group__errors.html#ga56882b290db23261cc6c053c40c2d08e doc>+ | Error'VersionUnavailable -- ^ <http://www.glfw.org/docs/3.3/group__errors.html#gad16c5565b4a69f9c2a9ac2c0dbc89462 doc>+ | Error'PlatformError -- ^ <http://www.glfw.org/docs/3.3/group__errors.html#gad44162d78100ea5e87cdd38426b8c7a1 doc>+ | Error'FormatUnavailable -- ^ <http://www.glfw.org/docs/3.3/group__errors.html#ga196e125ef261d94184e2b55c05762f14 doc>+ deriving (Bounded, Data, Enum, Eq, Ord, Read, Show, Typeable, Generic)++instance NFData Error++--------------------------------------------------------------------------------+-- Initialization and version information++-- | Initialization hints are set before glfwInit and affect how the library+-- behaves until termination. Hints are set with glfwInitHint. See+-- <https://www.glfw.org/docs/3.3/intro_guide.html#init_hints Init Hints>+data InitHint+ = InitHint'JoystickHatButtons+ | InitHint'CocoaChdirResources+ | InitHint'CocoaMenubar+ deriving (Bounded, Data, Enum, Eq, Ord, Read, Show, Typeable, Generic)++instance NFData InitHint++-- | The library version of the GLFW implementation in use.+-- See <http://www.glfw.org/docs/3.3/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.3/monitor.html Monitor Guide>+newtype Monitor = Monitor+ { unMonitor :: Ptr C'GLFWmonitor+ } deriving (Data, Eq, Ord, Show, Typeable, Generic)++-- | Part of the t'Graphics.UI.GLFW.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.3/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.3/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)+ , storedWindowContentScaleFun :: !(IORef C'GLFWwindowcontentscalefun)+ , storedWindowMaximizeFun :: !(IORef C'GLFWwindowmaximizefun)+ , storedDropFun :: !(IORef C'GLFWdropfun)+ }++-- | Represents a GLFW window value.+-- See the <http://www.glfw.org/docs/3.3/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.3/window.html#window_hints Window Hints>,+-- particularly <http://www.glfw.org/docs/3.3/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+ | WindowHint'TransparentFramebuffer !Bool+ | WindowHint'CenterCursor !Bool+ | WindowHint'FocusOnShow !Bool+ | WindowHint'ScaleToMonitor !Bool+ | WindowHint'CocoaRetinaFramebuffer !Bool+ | WindowHint'CocoaGraphicsSwitching !Bool+ | WindowHint'CocoaFrameName !String+ | WindowHint'X11ClassName !String+ | WindowHint'X11InstanceName !String+ deriving (Data, Eq, Ord, Read, Show, Typeable, Generic)++instance NFData WindowHint++-- | A window-specific attribute.+-- See <https://www.glfw.org/docs/3.3/window_guide.html#window_attribs Window Attributes>+data WindowAttrib+ = WindowAttrib'Decorated+ | WindowAttrib'Resizable+ | WindowAttrib'Floating+ | WindowAttrib'AutoIconify+ | WindowAttrib'FocusOnShow+ | WindowAttrib'Hovered+ deriving (Bounded, Data, Enum, Eq, Ord, Read, Show, Typeable, Generic)++instance NFData WindowAttrib++-- | 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+ | ContextCreationAPI'OSMesa+ 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.3/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 'Graphics.UI.GLFW.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.3/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+-- 'Graphics.UI.GLFW.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 t'Graphics.UI.GLFW.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++-- | The valid hat states of a joystick. Part of the+-- <https://www.glfw.org/docs/3.3/input_guide.html#joystick_hat joystick hat>+-- system.+data JoystickHatState+ = JoystickHatState'Centered+ | JoystickHatState'Up+ | JoystickHatState'Right+ | JoystickHatState'Down+ | JoystickHatState'Left+ | JoystickHatState'RightUp+ | JoystickHatState'RightDown+ | JoystickHatState'LeftUp+ | JoystickHatState'LeftDown+ deriving (Bounded, Data, Enum, Eq, Ord, Read, Show, Typeable, Generic)++instance NFData JoystickHatState++-- | Part of the <http://www.Graphics.UI.GLFW.org/docs/3.3/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 'Graphics.UI.GLFW.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.3/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 'Graphics.UI.GLFW.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+ , modifierKeysCapsLock :: !Bool+ , modifierKeysNumLock :: !Bool+ } deriving (Data, Eq, Ord, Read, Show, Typeable, Generic)++instance NFData ModifierKeys++-- | The different types of buttons we can find on a Gamepad.+data GamepadButton+ = GamepadButton'A+ | GamepadButton'B+ | GamepadButton'X+ | GamepadButton'Y+ | GamepadButton'LeftBumper+ | GamepadButton'RightBumper+ | GamepadButton'Back+ | GamepadButton'Start+ | GamepadButton'Guide+ | GamepadButton'LeftThumb+ | GamepadButton'RightThumb+ | GamepadButton'DpadUp+ | GamepadButton'DpadRight+ | GamepadButton'DpadDown+ | GamepadButton'DpadLeft+ | GamepadButton'Cross+ | GamepadButton'Circle+ | GamepadButton'Square+ | GamepadButton'Triangle+ deriving (Bounded, Data, Enum, Eq, Ord, Read, Show, Typeable, Generic)++instance NFData GamepadButton++-- | The states in which the gamepad buttons are found+data GamepadButtonState+ = GamepadButtonState'Pressed+ | GamepadButtonState'Released+ deriving (Bounded, Data, Enum, Eq, Ord, Read, Show, Typeable, Generic)++instance NFData GamepadButtonState++-- | The different axes along which we can measure continuous input on a Gamepad+data GamepadAxis+ = GamepadAxis'LeftX+ | GamepadAxis'LeftY+ | GamepadAxis'RightX+ | GamepadAxis'RightY+ | GamepadAxis'LeftTrigger+ | GamepadAxis'RightTrigger+ deriving (Bounded, Data, Enum, Eq, Ord, Read, Show, Typeable, Generic)++instance NFData GamepadAxis++-- | This describes the input state of a gamepad+data GamepadState = GamepadState+ { getButtonState :: GamepadButton -> GamepadButtonState+ -- ^ Returns the current state of the given button+ , getAxisState :: GamepadAxis -> Float+ -- ^ Returns a value in the range [-1.0, 1.0] for the+ -- given game axis+ } deriving (Typeable, Generic)++instance Eq GamepadState where+ a == b =+ let compareSt f x = (&& (f a x == f b x))+ in foldr (compareSt getButtonState) True [minBound..maxBound] &&+ foldr (compareSt getAxisState) True [minBound..maxBound]++instance NFData GamepadState++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)]+ , let (r, g, b, a) = gen x y+ , channel <- [r, g, b, a]+ ]+ }++instance NFData Image++-- | Represents 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.3/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
@@ -1,44 +1,44 @@-GLFW-b -====== -[](http://hackage.haskell.org/package/GLFW-b) - -## Description - -[Haskell][1] bindings to [GLFW][2], an Open Source, multi-platform library for -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]. - -For a demonstration of GLFW-b, see [GLFW-b-demo][5]. - -When running GLFW-b in GHCI, don't forget to - - :set -fno-ghci-sandbox - -since GHCI can (and might) run each line of your code in a fresh unbounded -thread. - -## Contributing - -This package uses git-flow as development model, in short that means that: - -1. New features should be added to "develop" branch. -2. "master" branch is reserved for stable releases. -3. Patches for bugs related with previous releases should always be done in - "hotfixes" branch. -4. All merge commits to master from "hotfixes" should be done - using the "--no-ff" flag and from "develop" should avoid merging commits. - -Until we have a defined road-map we are going to leave out "release -"branches" and "feature branches". For more information about this development -model please refer to [this site.][6] - -Thanks you, and happy coding. - -[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 -[5]: https://github.com/bsl/GLFW-b-demo -[6]: http://nvie.com/posts/a-successful-git-branching-model/ +GLFW-b+======+[](http://hackage.haskell.org/package/GLFW-b)++## Description++[Haskell][1] bindings to [GLFW][2], an Open Source, multi-platform library for+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.3, [released 2019-04-15][4].++For a demonstration of GLFW-b, see [GLFW-b-demo][5].++When running GLFW-b in GHCI, don't forget to++ :set -fno-ghci-sandbox++since GHCI can (and might) run each line of your code in a fresh unbounded+thread.++## Contributing++This package uses git-flow as development model, in short that means that:++1. New features should be added to "develop" branch.+2. "master" branch is reserved for stable releases.+3. Patches for bugs related with previous releases should always be done in+ "hotfixes" branch.+4. All merge commits to master from "hotfixes" should be done+ using the "--no-ff" flag and from "develop" should avoid merging commits.++Until we have a defined road-map we are going to leave out "release+"branches" and "feature branches". For more information about this development+model please refer to [this site.][6]++Thanks you, and happy coding.++[1]: http://www.haskell.org/+[2]: http://www.glfw.org/+[3]: https://github.com/bsl/bindings-GLFW+[4]: http://www.glfw.org/Version-3.3-released.html+[5]: https://github.com/bsl/GLFW-b-demo+[6]: http://nvie.com/posts/a-successful-git-branching-model/
Test.hs view
@@ -1,685 +1,683 @@--- base -import Control.Concurrent (threadDelay) -import Control.Monad (forM_) -import Data.Char (isAscii) -import Data.Bits (xor) -import Data.List (intercalate, isPrefixOf) -import Data.Maybe (isNothing) - --- 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] - - GLFW.initHint GLFW.InitHint'CocoaChdirResources False - True <- GLFW.init - - Just mon <- GLFW.getPrimaryMonitor - - GLFW.windowHint $ GLFW.WindowHint'Visible False - GLFW.windowHint $ GLFW.WindowHint'CocoaFrameName "GLFW-b test" - 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 = 3 -versionRevision = 0 - -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) - ] - --------------------------------------------------------------------------------- - -glfwTest :: String -> IO () -> Test -glfwTest name test = testCase name $ do - GLFW.clearError - test - err <- GLFW.getError - case err of - Nothing -> return () - Just e -> assertFailure $ - concat ["Test '", name, "' generated error: ", show e] - -tests :: GLFW.Monitor -> GLFW.Window -> [Test] -tests mon win = - [ testGroup "Initialization and version information" - [ testCase "getVersion" test_getVersion - , testCase "getVersionString" test_getVersionString - , testCase "getError" test_getError - ] - , testGroup "Monitor handling" - [ glfwTest "getMonitors" test_getMonitors - , glfwTest "getPrimaryMonitor" test_getPrimaryMonitor - , glfwTest "getMonitorPos" $ test_getMonitorPos mon - , glfwTest "getMonitorPhysicalSize" $ test_getMonitorPhysicalSize mon - , glfwTest "getMonitorWorkarea" $ test_getMonitorWorkarea mon - , glfwTest "getMonitorName" $ test_getMonitorName mon - , glfwTest "getVideoModes" $ test_getVideoModes mon - , glfwTest "getVideoMode" $ test_getVideoMode mon - , glfwTest "getGamma" $ test_getGammaRamp mon - ] - , testGroup "Window handling" - [ glfwTest "defaultWindowHints" test_defaultWindowHints - - -- Test window attributes - , glfwTest "getWindowFocused" $ test_getWindowFocused win - , glfwTest "getWindowResizable" $ test_getWindowResizable win - , glfwTest "getWindowDecorated" $ test_getWindowDecorated win - , glfwTest "getWindowClientAPI" $ test_getWindowClientAPI win - , glfwTest "window context version" $ test_window_context_version win - , glfwTest "getWindowContextRobustness" $ test_getWindowContextRobustness win - , glfwTest "getWindowOpenGLForwardCompat" $ test_getWindowOpenGLForwardCompat win - , glfwTest "getWindowOpenGLDebugContext" $ test_getWindowOpenGLDebugContext win - , glfwTest "getWindowOpenGLProfile" $ test_getWindowOpenGLProfile win - , glfwTest "window attribs" $ test_windowAttribs win - , glfwTest "window close flag" $ test_window_close_flag win - , glfwTest "setWindowOpacity" $ test_window_opacity win - , glfwTest "setWindowTitle" $ test_setWindowTitle win - , glfwTest "window pos" $ test_window_pos win - , glfwTest "window size" $ test_window_size win - , glfwTest "getWindowFrameSize" $ test_getWindowFrameSize win - , glfwTest "getFramebufferSize" $ test_getFramebufferSize win - , glfwTest "iconification" $ test_iconification win - -- , glfwTest "show/hide" $ test_show_hide win - , glfwTest "getWindowMonitor" $ test_getWindowMonitor win mon - , glfwTest "setWindowed" $ test_setWindowed win - , glfwTest "setWindowIcon" $ test_setWindowIcon win - , glfwTest "maximizeWindow" $ test_maximizeWindow win - , glfwTest "setWindowSizeLimits" $ test_setWindowSizeLimits win - , glfwTest "setWindowAspectRatio" $ test_setWindowAspectRatio win - , glfwTest "focusWindow" $ test_focusWindow win - , glfwTest "cursor pos" $ test_cursor_pos win - , glfwTest "pollEvents" test_pollEvents - , glfwTest "waitEvents" test_waitEvents - , glfwTest "waitEventsTimeout" test_waitEventsTimeout - ] - , testGroup "Input handling" - [ glfwTest "cursor input mode" $ test_cursor_input_mode win - , glfwTest "sticky keys input mode" $ test_sticky_keys_input_mode win - , glfwTest "sticky mouse buttons input mode" $ test_sticky_mouse_buttons_input_mode win - , glfwTest "joystickPresent" test_joystickPresent - , glfwTest "getJoystickAxes" test_getJoystickAxes - , glfwTest "getJoystickButtons" test_getJoystickButtons - , glfwTest "getJoystickName" test_getJoystickName - , glfwTest "getKeyName" test_getKeyName - , glfwTest "getGamepadState" test_getGamepadState - ] - , testGroup "Time" - [ glfwTest "getTime" test_getTime - , glfwTest "setTime" test_setTime - , glfwTest "getTimerValue" test_getTimerValue - , glfwTest "getTimerFrequency" test_getTimerFrequency - ] - , testGroup "Context" - [ glfwTest "getCurrentContext" $ test_getCurrentContext win - , glfwTest "swapBuffers" $ test_swapBuffers win - , glfwTest "swapInterval" test_swapInterval - , glfwTest "extensionSupported" test_extensionSupported - ] - , testGroup "Clipboard" - [ glfwTest "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_getError :: IO () -test_getError = GLFW.getError >>= assertBool "Got GLFW error!" . isNothing - -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_getMonitorWorkarea :: GLFW.Monitor -> IO () -test_getMonitorWorkarea mon = do - (x, y, w, h) <- GLFW.getMonitorWorkarea mon - assertBool "workarea x nonnegative" $ x >= 0 - assertBool "workarea y nonnegative" $ y >= 0 - assertBool "workarea width positive" $ w > 0 - assertBool "workarea height positive" $ h > 0 - -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_windowAttribs :: GLFW.Window -> IO () -test_windowAttribs win = do - oldRsz <- GLFW.getWindowAttrib win GLFW.WindowAttrib'Resizable - - GLFW.setWindowAttrib win GLFW.WindowAttrib'Resizable False - GLFW.getWindowAttrib win GLFW.WindowAttrib'Resizable >>= (@?= False) - - GLFW.setWindowAttrib win GLFW.WindowAttrib'Resizable True - rsz <- GLFW.getWindowAttrib win GLFW.WindowAttrib'Resizable - rsz @?= True - - GLFW.setWindowAttrib win GLFW.WindowAttrib'Resizable oldRsz - -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_window_opacity :: GLFW.Window -> IO () -test_window_opacity win = do - oldOpacity <- GLFW.getWindowOpacity win - - GLFW.setWindowOpacity win 0.27 - opacity <- GLFW.getWindowOpacity win - assertBool "Opacity is close to what we set it to." $ - (abs (opacity - 0.27)) < 0.01 - - GLFW.setWindowOpacity win oldOpacity - -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_getGamepadState :: IO () -test_getGamepadState = - forM_ joysticks $ \js -> do - mst <- GLFW.getGamepadState js - case mst of - (Just st) -> do - GLFW.joystickIsGamepad js >>= assertBool "Is gamepad" - GLFW.getGamepadName js >>= assertBool "Gamepad has name" . not . null - forM_ [minBound..maxBound] $ assertBool "Button not pressed" - . (== GLFW.GamepadButtonState'Released) - . GLFW.getButtonState st - _ -> return () - --------------------------------------------------------------------------------- - -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 - result <- GLFW.getClipboardString win - - err <- GLFW.getError - return $ case err of - Just (GLFW.Error'FormatUnavailable, _) -> Just s - _ -> result - --------------------------------------------------------------------------------- - -{-# 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)+import Data.Maybe (isNothing)++-- 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]++ GLFW.initHint GLFW.InitHint'CocoaChdirResources False+ True <- GLFW.init++ Just mon <- GLFW.getPrimaryMonitor++ GLFW.windowHint $ GLFW.WindowHint'Visible False+ GLFW.windowHint $ GLFW.WindowHint'CocoaFrameName "GLFW-b test"+ 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 = 3+versionRevision = 9++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)+ ]++--------------------------------------------------------------------------------++glfwTest :: String -> IO () -> Test+glfwTest name test = testCase name $ do+ GLFW.clearError+ test+ err <- GLFW.getError+ case err of+ Nothing -> return ()+ Just e -> assertFailure $+ concat ["Test '", name, "' generated error: ", show e]++tests :: GLFW.Monitor -> GLFW.Window -> [Test]+tests mon win =+ [ testGroup "Initialization and version information"+ [ testCase "getVersion" test_getVersion+ , testCase "getVersionString" test_getVersionString+ , testCase "getError" test_getError+ ]+ , testGroup "Monitor handling"+ [ glfwTest "getMonitors" test_getMonitors+ , glfwTest "getPrimaryMonitor" test_getPrimaryMonitor+ , glfwTest "getMonitorPos" $ test_getMonitorPos mon+ , glfwTest "getMonitorPhysicalSize" $ test_getMonitorPhysicalSize mon+ , glfwTest "getMonitorWorkarea" $ test_getMonitorWorkarea mon+ , glfwTest "getMonitorName" $ test_getMonitorName mon+ , glfwTest "getVideoModes" $ test_getVideoModes mon+ , glfwTest "getVideoMode" $ test_getVideoMode mon+ , glfwTest "getGamma" $ test_getGammaRamp mon+ ]+ , testGroup "Window handling"+ [ glfwTest "defaultWindowHints" test_defaultWindowHints++ -- Test window attributes+ , glfwTest "getWindowFocused" $ test_getWindowFocused win+ , glfwTest "getWindowResizable" $ test_getWindowResizable win+ , glfwTest "getWindowDecorated" $ test_getWindowDecorated win+ , glfwTest "getWindowClientAPI" $ test_getWindowClientAPI win+ , glfwTest "window context version" $ test_window_context_version win+ , glfwTest "getWindowContextRobustness" $ test_getWindowContextRobustness win+ , glfwTest "getWindowOpenGLForwardCompat" $ test_getWindowOpenGLForwardCompat win+ , glfwTest "getWindowOpenGLDebugContext" $ test_getWindowOpenGLDebugContext win+ , glfwTest "getWindowOpenGLProfile" $ test_getWindowOpenGLProfile win+ , glfwTest "window attribs" $ test_windowAttribs win+ , glfwTest "window close flag" $ test_window_close_flag win+ , glfwTest "setWindowOpacity" $ test_window_opacity win+ , glfwTest "setWindowTitle" $ test_setWindowTitle win+ , glfwTest "window pos" $ test_window_pos win+ , glfwTest "window size" $ test_window_size win+ , glfwTest "getWindowFrameSize" $ test_getWindowFrameSize win+ , glfwTest "getFramebufferSize" $ test_getFramebufferSize win+ , glfwTest "iconification" $ test_iconification win+ -- , glfwTest "show/hide" $ test_show_hide win+ , glfwTest "getWindowMonitor" $ test_getWindowMonitor win mon+ , glfwTest "setWindowed" $ test_setWindowed win+ , glfwTest "setWindowIcon" $ test_setWindowIcon win+ , glfwTest "maximizeWindow" $ test_maximizeWindow win+ , glfwTest "setWindowSizeLimits" $ test_setWindowSizeLimits win+ , glfwTest "setWindowAspectRatio" $ test_setWindowAspectRatio win+ , glfwTest "focusWindow" $ test_focusWindow win+ , glfwTest "cursor pos" $ test_cursor_pos win+ , glfwTest "pollEvents" test_pollEvents+ , glfwTest "waitEvents" test_waitEvents+ , glfwTest "waitEventsTimeout" test_waitEventsTimeout+ ]+ , testGroup "Input handling"+ [ glfwTest "cursor input mode" $ test_cursor_input_mode win+ , glfwTest "sticky keys input mode" $ test_sticky_keys_input_mode win+ , glfwTest "sticky mouse buttons input mode" $ test_sticky_mouse_buttons_input_mode win+ , glfwTest "joystickPresent" test_joystickPresent+ , glfwTest "getJoystickAxes" test_getJoystickAxes+ , glfwTest "getJoystickButtons" test_getJoystickButtons+ , glfwTest "getJoystickName" test_getJoystickName+ , glfwTest "getKeyName" test_getKeyName+ , glfwTest "getGamepadState" test_getGamepadState+ ]+ , testGroup "Time"+ [ glfwTest "getTime" test_getTime+ , glfwTest "setTime" test_setTime+ , glfwTest "getTimerValue" test_getTimerValue+ , glfwTest "getTimerFrequency" test_getTimerFrequency+ ]+ , testGroup "Context"+ [ glfwTest "getCurrentContext" $ test_getCurrentContext win+ , glfwTest "swapBuffers" $ test_swapBuffers win+ , glfwTest "swapInterval" test_swapInterval+ , glfwTest "extensionSupported" test_extensionSupported+ ]+ , testGroup "Clipboard"+ [ glfwTest "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_getError :: IO ()+test_getError = GLFW.getError >>= assertBool "Got GLFW error!" . isNothing++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_getMonitorWorkarea :: GLFW.Monitor -> IO ()+test_getMonitorWorkarea mon = do+ (x, y, w, h) <- GLFW.getMonitorWorkarea mon+ assertBool "workarea x nonnegative" $ x >= 0+ assertBool "workarea y nonnegative" $ y >= 0+ assertBool "workarea width positive" $ w > 0+ assertBool "workarea height positive" $ h > 0++test_getMonitorName :: GLFW.Monitor -> IO ()+test_getMonitorName mon = do+ mname <- GLFW.getMonitorName mon+ case mname of+ Nothing -> assertFailure ""+ Just name -> 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_windowAttribs :: GLFW.Window -> IO ()+test_windowAttribs win = do+ oldRsz <- GLFW.getWindowAttrib win GLFW.WindowAttrib'Resizable++ GLFW.setWindowAttrib win GLFW.WindowAttrib'Resizable False+ GLFW.getWindowAttrib win GLFW.WindowAttrib'Resizable >>= (@?= False)++ GLFW.setWindowAttrib win GLFW.WindowAttrib'Resizable True+ rsz <- GLFW.getWindowAttrib win GLFW.WindowAttrib'Resizable+ rsz @?= True++ GLFW.setWindowAttrib win GLFW.WindowAttrib'Resizable oldRsz++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_window_opacity :: GLFW.Window -> IO ()+test_window_opacity win = do+ oldOpacity <- GLFW.getWindowOpacity win++ GLFW.setWindowOpacity win 0.27+ opacity <- GLFW.getWindowOpacity win+ assertBool "Opacity is close to what we set it to." $+ (abs (opacity - 0.27)) < 0.01++ GLFW.setWindowOpacity win oldOpacity++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_getGamepadState :: IO ()+test_getGamepadState =+ forM_ joysticks $ \js -> do+ mst <- GLFW.getGamepadState js+ case mst of+ (Just st) -> do+ GLFW.joystickIsGamepad js >>= assertBool "Is gamepad"+ GLFW.getGamepadName js >>= assertBool "Gamepad has name" . not . null+ forM_ [minBound..maxBound] $ assertBool "Button not pressed"+ . (== GLFW.GamepadButtonState'Released)+ . GLFW.getButtonState st+ _ -> return ()++--------------------------------------------------------------------------------++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+ result <- GLFW.getClipboardString win++ err <- GLFW.getError+ return $ case err of+ Just (GLFW.Error'FormatUnavailable, _) -> Just s+ _ -> result++--------------------------------------------------------------------------------++{-# ANN module "HLint: ignore Use camelCase" #-}