@@ -24,10 +24,12 @@ import Data.Maybe ( isJust, isNothing, fromJust )
24import Data.Word
24import Data.Word
26import Foreign.Ptr
26import Foreign.Ptr
27−import Foreign.C.Types ( CLong, CSize )
27+import Foreign.C.Types ( CLong, CSize, CInt )
29import qualified System.Console.Terminfo as Terminfo
29import qualified System.Console.Terminfo as Terminfo
30import System.IO
30import System.IO
31+import System.Posix.IO
32+import System.Posix.Types ( Fd(..) )
32data Term = Term
34data Term = Term
33 { term_info_ID :: String
35 { term_info_ID :: String
@@ -42,6 +44,7 @@ data Term = Term
42 , set_default_attr :: CapExpression
44 , set_default_attr :: CapExpression
43 , clear_screen :: CapExpression
45 , clear_screen :: CapExpression
44 , display_attr_caps :: DisplayAttrCaps
46 , display_attr_caps :: DisplayAttrCaps
47data DisplayAttrCaps = DisplayAttrCaps
50data DisplayAttrCaps = DisplayAttrCaps
@@ -90,6 +93,7 @@ terminal_instance in_ID = do
90 case parse_result of
93 case parse_result of
91 Left e -> fail $ show e
94 Left e -> fail $ show e
92 Right cap -> return $ Just cap
95 Right cap -> return $ Just cap
96+ term_fd <- liftIO $ dup stdOutput
94 <*> pure in_ID
98 <*> pure in_ID
95 <*> pure ti
99 <*> pure ti
@@ -103,6 +107,7 @@ terminal_instance in_ID = do
103 <*> require_cap "sgr0"
107 <*> require_cap "sgr0"
104 <*> require_cap "clear"
108 <*> require_cap "clear"
105 <*> current_display_attr_caps ti
109 <*> current_display_attr_caps ti
107current_display_attr_caps :: ( Applicative m, MonadIO m )
112current_display_attr_caps :: ( Applicative m, MonadIO m )
108 => Terminfo.Terminal
113 => Terminfo.Terminal
@@ -165,16 +170,17 @@ instance Terminal Term where
165 | otherwise -> return $ DisplayRegion (toEnum w) (toEnum h)
170 | otherwise -> return $ DisplayRegion (toEnum w) (toEnum h)
167 -- Output the byte buffer of the specified size to the terminal device.
172 -- Output the byte buffer of the specified size to the terminal device.
168− output_byte_buffer _t out_ptr out_byte_count = do
173+ output_byte_buffer t out_ptr out_byte_count = do
169 -- flush is required *before* the c_output_byte_buffer call
174 -- flush is required *before* the c_output_byte_buffer call
170 -- otherwise there may still be data in GHC's internal stdout buffer.
175 -- otherwise there may still be data in GHC's internal stdout buffer.
171 hFlush stdout
176 hFlush stdout
177+ let Fd c_fd = term_fd t
172 if out_byte_count /= 0
178 if out_byte_count /= 0
173− then c_output_byte_buffer out_ptr ( toEnum $! fromEnum out_byte_count )
179+ then c_output_byte_buffer c_fd out_ptr ( toEnum $! fromEnum out_byte_count )
174 else return ()
180 else return ()
176foreign import ccall unsafe "output_buffer.h stdout_output_buffer" c_output_byte_buffer
182foreign import ccall unsafe "output_buffer.h stdout_output_buffer" c_output_byte_buffer
177− :: Ptr Word8 -> CSize -> IO ()
183+ :: CInt -> Ptr Word8 -> CSize -> IO ()
178foreign import ccall "gwinsz.h c_get_window_size" c_get_window_size
184foreign import ccall "gwinsz.h c_get_window_size" c_get_window_size
179 :: IO CLong
185 :: IO CLong