-- Copyright 2009-2010 Corey O'Connor module Graphics.Vty.Output.XTermColor ( reserveTerminal ) where import Graphics.Vty.Output.Interface import qualified Graphics.Vty.Output.TerminfoBased as TerminfoBased import Blaze.ByteString.Builder (writeToByteString) import Blaze.ByteString.Builder.Word (writeWord8) import Control.Applicative import Control.Monad.Trans import Data.Foldable (foldMap) import System.IO -- | Initialize the display to UTF-8. reserveTerminal :: ( Applicative m, MonadIO m ) => String -> Handle -> m Output reserveTerminal variant outHandle = liftIO $ do let flushedPut str = do hPutStr outHandle str hFlush outHandle -- If the terminal variant is xterm-color use xterm instead since, more often than not, -- xterm-color is broken. let variant' = if variant == "xterm-color" then "xterm" else variant flushedPut setUtf8CharSet t <- TerminfoBased.reserveTerminal variant' outHandle let t' = t { terminalID = terminalID t ++ " (xterm-color)" , releaseTerminal = do liftIO $ flushedPut setDefaultCharSet releaseTerminal t , mkDisplayContext = \tActual r -> do dc <- mkDisplayContext t tActual r return $ dc { inlineHack = xtermInlineHack t' } } return t' -- | These sequences set xterm based terminals to UTF-8 output. -- -- \todo I don't know of a terminfo cap that is equivalent to this. setUtf8CharSet, setDefaultCharSet :: String setUtf8CharSet = "\ESC%G" setDefaultCharSet = "\ESC%@" -- | I think xterm is broken: Reseting the background color as the first bytes serialized on a -- new line does not effect the background color xterm uses to clear the line. Which is used -- *after* the next newline. xtermInlineHack :: Output -> IO () xtermInlineHack t = do let writeReset = foldMap (writeWord8.toEnum.fromEnum) "\ESC[K" outputByteBuffer t $ writeToByteString writeReset