Output: add setDisplayBounds field and implementation for TerminfoBased backend

This commit is contained in:
Jonathan Daugherty 2020-07-15 13:49:05 -07:00
parent 5922c53459
commit 6a9c90da0e
5 changed files with 24 additions and 0 deletions

View File

@ -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);
}
}

View File

@ -1 +1,2 @@
unsigned long vty_c_get_window_size(void);
unsigned long vty_c_set_window_size(int fd, unsigned long val);

View File

@ -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.

View File

@ -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"

View File

@ -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