on d64ff96 help sign in
vty/src/Graphics/Vty/Output.hs
106 lines 3.9 kB history raw
1{-# LANGUAGE RecordWildCards #-}
2{-# LANGUAGE NamedFieldPuns #-}
3-- | This module provides functions for accessing the current terminal
4-- or a specific terminal device.
5--
6-- See also:
7--
8-- 1. "Graphics.Vty.Output": This instantiates an abtract interface
9-- to the terminal based on the @TERM@ and @COLORTERM@ environment
10-- variables.
11--
12-- 2. "Graphics.Vty.Output.Interface": Defines the generic interface all
13-- terminal modules need to implement.
14--
15-- 3. "Graphics.Vty.Output.TerminfoBased": Defines a terminal instance
16-- that uses terminfo for all control strings. No attempt is made to
17-- change the character set to UTF-8 for these terminals.
18--
19-- 4. "Graphics.Vty.Output.XTermColor": This module contains an
20-- interface suitable for xterm-like terminals. These are the terminals
21-- where @TERM@ begins with @xterm@. This does use terminfo for as many
22-- control codes as possible.
23module Graphics.Vty.Output
24 ( outputForConfig
25 , setCursorPos
26 , hideCursor
27 , showCursor
28 )
29where
31import Control.Monad (when)
33import Graphics.Vty.Config
34import Graphics.Vty.Image (regionWidth, regionHeight)
35import Graphics.Vty.Output.Interface
36import Graphics.Vty.Output.XTermColor as XTermColor
37import Graphics.Vty.Output.TerminfoBased as TerminfoBased
39import Blaze.ByteString.Builder (writeToByteString)
41import Control.Monad.Trans
43import Data.List (isPrefixOf)
44import Data.Monoid ((<>))
46-- | Returns an `Output` for the terminal specified in `Config`.
47--
48-- The specific Output implementation used is hidden from the API user.
49-- All terminal implementations are assumed to perform more, or less,
50-- the same. Currently, all implementations use terminfo for at least
51-- some terminal specific information.
52--
53-- If a terminal implementation is developed for a terminal without
54-- terminfo support then Vty should work as expected on that terminal.
55--
56-- Selection of a terminal is done as follows:
57--
58-- * If TERM contains "xterm" or "screen", use XTermColor.
59-- * otherwise use the TerminfoBased driver.
60outputForConfig :: Config -> IO Output
61outputForConfig Config{ outputFd = Just fd, termName = Just termName, .. } = do
62 t <- if "xterm" `isPrefixOf` termName || "screen" `isPrefixOf` termName
63 then XTermColor.reserveTerminal termName fd
64 -- Not an xterm-like terminal. try for generic terminfo.
65 else TerminfoBased.reserveTerminal termName fd
67 case mouseMode of
68 Just s -> setMode t Mouse s
69 Nothing -> return ()
71 case bracketedPasteMode of
72 Just s -> setMode t BracketedPaste s
73 Nothing -> return ()
75 return t
76outputForConfig config = (<> config) <$> standardIOConfig >>= outputForConfig
78-- | Sets the cursor position to the given output column and row.
79--
80-- This is not necessarially the same as the character position with the
81-- same coordinates. Characters can be a variable number of columns in
82-- width.
83--
84-- Currently, the only way to set the cursor position to a given
85-- character coordinate is to specify the coordinate in the Picture
86-- instance provided to 'outputPicture' or 'refresh'.
87setCursorPos :: MonadIO m => Output -> Int -> Int -> m ()
88setCursorPos t x y = do
89 bounds <- displayBounds t
90 when (x >= 0 && x < regionWidth bounds && y >= 0 && y < regionHeight bounds) $ do
91 dc <- displayContext t bounds
92 liftIO $ outputByteBuffer t $ writeToByteString $ writeMoveCursor dc x y
94-- | Hides the cursor.
95hideCursor :: MonadIO m => Output -> m ()
96hideCursor t = do
97 bounds <- displayBounds t
98 dc <- displayContext t bounds
99 liftIO $ outputByteBuffer t $ writeToByteString $ writeHideCursor dc
101-- | Shows the cursor.
102showCursor :: MonadIO m => Output -> m ()
103showCursor t = do
104 bounds <- displayBounds t
105 dc <- displayContext t bounds
106 liftIO $ outputByteBuffer t $ writeToByteString $ writeShowCursor dc