--------------------------------------------------------------------------------
-- |
-- Module      :  Graphics.UI.GLUT.GameMode
-- Copyright   :  (c) Sven Panne 2002-2018
-- License     :  BSD3
--
-- Maintainer  :  Sven Panne <svenpanne@gmail.com>
-- Stability   :  stable
-- Portability :  portable
--
-- In addition to the functionality offered by
-- 'Graphics.UI.GLUT.Window.fullScreen', GLUT offers an sub-API to change the
-- screen resolution, color depth, and refresh rate of the display for a single
-- full screen window. This mode of operation is called /game mode/, and is
-- restricted in various ways: No pop-up menus are allowed for this full screen
-- window, no other (sub-)windows can be created, and all other applications are
-- hidden.
--
-- /X Implementation Notes:/ Note that game mode is not fully supported in the
-- original GLUT for X, it is essentially the same as using
-- 'Graphics.UI.GLUT.Window.fullScreen'. The GLUT clone freeglut
-- (see <http://freeglut.sourceforge.net/>) does not have this restriction.
--
--------------------------------------------------------------------------------

module Graphics.UI.GLUT.GameMode (
   GameModeCapability(..), GameModeCapabilityDescription(..),
   gameModeCapabilities, enterGameMode, leaveGameMode,
   BitsPerPlane, RefreshRate, GameModeInfo(..), gameModeInfo,
   gameModeActive
) where

import Control.Monad.IO.Class ( MonadIO(..) )
import Data.List ( intersperse )
import Data.StateVar ( GettableStateVar, makeGettableStateVar
                     , SettableStateVar, makeSettableStateVar )
import Foreign.C.String ( withCString )
import Graphics.Rendering.OpenGL ( Size(..), GLenum )

import Graphics.UI.GLUT.Raw
import Graphics.UI.GLUT.Types

--------------------------------------------------------------------------------

-- | Capabilities for 'gameModeCapabilities'

data GameModeCapability
   = GameModeWidth         -- ^ Width of the screen resolution in pixels
   | GameModeHeight        -- ^ Height of the screen resolution in pixels
   | GameModeBitsPerPlane  -- ^ Color depth of the screen in bits
   | GameModeRefreshRate   -- ^ Refresh rate in Hertz
   | GameModeNum           -- ^ Match the Nth frame buffer configuration
                           --   compatible with the given capabilities
                           --   (numbering starts at 1)
   deriving ( GameModeCapability -> GameModeCapability -> Bool
(GameModeCapability -> GameModeCapability -> Bool)
-> (GameModeCapability -> GameModeCapability -> Bool)
-> Eq GameModeCapability
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: GameModeCapability -> GameModeCapability -> Bool
$c/= :: GameModeCapability -> GameModeCapability -> Bool
== :: GameModeCapability -> GameModeCapability -> Bool
$c== :: GameModeCapability -> GameModeCapability -> Bool
Eq, Eq GameModeCapability
Eq GameModeCapability
-> (GameModeCapability -> GameModeCapability -> Ordering)
-> (GameModeCapability -> GameModeCapability -> Bool)
-> (GameModeCapability -> GameModeCapability -> Bool)
-> (GameModeCapability -> GameModeCapability -> Bool)
-> (GameModeCapability -> GameModeCapability -> Bool)
-> (GameModeCapability -> GameModeCapability -> GameModeCapability)
-> (GameModeCapability -> GameModeCapability -> GameModeCapability)
-> Ord GameModeCapability
GameModeCapability -> GameModeCapability -> Bool
GameModeCapability -> GameModeCapability -> Ordering
GameModeCapability -> GameModeCapability -> GameModeCapability
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: GameModeCapability -> GameModeCapability -> GameModeCapability
$cmin :: GameModeCapability -> GameModeCapability -> GameModeCapability
max :: GameModeCapability -> GameModeCapability -> GameModeCapability
$cmax :: GameModeCapability -> GameModeCapability -> GameModeCapability
>= :: GameModeCapability -> GameModeCapability -> Bool
$c>= :: GameModeCapability -> GameModeCapability -> Bool
> :: GameModeCapability -> GameModeCapability -> Bool
$c> :: GameModeCapability -> GameModeCapability -> Bool
<= :: GameModeCapability -> GameModeCapability -> Bool
$c<= :: GameModeCapability -> GameModeCapability -> Bool
< :: GameModeCapability -> GameModeCapability -> Bool
$c< :: GameModeCapability -> GameModeCapability -> Bool
compare :: GameModeCapability -> GameModeCapability -> Ordering
$ccompare :: GameModeCapability -> GameModeCapability -> Ordering
$cp1Ord :: Eq GameModeCapability
Ord, Int -> GameModeCapability -> ShowS
[GameModeCapability] -> ShowS
GameModeCapability -> String
(Int -> GameModeCapability -> ShowS)
-> (GameModeCapability -> String)
-> ([GameModeCapability] -> ShowS)
-> Show GameModeCapability
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [GameModeCapability] -> ShowS
$cshowList :: [GameModeCapability] -> ShowS
show :: GameModeCapability -> String
$cshow :: GameModeCapability -> String
showsPrec :: Int -> GameModeCapability -> ShowS
$cshowsPrec :: Int -> GameModeCapability -> ShowS
Show )

gameModeCapabilityToString :: GameModeCapability -> String
gameModeCapabilityToString :: GameModeCapability -> String
gameModeCapabilityToString GameModeCapability
x = case GameModeCapability
x of
   GameModeCapability
GameModeWidth        -> String
"width"
   GameModeCapability
GameModeHeight       -> String
"height"
   GameModeCapability
GameModeBitsPerPlane -> String
"bpp"
   GameModeCapability
GameModeRefreshRate  -> String
"hertz"
   GameModeCapability
GameModeNum          -> String
"num"

-- | A single capability description for 'gameModeCapabilities'.

data GameModeCapabilityDescription = Where' GameModeCapability Relation Int
   deriving ( GameModeCapabilityDescription
-> GameModeCapabilityDescription -> Bool
(GameModeCapabilityDescription
 -> GameModeCapabilityDescription -> Bool)
-> (GameModeCapabilityDescription
    -> GameModeCapabilityDescription -> Bool)
-> Eq GameModeCapabilityDescription
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: GameModeCapabilityDescription
-> GameModeCapabilityDescription -> Bool
$c/= :: GameModeCapabilityDescription
-> GameModeCapabilityDescription -> Bool
== :: GameModeCapabilityDescription
-> GameModeCapabilityDescription -> Bool
$c== :: GameModeCapabilityDescription
-> GameModeCapabilityDescription -> Bool
Eq, Eq GameModeCapabilityDescription
Eq GameModeCapabilityDescription
-> (GameModeCapabilityDescription
    -> GameModeCapabilityDescription -> Ordering)
-> (GameModeCapabilityDescription
    -> GameModeCapabilityDescription -> Bool)
-> (GameModeCapabilityDescription
    -> GameModeCapabilityDescription -> Bool)
-> (GameModeCapabilityDescription
    -> GameModeCapabilityDescription -> Bool)
-> (GameModeCapabilityDescription
    -> GameModeCapabilityDescription -> Bool)
-> (GameModeCapabilityDescription
    -> GameModeCapabilityDescription -> GameModeCapabilityDescription)
-> (GameModeCapabilityDescription
    -> GameModeCapabilityDescription -> GameModeCapabilityDescription)
-> Ord GameModeCapabilityDescription
GameModeCapabilityDescription
-> GameModeCapabilityDescription -> Bool
GameModeCapabilityDescription
-> GameModeCapabilityDescription -> Ordering
GameModeCapabilityDescription
-> GameModeCapabilityDescription -> GameModeCapabilityDescription
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: GameModeCapabilityDescription
-> GameModeCapabilityDescription -> GameModeCapabilityDescription
$cmin :: GameModeCapabilityDescription
-> GameModeCapabilityDescription -> GameModeCapabilityDescription
max :: GameModeCapabilityDescription
-> GameModeCapabilityDescription -> GameModeCapabilityDescription
$cmax :: GameModeCapabilityDescription
-> GameModeCapabilityDescription -> GameModeCapabilityDescription
>= :: GameModeCapabilityDescription
-> GameModeCapabilityDescription -> Bool
$c>= :: GameModeCapabilityDescription
-> GameModeCapabilityDescription -> Bool
> :: GameModeCapabilityDescription
-> GameModeCapabilityDescription -> Bool
$c> :: GameModeCapabilityDescription
-> GameModeCapabilityDescription -> Bool
<= :: GameModeCapabilityDescription
-> GameModeCapabilityDescription -> Bool
$c<= :: GameModeCapabilityDescription
-> GameModeCapabilityDescription -> Bool
< :: GameModeCapabilityDescription
-> GameModeCapabilityDescription -> Bool
$c< :: GameModeCapabilityDescription
-> GameModeCapabilityDescription -> Bool
compare :: GameModeCapabilityDescription
-> GameModeCapabilityDescription -> Ordering
$ccompare :: GameModeCapabilityDescription
-> GameModeCapabilityDescription -> Ordering
$cp1Ord :: Eq GameModeCapabilityDescription
Ord, Int -> GameModeCapabilityDescription -> ShowS
[GameModeCapabilityDescription] -> ShowS
GameModeCapabilityDescription -> String
(Int -> GameModeCapabilityDescription -> ShowS)
-> (GameModeCapabilityDescription -> String)
-> ([GameModeCapabilityDescription] -> ShowS)
-> Show GameModeCapabilityDescription
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [GameModeCapabilityDescription] -> ShowS
$cshowList :: [GameModeCapabilityDescription] -> ShowS
show :: GameModeCapabilityDescription -> String
$cshow :: GameModeCapabilityDescription -> String
showsPrec :: Int -> GameModeCapabilityDescription -> ShowS
$cshowsPrec :: Int -> GameModeCapabilityDescription -> ShowS
Show )

gameModeCapabilityDescriptionToString :: GameModeCapabilityDescription -> String
gameModeCapabilityDescriptionToString :: GameModeCapabilityDescription -> String
gameModeCapabilityDescriptionToString (Where' GameModeCapability
c Relation
r Int
i) =
      GameModeCapability -> String
gameModeCapabilityToString GameModeCapability
c String -> ShowS
forall a. [a] -> [a] -> [a]
++ Relation -> String
relationToString Relation
r String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
i

--------------------------------------------------------------------------------

-- | Controls the /game mode/ to be used when 'enterGameMode' is called. It is
-- described by a list of zero or more capability descriptions, which are
-- translated into a set of criteria used to select the appropriate screen
-- configuration. The criteria are matched in strict left to right order of
-- precdence. That is, the first specified criterion (leftmost) takes precedence
-- over the later criteria for non-exact criteria
-- ('Graphics.UI.GLUT.Initialization.IsGreaterThan',
-- 'Graphics.UI.GLUT.Initialization.IsLessThan', etc.). Exact criteria
-- ('Graphics.UI.GLUT.Initialization.IsEqualTo',
-- 'Graphics.UI.GLUT.Initialization.IsNotEqualTo') must match exactly so
-- precedence is not relevant.
--
-- To determine which configuration will actually be tried by 'enterGameMode'
-- (if any), use 'gameModeInfo'.
--
-- Note that even for game mode the current values of
-- 'Graphics.UI.GLUT.Initialization.initialDisplayMode'or
-- 'Graphics.UI.GLUT.Initialization.initialDisplayCapabilities' will
-- determine which buffers are available, if double buffering is used or not,
-- etc.

gameModeCapabilities :: SettableStateVar [GameModeCapabilityDescription]
gameModeCapabilities :: SettableStateVar [GameModeCapabilityDescription]
gameModeCapabilities = ([GameModeCapabilityDescription] -> IO ())
-> SettableStateVar [GameModeCapabilityDescription]
forall a. (a -> IO ()) -> SettableStateVar a
makeSettableStateVar (([GameModeCapabilityDescription] -> IO ())
 -> SettableStateVar [GameModeCapabilityDescription])
-> ([GameModeCapabilityDescription] -> IO ())
-> SettableStateVar [GameModeCapabilityDescription]
forall a b. (a -> b) -> a -> b
$ \[GameModeCapabilityDescription]
ds ->
   String -> (CString -> IO ()) -> IO ()
forall a. String -> (CString -> IO a) -> IO a
withCString ([GameModeCapabilityDescription] -> String
descriptionsToString [GameModeCapabilityDescription]
ds) CString -> IO ()
forall (m :: * -> *). MonadIO m => CString -> m ()
glutGameModeString

-- freeglut currently handles only simple game mode descriptions like "WxH:B@R",
-- so we try hard to use this format instead of the more general format allowed
-- by the "real" GLUT.
descriptionsToString :: [GameModeCapabilityDescription] -> String
descriptionsToString :: [GameModeCapabilityDescription] -> String
descriptionsToString [GameModeCapabilityDescription]
ds =
   let ws :: [Int]
ws = [ Int
x | Where' GameModeCapability
GameModeWidth        Relation
IsEqualTo Int
x <- [GameModeCapabilityDescription]
ds ]
       hs :: [Int]
hs = [ Int
x | Where' GameModeCapability
GameModeHeight       Relation
IsEqualTo Int
x <- [GameModeCapabilityDescription]
ds ]
       bs :: [Int]
bs = [ Int
x | Where' GameModeCapability
GameModeBitsPerPlane Relation
IsEqualTo Int
x <- [GameModeCapabilityDescription]
ds ]
       rs :: [Int]
rs = [ Int
x | Where' GameModeCapability
GameModeRefreshRate  Relation
IsEqualTo Int
x <- [GameModeCapabilityDescription]
ds ]
       allSimple :: Bool
allSimple = ([Int] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Int]
ws Int -> Int -> Int
forall a. Num a => a -> a -> a
+ [Int] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Int]
hs Int -> Int -> Int
forall a. Num a => a -> a -> a
+ [Int] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Int]
bs Int -> Int -> Int
forall a. Num a => a -> a -> a
+ [Int] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Int]
rs) Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== ([GameModeCapabilityDescription] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [GameModeCapabilityDescription]
ds)
       dimensionsOK :: Bool
dimensionsOK = ([Int] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Int]
ws) Bool -> Bool -> Bool
forall a. Eq a => a -> a -> Bool
== ([Int] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Int]
hs)
   in if Bool
allSimple Bool -> Bool -> Bool
&& Bool
dimensionsOK
         then [Int] -> [Int] -> [Int] -> [Int] -> String
simpleCapStr [Int]
ws [Int]
hs [Int]
bs [Int]
rs
         else [GameModeCapabilityDescription] -> String
generalCapStr [GameModeCapabilityDescription]
ds

simpleCapStr :: [Int] -> [Int] -> [Int] -> [Int] -> String
simpleCapStr :: [Int] -> [Int] -> [Int] -> [Int] -> String
simpleCapStr [Int]
ws [Int]
hs [Int]
bs [Int]
rs =
   String -> [Int] -> String
forall a. Show a => String -> [a] -> String
showCap String
"" [Int]
ws String -> ShowS
forall a. [a] -> [a] -> [a]
++ String -> [Int] -> String
forall a. Show a => String -> [a] -> String
showCap String
"x" [Int]
hs String -> ShowS
forall a. [a] -> [a] -> [a]
++ String -> [Int] -> String
forall a. Show a => String -> [a] -> String
showCap String
":" [Int]
bs String -> ShowS
forall a. [a] -> [a] -> [a]
++ String -> [Int] -> String
forall a. Show a => String -> [a] -> String
showCap String
"@" [Int]
rs
   where showCap :: String -> [a] -> String
showCap String
_      []    = String
""
         showCap String
prefix (a
x:[a]
_) = String
prefix String -> ShowS
forall a. [a] -> [a] -> [a]
++ a -> String
forall a. Show a => a -> String
show a
x

generalCapStr :: [GameModeCapabilityDescription] -> String
generalCapStr :: [GameModeCapabilityDescription] -> String
generalCapStr =
   [String] -> String
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat ([String] -> String)
-> ([GameModeCapabilityDescription] -> [String])
-> [GameModeCapabilityDescription]
-> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> [String] -> [String]
forall a. a -> [a] -> [a]
intersperse String
" " ([String] -> [String])
-> ([GameModeCapabilityDescription] -> [String])
-> [GameModeCapabilityDescription]
-> [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (GameModeCapabilityDescription -> String)
-> [GameModeCapabilityDescription] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map GameModeCapabilityDescription -> String
gameModeCapabilityDescriptionToString

--------------------------------------------------------------------------------

-- | Enter /game mode/, trying to change resolution, refresh rate, etc., as
-- specified by the current value of 'gameModeCapabilities'. An identifier for
-- the game mode window and a flag, indicating if the display mode actually
-- changed, are returned. The game mode window is made the /current window/.
--
-- Re-entering /game mode/ is allowed, the previous game mode window gets
-- destroyed by this, and a new one is created.

enterGameMode :: MonadIO m => m (Window, Bool)
enterGameMode :: m (Window, Bool)
enterGameMode = do
   CInt
w <- m CInt
forall (m :: * -> *). MonadIO m => m CInt
glutEnterGameMode
   Bool
c <- GLenum -> m Bool
forall (m :: * -> *). MonadIO m => GLenum -> m Bool
getBool GLenum
glut_GAME_MODE_DISPLAY_CHANGED
   (Window, Bool) -> m (Window, Bool)
forall (m :: * -> *) a. Monad m => a -> m a
return (CInt -> Window
Window CInt
w, Bool
c)

--------------------------------------------------------------------------------

-- | Leave /game mode/, restoring the old display mode and destroying the game
-- mode window.

leaveGameMode :: MonadIO m => m ()
leaveGameMode :: m ()
leaveGameMode = m ()
forall (m :: * -> *). MonadIO m => m ()
glutLeaveGameMode

--------------------------------------------------------------------------------

-- | The color depth of the screen, measured in bits (e.g. 8, 16, 24, 32, ...)

type BitsPerPlane = Int

-- | The refresh rate of the screen, measured in Hertz (e.g. 60, 75, 100, ...)

type RefreshRate = Int

data GameModeInfo = GameModeInfo Size BitsPerPlane RefreshRate
   deriving ( GameModeInfo -> GameModeInfo -> Bool
(GameModeInfo -> GameModeInfo -> Bool)
-> (GameModeInfo -> GameModeInfo -> Bool) -> Eq GameModeInfo
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: GameModeInfo -> GameModeInfo -> Bool
$c/= :: GameModeInfo -> GameModeInfo -> Bool
== :: GameModeInfo -> GameModeInfo -> Bool
$c== :: GameModeInfo -> GameModeInfo -> Bool
Eq, Eq GameModeInfo
Eq GameModeInfo
-> (GameModeInfo -> GameModeInfo -> Ordering)
-> (GameModeInfo -> GameModeInfo -> Bool)
-> (GameModeInfo -> GameModeInfo -> Bool)
-> (GameModeInfo -> GameModeInfo -> Bool)
-> (GameModeInfo -> GameModeInfo -> Bool)
-> (GameModeInfo -> GameModeInfo -> GameModeInfo)
-> (GameModeInfo -> GameModeInfo -> GameModeInfo)
-> Ord GameModeInfo
GameModeInfo -> GameModeInfo -> Bool
GameModeInfo -> GameModeInfo -> Ordering
GameModeInfo -> GameModeInfo -> GameModeInfo
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: GameModeInfo -> GameModeInfo -> GameModeInfo
$cmin :: GameModeInfo -> GameModeInfo -> GameModeInfo
max :: GameModeInfo -> GameModeInfo -> GameModeInfo
$cmax :: GameModeInfo -> GameModeInfo -> GameModeInfo
>= :: GameModeInfo -> GameModeInfo -> Bool
$c>= :: GameModeInfo -> GameModeInfo -> Bool
> :: GameModeInfo -> GameModeInfo -> Bool
$c> :: GameModeInfo -> GameModeInfo -> Bool
<= :: GameModeInfo -> GameModeInfo -> Bool
$c<= :: GameModeInfo -> GameModeInfo -> Bool
< :: GameModeInfo -> GameModeInfo -> Bool
$c< :: GameModeInfo -> GameModeInfo -> Bool
compare :: GameModeInfo -> GameModeInfo -> Ordering
$ccompare :: GameModeInfo -> GameModeInfo -> Ordering
$cp1Ord :: Eq GameModeInfo
Ord, Int -> GameModeInfo -> ShowS
[GameModeInfo] -> ShowS
GameModeInfo -> String
(Int -> GameModeInfo -> ShowS)
-> (GameModeInfo -> String)
-> ([GameModeInfo] -> ShowS)
-> Show GameModeInfo
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [GameModeInfo] -> ShowS
$cshowList :: [GameModeInfo] -> ShowS
show :: GameModeInfo -> String
$cshow :: GameModeInfo -> String
showsPrec :: Int -> GameModeInfo -> ShowS
$cshowsPrec :: Int -> GameModeInfo -> ShowS
Show )

--------------------------------------------------------------------------------

-- | Return 'Just' the mode which would be tried by the next call to
-- 'enterGameMode'. Returns 'Nothing' if the mode requested by the current value
-- of 'gameModeCapabilities' is not possible, in which case 'enterGameMode'
-- would simply create a full screen window using the current mode.

gameModeInfo :: GettableStateVar (Maybe GameModeInfo)
gameModeInfo :: GettableStateVar (Maybe GameModeInfo)
gameModeInfo = GettableStateVar (Maybe GameModeInfo)
-> GettableStateVar (Maybe GameModeInfo)
forall a. IO a -> IO a
makeGettableStateVar (GettableStateVar (Maybe GameModeInfo)
 -> GettableStateVar (Maybe GameModeInfo))
-> GettableStateVar (Maybe GameModeInfo)
-> GettableStateVar (Maybe GameModeInfo)
forall a b. (a -> b) -> a -> b
$ do
   Bool
possible <- GLenum -> IO Bool
forall (m :: * -> *). MonadIO m => GLenum -> m Bool
getBool GLenum
glut_GAME_MODE_POSSIBLE
   if Bool
possible
      then do
         CInt
w <- GLenum -> IO CInt
forall (m :: * -> *). MonadIO m => GLenum -> m CInt
glutGameModeGet GLenum
glut_GAME_MODE_WIDTH
         CInt
h <- GLenum -> IO CInt
forall (m :: * -> *). MonadIO m => GLenum -> m CInt
glutGameModeGet GLenum
glut_GAME_MODE_HEIGHT
         let size :: Size
size = GLsizei -> GLsizei -> Size
Size (CInt -> GLsizei
forall a b. (Integral a, Num b) => a -> b
fromIntegral CInt
w) (CInt -> GLsizei
forall a b. (Integral a, Num b) => a -> b
fromIntegral CInt
h)
         CInt
b <- GLenum -> IO CInt
forall (m :: * -> *). MonadIO m => GLenum -> m CInt
glutGameModeGet GLenum
glut_GAME_MODE_PIXEL_DEPTH
         CInt
r <- GLenum -> IO CInt
forall (m :: * -> *). MonadIO m => GLenum -> m CInt
glutGameModeGet GLenum
glut_GAME_MODE_REFRESH_RATE
         Maybe GameModeInfo -> GettableStateVar (Maybe GameModeInfo)
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe GameModeInfo -> GettableStateVar (Maybe GameModeInfo))
-> Maybe GameModeInfo -> GettableStateVar (Maybe GameModeInfo)
forall a b. (a -> b) -> a -> b
$ GameModeInfo -> Maybe GameModeInfo
forall a. a -> Maybe a
Just (GameModeInfo -> Maybe GameModeInfo)
-> GameModeInfo -> Maybe GameModeInfo
forall a b. (a -> b) -> a -> b
$ Size -> Int -> Int -> GameModeInfo
GameModeInfo Size
size (CInt -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral CInt
b) (CInt -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral CInt
r)
      else Maybe GameModeInfo -> GettableStateVar (Maybe GameModeInfo)
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe GameModeInfo
forall a. Maybe a
Nothing

getBool :: MonadIO m => GLenum -> m Bool
getBool :: GLenum -> m Bool
getBool GLenum
x = do
  CInt
val <- GLenum -> m CInt
forall (m :: * -> *). MonadIO m => GLenum -> m CInt
glutGameModeGet GLenum
x
  Bool -> m Bool
forall (m :: * -> *) a. Monad m => a -> m a
return (Bool -> m Bool) -> Bool -> m Bool
forall a b. (a -> b) -> a -> b
$ CInt
val CInt -> CInt -> Bool
forall a. Eq a => a -> a -> Bool
/= CInt
0

--------------------------------------------------------------------------------

-- | Contains 'True' when the /game mode/ is active, 'False' otherwise.

gameModeActive :: GettableStateVar Bool
gameModeActive :: IO Bool
gameModeActive = IO Bool -> IO Bool
forall a. IO a -> IO a
makeGettableStateVar (IO Bool -> IO Bool) -> IO Bool -> IO Bool
forall a b. (a -> b) -> a -> b
$ GLenum -> IO Bool
forall (m :: * -> *). MonadIO m => GLenum -> m Bool
getBool GLenum
glut_GAME_MODE_ACTIVE