{-# 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)