From 6a9c90da0e093cec1d4903924eb0f6a33be489cb Mon Sep 17 00:00:00 2001 From: Jonathan Daugherty Date: Wed, 15 Jul 2020 13:49:05 -0700 Subject: [PATCH] Output: add setDisplayBounds field and implementation for TerminfoBased backend --- cbits/gwinsz.c | 9 +++++++++ cbits/gwinsz.h | 1 + src/Graphics/Vty/Output/Interface.hs | 2 ++ src/Graphics/Vty/Output/Mock.hs | 1 + src/Graphics/Vty/Output/TerminfoBased.hs | 11 +++++++++++ 5 files changed, 24 insertions(+) diff --git a/cbits/gwinsz.c b/cbits/gwinsz.c index 0aa7ef6..14bb573 100644 --- a/cbits/gwinsz.c +++ b/cbits/gwinsz.c @@ -7,3 +7,12 @@ unsigned long vty_c_get_window_size(int fd) { else return 0x190050; } + +void vty_c_set_window_size(int fd, unsigned long val) { + struct winsize w; + if (ioctl(fd, TIOCGWINSZ, &w) >= 0) { + w.ws_row = val >> 16; + w.ws_col = val & 0xFFFF; + ioctl(fd, TIOCSWINSZ, &w); + } +} diff --git a/cbits/gwinsz.h b/cbits/gwinsz.h index 4cd4b71..934deb9 100644 --- a/cbits/gwinsz.h +++ b/cbits/gwinsz.h @@ -1 +1,2 @@ unsigned long vty_c_get_window_size(void); +unsigned long vty_c_set_window_size(int fd, unsigned long val); diff --git a/src/Graphics/Vty/Output/Interface.hs b/src/Graphics/Vty/Output/Interface.hs index 72a3b06..42ff289 100644 --- a/src/Graphics/Vty/Output/Interface.hs +++ b/src/Graphics/Vty/Output/Interface.hs @@ -73,6 +73,8 @@ data Output = Output -- | Return the display to the state before `reserveDisplay` If no -- previous state then set the display state to the initial state. , releaseDisplay :: IO () + -- | Sets the current display bounds (width, height). + , setDisplayBounds :: (Int, Int) -> IO () -- | Returns the current display bounds. , displayBounds :: IO DisplayRegion -- | Output the bytestring to the terminal device. diff --git a/src/Graphics/Vty/Output/Mock.hs b/src/Graphics/Vty/Output/Mock.hs index 3024e2a..c33d93f 100644 --- a/src/Graphics/Vty/Output/Mock.hs +++ b/src/Graphics/Vty/Output/Mock.hs @@ -48,6 +48,7 @@ mockTerminal r = liftIO $ do , releaseDisplay = return () , ringTerminalBell = return () , supportsBell = return False + , setDisplayBounds = const $ return () , displayBounds = return r , outputByteBuffer = \bytes -> do putStrLn $ "mock outputByteBuffer of " ++ show (BS.length bytes) ++ " bytes" diff --git a/src/Graphics/Vty/Output/TerminfoBased.hs b/src/Graphics/Vty/Output/TerminfoBased.hs index 1d71224..4c722ef 100644 --- a/src/Graphics/Vty/Output/TerminfoBased.hs +++ b/src/Graphics/Vty/Output/TerminfoBased.hs @@ -10,10 +10,12 @@ -- Copyright Corey O'Connor (coreyoconnor@gmail.com) module Graphics.Vty.Output.TerminfoBased ( reserveTerminal + , setWindowSize ) where import Control.Monad (when) +import Data.Bits (shiftL) import qualified Data.ByteString as BS import Data.ByteString.Internal (toForeignPtr) import Data.Terminfo.Parse @@ -174,6 +176,8 @@ reserveTerminal termName outFd = do , releaseDisplay = do maybeSendCap rmcup [] maybeSendCap cnorm [] + , setDisplayBounds = \(w, h) -> + setWindowSize outFd (w, h) , displayBounds = do rawSize <- getWindowSize outFd case rawSize of @@ -244,6 +248,13 @@ getWindowSize fd = do (a,b) <- (`divMod` 65536) `fmap` c_getWindowSize fd return (fromIntegral b, fromIntegral a) +foreign import ccall "gwinsz.h vty_c_set_window_size" c_setWindowSize :: Fd -> CLong -> IO () + +setWindowSize :: Fd -> (Int, Int) -> IO () +setWindowSize fd (w, h) = do + let val = (h `shiftL` 16) + w + c_setWindowSize fd $ fromIntegral val + terminfoDisplayContext :: Output -> TerminfoCaps -> DisplayRegion -> IO DisplayContext terminfoDisplayContext tActual terminfoCaps r = return dc where dc = DisplayContext