@@ -78,7 +78,7 @@ send_cap_to_terminal t cap cap_params = do
78 - should be used instead of the generic "sgr" string capability.
78 - should be used instead of the generic "sgr" string capability.
80reserve_terminal :: ( Applicative m, MonadIO m ) => String -> Handle -> m Terminal
80reserve_terminal :: ( Applicative m, MonadIO m ) => String -> Handle -> m Terminal
81−reserve_terminal in_ID out_handle = liftIO $ mfix $ \self -> do
81+reserve_terminal in_ID out_handle = liftIO $ do
82 ti <- Terminfo.setupTerm in_ID
82 ti <- Terminfo.setupTerm in_ID
83 -- assumes set foreground always implies set background exists.
83 -- assumes set foreground always implies set background exists.
84 -- if set foreground is not set then all color changing style attributes are filtered.
84 -- if set foreground is not set then all color changing style attributes are filtered.
@@ -112,42 +112,44 @@ reserve_terminal in_ID out_handle = liftIO $ mfix $ \self -> do
112 <*> require_cap ti "clear"
112 <*> require_cap ti "clear"
113 <*> require_cap ti "el"
113 <*> require_cap ti "el"
114 <*> current_display_attr_caps ti
114 <*> current_display_attr_caps ti
115− let send_cap s = send_cap_to_terminal self (s terminfo_caps)
116− maybe_send_cap s = when (isJust $ s terminfo_caps) . send_cap (fromJust . s)
117 new_assumed_state_ref <- newIORef initial_assumed_state
115 new_assumed_state_ref <- newIORef initial_assumed_state
118− return $ Terminal
116+ let t = Terminal
119− { terminal_ID = in_ID
117+ { terminal_ID = in_ID
120− , release_terminal = liftIO $ do
118+ , release_terminal = liftIO $ do
121− send_cap set_default_attr []
119+ send_cap set_default_attr []
122− maybe_send_cap cnorm []
120+ maybe_send_cap cnorm []
123− hClose out_handle
121+ hClose out_handle
124− , reserve_display = liftIO $ do
122+ , reserve_display = liftIO $ do
125− -- If there is no support for smcup: Clear the screen and then move the mouse to the
123+ -- If there is no support for smcup: Clear the screen and then move the mouse to the
126− -- home position to approximate the behavior.
124+ -- home position to approximate the behavior.
127− maybe_send_cap smcup []
125+ maybe_send_cap smcup []
128− hFlush out_handle
126+ hFlush out_handle
129− send_cap clear_screen []
127+ send_cap clear_screen []
130− , release_display = liftIO $ do
128+ , release_display = liftIO $ do
131− maybe_send_cap rmcup []
129+ maybe_send_cap rmcup []
132− maybe_send_cap cnorm []
130+ maybe_send_cap cnorm []
133− , display_bounds = do
131+ , display_bounds = do
134− raw_size <- liftIO $ get_window_size
132+ raw_size <- liftIO $ get_window_size
135− case raw_size of
133+ case raw_size of
136− (w, h) | w < 0 || h < 0 -> fail $ "getwinsize returned < 0 : " ++ show raw_size
134+ (w, h) | w < 0 || h < 0 -> fail $ "getwinsize returned < 0 : " ++ show raw_size
137− | otherwise -> return $ DisplayRegion (toEnum w) (toEnum h)
135+ | otherwise -> return $ DisplayRegion (toEnum w) (toEnum h)
138− , output_byte_buffer = \out_ptr out_byte_count -> do
136+ , output_byte_buffer = \out_ptr out_byte_count -> do
139− hPutBuf out_handle out_ptr (fromEnum out_byte_count)
137+ hPutBuf out_handle out_ptr (fromEnum out_byte_count)
140− hFlush out_handle
138+ hFlush out_handle
141− , context_color_count
139+ , context_color_count
142− = case supports_no_colors terminfo_caps of
140+ = case supports_no_colors terminfo_caps of
143− False -> case Terminfo.getCapability ti (Terminfo.tiGetNum "colors" ) of
141+ False -> case Terminfo.getCapability ti (Terminfo.tiGetNum "colors" ) of
144− Nothing -> 8
142+ Nothing -> 8
145− Just v -> toEnum v
143+ Just v -> toEnum v
146− True -> 1
144+ True -> 1
147− , supports_cursor_visibility = isJust $ civis terminfo_caps
145+ , supports_cursor_visibility = isJust $ civis terminfo_caps
148− , assumed_state_ref = new_assumed_state_ref
146+ , assumed_state_ref = new_assumed_state_ref
149− , mk_display_context = mk_terminfo_display_context terminfo_caps
147+ -- would be better to use fix, but I'm having issues avoiding <<loop>>
148+ , display_context = liftIO . terminfo_display_context terminfo_caps t
150+ send_cap s = send_cap_to_terminal t (s terminfo_caps)
151+ maybe_send_cap s = when (isJust $ s terminfo_caps) . send_cap (fromJust . s)
152require_cap :: (Applicative m, MonadIO m) => Terminfo.Terminal -> String -> m CapExpression
154require_cap :: (Applicative m, MonadIO m) => Terminfo.Terminal -> String -> m CapExpression
153require_cap ti cap_name
155require_cap ti cap_name
@@ -189,35 +191,39 @@ get_window_size = do
189 (a,b) <- (`divMod` 65536) `fmap` c_get_window_size
191 (a,b) <- (`divMod` 65536) `fmap` c_get_window_size
190 return (fromIntegral b, fromIntegral a)
192 return (fromIntegral b, fromIntegral a)
192−mk_terminfo_display_context :: TerminfoCaps -> DisplayContext -> IO DisplayContext
194+terminfo_display_context :: TerminfoCaps -> Terminal -> DisplayRegion -> IO DisplayContext
193−mk_terminfo_display_context terminfo_caps self = do
195+terminfo_display_context terminfo_caps t r = do
194− return $ self
196+ let dc = DisplayContext
197+ { context_region = r
198+ , context_device = t
195− { move_cursor_required_bytes = \x y -> cap_expression_required_bytes (cup terminfo_caps)
199+ , move_cursor_required_bytes = \x y -> cap_expression_required_bytes (cup terminfo_caps)
196− [toEnum y, toEnum x]
200+ [toEnum y, toEnum x]
197− , serialize_move_cursor = \x y out_ptr -> serialize_cap_expression (cup terminfo_caps)
201+ , serialize_move_cursor = \x y out_ptr -> serialize_cap_expression (cup terminfo_caps)
198− [toEnum y, toEnum x]
202+ [toEnum y, toEnum x]
200− , show_cursor_required_bytes = case cnorm terminfo_caps of
204+ , show_cursor_required_bytes = case cnorm terminfo_caps of
201− Nothing -> error "this terminal does not support show cursor"
205+ Nothing -> error "this terminal does not support show cursor"
202− Just c -> cap_expression_required_bytes c []
206+ Just c -> cap_expression_required_bytes c []
203− , serialize_show_cursor = \out_ptr -> do
207+ , serialize_show_cursor = \out_ptr -> do
204− case cnorm terminfo_caps of
208+ case cnorm terminfo_caps of
205− Nothing -> fail "this terminal does not support show cursor"
209+ Nothing -> fail "this terminal does not support show cursor"
206− Just c -> serialize_cap_expression c [] out_ptr
210+ Just c -> serialize_cap_expression c [] out_ptr
207− , hide_cursor_required_bytes = case civis terminfo_caps of
211+ , hide_cursor_required_bytes = case civis terminfo_caps of
208− Nothing -> error "this terminal does not support hide cursor"
212+ Nothing -> error "this terminal does not support hide cursor"
209− Just c -> cap_expression_required_bytes c []
213+ Just c -> cap_expression_required_bytes c []
210− , serialize_hide_cursor = \out_ptr -> do
214+ , serialize_hide_cursor = \out_ptr -> do
211− case civis terminfo_caps of
215+ case civis terminfo_caps of
212− Nothing -> fail "this terminal does not support hide cursor"
216+ Nothing -> fail "this terminal does not support hide cursor"
213− Just c -> serialize_cap_expression c [] out_ptr
217+ Just c -> serialize_cap_expression c [] out_ptr
214− , attr_required_bytes = \_prev_attr _req_attr _diffs -> assumed_attr_required_bytes
218+ , attr_required_bytes = \_prev_attr _req_attr _diffs -> assumed_attr_required_bytes
215− , serialize_set_attr = terminfo_serialize_set_attr self terminfo_caps
219+ , serialize_set_attr = terminfo_serialize_set_attr dc terminfo_caps
216− , default_attr_required_bytes = cap_expression_required_bytes (set_default_attr terminfo_caps) []
220+ , default_attr_required_bytes = cap_expression_required_bytes (set_default_attr terminfo_caps) []
217− , serialize_default_attr = serialize_cap_expression (set_default_attr terminfo_caps) []
221+ , serialize_default_attr = serialize_cap_expression (set_default_attr terminfo_caps) []
218− , row_end_required_bytes = cap_expression_required_bytes (clear_eol terminfo_caps) []
222+ , row_end_required_bytes = cap_expression_required_bytes (clear_eol terminfo_caps) []
219− , serialize_row_end = serialize_cap_expression (clear_eol terminfo_caps) []
223+ , serialize_row_end = serialize_cap_expression (clear_eol terminfo_caps) []
224+ , inline_hack = return ()
222-- | Instead of evaluating all the rules related to setting display attributes twice (once in
228-- | Instead of evaluating all the rules related to setting display attributes twice (once in
223-- required bytes and again in serialize) or some memoization scheme just return a size
229-- required bytes and again in serialize) or some memoization scheme just return a size