module System.Console.Terminal.Posix
( size, fdSize, hSize
) where
import System.Console.Terminal.Common
import Control.Exception (catch)
import Data.Typeable (cast)
import Foreign
import Foreign.C.Error
import Foreign.C.Types
import GHC.IO.FD (FD(FD, fdFD))
import GHC.IO.Handle.Internals (withHandle_)
import GHC.IO.Handle.Types (Handle, Handle__(Handle__, haDevice))
import System.Posix.Types (Fd(Fd))
data CWin = CWin CUShort CUShort
instance Storable CWin where
sizeOf _ = ((8))
alignment _ = (2)
peek ptr = do
row <- ((\hsc_ptr -> peekByteOff hsc_ptr 0)) ptr
col <- ((\hsc_ptr -> peekByteOff hsc_ptr 2)) ptr
return $ CWin row col
poke ptr (CWin row col) = do
((\hsc_ptr -> pokeByteOff hsc_ptr 0)) ptr row
((\hsc_ptr -> pokeByteOff hsc_ptr 2)) ptr col
fdSize :: Integral n => Fd -> IO (Maybe (Window n))
fdSize (Fd fd) = with (CWin 0 0) $ \ws -> do
throwErrnoIfMinus1 "ioctl" $
ioctl fd (21523) ws
CWin row col <- peek ws
return . Just $ Window (fromIntegral row) (fromIntegral col)
`catch`
handler
where
handler :: IOError -> IO (Maybe (Window h))
handler _ = return Nothing
foreign import ccall "sys/ioctl.h ioctl"
ioctl :: CInt -> CInt -> Ptr CWin -> IO CInt
size :: Integral n => IO (Maybe (Window n))
size = fdSize (Fd (1))
hSize :: Integral n => Handle -> IO (Maybe (Window n))
hSize h = withHandle_ "hSize" h $ \Handle__ { haDevice = dev } ->
case cast dev of
Nothing -> return Nothing
Just FD { fdFD = fd } -> fdSize (Fd fd)