    {-# LINE 1 "Basement/Terminal/Size.hsc" #-}
    {-# LANGUAGE CApiFFI #-}
    module Basement.Terminal.Size
        ( getDimensions
        ) where

    import           Foreign
    import           Foreign.C
    import           Basement.Compat.Base
    import           Basement.Types.OffsetSize
    import           Basement.Numerical.Subtractive
    import           Basement.Numerical.Additive
    import           Prelude (fromIntegral)

    {-# LINE 22 "Basement/Terminal/Size.hsc" #-}

    {-# LINE 26 "Basement/Terminal/Size.hsc" #-}

    {-# LINE 27 "Basement/Terminal/Size.hsc" #-}

    {-# LINE 33 "Basement/Terminal/Size.hsc" #-}

    {-# LINE 35 "Basement/Terminal/Size.hsc" #-}
    data Winsize = Winsize
        { ws_row    :: !Word16
        , ws_col    :: !Word16
        , ws_xpixel :: !Word16
        , ws_ypixel :: !Word16
        }

    instance Storable Winsize where
        sizeOf :: Winsize -> Int
    sizeOf Winsize
    _ = (Int
    8)
    {-# LINE 44 "Basement/Terminal/Size.hsc" #-}
        alignment _ = 2
    {-# LINE 45 "Basement/Terminal/Size.hsc" #-}
        peek ptr = do
            r <- (\hsc_ptr -> peekByteOff hsc_ptr 0) ptr
    {-# LINE 47 "Basement/Terminal/Size.hsc" #-}
            c <- (\hsc_ptr -> peekByteOff hsc_ptr 2) ptr
    {-# LINE 48 "Basement/Terminal/Size.hsc" #-}
            x <- (\hsc_ptr -> peekByteOff hsc_ptr 4) ptr
    {-# LINE 49 "Basement/Terminal/Size.hsc" #-}
            y <- (\hsc_ptr -> peekByteOff hsc_ptr 6) ptr
    {-# LINE 50 "Basement/Terminal/Size.hsc" #-}
            return (Winsize r c x y)
        poke :: Ptr Winsize -> Winsize -> IO ()
    poke Ptr Winsize
    ptr (Winsize Word16
    r Word16
    c Word16
    x Word16
    y) = do
            (\Ptr Winsize
    hsc_ptr -> Ptr Winsize -> Int -> Word16 -> IO ()
    forall b. Ptr b -> Int -> Word16 -> IO ()
    forall a b. Storable a => Ptr b -> Int -> a -> IO ()
    pokeByteOff Ptr Winsize
    hsc_ptr Int
    0) Ptr Winsize
    ptr Word16
    r
    {-# LINE 53 "Basement/Terminal/Size.hsc" #-}
            (\Ptr Winsize
    hsc_ptr -> Ptr Winsize -> Int -> Word16 -> IO ()
    forall b. Ptr b -> Int -> Word16 -> IO ()
    forall a b. Storable a => Ptr b -> Int -> a -> IO ()
    pokeByteOff Ptr Winsize
    hsc_ptr Int
    2) Ptr Winsize
    ptr Word16
    c
    {-# LINE 54 "Basement/Terminal/Size.hsc" #-}
            (\Ptr Winsize
    hsc_ptr -> Ptr Winsize -> Int -> Word16 -> IO ()
    forall b. Ptr b -> Int -> Word16 -> IO ()
    forall a b. Storable a => Ptr b -> Int -> a -> IO ()
    pokeByteOff Ptr Winsize
    hsc_ptr Int
    4) Ptr Winsize
    ptr Word16
    x
    {-# LINE 55 "Basement/Terminal/Size.hsc" #-}
            (\Ptr Winsize
    hsc_ptr -> Ptr Winsize -> Int -> Word16 -> IO ()
    forall b. Ptr b -> Int -> Word16 -> IO ()
    forall a b. Storable a => Ptr b -> Int -> a -> IO ()
    pokeByteOff Ptr Winsize
    hsc_ptr Int
    6) Ptr Winsize
    ptr Word16
    y
    {-# LINE 56 "Basement/Terminal/Size.hsc" #-}

    {-# LINE 129 "Basement/Terminal/Size.hsc" #-}
    -- defined FOUNDATION_SYSTEM_WINDOWS

    {-# LINE 132 "Basement/Terminal/Size.hsc" #-}

    foreign import capi "sys/ioctl.h ioctl" c_ioctl :: CInt -> CULong -> Ptr a -> IO CInt

    -- | Get the terminal windows size
    tiocgwinsz :: CULong
    tiocgwinsz :: CULong
    tiocgwinsz = Word -> CULong
    forall a b. (Integral a, Num b) => a -> b
    Prelude.fromIntegral (Word
    21523 :: Word)
    {-# LINE 138 "Basement/Terminal/Size.hsc" #-}

    {-# LINE 143 "Basement/Terminal/Size.hsc" #-}

    {-# LINE 145 "Basement/Terminal/Size.hsc" #-}
    ioctlWinsize :: CInt -> IO (Maybe (CountOf Char, CountOf Char))
    ioctlWinsize :: CInt -> IO (Maybe (CountOf Char, CountOf Char))
    ioctlWinsize CInt
    fd = (Ptr Winsize -> IO (Maybe (CountOf Char, CountOf Char)))
    -> IO (Maybe (CountOf Char, CountOf Char))
    forall a b. Storable a => (Ptr a -> IO b) -> IO b
    alloca ((Ptr Winsize -> IO (Maybe (CountOf Char, CountOf Char)))
     -> IO (Maybe (CountOf Char, CountOf Char)))
    -> (Ptr Winsize -> IO (Maybe (CountOf Char, CountOf Char)))
    -> IO (Maybe (CountOf Char, CountOf Char))
    forall a b. (a -> b) -> a -> b
    $ \Ptr Winsize
    winsizePtr -> do
        CInt
    status <- CInt -> CULong -> Ptr Winsize -> IO CInt
    forall a. CInt -> CULong -> Ptr a -> IO CInt
    c_ioctl CInt
    fd CULong
    tiocgwinsz Ptr Winsize
    winsizePtr
        if CInt
    status CInt -> CInt -> Bool
    forall a. Eq a => a -> a -> Bool
    == (-CInt
    1 :: CInt)
            then Maybe (CountOf Char, CountOf Char)
    -> IO (Maybe (CountOf Char, CountOf Char))
    forall a. a -> IO a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure Maybe (CountOf Char, CountOf Char)
    forall a. Maybe a
    Nothing
            else (CountOf Char, CountOf Char) -> Maybe (CountOf Char, CountOf Char)
    forall a. a -> Maybe a
    Just ((CountOf Char, CountOf Char)
     -> Maybe (CountOf Char, CountOf Char))
    -> (Winsize -> (CountOf Char, CountOf Char))
    -> Winsize
    -> Maybe (CountOf Char, CountOf Char)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . Winsize -> (CountOf Char, CountOf Char)
    forall {ty} {ty}. Winsize -> (CountOf ty, CountOf ty)
    toDimensions (Winsize -> Maybe (CountOf Char, CountOf Char))
    -> IO Winsize -> IO (Maybe (CountOf Char, CountOf Char))
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Ptr Winsize -> IO Winsize
    forall a. Storable a => Ptr a -> IO a
    peek Ptr Winsize
    winsizePtr
      where
        toDimensions :: Winsize -> (CountOf ty, CountOf ty)
    toDimensions Winsize
    winsize =
            ( Int -> CountOf ty
    forall ty. Int -> CountOf ty
    CountOf (Int -> CountOf ty) -> (Winsize -> Int) -> Winsize -> CountOf ty
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . Word16 -> Int
    forall a b. (Integral a, Num b) => a -> b
    Prelude.fromIntegral (Word16 -> Int) -> (Winsize -> Word16) -> Winsize -> Int
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . Winsize -> Word16
    ws_col (Winsize -> CountOf ty) -> Winsize -> CountOf ty
    forall a b. (a -> b) -> a -> b
    $ Winsize
    winsize
            , Int -> CountOf ty
    forall ty. Int -> CountOf ty
    CountOf (Int -> CountOf ty) -> (Winsize -> Int) -> Winsize -> CountOf ty
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . Word16 -> Int
    forall a b. (Integral a, Num b) => a -> b
    Prelude.fromIntegral (Word16 -> Int) -> (Winsize -> Word16) -> Winsize -> Int
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . Winsize -> Word16
    ws_row (Winsize -> CountOf ty) -> Winsize -> CountOf ty
    forall a b. (a -> b) -> a -> b
    $ Winsize
    winsize)

    {-# LINE 174 "Basement/Terminal/Size.hsc" #-}
    -- defined FOUNDATION_SYSTEM_WINDOWS

    -- | Return the size of the current terminal
    --
    -- If the system is not supported or that querying the system result in an error
    -- then a default size of (80, 24) will be given back.
    getDimensions :: IO (CountOf Char, CountOf Char)
    getDimensions :: IO (CountOf Char, CountOf Char)
    getDimensions =

    {-# LINE 185 "Basement/Terminal/Size.hsc" #-}
        (CountOf Char, CountOf Char)
    -> ((CountOf Char, CountOf Char) -> (CountOf Char, CountOf Char))
    -> Maybe (CountOf Char, CountOf Char)
    -> (CountOf Char, CountOf Char)
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe (CountOf Char, CountOf Char)
    defaultSize (CountOf Char, CountOf Char) -> (CountOf Char, CountOf Char)
    forall a. a -> a
    forall {k} (cat :: k -> k -> *) (a :: k). Category cat => cat a a
    id (Maybe (CountOf Char, CountOf Char)
     -> (CountOf Char, CountOf Char))
    -> IO (Maybe (CountOf Char, CountOf Char))
    -> IO (CountOf Char, CountOf Char)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> CInt -> IO (Maybe (CountOf Char, CountOf Char))
    ioctlWinsize CInt
    0

    {-# LINE 189 "Basement/Terminal/Size.hsc" #-}
      where
        defaultSize :: (CountOf Char, CountOf Char)
    defaultSize = (CountOf Char
    80, CountOf Char
    24)