@@ -10,10 +10,12 @@
10-- Copyright Corey O'Connor (coreyoconnor@gmail.com)
10-- Copyright Corey O'Connor (coreyoconnor@gmail.com)
11module Graphics.Vty.Output.TerminfoBased
11module Graphics.Vty.Output.TerminfoBased
12 ( reserveTerminal
12 ( reserveTerminal
16import Control.Monad (when)
17import Control.Monad (when)
18+import Data.Bits (shiftL)
17import qualified Data.ByteString as BS
19import qualified Data.ByteString as BS
18import Data.ByteString.Internal (toForeignPtr)
20import Data.ByteString.Internal (toForeignPtr)
19import Data.Terminfo.Parse
21import Data.Terminfo.Parse
@@ -66,6 +68,8 @@ data DisplayAttrCaps = DisplayAttrCaps
66 , exitStandout :: Maybe CapExpression
68 , exitStandout :: Maybe CapExpression
67 , enterItalic :: Maybe CapExpression
69 , enterItalic :: Maybe CapExpression
68 , exitItalic :: Maybe CapExpression
70 , exitItalic :: Maybe CapExpression
71+ , enterStrikethrough :: Maybe CapExpression
72+ , exitStrikethrough :: Maybe CapExpression
69 , enterUnderline :: Maybe CapExpression
73 , enterUnderline :: Maybe CapExpression
70 , exitUnderline :: Maybe CapExpression
74 , exitUnderline :: Maybe CapExpression
71 , enterReverseVideo :: Maybe CapExpression
75 , enterReverseVideo :: Maybe CapExpression
@@ -164,6 +168,10 @@ reserveTerminal termName outFd = do
164 sendCap setDefaultAttr []
168 sendCap setDefaultAttr []
165 maybeSendCap cnorm []
169 maybeSendCap cnorm []
166 , supportsBell = return $ isJust $ ringBellAudio terminfoCaps
170 , supportsBell = return $ isJust $ ringBellAudio terminfoCaps
171+ , supportsItalics = return $ (isJust $ enterItalic (displayAttrCaps terminfoCaps)) &&
172+ (isJust $ exitItalic (displayAttrCaps terminfoCaps))
173+ , supportsStrikethrough = return $ (isJust $ enterStrikethrough (displayAttrCaps terminfoCaps)) &&
174+ (isJust $ exitStrikethrough (displayAttrCaps terminfoCaps))
167 , ringTerminalBell = maybeSendCap ringBellAudio []
175 , ringTerminalBell = maybeSendCap ringBellAudio []
168 , reserveDisplay = do
176 , reserveDisplay = do
169 -- If there is no support for smcup: Clear the screen
177 -- If there is no support for smcup: Clear the screen
@@ -174,6 +182,8 @@ reserveTerminal termName outFd = do
174 , releaseDisplay = do
182 , releaseDisplay = do
175 maybeSendCap rmcup []
183 maybeSendCap rmcup []
176 maybeSendCap cnorm []
184 maybeSendCap cnorm []
185+ , setDisplayBounds = \(w, h) ->
186+ setWindowSize outFd (w, h)
177 , displayBounds = do
187 , displayBounds = do
178 rawSize <- getWindowSize outFd
188 rawSize <- getWindowSize outFd
179 case rawSize of
189 case rawSize of
@@ -231,6 +241,8 @@ currentDisplayAttrCaps ti
231 <*> probeCap ti "rmso"
241 <*> probeCap ti "rmso"
232 <*> probeCap ti "sitm"
242 <*> probeCap ti "sitm"
233 <*> probeCap ti "ritm"
243 <*> probeCap ti "ritm"
244+ <*> probeCap ti "smxx"
245+ <*> probeCap ti "rmxx"
234 <*> probeCap ti "smul"
246 <*> probeCap ti "smul"
235 <*> probeCap ti "rmul"
247 <*> probeCap ti "rmul"
236 <*> probeCap ti "rev"
248 <*> probeCap ti "rev"
@@ -244,6 +256,13 @@ getWindowSize fd = do
244 (a,b) <- (`divMod` 65536) `fmap` c_getWindowSize fd
256 (a,b) <- (`divMod` 65536) `fmap` c_getWindowSize fd
245 return (fromIntegral b, fromIntegral a)
257 return (fromIntegral b, fromIntegral a)
259+foreign import ccall "gwinsz.h vty_c_set_window_size" c_setWindowSize :: Fd -> CLong -> IO ()
261+setWindowSize :: Fd -> (Int, Int) -> IO ()
262+setWindowSize fd (w, h) = do
263+ let val = (h `shiftL` 16) + w
264+ c_setWindowSize fd $ fromIntegral val
247terminfoDisplayContext :: Output -> TerminfoCaps -> DisplayRegion -> IO DisplayContext
266terminfoDisplayContext :: Output -> TerminfoCaps -> DisplayRegion -> IO DisplayContext
248terminfoDisplayContext tActual terminfoCaps r = return dc
267terminfoDisplayContext tActual terminfoCaps r = return dc
249 where dc = DisplayContext
268 where dc = DisplayContext
@@ -259,7 +278,11 @@ terminfoDisplayContext tActual terminfoCaps r = return dc
259 , writeSetAttr = terminfoWriteSetAttr dc terminfoCaps
278 , writeSetAttr = terminfoWriteSetAttr dc terminfoCaps
260 , writeDefaultAttr = \urlsEnabled ->
279 , writeDefaultAttr = \urlsEnabled ->
261 writeCapExpr (setDefaultAttr terminfoCaps) [] `mappend`
280 writeCapExpr (setDefaultAttr terminfoCaps) [] `mappend`
262− (if urlsEnabled then writeURLEscapes EndLink else mempty)
281+ (if urlsEnabled then writeURLEscapes EndLink else mempty) `mappend`
282+ (case exitStrikethrough $ displayAttrCaps terminfoCaps of
283+ Just cap -> writeCapExpr cap []
263 , writeRowEnd = writeCapExpr (clearEol terminfoCaps) []
286 , writeRowEnd = writeCapExpr (clearEol terminfoCaps) []
264 , inlineHack = return ()
287 , inlineHack = return ()
@@ -337,6 +360,7 @@ terminfoWriteSetAttr dc terminfoCaps urlsEnabled prevAttr reqAttr diffs =
338 (sgrArgsForState state)
361 (sgrArgsForState state)
339 `mappend` setItalics
362 `mappend` setItalics
363+ `mappend` setStrikethrough
340 `mappend` setColors
364 `mappend` setColors
341 -- Otherwise the display colors are not changing or changing
365 -- Otherwise the display colors are not changing or changing
342 -- between two non-default points.
366 -- between two non-default points.
@@ -364,6 +388,7 @@ terminfoWriteSetAttr dc terminfoCaps urlsEnabled prevAttr reqAttr diffs =
365 (sgrArgsForState state)
389 (sgrArgsForState state)
366 `mappend` setItalics
390 `mappend` setItalics
391+ `mappend` setStrikethrough
367 `mappend` setColors
392 `mappend` setColors
369 urlAttrs True = writeURLEscapes (urlDiff diffs)
394 urlAttrs True = writeURLEscapes (urlDiff diffs)
@@ -381,6 +406,11 @@ terminfoWriteSetAttr dc terminfoCaps urlsEnabled prevAttr reqAttr diffs =
381 , Just sitm <- enterItalic (displayAttrCaps terminfoCaps)
406 , Just sitm <- enterItalic (displayAttrCaps terminfoCaps)
382 = writeCapExpr sitm []
407 = writeCapExpr sitm []
383 | otherwise = mempty
408 | otherwise = mempty
410+ | hasStyle (fixedStyle attr) strikethrough
411+ , Just smxx <- enterStrikethrough (displayAttrCaps terminfoCaps)
412+ = writeCapExpr smxx []
413+ | otherwise = mempty
384 setColors =
414 setColors =
385 (case fixedForeColor attr of
415 (case fixedForeColor attr of
386 Just c -> writeCapExpr (setForeColor terminfoCaps)
416 Just c -> writeCapExpr (setForeColor terminfoCaps)
@@ -449,6 +479,7 @@ data DisplayAttrState = DisplayAttrState
449 { applyStandout :: Bool
479 { applyStandout :: Bool
450 , applyUnderline :: Bool
480 , applyUnderline :: Bool
451 , applyItalic :: Bool
481 , applyItalic :: Bool
482+ , applyStrikethrough :: Bool
452 , applyReverseVideo :: Bool
483 , applyReverseVideo :: Bool
453 , applyBlink :: Bool
484 , applyBlink :: Bool
454 , applyDim :: Bool
485 , applyDim :: Bool
@@ -485,6 +516,8 @@ reqDisplayCapSeqFor caps s diffs
485 -- set state cap then just use the set state cap.
516 -- set state cap then just use the set state cap.
486 ( True, True ) -> SetState $ stateForStyle s
517 ( True, True ) -> SetState $ stateForStyle s
519+ noEnterExitCap ApplyStrikethrough = isNothing $ enterStrikethrough caps
520+ noEnterExitCap RemoveStrikethrough = isNothing $ exitStrikethrough caps
488 noEnterExitCap ApplyItalic = isNothing $ enterItalic caps
521 noEnterExitCap ApplyItalic = isNothing $ enterItalic caps
489 noEnterExitCap RemoveItalic = isNothing $ exitItalic caps
522 noEnterExitCap RemoveItalic = isNothing $ exitItalic caps
490 noEnterExitCap ApplyStandout = isNothing $ enterStandout caps
523 noEnterExitCap ApplyStandout = isNothing $ enterStandout caps
@@ -499,6 +532,8 @@ reqDisplayCapSeqFor caps s diffs
499 noEnterExitCap RemoveDim = True
532 noEnterExitCap RemoveDim = True
500 noEnterExitCap ApplyBold = isNothing $ enterBoldMode caps
533 noEnterExitCap ApplyBold = isNothing $ enterBoldMode caps
501 noEnterExitCap RemoveBold = True
534 noEnterExitCap RemoveBold = True
535+ enterExitCap ApplyStrikethrough = fromJust $ enterStrikethrough caps
536+ enterExitCap RemoveStrikethrough = fromJust $ exitStrikethrough caps
502 enterExitCap ApplyItalic = fromJust $ enterItalic caps
537 enterExitCap ApplyItalic = fromJust $ enterItalic caps
503 enterExitCap RemoveItalic = fromJust $ exitItalic caps
538 enterExitCap RemoveItalic = fromJust $ exitItalic caps
504 enterExitCap ApplyStandout = fromJust $ enterStandout caps
539 enterExitCap ApplyStandout = fromJust $ enterStandout caps
@@ -515,6 +550,7 @@ stateForStyle s = DisplayAttrState
515 { applyStandout = isStyleSet standout
550 { applyStandout = isStyleSet standout
516 , applyUnderline = isStyleSet underline
551 , applyUnderline = isStyleSet underline
517 , applyItalic = isStyleSet italic
552 , applyItalic = isStyleSet italic
553+ , applyStrikethrough = isStyleSet strikethrough
518 , applyReverseVideo = isStyleSet reverseVideo
554 , applyReverseVideo = isStyleSet reverseVideo
519 , applyBlink = isStyleSet blink
555 , applyBlink = isStyleSet blink
520 , applyDim = isStyleSet dim
556 , applyDim = isStyleSet dim
@@ -527,6 +563,7 @@ styleToApplySeq s = concat
527 [ applyIfRequired ApplyStandout standout
563 [ applyIfRequired ApplyStandout standout
528 , applyIfRequired ApplyUnderline underline
564 , applyIfRequired ApplyUnderline underline
529 , applyIfRequired ApplyItalic italic
565 , applyIfRequired ApplyItalic italic
566+ , applyIfRequired ApplyStrikethrough strikethrough
530 , applyIfRequired ApplyReverseVideo reverseVideo
567 , applyIfRequired ApplyReverseVideo reverseVideo
531 , applyIfRequired ApplyBlink blink
568 , applyIfRequired ApplyBlink blink
532 , applyIfRequired ApplyDim dim
569 , applyIfRequired ApplyDim dim