-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
231 additions
and
60 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
#ifndef BEARMONADTERMINAL_H | ||
#define BEARMONADTERMINAL_H | ||
|
||
#include "BearLibTerminal.h" | ||
#include <string.h> | ||
|
||
void terminal_print_ptr(int x, int y, const char* s, dimensions_t* dim) | ||
{ | ||
dimensions_t d = terminal_print(x, y, s); | ||
memcpy(dim, &d, sizeof(*dim)); | ||
} | ||
|
||
void terminal_print_ext_ptr(int x, int y, int w, int h, int align, const char* s, dimensions_t* dim) | ||
{ | ||
dimensions_t d = terminal_print_ext(x, y, w, h, align, s); | ||
memcpy(dim, &d, sizeof(*dim)); | ||
} | ||
|
||
void terminal_measure_ptr(const char* s, dimensions_t* dim) | ||
{ | ||
dimensions_t d = terminal_measure(s); | ||
memcpy(dim, &d, sizeof(*dim)); | ||
} | ||
|
||
void terminal_measure_ext_ptr(int w, int h, const char* s, dimensions_t* dim) | ||
{ | ||
dimensions_t d = terminal_measure_ext(w, h, s); | ||
memcpy(dim, &d, sizeof(*dim)); | ||
} | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,62 +1,109 @@ | ||
{-# LANGUAGE CApiFFI #-} | ||
{-# LANGUAGE CPP #-} | ||
{-# LANGUAGE RecordWildCards #-} | ||
module BearMonadTerminal where | ||
|
||
import Foreign.C.Types | ||
import Foreign.C.String | ||
import Foreign.Ptr | ||
import BearMonadTerminal.Raw | ||
import Data.Text ( Text ) | ||
import Control.Monad.IO.Class (MonadIO (..)) | ||
import GHC.Generics | ||
import Control.Concurrent (runInBoundThread) | ||
import Foreign.C | ||
import qualified Data.Text.Lazy.Builder as LT | ||
import qualified Data.List as L | ||
import Data.Maybe | ||
import qualified Data.Text as T | ||
import Data.Functor (void) | ||
import Foreign.Marshal.Alloc | ||
import Foreign.Storable | ||
import qualified Data.Text.Lazy.Encoding as LT | ||
import qualified Data.ByteString as BS | ||
import qualified Data.Text.Internal.StrictBuilder as B | ||
|
||
data Dimensions = Dimensions | ||
{ width :: CInt | ||
, height :: CInt | ||
class BearLibConfigString s where | ||
toConfigString :: s -> LT.Builder | ||
|
||
data Cellsize = Auto | Size (Int, Int) | ||
deriving stock (Eq, Ord, Show, Generic) | ||
|
||
instance BearLibConfigString (Int, Int) where | ||
toConfigString (x, y) = LT.fromString (show x) <> LT.singleton 'x' <> LT.fromString (show y) | ||
|
||
instance BearLibConfigString Cellsize where | ||
toConfigString Auto = LT.fromText "auto" | ||
toConfigString (Size s) = toConfigString s | ||
|
||
instance BearLibConfigString Text where | ||
toConfigString s = LT.singleton '"' <> LT.fromText (T.replace "\"" "\"\"" s) <> LT.singleton '"' | ||
|
||
instance BearLibConfigString String where | ||
toConfigString s = LT.singleton '"' <> LT.fromText (T.replace "\"" "\"\"" $ T.pack s) <> LT.singleton '"' | ||
|
||
instance BearLibConfigString Bool where | ||
toConfigString True = LT.fromText "true" | ||
toConfigString False = LT.fromText "false" | ||
|
||
newtype ConfigOption = ConfigOption { unConfig :: (Text, LT.Builder) } | ||
|
||
instance BearLibConfigString ConfigOption where | ||
toConfigString (ConfigOption (t, v)) = LT.fromText t <> LT.singleton '=' <> v | ||
|
||
toByteString :: BearLibConfigString c => c -> BS.ByteString | ||
toByteString = BS.toStrict . LT.encodeUtf8 . LT.toLazyText . toConfigString | ||
|
||
data WindowOptions = WindowOptions | ||
{ size :: Maybe (Int, Int) | ||
, cellsize :: Maybe Cellsize | ||
, title :: Maybe Text | ||
, icon :: Maybe FilePath | ||
, resizeable :: Maybe Bool | ||
, fullscreen :: Maybe Bool | ||
} deriving stock (Show, Eq, Ord) | ||
|
||
defaultWindowOptions :: WindowOptions | ||
defaultWindowOptions = WindowOptions | ||
{ size = Just (80, 125) | ||
, cellsize = Just Auto | ||
, title = Just "BearMonadTerminal" | ||
, icon = Nothing | ||
, resizeable = Just False | ||
, fullscreen = Just False | ||
} | ||
instance BearLibConfigString WindowOptions where | ||
toConfigString WindowOptions{..} = | ||
let f :: Functor f => BearLibConfigString g => Text -> f g -> f ConfigOption | ||
f t = fmap (ConfigOption . (t,) . toConfigString) | ||
mkOptions = map toConfigString $ catMaybes | ||
[ f "size" size | ||
, f "cellsize" cellsize | ||
, f "title" title | ||
-- todo: work out how filepaths should work | ||
-- todo: this should probably be done with generics | ||
, f "icon" icon | ||
, f "resizeable" resizeable | ||
, f "fullscreen" fullscreen | ||
] | ||
in | ||
case mkOptions of | ||
[] -> mempty | ||
opts -> LT.fromText "window: " <> mconcat (L.intersperse (LT.singleton ',') $ opts) <> LT.singleton ';' | ||
|
||
makeWindow :: IO () | ||
makeWindow = void $ runInBoundThread $ do | ||
void c_terminal_open | ||
c_terminal_refresh | ||
c_terminal_refresh | ||
c_terminal_delay 1000 | ||
c2 <- newCString "hello, world!🐒" | ||
v <- alloca (\p -> c_terminal_print_ptr 14 14 c2 p >> peek @Dimensions p) | ||
print v | ||
c_terminal_refresh | ||
c_terminal_delay 5000 | ||
c_terminal_close | ||
return () | ||
|
||
instance Storable Dimensions where | ||
sizeOf _ = 8 | ||
alignment _ = 4 | ||
poke p Dimensions{..} = do | ||
pokeByteOff p 0 width | ||
pokeByteOff p 4 height | ||
peek p = do | ||
width <- peekByteOff p 0 | ||
height <- peekByteOff p 4 | ||
return $ Dimensions width height | ||
|
||
foreign import capi unsafe "BearLibTerminal.h terminal_open" c_terminal_open :: IO CInt | ||
foreign import capi unsafe "BearLibTerminal.h terminal_close" c_terminal_close :: IO () | ||
foreign import capi unsafe "BearLibTerminal.h terminal_set" c_terminal_set :: CString -> IO CInt | ||
|
||
foreign import capi unsafe "BearLibTerminal.h terminal_color" c_terminal_color :: CUInt -> IO () | ||
foreign import capi unsafe "BearLibTerminal.h terminal_bkcolor" c_terminal_bkcolor :: CUInt -> IO () | ||
foreign import capi unsafe "BearLibTerminal.h terminal_composition" c_terminal_composition :: CInt -> IO () | ||
foreign import capi unsafe "BearLibTerminal.h terminal_layer" c_terminal_layer :: CInt -> IO () | ||
|
||
foreign import capi unsafe "BearLibTerminal.h terminal_clear" c_terminal_clear :: IO () | ||
foreign import capi unsafe "BearLibTerminal.h terminal_clear_area" c_terminal_clear_area :: CInt -> CInt -> CInt -> CInt -> IO () | ||
foreign import capi unsafe "BearLibTerminal.h terminal_crop" c_terminal_crop :: CInt -> CInt -> CInt -> CInt -> IO () | ||
foreign import capi safe "BearLibTerminal.h terminal_refresh" c_terminal_refresh :: IO () | ||
foreign import capi unsafe "BearLibTerminal.h terminal_put" c_terminal_put :: CInt -> CInt -> CInt -> IO () | ||
foreign import capi unsafe "BearLibTerminal.h terminal_pick" c_terminal_pick :: CInt -> CInt -> CInt -> IO CInt | ||
foreign import capi unsafe "BearLibTerminal.h terminal_pick_color" c_terminal_pick_color :: CInt -> CInt -> CInt -> IO CUInt | ||
foreign import capi unsafe "BearLibTerminal.h terminal_pick_bkcolor" c_terminal_pick_bkcolor :: CInt -> CInt -> IO CUInt | ||
foreign import capi unsafe "BearLibTerminal.h terminal_put_ext" c_terminal_put_ext :: CInt -> CInt -> CInt -> CInt -> CInt -> Ptr CUInt -> IO () | ||
foreign import capi unsafe "BearMonadTerminal.h terminal_print_ptr" c_terminal_print_ptr :: CInt -> CInt -> CString -> Ptr Dimensions -> IO () | ||
--foreign import capi unsafe "BearLibTerminal.h terminal_printf" c_terminal_printf :: CInt -> CInt -> CString -> IO CUInt | ||
--foreign import capi unsafe "BearLibTerminal.h terminal_wprint" c_terminal_wprint :: CInt -> CInt -> CString -> IO () | ||
--foreign import capi unsafe "BearLibTerminal.h terminal_wprintf" c_terminal_wprint :: CInt -> CInt -> CString -> IO () | ||
--foreign import capi unsafe "BearLibTerminal.h terminal_print_ext" c_terminal_print_ext :: CInt -> CInt -> CInt -> CInt -> CInt -> CString -> IO CUInt | ||
-- also missing f/w options here, and also for measure | ||
--foreign import capi unsafe "BearLibTerminal.h terminal_measure" c_terminal_measure :: CString -> IO CUInt | ||
--foreign import capi unsafe "BearLibTerminal.h terminal_measure_ext" c_terminal_measure_ext :: CInt -> CInt -> CString -> IO CUInt | ||
|
||
foreign import capi unsafe "BearLibTerminal.h terminal_state" c_terminal_state :: CInt -> IO CInt | ||
--foreign import capi unsafe "BearLibTerminal.h terminal_check" c_terminal_check :: CInt -> IO CInt | ||
foreign import capi unsafe "BearLibTerminal.h terminal_has_input" c_terminal_has_input :: IO CInt | ||
foreign import capi unsafe "BearLibTerminal.h terminal_read" c_terminal_read :: IO CInt | ||
foreign import capi unsafe "BearLibTerminal.h terminal_peek" c_terminal_peek :: IO CInt | ||
-- also read_wstr | ||
foreign import capi unsafe "BearLibTerminal.h terminal_read_str" c_read_str :: CInt -> CInt -> Ptr CUChar -> CInt -> IO CUInt | ||
|
||
-- not bothering with: terminal_delay, color_from_name, color_from_argb | ||
initWindow :: MonadIO m => m () | ||
initWindow = do | ||
terminalOpen | ||
terminalSet defaultWindowOptions | ||
liftIO $ c_terminal_refresh | ||
liftIO $ c_terminal_refresh | ||
liftIO $ c_terminal_delay 5000 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
{-# LANGUAGE CApiFFI #-} | ||
{-# LANGUAGE RecordWildCards #-} | ||
|
||
module BearMonadTerminal.Raw where | ||
|
||
import Foreign.C.Types | ||
import Foreign.C.String | ||
import Foreign.Ptr | ||
import Foreign.Storable | ||
import Control.Monad.IO.Class | ||
import Data.ByteString | ||
import qualified Data.ByteString as BS | ||
|
||
data Dimensions = Dimensions | ||
{ width :: Int | ||
, height :: Int | ||
} deriving stock (Show) | ||
|
||
instance Storable Dimensions where | ||
sizeOf _ = 8 | ||
alignment _ = 4 | ||
poke p Dimensions{..} = do | ||
pokeByteOff p 0 width | ||
pokeByteOff p 4 height | ||
peek p = do | ||
width <- peekByteOff p 0 | ||
height <- peekByteOff p 4 | ||
return $ Dimensions width height | ||
|
||
asBool :: CInt -> Bool | ||
asBool = (== 1) | ||
|
||
foreign import capi safe "BearLibTerminal.h terminal_open" c_terminal_open :: IO CInt | ||
|
||
terminalOpen :: MonadIO m => m Bool | ||
terminalOpen = asBool <$> liftIO c_terminal_open | ||
|
||
foreign import capi safe "BearLibTerminal.h terminal_close" c_terminal_close :: IO () | ||
|
||
terminalClose :: MonadIO m => m () | ||
terminalClose = liftIO c_terminal_close | ||
|
||
foreign import capi safe "BearLibTerminal.h terminal_set" c_terminal_set :: CString -> IO CInt | ||
|
||
terminalSetCString :: MonadIO m => CString -> m Bool | ||
terminalSetCString = liftIO . (fmap asBool . c_terminal_set) | ||
|
||
terminalSetBS :: MonadIO m => ByteString -> m Bool | ||
terminalSetBS = liftIO . flip BS.useAsCString terminalSetCString | ||
|
||
foreign import capi safe "BearLibTerminal.h terminal_color" c_terminal_color :: CUInt -> IO () | ||
|
||
--terminalColorUInt :: | ||
foreign import capi safe "BearLibTerminal.h terminal_bkcolor" c_terminal_bkcolor :: CUInt -> IO () | ||
foreign import capi safe "BearLibTerminal.h terminal_composition" c_terminal_composition :: CInt -> IO () | ||
foreign import capi safe "BearLibTerminal.h terminal_layer" c_terminal_layer :: CInt -> IO () | ||
|
||
foreign import capi safe "BearLibTerminal.h terminal_clear" c_terminal_clear :: IO () | ||
foreign import capi safe "BearLibTerminal.h terminal_clear_area" c_terminal_clear_area :: CInt -> CInt -> CInt -> CInt -> IO () | ||
foreign import capi safe "BearLibTerminal.h terminal_crop" c_terminal_crop :: CInt -> CInt -> CInt -> CInt -> IO () | ||
foreign import capi safe "BearLibTerminal.h terminal_refresh" c_terminal_refresh :: IO () | ||
foreign import capi safe "BearLibTerminal.h terminal_put" c_terminal_put :: CInt -> CInt -> CInt -> IO () | ||
foreign import capi unsafe "BearLibTerminal.h terminal_pick" c_terminal_pick :: CInt -> CInt -> CInt -> IO CInt | ||
foreign import capi unsafe "BearLibTerminal.h terminal_pick_color" c_terminal_pick_color :: CInt -> CInt -> CInt -> IO CUInt | ||
foreign import capi unsafe "BearLibTerminal.h terminal_pick_bkcolor" c_terminal_pick_bkcolor :: CInt -> CInt -> IO CUInt | ||
foreign import capi safe "BearLibTerminal.h terminal_put_ext" c_terminal_put_ext :: CInt -> CInt -> CInt -> CInt -> CInt -> Ptr CUInt -> IO () | ||
foreign import capi safe "BearMonadTerminal.h terminal_print_ptr" c_terminal_print_ptr :: CInt -> CInt -> CString -> Ptr Dimensions -> IO () | ||
foreign import capi safe "BearMonadTerminal.h terminal_print_ext_ptr" c_terminal_print_ext_ptr :: CInt -> CInt -> CInt -> CInt -> CInt -> CString -> Ptr Dimensions -> IO () | ||
-- I don't know if wchar is actually useful here. | ||
-- I don't care enough to try and wrap va_list around the printf variants. | ||
-- so that's printf, printf_ext, wprint, wprintf, wprint_ext, wprintf_ext | ||
-- measuref, wmeasure, measuref_ext, wmeasuref_ext | ||
foreign import capi unsafe "BearMonadTerminal.h terminal_measure_ptr" c_terminal_measure_ptr :: CString -> Ptr Dimensions -> IO () | ||
foreign import capi unsafe "BearMonadTerminal.h terminal_measure_ext_ptr" c_terminal_measure_ext_ptr :: CInt -> CInt -> CString -> Ptr Dimensions -> IO () | ||
|
||
foreign import capi safe "BearLibTerminal.h terminal_state" c_terminal_state :: CInt -> IO CInt | ||
-- unnecessary | ||
--foreign import capi unsafe "BearLibTerminal.h terminal_check" c_terminal_check :: CInt -> IO CInt | ||
foreign import capi safe "BearLibTerminal.h terminal_has_input" c_terminal_has_input :: IO CInt | ||
foreign import capi safe "BearLibTerminal.h terminal_read" c_terminal_read :: IO CInt | ||
foreign import capi safe "BearLibTerminal.h terminal_peek" c_terminal_peek :: IO CInt | ||
-- also read_wstr | ||
foreign import capi safe "BearLibTerminal.h terminal_read_str" c_read_str :: CInt -> CInt -> Ptr CUChar -> CInt -> IO CUInt | ||
foreign import capi safe "BearLibTerminal.h terminal_delay" c_terminal_delay :: CInt -> IO () | ||
|
||
-- not bothering with: color_from_name, color_from_argb | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters