{-# 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 _ = (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 r c x y) = do
(\hsc_ptr -> pokeByteOff hsc_ptr 0) ptr r
{-# LINE 53 "Basement/Terminal/Size.hsc" #-}
(\hsc_ptr -> pokeByteOff hsc_ptr 2) ptr c
{-# LINE 54 "Basement/Terminal/Size.hsc" #-}
(\hsc_ptr -> pokeByteOff hsc_ptr 4) ptr x
{-# LINE 55 "Basement/Terminal/Size.hsc" #-}
(\hsc_ptr -> pokeByteOff hsc_ptr 6) ptr y
{-# LINE 56 "Basement/Terminal/Size.hsc" #-}
{-# LINE 129 "Basement/Terminal/Size.hsc" #-}
{-# LINE 132 "Basement/Terminal/Size.hsc" #-}
foreign import capi "sys/ioctl.h ioctl" c_ioctl :: CInt -> CULong -> Ptr a -> IO CInt
tiocgwinsz :: CULong
tiocgwinsz = Prelude.fromIntegral (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 fd = alloca $ \winsizePtr -> do
status <- c_ioctl fd tiocgwinsz winsizePtr
if status == (-1 :: CInt)
then pure Nothing
else Just . toDimensions <$> peek winsizePtr
where
toDimensions winsize =
( CountOf . Prelude.fromIntegral . ws_col $ winsize
, CountOf . Prelude.fromIntegral . ws_row $ winsize)
{-# LINE 174 "Basement/Terminal/Size.hsc" #-}
getDimensions :: IO (CountOf Char, CountOf Char)
getDimensions =
{-# LINE 185 "Basement/Terminal/Size.hsc" #-}
maybe defaultSize id <$> ioctlWinsize 0
{-# LINE 189 "Basement/Terminal/Size.hsc" #-}
where
defaultSize = (80, 24)