on afa2cb0 help sign in
vty/src/Graphics/Vty/Output.hs
104 lines 3.8 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 Data.List (isPrefixOf)
42import Data.Monoid ((<>))
44-- | Returns an `Output` for the terminal specified in `Config`.
45--
46-- The specific Output implementation used is hidden from the API user.
47-- All terminal implementations are assumed to perform more, or less,
48-- the same. Currently, all implementations use terminfo for at least
49-- some terminal specific information.
50--
51-- If a terminal implementation is developed for a terminal without
52-- terminfo support then Vty should work as expected on that terminal.
53--
54-- Selection of a terminal is done as follows:
55--
56-- * If TERM contains "xterm" or "screen", use XTermColor.
57-- * otherwise use the TerminfoBased driver.
58outputForConfig :: Config -> IO Output
59outputForConfig Config{ outputFd = Just fd, termName = Just termName, .. } = do
60 t <- if "xterm" `isPrefixOf` termName || "screen" `isPrefixOf` termName
61 then XTermColor.reserveTerminal termName fd
62 -- Not an xterm-like terminal. try for generic terminfo.
63 else TerminfoBased.reserveTerminal termName fd
65 case mouseMode of
66 Just s -> setMode t Mouse s
67 Nothing -> return ()
69 case bracketedPasteMode of
70 Just s -> setMode t BracketedPaste s
71 Nothing -> return ()
73 return t
74outputForConfig config = (<> config) <$> standardIOConfig >>= outputForConfig
76-- | Sets the cursor position to the given output column and row.
77--
78-- This is not necessarially the same as the character position with the
79-- same coordinates. Characters can be a variable number of columns in
80-- width.
81--
82-- Currently, the only way to set the cursor position to a given
83-- character coordinate is to specify the coordinate in the Picture
84-- instance provided to 'outputPicture' or 'refresh'.
85setCursorPos :: Output -> Int -> Int -> IO ()
86setCursorPos t x y = do
87 bounds <- displayBounds t
88 when (x >= 0 && x < regionWidth bounds && y >= 0 && y < regionHeight bounds) $ do
89 dc <- displayContext t bounds
90 outputByteBuffer t $ writeToByteString $ writeMoveCursor dc x y
92-- | Hides the cursor.
93hideCursor :: Output -> IO ()
94hideCursor t = do
95 bounds <- displayBounds t
96 dc <- displayContext t bounds
97 outputByteBuffer t $ writeToByteString $ writeHideCursor dc
99-- | Shows the cursor.
100showCursor :: Output -> IO ()
101showCursor t = do
102 bounds <- displayBounds t
103 dc <- displayContext t bounds
104 outputByteBuffer t $ writeToByteString $ writeShowCursor dc