@@ -1,3 +1,4 @@
1+{-# LANGUAGE RecordWildCards #-}
12{-# LANGUAGE FlexibleInstances #-}
23{-# LANGUAGE OverloadedStrings #-}
34{-# LANGUAGE CPP #-}
@@ -25,7 +26,7 @@ import Graphics.Vty.Image (DisplayRegion)
2526import Graphics.Vty.DisplayAttributes
2627import Graphics.Vty.Output.Interface
2728
28−import Blaze.ByteString.Builder (Write, writeToByteString, writeStorable, writeWord8)
29+import Blaze.ByteString.Builder (Write, writeToByteString, writeStorable)
2930
3031import Data.IORef
3132import Data.Maybe (isJust, isNothing, fromJust)
@@ -49,6 +50,7 @@ data TerminfoCaps = TerminfoCaps
4950 , cup :: CapExpression
5051 , cnorm :: Maybe CapExpression
5152 , civis :: Maybe CapExpression
53+ , supportsNoColors :: Bool
5254 , useAltColorMap :: Bool
5355 , setForeColor :: CapExpression
5456 , setBackColor :: CapExpression
@@ -103,28 +105,28 @@ sendCapToTerminal t cap capParams = do
103105--
104106-- * Providing independent string capabilities for all display
105107-- attributes.
106−reserveTerminal :: String -> Fd -> ColorMode -> IO Output
107−reserveTerminal termName outFd colorMode = do
108+reserveTerminal :: String -> Fd -> IO Output
109+reserveTerminal termName outFd = do
108110 ti <- Terminfo.setupTerm termName
109111 -- assumes set foreground always implies set background exists.
110112 -- if set foreground is not set then all color changing style
111113 -- attributes are filtered.
112114 msetaf <- probeCap ti "setaf"
113115 msetf <- probeCap ti "setf"
114− let (useAlt, setForeCap)
116+ let (noColors, useAlt, setForeCap)
115117 = case msetaf of
116− Just setaf -> (False, setaf)
118+ Just setaf -> (False, False, setaf)
117119 Nothing -> case msetf of
118− Just setf -> (True, setf)
119− Nothing -> (True, error $ "no fore color support for terminal " ++ termName)
120+ Just setf -> (False, True, setf)
121+ Nothing -> (True, True, error $ "no fore color support for terminal " ++ termName)
120122 msetab <- probeCap ti "setab"
121123 msetb <- probeCap ti "setb"
122− let setBackCap
124+ let set_back_cap
123125 = case msetab of
124− Just setab -> setab
125126 Nothing -> case msetb of
126127 Just setb -> setb
127128 Nothing -> error $ "no back color support for terminal " ++ termName
129+ Just setab -> setab
128130
129131 hyperlinkModeStatus <- newIORef False
130132 newAssumedStateRef <- newIORef initialAssumedState
@@ -150,9 +152,10 @@ reserveTerminal termName outFd colorMode = do
150152 <*> requireCap ti "cup"
151153 <*> probeCap ti "cnorm"
152154 <*> probeCap ti "civis"
155+ <*> pure noColors
153156 <*> pure useAlt
154157 <*> pure setForeCap
155− <*> pure setBackCap
158+ <*> pure set_back_cap
156159 <*> requireCap ti "sgr0"
157160 <*> requireCap ti "clear"
158161 <*> requireCap ti "el"
@@ -192,12 +195,17 @@ reserveTerminal termName outFd colorMode = do
192195 when (toEnum len /= actualLen) $ fail $ "Graphics.Vty.Output: outputByteBuffer "
193196 ++ "length mismatch. " ++ show len ++ " /= " ++ show actualLen
194197 ++ " Please report this bug to vty project."
198+ , contextColorCount
199+ = case supportsNoColors terminfoCaps of
200+ False -> case Terminfo.getCapability ti (Terminfo.tiGetNum "colors" ) of
201+ Nothing -> 8
202+ Just v -> toEnum v
203+ True -> 1
195204 , supportsCursorVisibility = isJust $ civis terminfoCaps
196205 , supportsMode = terminfoModeSupported
197206 , setMode = terminfoSetMode
198207 , getModeStatus = terminfoModeStatus
199208 , assumedStateRef = newAssumedStateRef
200− , outputColorMode = colorMode
201209 -- I think fix would help assure tActual is the only
202210 -- reference. I was having issues tho.
203211 , mkDisplayContext = (`terminfoDisplayContext` terminfoCaps)
@@ -295,7 +303,7 @@ writeURLEscapes NoLinkChange =
295303-- | Portably setting the display attributes is a giant pain in the ass.
296304--
297305-- If the terminal supports the sgr capability (which sets the on/off
298−-- state of each style directly; and, for no good reason, resets the
306+-- state of each style directly ; and, for no good reason, resets the
299307-- colors to the default) this procedure is used:
300308--
301309-- 0. set the style attributes. This resets the fore and back color.
@@ -334,9 +342,9 @@ terminfoWriteSetAttr dc terminfoCaps urlsEnabled prevAttr reqAttr diffs =
334342 -- The only way to reset either color, portably, to the default
335343 -- is to use either the set state capability or the set default
336344 -- capability.
337− True -> do
345+ True -> do
338346 case reqDisplayCapSeqFor (displayAttrCaps terminfoCaps)
339− (fixedStyle attr)
347+ (fixedStyle attr )
340348 (styleToApplySeq $ fixedStyle attr) of
341349 -- only way to reset a color to the defaults
342350 EnterExitSeq caps -> writeDefaultAttr dc urlsEnabled
@@ -369,9 +377,9 @@ terminfoWriteSetAttr dc terminfoCaps urlsEnabled prevAttr reqAttr diffs =
369377 -- applied states.
370378 EnterExitSeq caps -> foldMap (\cap -> writeCapExpr cap []) caps
371379 `mappend`
372− writeColorDiff Foreground (foreColorDiff diffs)
380+ writeColorDiff setForeColor (foreColorDiff diffs)
373381 `mappend`
374− writeColorDiff Background (backColorDiff diffs)
382+ writeColorDiff setBackColor (backColorDiff diffs)
375383 -- implicitly resets the colors to the defaults
376384 SetState state -> writeCapExpr (fromJust $ setAttrStates
377385 $ displayAttrCaps terminfoCaps
@@ -403,65 +411,29 @@ terminfoWriteSetAttr dc terminfoCaps urlsEnabled prevAttr reqAttr diffs =
403411 | otherwise = mempty
404412 setColors =
405413 (case fixedForeColor attr of
406− Just c -> writeColor Foreground c
414+ Just c -> writeCapExpr (setForeColor terminfoCaps)
415+ [toEnum $ colorMap c]
407416 Nothing -> mempty)
408417 `mappend`
409418 (case fixedBackColor attr of
410− Just c -> writeColor Background c
419+ Just c -> writeCapExpr (setBackColor terminfoCaps)
420+ [toEnum $ colorMap c]
411421 Nothing -> mempty)
412− writeColorDiff _side NoColorChange
422+ writeColorDiff _f NoColorChange
413423 = mempty
414− writeColorDiff _side ColorToDefault
424+ writeColorDiff _f ColorToDefault
415425 = error "ColorToDefault is not a possible case for applyColorDiffs"
416− writeColorDiff side (SetColor c)
417− = writeColor side c
418−
419− writeColor side (RGBColor r g b) =
420− case outputColorMode (contextDevice dc) of
421− FullColor ->
422− hardcodeColor side (r, g, b)
423− _ ->
424− error "clampColor should remove rgb colors in standard mode"
425− writeColor side c =
426− writeCapExpr (setSideColor side terminfoCaps) [toEnum $ colorMap c]
427−
428−-- a color can either be in the foreground or the background
429−data ColorSide = Foreground | Background
430−
431−-- get the capability for drawing a color on a specific side
432−setSideColor :: ColorSide -> TerminfoCaps -> CapExpression
433−setSideColor Foreground = setForeColor
434−setSideColor Background = setBackColor
435−
436−hardcodeColor :: ColorSide -> (Word8, Word8, Word8) -> Write
437−hardcodeColor side (r, g, b) =
438− -- hardcoded color codes are formatted as "\x1b[{side};2;{r};{g};{b}m"
439− mconcat [ writeStr "\x1b[", sideCode, delimiter, writeChar '2', delimiter
440− , writeColor r, delimiter, writeColor g, delimiter, writeColor b
441− , writeChar 'm']
442− where
443− writeChar = writeWord8 . fromIntegral . fromEnum
444− writeStr = mconcat . map writeChar
445− writeColor = writeStr . show
446− delimiter = writeChar ';'
447− -- 38/48 are used to set whether we should write to the
448− -- foreground/background. I really don't want to know why.
449− sideCode = case side of
450− Foreground -> writeStr "38"
451− Background -> writeStr "48"
426+ writeColorDiff f (SetColor c)
427+ = writeCapExpr (f terminfoCaps) [toEnum $ colorMap c]
452428
453429-- | The color table used by a terminal is a 16 color set followed by a
454430-- 240 color set that might not be supported by the terminal.
455431--
456−-- This takes a Color which clearly identifies which palette to use and
457−-- computes the index into the full 256 color palette.
432+-- This takes a Color which clearly identifies which pallete to use and
433+-- computes the index into the full 256 color pallete.
458434ansiColorIndex :: Color -> Int
459435ansiColorIndex (ISOColor v) = fromEnum v
460436ansiColorIndex (Color240 v) = 16 + fromEnum v
461−ansiColorIndex (RGBColor _ _ _) =
462− error $ unlines [ "Attempted to create color index from rgb color."
463− , "This is currently unsupported, and shouldn't ever happen"
464− ]
465437
466438-- | For terminals without setaf/setab
467439--
@@ -478,10 +450,6 @@ altColorIndex (ISOColor 6) = 3
478450altColorIndex (ISOColor 7) = 7
479451altColorIndex (ISOColor v) = fromEnum v
480452altColorIndex (Color240 v) = 16 + fromEnum v
481−altColorIndex (RGBColor _ _ _) =
482− error $ unlines [ "Attempted to create color index from rgb color."
483− , "This is currently unsupported, and shouldn't ever happen"
484− ]
485453
486454{- | The sequence of terminfo caps to apply a given style are determined
487455 - according to these rules.