diff --git a/termbox2-bindings-c/src/Termbox2/Bindings/C/Internal/Functions.hs b/termbox2-bindings-c/src/Termbox2/Bindings/C/Internal/Functions.hs index cbd0078..0ef8d3a 100644 --- a/termbox2-bindings-c/src/Termbox2/Bindings/C/Internal/Functions.hs +++ b/termbox2-bindings-c/src/Termbox2/Bindings/C/Internal/Functions.hs @@ -42,48 +42,149 @@ foreign import capi unsafe "termbox2.h tb_cell_buffer" tb_cell_buffer :: IO (Ptr Tb_cell) -- | Clear the back buffer. +-- +-- Can fail with: +-- +-- * __TB_ERR_MEM__ +-- * __TB_ERR_NOT_INIT__ foreign import capi unsafe "termbox2.h tb_clear" tb_clear :: IO CInt -- | Append a code point to a cell in the back buffer. +-- +-- Can fail with: +-- +-- * __TB_ERR_MEM__ +-- * __TB_ERR_NOT_INIT__ +-- * __TB_ERR_OUT_OF_BOUNDS__ foreign import capi unsafe "termbox2.h tb_extend_cell" tb_extend_cell :: CInt -> CInt -> Word32 -> IO CInt -- | Get the terminal and resize file descriptors. +-- +-- Can fail with: +-- +-- * __TB_ERR_NOT_INIT__ foreign import capi unsafe "termbox2.h tb_get_fds" tb_get_fds :: Ptr CInt -> Ptr CInt -> IO CInt -- | Get the terminal height. +-- +-- Can fail with: +-- +-- * __TB_ERR_NOT_INIT__ foreign import capi unsafe "termbox2.h tb_height" tb_height :: IO CInt -- | Hide the cursor in the back buffer. +-- +-- Can fail with: +-- +-- * __TB_ERR_MEM__ +-- * __TB_ERR_NOT_INIT__ foreign import capi unsafe "termbox2.h tb_hide_cursor" tb_hide_cursor :: IO CInt -- | Initialize the @termbox@ library. +-- +-- Can fail with: +-- +-- * __TB_ERR__ +-- * __TB_ERR_INIT_ALREADY__ +-- * __TB_ERR_INIT_OPEN__ +-- * __TB_ERR_MEM__ +-- * __TB_ERR_NO_TERM__ +-- * __TB_ERR_RESIZE_IOCTL__ +-- * __TB_ERR_RESIZE_PIPE__ +-- * __TB_ERR_RESIZE_POLL__ +-- * __TB_ERR_RESIZE_READ__ +-- * __TB_ERR_RESIZE_SIGACTION__ +-- * __TB_ERR_RESIZE_SSCANF__ +-- * __TB_ERR_RESIZE_WRITE__ +-- * __TB_ERR_TCGETATTR__ +-- * __TB_ERR_TCSETATTR__ +-- * __TB_ERR_UNSUPPORTED_TERM__ foreign import capi unsafe "termbox2.h tb_init" tb_init :: IO CInt -- | Initialize the @termbox@ library. -- -- > tb_init = tb_init_fd(0) +-- +-- Can fail with: +-- +-- * __TB_ERR__ +-- * __TB_ERR_INIT_ALREADY__ +-- * __TB_ERR_INIT_OPEN__ +-- * __TB_ERR_MEM__ +-- * __TB_ERR_NO_TERM__ +-- * __TB_ERR_RESIZE_IOCTL__ +-- * __TB_ERR_RESIZE_PIPE__ +-- * __TB_ERR_RESIZE_POLL__ +-- * __TB_ERR_RESIZE_READ__ +-- * __TB_ERR_RESIZE_SIGACTION__ +-- * __TB_ERR_RESIZE_SSCANF__ +-- * __TB_ERR_RESIZE_WRITE__ +-- * __TB_ERR_TCGETATTR__ +-- * __TB_ERR_TCSETATTR__ +-- * __TB_ERR_UNSUPPORTED_TERM__ foreign import capi unsafe "termbox2.h tb_init_fd" tb_init_fd :: CInt -> IO CInt -- | Initialize the @termbox@ library. -- -- > tb_init = tb_init_file("/dev/tty") +-- +-- Can fail with: +-- +-- * __TB_ERR__ +-- * __TB_ERR_INIT_ALREADY__ +-- * __TB_ERR_INIT_OPEN__ +-- * __TB_ERR_MEM__ +-- * __TB_ERR_NO_TERM__ +-- * __TB_ERR_RESIZE_IOCTL__ +-- * __TB_ERR_RESIZE_PIPE__ +-- * __TB_ERR_RESIZE_POLL__ +-- * __TB_ERR_RESIZE_READ__ +-- * __TB_ERR_RESIZE_SIGACTION__ +-- * __TB_ERR_RESIZE_SSCANF__ +-- * __TB_ERR_RESIZE_WRITE__ +-- * __TB_ERR_TCGETATTR__ +-- * __TB_ERR_TCSETATTR__ +-- * __TB_ERR_UNSUPPORTED_TERM__ foreign import capi unsafe "termbox2.h tb_init_file" tb_init_file :: CString -> IO CInt -- | Initialize the @termbox@ library. -- -- > tb_init = tb_init_rwfd(0, 0) +-- +-- Can fail with: +-- +-- * __TB_ERR__ +-- * __TB_ERR_INIT_ALREADY__ +-- * __TB_ERR_INIT_OPEN__ +-- * __TB_ERR_MEM__ +-- * __TB_ERR_NO_TERM__ +-- * __TB_ERR_RESIZE_IOCTL__ +-- * __TB_ERR_RESIZE_PIPE__ +-- * __TB_ERR_RESIZE_POLL__ +-- * __TB_ERR_RESIZE_READ__ +-- * __TB_ERR_RESIZE_SIGACTION__ +-- * __TB_ERR_RESIZE_SSCANF__ +-- * __TB_ERR_RESIZE_WRITE__ +-- * __TB_ERR_TCGETATTR__ +-- * __TB_ERR_TCSETATTR__ +-- * __TB_ERR_UNSUPPORTED_TERM__ foreign import capi unsafe "termbox2.h tb_init_rwfd" tb_init_rwfd :: CInt -> CInt -> IO CInt -- | Invalidate the screen, causing a redraw. This is mainly used after switching output modes. +-- +-- Can fail with: +-- +-- * __TB_ERR_MEM__ +-- * __TB_ERR_NOT_INIT__ foreign import capi unsafe "termbox2.h tb_invalidate" tb_invalidate :: IO CInt @@ -92,14 +193,46 @@ foreign import capi unsafe "termbox2.h tb_last_errno" tb_last_errno :: IO CInt -- | Wait up to a number of milliseconds for an event. +-- +-- Can fail with: +-- +-- * __TB_ERR_MEM__ +-- * __TB_ERR_NOT_INIT__ +-- * __TB_ERR_NO_EVENT__ +-- * __TB_ERR_POLL__ +-- * __TB_ERR_READ__ +-- * __TB_ERR_RESIZE_IOCTL__ +-- * __TB_ERR_RESIZE_POLL__ +-- * __TB_ERR_RESIZE_READ__ +-- * __TB_ERR_RESIZE_SSCANF__ +-- * __TB_ERR_RESIZE_WRITE__ foreign import capi interruptible "termbox2.h tb_peek_event" tb_peek_event :: Ptr Tb_event -> CInt -> IO CInt -- | Wait for an event. +-- +-- Can fail with: +-- +-- * __TB_ERR_MEM__ +-- * __TB_ERR_NOT_INIT__ +-- * __TB_ERR_POLL__ +-- * __TB_ERR_READ__ +-- * __TB_ERR_RESIZE_IOCTL__ +-- * __TB_ERR_RESIZE_POLL__ +-- * __TB_ERR_RESIZE_READ__ +-- * __TB_ERR_RESIZE_SSCANF__ +-- * __TB_ERR_RESIZE_WRITE__ foreign import capi interruptible "termbox2.h tb_poll_event" tb_poll_event :: Ptr Tb_event -> IO CInt -- | Synchronize the back buffer with the terminal. +-- +-- Can fail with: +-- +-- * __TB_ERR__ +-- * __TB_ERR_MEM__ +-- * __TB_ERR_NOT_INIT__ +-- * __TB_ERR_OUT_OF_BOUNDS__ foreign import capi unsafe "termbox2.h tb_present" tb_present :: IO CInt @@ -152,5 +285,9 @@ foreign import capi unsafe "termbox2.h tb_strerror" tb_strerror :: CInt -> IO (ConstPtr CChar) -- | Get the terminal width. +-- +-- Can fail with: +-- +-- * __TB_ERR_NOT_INIT__ foreign import capi unsafe "termbox2.h tb_width" tb_width :: IO CInt diff --git a/termbox2-bindings-hs/examples/Demo.hs b/termbox2-bindings-hs/examples/Demo.hs new file mode 100644 index 0000000..bc2ae76 --- /dev/null +++ b/termbox2-bindings-hs/examples/Demo.hs @@ -0,0 +1,43 @@ +{-# LANGUAGE OverloadedRecordDot #-} +{-# LANGUAGE OverloadedStrings #-} +{-# OPTIONS_GHC -Wno-unused-do-bind #-} + +module Main (main) where + +import Data.Text qualified as Text +import Termbox2.Bindings.Hs +import Text.Printf (printf) + +-- This simple example ignores all result codes :) + +main :: IO () +main = do + tb_init + tb_print 0 0 (TB_RED <> TB_BOLD) TB_DEFAULT "hello from haskell" + tb_print 0 1 TB_GREEN TB_DEFAULT "press any key" + tb_present + Right event <- tb_poll_event + tb_print + 0 + 2 + TB_YELLOW + TB_DEFAULT + ( Text.pack + ( printf + "event: type=%s mod=%s key=%s ch=%d w=%d h=%d x=%d y=%d" + (show event.type_) + (show event.mod) + (show event.key) + event.ch + event.w + event.h + event.x + event.y + ) + ) + tb_present + tb_print 0 3 TB_BLUE TB_DEFAULT "press any key to quit" + tb_present + tb_poll_event + tb_shutdown + pure () diff --git a/termbox2-bindings-hs/src/Termbox2/Bindings/Hs.hs b/termbox2-bindings-hs/src/Termbox2/Bindings/Hs.hs index a6d8230..d8aff27 100644 --- a/termbox2-bindings-hs/src/Termbox2/Bindings/Hs.hs +++ b/termbox2-bindings-hs/src/Termbox2/Bindings/Hs.hs @@ -52,6 +52,16 @@ module Termbox2.Bindings.Hs -- * Types Tb_attr ( Tb_attr, + TB_DEFAULT, + TB_BLACK, + TB_BLUE, + TB_CYAN, + TB_GREEN, + TB_HI_BLACK, + TB_MAGENTA, + TB_RED, + TB_WHITE, + TB_YELLOW, TB_BLINK, TB_BOLD, TB_BRIGHT, @@ -64,19 +74,6 @@ module Termbox2.Bindings.Hs TB_UNDERLINE, TB_UNDERLINE_2 ), - Tb_color - ( Tb_color, - TB_DEFAULT, - TB_BLACK, - TB_BLUE, - TB_CYAN, - TB_GREEN, - TB_HI_BLACK, - TB_MAGENTA, - TB_RED, - TB_WHITE, - TB_YELLOW - ), Tb_error ( Tb_error, TB_ERR, @@ -205,7 +202,6 @@ module Termbox2.Bindings.Hs where import Termbox2.Bindings.Hs.Internal.Attr (Tb_attr (..)) -import Termbox2.Bindings.Hs.Internal.Color (Tb_color (..)) import Termbox2.Bindings.Hs.Internal.Error (Tb_error (..)) import Termbox2.Bindings.Hs.Internal.Event (Tb_event (..)) import Termbox2.Bindings.Hs.Internal.EventMod (Tb_event_mod (..), _TB_MOD_ALT, _TB_MOD_CTRL, _TB_MOD_MOTION, _TB_MOD_SHIFT) diff --git a/termbox2-bindings-hs/src/Termbox2/Bindings/Hs/Internal/Attr.hs b/termbox2-bindings-hs/src/Termbox2/Bindings/Hs/Internal/Attr.hs index 02a4c20..76f7c42 100644 --- a/termbox2-bindings-hs/src/Termbox2/Bindings/Hs/Internal/Attr.hs +++ b/termbox2-bindings-hs/src/Termbox2/Bindings/Hs/Internal/Attr.hs @@ -1,6 +1,16 @@ module Termbox2.Bindings.Hs.Internal.Attr ( Tb_attr ( Tb_attr, + TB_DEFAULT, + TB_BLACK, + TB_BLUE, + TB_CYAN, + TB_GREEN, + TB_HI_BLACK, + TB_MAGENTA, + TB_RED, + TB_WHITE, + TB_YELLOW, TB_BLINK, TB_BOLD, TB_BRIGHT, @@ -19,17 +29,27 @@ where import Data.Bits ((.|.)) import Data.Word (Word64) import Termbox2.Bindings.C - ( _TB_BLINK, + ( _TB_BLACK, + _TB_BLINK, + _TB_BLUE, _TB_BOLD, _TB_BRIGHT, + _TB_CYAN, + _TB_DEFAULT, _TB_DIM, + _TB_GREEN, + _TB_HI_BLACK, _TB_INVISIBLE, _TB_ITALIC, + _TB_MAGENTA, _TB_OVERLINE, + _TB_RED, _TB_REVERSE, _TB_STRIKEOUT, _TB_UNDERLINE, _TB_UNDERLINE_2, + _TB_WHITE, + _TB_YELLOW, ) -- | An attribute. @@ -45,6 +65,66 @@ instance Semigroup Tb_attr where Tb_attr cx <> Tb_attr cy = Tb_attr (cx .|. cy) +pattern TB_DEFAULT :: Tb_attr +pattern TB_DEFAULT <- + ((== Tb_attr _TB_DEFAULT) -> True) + where + TB_DEFAULT = Tb_attr _TB_DEFAULT + +pattern TB_BLACK :: Tb_attr +pattern TB_BLACK <- + ((== Tb_attr _TB_BLACK) -> True) + where + TB_BLACK = Tb_attr _TB_BLACK + +pattern TB_BLUE :: Tb_attr +pattern TB_BLUE <- + ((== Tb_attr _TB_BLUE) -> True) + where + TB_BLUE = Tb_attr _TB_BLUE + +pattern TB_CYAN :: Tb_attr +pattern TB_CYAN <- + ((== Tb_attr _TB_CYAN) -> True) + where + TB_CYAN = Tb_attr _TB_CYAN + +pattern TB_GREEN :: Tb_attr +pattern TB_GREEN <- + ((== Tb_attr _TB_GREEN) -> True) + where + TB_GREEN = Tb_attr _TB_GREEN + +pattern TB_HI_BLACK :: Tb_attr +pattern TB_HI_BLACK <- + ((== Tb_attr _TB_HI_BLACK) -> True) + where + TB_HI_BLACK = Tb_attr _TB_HI_BLACK + +pattern TB_MAGENTA :: Tb_attr +pattern TB_MAGENTA <- + ((== Tb_attr _TB_MAGENTA) -> True) + where + TB_MAGENTA = Tb_attr _TB_MAGENTA + +pattern TB_RED :: Tb_attr +pattern TB_RED <- + ((== Tb_attr _TB_RED) -> True) + where + TB_RED = Tb_attr _TB_RED + +pattern TB_WHITE :: Tb_attr +pattern TB_WHITE <- + ((== Tb_attr _TB_WHITE) -> True) + where + TB_WHITE = Tb_attr _TB_WHITE + +pattern TB_YELLOW :: Tb_attr +pattern TB_YELLOW <- + ((== Tb_attr _TB_YELLOW) -> True) + where + TB_YELLOW = Tb_attr _TB_YELLOW + pattern TB_BLINK :: Tb_attr pattern TB_BLINK <- ((== Tb_attr _TB_BLINK) -> True) diff --git a/termbox2-bindings-hs/src/Termbox2/Bindings/Hs/Internal/Color.hs b/termbox2-bindings-hs/src/Termbox2/Bindings/Hs/Internal/Color.hs deleted file mode 100644 index ac476d5..0000000 --- a/termbox2-bindings-hs/src/Termbox2/Bindings/Hs/Internal/Color.hs +++ /dev/null @@ -1,85 +0,0 @@ -module Termbox2.Bindings.Hs.Internal.Color - ( Tb_color - ( Tb_color, - TB_DEFAULT, - TB_BLACK, - TB_BLUE, - TB_CYAN, - TB_GREEN, - TB_HI_BLACK, - TB_MAGENTA, - TB_RED, - TB_WHITE, - TB_YELLOW - ), - ) -where - -import Data.Word (Word64) -import Termbox2.Bindings.C - --- | A color. -newtype Tb_color - = Tb_color Word64 - deriving stock (Eq, Ord) - deriving newtype (Num, Show) - -pattern TB_DEFAULT :: Tb_color -pattern TB_DEFAULT <- - ((== Tb_color _TB_DEFAULT) -> True) - where - TB_DEFAULT = Tb_color _TB_DEFAULT - -pattern TB_BLACK :: Tb_color -pattern TB_BLACK <- - ((== Tb_color _TB_BLACK) -> True) - where - TB_BLACK = Tb_color _TB_BLACK - -pattern TB_BLUE :: Tb_color -pattern TB_BLUE <- - ((== Tb_color _TB_BLUE) -> True) - where - TB_BLUE = Tb_color _TB_BLUE - -pattern TB_CYAN :: Tb_color -pattern TB_CYAN <- - ((== Tb_color _TB_CYAN) -> True) - where - TB_CYAN = Tb_color _TB_CYAN - -pattern TB_GREEN :: Tb_color -pattern TB_GREEN <- - ((== Tb_color _TB_GREEN) -> True) - where - TB_GREEN = Tb_color _TB_GREEN - -pattern TB_HI_BLACK :: Tb_color -pattern TB_HI_BLACK <- - ((== Tb_color _TB_HI_BLACK) -> True) - where - TB_HI_BLACK = Tb_color _TB_HI_BLACK - -pattern TB_MAGENTA :: Tb_color -pattern TB_MAGENTA <- - ((== Tb_color _TB_MAGENTA) -> True) - where - TB_MAGENTA = Tb_color _TB_MAGENTA - -pattern TB_RED :: Tb_color -pattern TB_RED <- - ((== Tb_color _TB_RED) -> True) - where - TB_RED = Tb_color _TB_RED - -pattern TB_WHITE :: Tb_color -pattern TB_WHITE <- - ((== Tb_color _TB_WHITE) -> True) - where - TB_WHITE = Tb_color _TB_WHITE - -pattern TB_YELLOW :: Tb_color -pattern TB_YELLOW <- - ((== Tb_color _TB_YELLOW) -> True) - where - TB_YELLOW = Tb_color _TB_YELLOW diff --git a/termbox2-bindings-hs/src/Termbox2/Bindings/Hs/Internal/EventMod.hs b/termbox2-bindings-hs/src/Termbox2/Bindings/Hs/Internal/EventMod.hs index 0d33a72..ce932ef 100644 --- a/termbox2-bindings-hs/src/Termbox2/Bindings/Hs/Internal/EventMod.hs +++ b/termbox2-bindings-hs/src/Termbox2/Bindings/Hs/Internal/EventMod.hs @@ -7,17 +7,32 @@ module Termbox2.Bindings.Hs.Internal.EventMod ) where -import Data.Bits (Bits, (.|.)) +import Data.Bits (Bits, (.&.), (.|.)) import Data.Coerce (coerce) +import Data.List qualified as List +import Data.Maybe (mapMaybe) import Data.Word (Word8) import Termbox2.Bindings.C qualified as Termbox -- | An event modifier. newtype Tb_event_mod = Tb_event_mod Word8 - deriving stock (Eq, Ord, Show) + deriving stock (Eq, Ord) deriving newtype (Bits) +instance Show Tb_event_mod where + show x + | uncomponents bs == x = + if null bs + then "mempty" + else List.intercalate " <> " (map show1 bs) + | otherwise = "Tb_event_mod " ++ show (coerce @_ @Word8 x) + where + bs = components x + +instance Monoid Tb_event_mod where + mempty = Tb_event_mod 0 + instance Semigroup Tb_event_mod where (<>) = coerce ((.|.) :: Word8 -> Word8 -> Word8) @@ -36,3 +51,31 @@ _TB_MOD_SHIFT = _TB_MOD_MOTION :: Tb_event_mod _TB_MOD_MOTION = Tb_event_mod Termbox._TB_MOD_MOTION + +-- Random helpers that power the Show instance + +-- break a mod into its one-bit components +components :: Tb_event_mod -> [Tb_event_mod] +components x = + mapMaybe + (\b -> if contains b x then Just b else Nothing) + [_TB_MOD_ALT, _TB_MOD_CTRL, _TB_MOD_SHIFT, _TB_MOD_MOTION] + +-- combine one-bit components into a mod +uncomponents :: [Tb_event_mod] -> Tb_event_mod +uncomponents = + coerce @([Word8] -> Word8) (List.foldl' (.|.) 0) + +-- show one bit +show1 :: Tb_event_mod -> String +show1 x + | x == _TB_MOD_ALT = "_TB_MOD_ALT" + | x == _TB_MOD_CTRL = "_TB_MOD_CTRL" + | x == _TB_MOD_SHIFT = "_TB_MOD_SHIFT" + | x == _TB_MOD_MOTION = "_TB_MOD_MOTION" + | otherwise = "" -- impossible + +-- contains x y: does y contain single-bit x? +contains :: Tb_event_mod -> Tb_event_mod -> Bool +contains (Tb_event_mod x) (Tb_event_mod y) = + x .&. y == x diff --git a/termbox2-bindings-hs/src/Termbox2/Bindings/Hs/Internal/Functions.hs b/termbox2-bindings-hs/src/Termbox2/Bindings/Hs/Internal/Functions.hs index 55fc91f..a3a326d 100644 --- a/termbox2-bindings-hs/src/Termbox2/Bindings/Hs/Internal/Functions.hs +++ b/termbox2-bindings-hs/src/Termbox2/Bindings/Hs/Internal/Functions.hs @@ -49,11 +49,22 @@ import Termbox2.Bindings.Hs.Internal.OutputMode (Tb_output_mode (Tb_output_mode) import Termbox2.Bindings.Hs.Internal.Prelude -- | Clear the back buffer. +-- +-- Can fail with: +-- +-- * __TB_ERR_MEM__ +-- * __TB_ERR_NOT_INIT__ tb_clear :: IO (Either Tb_error ()) tb_clear = check Termbox.tb_clear -- | Append a code point to a cell in the back buffer. +-- +-- Can fail with: +-- +-- * __TB_ERR_MEM__ +-- * __TB_ERR_NOT_INIT__ +-- * __TB_ERR_OUT_OF_BOUNDS__ tb_extend_cell :: -- | x Int -> @@ -66,6 +77,10 @@ tb_extend_cell x y ch = check (Termbox.tb_extend_cell (intToCInt x) (intToCInt y) (charToWord32 ch)) -- | Get the terminal and resize file descriptors. +-- +-- Can fail with: +-- +-- * __TB_ERR_NOT_INIT__ tb_get_fds :: IO (Either Tb_error (Fd, Fd)) tb_get_fds = alloca \p1 -> @@ -79,6 +94,10 @@ tb_get_fds = else pure (Left (Tb_error code)) -- | Get the input mode. +-- +-- Can fail with: +-- +-- * __TB_ERR_NOT_INIT__ tb_get_input_mode :: IO (Either Tb_error Tb_input_mode) tb_get_input_mode = do n <- Termbox.tb_set_input_mode Termbox._TB_INPUT_CURRENT @@ -88,6 +107,10 @@ tb_get_input_mode = do else Right (Tb_input_mode n) -- | Get the output mode. +-- +-- Can fail with: +-- +-- * __TB_ERR_NOT_INIT__ tb_get_output_mode :: IO (Either Tb_error Tb_output_mode) tb_get_output_mode = do n <- Termbox.tb_set_output_mode Termbox._TB_OUTPUT_CURRENT @@ -97,6 +120,10 @@ tb_get_output_mode = do else Right (Tb_output_mode n) -- | Get the terminal height. +-- +-- Can fail with: +-- +-- * __TB_ERR_NOT_INIT__ tb_height :: IO (Either Tb_error Int) tb_height = do n <- Termbox.tb_height @@ -106,11 +133,34 @@ tb_height = do else Right (cintToInt n) -- | Hide the cursor in the back buffer. +-- +-- Can fail with: +-- +-- * __TB_ERR_MEM__ +-- * __TB_ERR_NOT_INIT__ tb_hide_cursor :: IO (Either Tb_error ()) tb_hide_cursor = check Termbox.tb_hide_cursor -- | Initialize the @termbox@ library. +-- +-- Can fail with: +-- +-- * __TB_ERR__ +-- * __TB_ERR_INIT_ALREADY__ +-- * __TB_ERR_INIT_OPEN__ +-- * __TB_ERR_MEM__ +-- * __TB_ERR_NO_TERM__ +-- * __TB_ERR_RESIZE_IOCTL__ +-- * __TB_ERR_RESIZE_PIPE__ +-- * __TB_ERR_RESIZE_POLL__ +-- * __TB_ERR_RESIZE_READ__ +-- * __TB_ERR_RESIZE_SIGACTION__ +-- * __TB_ERR_RESIZE_SSCANF__ +-- * __TB_ERR_RESIZE_WRITE__ +-- * __TB_ERR_TCGETATTR__ +-- * __TB_ERR_TCSETATTR__ +-- * __TB_ERR_UNSUPPORTED_TERM__ tb_init :: IO (Either Tb_error ()) tb_init = check Termbox.tb_init @@ -118,6 +168,24 @@ tb_init = -- | Initialize the @termbox@ library. -- -- > tb_init = tb_init_fd(0) +-- +-- Can fail with: +-- +-- * __TB_ERR__ +-- * __TB_ERR_INIT_ALREADY__ +-- * __TB_ERR_INIT_OPEN__ +-- * __TB_ERR_MEM__ +-- * __TB_ERR_NO_TERM__ +-- * __TB_ERR_RESIZE_IOCTL__ +-- * __TB_ERR_RESIZE_PIPE__ +-- * __TB_ERR_RESIZE_POLL__ +-- * __TB_ERR_RESIZE_READ__ +-- * __TB_ERR_RESIZE_SIGACTION__ +-- * __TB_ERR_RESIZE_SSCANF__ +-- * __TB_ERR_RESIZE_WRITE__ +-- * __TB_ERR_TCGETATTR__ +-- * __TB_ERR_TCSETATTR__ +-- * __TB_ERR_UNSUPPORTED_TERM__ tb_init_fd :: Fd -> IO (Either Tb_error ()) tb_init_fd (Fd fd) = check (Termbox.tb_init_fd fd) @@ -125,6 +193,24 @@ tb_init_fd (Fd fd) = -- | Initialize the @termbox@ library. -- -- > tb_init = tb_init_file("/dev/tty") +-- +-- Can fail with: +-- +-- * __TB_ERR__ +-- * __TB_ERR_INIT_ALREADY__ +-- * __TB_ERR_INIT_OPEN__ +-- * __TB_ERR_MEM__ +-- * __TB_ERR_NO_TERM__ +-- * __TB_ERR_RESIZE_IOCTL__ +-- * __TB_ERR_RESIZE_PIPE__ +-- * __TB_ERR_RESIZE_POLL__ +-- * __TB_ERR_RESIZE_READ__ +-- * __TB_ERR_RESIZE_SIGACTION__ +-- * __TB_ERR_RESIZE_SSCANF__ +-- * __TB_ERR_RESIZE_WRITE__ +-- * __TB_ERR_TCGETATTR__ +-- * __TB_ERR_TCSETATTR__ +-- * __TB_ERR_UNSUPPORTED_TERM__ tb_init_file :: FilePath -> IO (Either Tb_error ()) tb_init_file path = withCString path \c_path -> @@ -133,11 +219,34 @@ tb_init_file path = -- | Initialize the @termbox@ library. -- -- > tb_init = tb_init_rwfd(0, 0) +-- +-- Can fail with: +-- +-- * __TB_ERR__ +-- * __TB_ERR_INIT_ALREADY__ +-- * __TB_ERR_INIT_OPEN__ +-- * __TB_ERR_MEM__ +-- * __TB_ERR_NO_TERM__ +-- * __TB_ERR_RESIZE_IOCTL__ +-- * __TB_ERR_RESIZE_PIPE__ +-- * __TB_ERR_RESIZE_POLL__ +-- * __TB_ERR_RESIZE_READ__ +-- * __TB_ERR_RESIZE_SIGACTION__ +-- * __TB_ERR_RESIZE_SSCANF__ +-- * __TB_ERR_RESIZE_WRITE__ +-- * __TB_ERR_TCGETATTR__ +-- * __TB_ERR_TCSETATTR__ +-- * __TB_ERR_UNSUPPORTED_TERM__ tb_init_rwfd :: Fd -> Fd -> IO (Either Tb_error ()) tb_init_rwfd (Fd r) (Fd w) = check (Termbox.tb_init_rwfd r w) -- | Invalidate the screen, causing a redraw. This is mainly used after switching output modes. +-- +-- Can fail with: +-- +-- * __TB_ERR_MEM__ +-- * __TB_ERR_NOT_INIT__ tb_invalidate :: IO (Either Tb_error ()) tb_invalidate = check Termbox.tb_invalidate @@ -148,6 +257,19 @@ tb_last_errno = coerce Termbox.tb_last_errno -- | Wait up to a number of milliseconds for an event. +-- +-- Can fail with: +-- +-- * __TB_ERR_MEM__ +-- * __TB_ERR_NOT_INIT__ +-- * __TB_ERR_NO_EVENT__ +-- * __TB_ERR_POLL__ +-- * __TB_ERR_READ__ +-- * __TB_ERR_RESIZE_IOCTL__ +-- * __TB_ERR_RESIZE_POLL__ +-- * __TB_ERR_RESIZE_READ__ +-- * __TB_ERR_RESIZE_SSCANF__ +-- * __TB_ERR_RESIZE_WRITE__ tb_peek_event :: Int -> IO (Either Tb_error Tb_event) tb_peek_event ms = alloca \eventPtr -> do @@ -159,6 +281,18 @@ tb_peek_event ms = else pure (Left (Tb_error code)) -- | Wait for an event. +-- +-- Can fail with: +-- +-- * __TB_ERR_MEM__ +-- * __TB_ERR_NOT_INIT__ +-- * __TB_ERR_POLL__ +-- * __TB_ERR_READ__ +-- * __TB_ERR_RESIZE_IOCTL__ +-- * __TB_ERR_RESIZE_POLL__ +-- * __TB_ERR_RESIZE_READ__ +-- * __TB_ERR_RESIZE_SSCANF__ +-- * __TB_ERR_RESIZE_WRITE__ tb_poll_event :: IO (Either Tb_error Tb_event) tb_poll_event = alloca \eventPtr -> do @@ -170,6 +304,13 @@ tb_poll_event = else pure (Left (Tb_error code)) -- | Synchronize the back buffer with the terminal. +-- +-- Can fail with: +-- +-- * __TB_ERR__ +-- * __TB_ERR_MEM__ +-- * __TB_ERR_NOT_INIT__ +-- * __TB_ERR_OUT_OF_BOUNDS__ tb_present :: IO (Either Tb_error ()) tb_present = check Termbox.tb_present @@ -298,6 +439,10 @@ tb_strerror (Tb_error code) = do Text.peekCStringLen (c_string, len) -- | Get the terminal width. +-- +-- Can fail with: +-- +-- * __TB_ERR_NOT_INIT__ tb_width :: IO (Either Tb_error Int) tb_width = do n <- Termbox.tb_width diff --git a/termbox2-bindings-hs/termbox2-bindings-hs.cabal b/termbox2-bindings-hs/termbox2-bindings-hs.cabal index af04c1a..4e096b7 100644 --- a/termbox2-bindings-hs/termbox2-bindings-hs.cabal +++ b/termbox2-bindings-hs/termbox2-bindings-hs.cabal @@ -72,7 +72,6 @@ library hs-source-dirs: src other-modules: Termbox2.Bindings.Hs.Internal.Attr - Termbox2.Bindings.Hs.Internal.Color Termbox2.Bindings.Hs.Internal.Error Termbox2.Bindings.Hs.Internal.Event Termbox2.Bindings.Hs.Internal.EventMod @@ -83,12 +82,13 @@ library Termbox2.Bindings.Hs.Internal.OutputMode Termbox2.Bindings.Hs.Internal.Prelude --- executable termbox2-bindings-hs-example-demo --- import: component --- if !flag(build-examples) --- buildable: False --- build-depends: --- base, --- termbox2-bindings-hs --- hs-source-dirs: examples --- main-is: Demo.hs +executable termbox2-bindings-hs-example-demo + import: component + -- if !flag(build-examples) + -- buildable: False + build-depends: + base, + termbox2-bindings-hs, + text, + hs-source-dirs: examples + main-is: Demo.hs