├── .gitignore ├── LICENSE ├── MakeLibs.idr ├── Makefile ├── NCurses ├── DEPS ├── Makefile ├── NCurses.ipkg ├── Test │ ├── Test.idr │ └── test.ipkg ├── ncurses_glue │ ├── Makefile │ ├── idris_ncurses.c │ └── idris_ncurses.h └── src │ └── System │ └── NCurses.idr ├── README.md ├── Readline ├── DEPS ├── Makefile ├── Readline.ipkg ├── Test │ ├── Reads.idr │ └── test.ipkg ├── readline_glue │ ├── Makefile │ ├── idris_readline.c │ └── idris_readline.h └── src │ └── System │ └── Readline.idr └── SDL ├── SDL.ipkg ├── Test ├── TestSDL.idr └── test.ipkg ├── sdlc ├── Makefile ├── idris_sdl.c └── idris_sdl.h └── src └── SDL.idr /.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | *.ttc 3 | *.ttm 4 | *.o 5 | *.d 6 | *.a 7 | *.dll 8 | 9 | # Editor/IDE Related 10 | .\#* # Emacs swap file 11 | *~ # Vim swap file 12 | # VS Code 13 | .vscode/* 14 | 15 | /build 16 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2020 Edwin Brady 2 | School of Computer Science, University of St Andrews 3 | All rights reserved. 4 | 5 | This code is derived from software written by Edwin Brady 6 | (ecb10@st-andrews.ac.uk). 7 | 8 | Redistribution and use in source and binary forms, with or without 9 | modification, are permitted provided that the following conditions 10 | are met: 11 | 1. Redistributions of source code must retain the above copyright 12 | notice, this list of conditions and the following disclaimer. 13 | 2. Redistributions in binary form must reproduce the above copyright 14 | notice, this list of conditions and the following disclaimer in the 15 | documentation and/or other materials provided with the distribution. 16 | 3. None of the names of the copyright holders may be used to endorse 17 | or promote products derived from this software without specific 18 | prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY 21 | EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 | PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE 24 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 27 | BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 28 | WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 29 | OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 30 | IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | 32 | *** End of disclaimer. *** 33 | -------------------------------------------------------------------------------- /MakeLibs.idr: -------------------------------------------------------------------------------- 1 | module Main 2 | 3 | import Data.List 4 | import Data.List1 5 | import Data.Strings 6 | 7 | import System 8 | import System.Directory 9 | 10 | pkgs : List String 11 | pkgs = ["NCurses", "Readline", "SDL"] 12 | 13 | {- A tool for building all the packages. 14 | 15 | For each package, checks that the dependencies listed in DEPS exist, and 16 | if they do, runs the request action (either "build", "install", or "clean". 17 | 18 | -} 19 | 20 | fail : String -> IO () 21 | fail str 22 | = do putStrLn str 23 | exitWith (ExitFailure 1) 24 | 25 | findCC : IO String 26 | findCC 27 | = do Nothing <- getEnv "CC" 28 | | Just cc => pure cc 29 | Nothing <- getEnv "IDRIS_CC" 30 | | Just cc => pure cc 31 | Nothing <- getEnv "IDRIS2_CC" 32 | | Just cc => pure cc 33 | pure "cc" 34 | 35 | -- Check for any missing dependencies. 36 | missingDeps : String -> IO (List String) 37 | missingDeps pkg 38 | = do depfile <- readFile "DEPS" 39 | let deps : List String 40 | = case depfile of 41 | Right ds => filter notEmpty (toList (lines ds)) 42 | Left _ => [] 43 | pure $ mapMaybe id !(traverse missing deps) 44 | where 45 | notEmpty : String -> Bool 46 | notEmpty str 47 | = if all isSpace (unpack str) 48 | then False 49 | else True 50 | 51 | missing : String -> IO (Maybe String) 52 | missing lib 53 | = do cc <- findCC 54 | ok <- system $ "echo \"int main(){}\" | " ++ cc ++ 55 | " -o /dev/null -l" ++ lib ++ " -x c - > /dev/null" 56 | if ok == 0 57 | then do putStrLn $ "Found lib" ++ lib 58 | pure Nothing 59 | else do putStrLn $ "Can't find lib" ++ lib 60 | pure (Just lib) 61 | 62 | pkgAction : String -> String -> IO () 63 | pkgAction act pkg 64 | = do [] <- missingDeps pkg 65 | | ds => do putStrLn $ "Skipping " ++ pkg 66 | putStrLn $ "\tdue to missing dependencies: " ++ show ds 67 | ok <- system $ "idris2 --" ++ act ++ " " ++ pkg ++ ".ipkg" 68 | if ok == 0 69 | then pure () 70 | else exitWith (ExitFailure 1) 71 | 72 | -- Move into the appropriate directory for a package, run the action, then 73 | -- come back out again. 74 | action : String -> String -> IO () 75 | action act pkg 76 | = do Just dir <- currentDir 77 | | Nothing => fail "Can't get current directory" 78 | True <- changeDir pkg 79 | | _ => fail $ "Can't find package directory " ++ show pkg 80 | 81 | pkgAction act pkg 82 | 83 | True <- changeDir dir 84 | | _ => fail $ "Can't get current directory" 85 | pure () 86 | 87 | build : IO () 88 | build = traverse_ (action "build") pkgs 89 | 90 | install : IO () 91 | install = traverse_ (action "install") pkgs 92 | 93 | clean : IO () 94 | clean = traverse_ (action "clean") pkgs 95 | 96 | usage : IO () 97 | usage = putStrLn "Usage: makelibs [build | install | clean]" 98 | 99 | main : IO () 100 | main 101 | = do [_, act] <- getArgs 102 | | _ => usage 103 | traverse_ (action act) pkgs 104 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: build install clean 2 | 3 | build: 4 | idris2 MakeLibs.idr -x build 5 | 6 | install: 7 | idris2 MakeLibs.idr -x install 8 | 9 | clean: 10 | idris2 MakeLibs.idr -x clean 11 | -------------------------------------------------------------------------------- /NCurses/DEPS: -------------------------------------------------------------------------------- 1 | ncurses 2 | -------------------------------------------------------------------------------- /NCurses/Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: build install clean 2 | 3 | build: 4 | idris2 --build readline.ipkg 5 | 6 | install: 7 | idris2 --install readline.ipkg 8 | 9 | clean: 10 | idris2 --clean readline.ipkg 11 | -------------------------------------------------------------------------------- /NCurses/NCurses.ipkg: -------------------------------------------------------------------------------- 1 | package ncurses 2 | 3 | version = 0.1 4 | 5 | sourcedir = "src" 6 | 7 | modules = System.NCurses 8 | 9 | preclean = "make -C ncurses_glue clean" 10 | prebuild = "make -C ncurses_glue" 11 | 12 | postinstall = "make -C ncurses_glue install" 13 | -------------------------------------------------------------------------------- /NCurses/Test/Test.idr: -------------------------------------------------------------------------------- 1 | import System.NCurses 2 | 3 | main1 : IO () 4 | main1 5 | = do initscr 6 | printw "Hello ncurses world!" 7 | refresh 8 | c <- getch 9 | endwin 10 | 11 | getString : IO String 12 | getString 13 | = do c <- getch 14 | if c == '\n' 15 | then pure "" 16 | else do rest <- getString 17 | pure (strCons c rest) 18 | 19 | main2 : IO () 20 | main2 21 | = do initscr 22 | printw "Hello ncurses world!" 23 | refresh 24 | str <- getnstr 10 25 | printw str 26 | c <- getch 27 | endwin 28 | -------------------------------------------------------------------------------- /NCurses/Test/test.ipkg: -------------------------------------------------------------------------------- 1 | package test 2 | 3 | opts = "-p ncurses" 4 | -------------------------------------------------------------------------------- /NCurses/ncurses_glue/Makefile: -------------------------------------------------------------------------------- 1 | IDRIS := idris2 2 | MACHINE := $(shell $(CC) -dumpmachine) 3 | 4 | ifneq (, $(findstring darwin, $(MACHINE))) 5 | OS :=darwin 6 | else ifneq (, $(findstring cygwin, $(MACHINE))) 7 | OS :=windows 8 | else ifneq (, $(findstring mingw, $(MACHINE))) 9 | OS :=windows 10 | else ifneq (, $(findstring windows, $(MACHINE))) 11 | OS :=windows 12 | else 13 | OS :=unix 14 | endif 15 | 16 | ifeq ($(OS), darwin) 17 | SHLIB_SUFFIX :=dylib 18 | else ifeq ($(OS), windows) 19 | SHLIB_SUFFIX :=dll 20 | else 21 | SHLIB_SUFFIX :=so 22 | endif 23 | 24 | LIBTARGET = libidrisncurses.$(SHLIB_SUFFIX) 25 | # TODO: Work out how to get the right install directory without hard coding 26 | # the version number! 27 | INSTALLDIR = `${IDRIS} --libdir`/ncurses-0.1/lib 28 | 29 | HDRS = idris_ncurses.h 30 | OBJS = idris_ncurses.o 31 | 32 | NCURSES_LIBS := -lncurses 33 | NCURSES_FLAGS := -fPIC 34 | 35 | CFLAGS = $(NCURSES_FLAGS) 36 | 37 | $(LIBTARGET): $(OBJS) 38 | $(CC) -o $(LIBTARGET) -shared $(OBJS) $(NCURSES_LIBS) $(NCURSES_FLAGS) 39 | 40 | clean: 41 | rm -f $(OBJS) $(LIBTARGET) 42 | 43 | install: 44 | @if ! [ -d $(INSTALLDIR) ]; then mkdir -p $(INSTALLDIR); fi 45 | install $(LIBTARGET) $(HDRS) $(INSTALLDIR) 46 | 47 | .PHONY: install clean 48 | -------------------------------------------------------------------------------- /NCurses/ncurses_glue/idris_ncurses.c: -------------------------------------------------------------------------------- 1 | #include "idris_ncurses.h" 2 | 3 | char* idris_getstr(int max) { 4 | char* str = malloc(max); 5 | getnstr(str, max); 6 | return str; 7 | } 8 | -------------------------------------------------------------------------------- /NCurses/ncurses_glue/idris_ncurses.h: -------------------------------------------------------------------------------- 1 | #ifndef _IDRIS_NCURSES_H 2 | #define _IDRIS_NCURSES_H 3 | 4 | #include 5 | #include 6 | 7 | char* idris_getstr(int max); 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /NCurses/src/System/NCurses.idr: -------------------------------------------------------------------------------- 1 | module System.NCurses 2 | 3 | ncurses : String -> String 4 | ncurses fn = "C:" ++ fn ++ ",libncurses 5" 5 | 6 | ncursesGlue : String -> String 7 | ncursesGlue fn = "C:" ++ fn ++ ",libidrisncurses" 8 | 9 | %foreign ncurses "refresh" 10 | prim_refresh : PrimIO () 11 | 12 | export 13 | refresh : IO () 14 | refresh = primIO prim_refresh 15 | 16 | %foreign ncurses "endwin" 17 | prim_endwin : PrimIO () 18 | 19 | export 20 | endwin : IO () 21 | endwin = primIO prim_endwin 22 | 23 | %foreign ncurses "getch" 24 | prim_getch : PrimIO Char 25 | 26 | export 27 | getch : IO Char 28 | getch = primIO prim_getch 29 | 30 | %foreign ncursesGlue "idris_getstr" 31 | prim_getstr : Int -> PrimIO String 32 | 33 | export 34 | getnstr : Int -> IO String 35 | getnstr x = primIO $ prim_getstr x 36 | 37 | %foreign ncurses "printw" 38 | prim_printw : String -> PrimIO () 39 | 40 | export 41 | printw : String -> IO () 42 | printw str = primIO $ prim_printw str 43 | 44 | %foreign ncurses "initscr" 45 | prim_initscr : PrimIO () 46 | 47 | export 48 | initscr : IO () 49 | initscr = primIO prim_initscr 50 | 51 | %foreign ncurses "putchar" 52 | prim_putchar : Char -> PrimIO () 53 | 54 | export 55 | putchar : Char -> IO () 56 | putchar c = primIO $ prim_putchar c 57 | 58 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Idris 2 CLibs 2 | ============= 3 | 4 | A collection of Idris 2 bindings to C libraries. Installing: 5 | 6 | * `make build` builds the libraries 7 | * `make install` installs the packages into the Idris 2 prefix 8 | * `make clean` cleans everything 9 | 10 | Only the libraries for which the C dependencies are available will be built. 11 | Currently, we have bindings for: 12 | 13 | * `NCurses` (status: just a few basic functions) 14 | * `Readline` (status: minimally useful) 15 | * `SDL` (status: just a few basic functions) 16 | 17 | Please don't expect any of these to be complete, well documented, or even 18 | particularly usable yet! Contributions are welcome :). 19 | 20 | (Please also don't expect a high level of support or maintenance, at the 21 | moment. Volunteers to help maintain the collection will be gratefully 22 | welcomed!) 23 | 24 | Structure 25 | --------- 26 | 27 | `MakeLibs.idr` lists the packages which will be installed, as a list of 28 | subdirectories each of which includes a C package. These subdirectories 29 | contain: 30 | 31 | * A file `.ipkg`, where `` is the subdirectory name 32 | * Optionally, a file `DEPS`, which lists the C libraries, one per line, 33 | required to use the library 34 | 35 | They might also include C glue code, built and installed via the `ipkg` 36 | file, and a `Test` directory. See `Readline` for a small example. 37 | 38 | Conventions 39 | ----------- 40 | 41 | Packages should export Idris bindings to the C interface as part of the 42 | `System` hierarchy. Ideally, functions should use the `HasIO` interface rather 43 | than using `IO` directly. 44 | 45 | It is fine to include higher level APIs (e.g. using monad transformers, or 46 | some kind of effect system) as long as the plain C bindings are also exposed. 47 | -------------------------------------------------------------------------------- /Readline/DEPS: -------------------------------------------------------------------------------- 1 | readline 2 | -------------------------------------------------------------------------------- /Readline/Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: build install clean 2 | 3 | build: 4 | idris2 --build readline.ipkg 5 | 6 | install: 7 | idris2 --install readline.ipkg 8 | 9 | clean: 10 | idris2 --clean readline.ipkg 11 | -------------------------------------------------------------------------------- /Readline/Readline.ipkg: -------------------------------------------------------------------------------- 1 | package readline 2 | 3 | version = 0.1 4 | 5 | sourcedir = "src" 6 | 7 | modules = System.Readline 8 | 9 | preclean = "make -C readline_glue clean" 10 | prebuild = "make -C readline_glue" 11 | 12 | postinstall = "make -C readline_glue install" 13 | -------------------------------------------------------------------------------- /Readline/Test/Reads.idr: -------------------------------------------------------------------------------- 1 | import System.Readline 2 | 3 | testComplete : Readline io => String -> io (List String) 4 | testComplete text = pure ["hamster", "foo", "bar"] 5 | 6 | loop : Readline io => io () 7 | loop = do Just x <- readline "> " 8 | | Nothing => putStrLn "EOF" 9 | putStrLn x 10 | when (x /= "") $ addHistory x 11 | if x /= "quit" 12 | then loop 13 | else putStrLn "Done" 14 | 15 | main : IO () 16 | main = do setCompletion testComplete 17 | loop 18 | -------------------------------------------------------------------------------- /Readline/Test/test.ipkg: -------------------------------------------------------------------------------- 1 | package test 2 | 3 | opts = "-p readline" 4 | -------------------------------------------------------------------------------- /Readline/readline_glue/Makefile: -------------------------------------------------------------------------------- 1 | IDRIS := idris2 2 | MACHINE := $(shell $(CC) -dumpmachine) 3 | 4 | ifneq (, $(findstring darwin, $(MACHINE))) 5 | OS :=darwin 6 | else ifneq (, $(findstring cygwin, $(MACHINE))) 7 | OS :=windows 8 | else ifneq (, $(findstring mingw, $(MACHINE))) 9 | OS :=windows 10 | else ifneq (, $(findstring windows, $(MACHINE))) 11 | OS :=windows 12 | else 13 | OS :=unix 14 | endif 15 | 16 | ifeq ($(OS), darwin) 17 | SHLIB_SUFFIX :=dylib 18 | else ifeq ($(OS), windows) 19 | SHLIB_SUFFIX :=dll 20 | else 21 | SHLIB_SUFFIX :=so 22 | endif 23 | 24 | LIBTARGET = libidrisreadline.$(SHLIB_SUFFIX) 25 | # TODO: Work out how to get the right install directory without hard coding 26 | # the version number! 27 | INSTALLDIR = `${IDRIS} --libdir`/readline-0.1/lib 28 | 29 | HDRS = idris_readline.h 30 | OBJS = idris_readline.o 31 | 32 | READLINE_LIBS := -lreadline 33 | READLINE_FLAGS := -fPIC 34 | 35 | CFLAGS = $(READLINE_FLAGS) 36 | 37 | $(LIBTARGET): $(OBJS) 38 | $(CC) -o $(LIBTARGET) -shared $(OBJS) $(READLINE_LIBS) $(READLINE_FLAGS) 39 | 40 | clean: 41 | rm -f $(OBJS) $(LIBTARGET) 42 | 43 | install: 44 | @if ! [ -d $(INSTALLDIR) ]; then mkdir -p $(INSTALLDIR); fi 45 | install $(LIBTARGET) $(HDRS) $(INSTALLDIR) 46 | 47 | .PHONY: install clean 48 | -------------------------------------------------------------------------------- /Readline/readline_glue/idris_readline.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "idris_readline.h" 5 | 6 | char* compentry_wrapper(const char* text, int i) { 7 | char* res = my_compentry(text, i); // res is on the Idris heap and freed on return 8 | if (res != NULL) { 9 | char* comp = malloc(strlen(res)+1); // Readline frees this 10 | strcpy(comp, res); 11 | return comp; 12 | } 13 | else { 14 | return NULL; 15 | } 16 | } 17 | 18 | void idrisrl_setCompletion(rl_compentry_func_t* fn) { 19 | rl_completion_entry_function = compentry_wrapper; 20 | my_compentry = fn; 21 | } 22 | 23 | char* getString(void* str) { 24 | return (char*)str; 25 | } 26 | 27 | void* mkString(char* str) { 28 | return (void*)str; 29 | } 30 | 31 | void* nullString() { 32 | return NULL; 33 | } 34 | 35 | int isNullString(void* str) { 36 | return str == NULL; 37 | } 38 | -------------------------------------------------------------------------------- /Readline/readline_glue/idris_readline.h: -------------------------------------------------------------------------------- 1 | #ifndef _IDRIS_READLINE_H 2 | #define _IDRIS_READLINE_H 3 | 4 | rl_compentry_func_t* my_compentry; 5 | 6 | void idrisrl_setCompletion(rl_compentry_func_t* fn); 7 | 8 | char* getString(void* str); 9 | void* mkString(char* str); 10 | void* nullString(); 11 | int isNullString(void* str); 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /Readline/src/System/Readline.idr: -------------------------------------------------------------------------------- 1 | module System.Readline 2 | 3 | rlib : String -> String 4 | rlib fn = "C:" ++ fn ++ ",libidrisreadline" 5 | 6 | public export 7 | interface HasIO io => Readline io where 8 | setCompletion : (String -> io (List String)) -> io () 9 | 10 | %foreign (rlib "getString") 11 | getString : Ptr String -> String 12 | 13 | %foreign (rlib "mkString") 14 | mkString : String -> Ptr String 15 | 16 | %foreign (rlib "nullString") 17 | nullString : Ptr String 18 | 19 | %foreign (rlib "isNullString") 20 | prim_isNullString : Ptr String -> Int 21 | 22 | isNullString : Ptr String -> Bool 23 | isNullString str = if prim_isNullString str == 0 then False else True 24 | 25 | %foreign (rlib "readline") 26 | prim_readline : String -> PrimIO (Ptr String) 27 | 28 | export 29 | readline : Readline io => String -> io (Maybe String) 30 | readline s 31 | = do mstr <- primIO $ prim_readline s 32 | if isNullString mstr 33 | then pure $ Nothing 34 | else pure $ Just (getString mstr) 35 | 36 | %foreign (rlib "add_history") 37 | prim_add_history : String -> PrimIO () 38 | 39 | export 40 | addHistory : Readline io => String -> io () 41 | addHistory s = primIO $ prim_add_history s 42 | 43 | %foreign (rlib "idrisrl_setCompletion") 44 | prim_setCompletion : (String -> Int -> PrimIO (Ptr String)) -> PrimIO () 45 | 46 | rlCompletion : (String -> IO (List String)) -> String -> 47 | IO (String -> Int -> IO (Maybe String)) 48 | rlCompletion ifn str 49 | = do all <- ifn str 50 | pure (\_, i => pure (find (fromInteger (cast i)) all)) 51 | where 52 | find : Nat -> List String -> Maybe String 53 | find _ [] = Nothing 54 | find Z (x :: xs) = Just x 55 | find (S k) (x :: xs) = find k xs 56 | 57 | export 58 | setCompletionFn : HasIO io => (String -> IO (List String)) -> io () 59 | setCompletionFn fn 60 | = primIO $ prim_setCompletion $ \s, i => toPrim $ 61 | do rfn <- rlCompletion fn s 62 | mstr <- rfn s i 63 | case mstr of 64 | Nothing => pure nullString 65 | Just str => pure (mkString str) 66 | 67 | export 68 | Readline IO where 69 | setCompletion = setCompletionFn 70 | 71 | -------------------------------------------------------------------------------- /SDL/SDL.ipkg: -------------------------------------------------------------------------------- 1 | package sdl 2 | 3 | version = 0.1 4 | 5 | sourcedir = "src" 6 | 7 | modules = SDL 8 | 9 | postbuild = "make -C sdlc" 10 | postinstall = "make -C sdlc install" 11 | 12 | -------------------------------------------------------------------------------- /SDL/Test/TestSDL.idr: -------------------------------------------------------------------------------- 1 | module TestSDL 2 | 3 | import SDL 4 | 5 | main : IO () 6 | main 7 | = do win <- createWindow "Hi" 0 0 640 480 8 | ren <- createRenderer win 9 | sdl_setRenderDrawColor ren 0 255 255 255 10 | sdl_renderClear ren 11 | sdl_renderPresent ren 12 | 13 | sdlDelay 1000 14 | sdlQuit 15 | -------------------------------------------------------------------------------- /SDL/Test/test.ipkg: -------------------------------------------------------------------------------- 1 | package test 2 | 3 | opts = "-p sdl" 4 | 5 | main = TestSDL 6 | 7 | executable = testsdl 8 | -------------------------------------------------------------------------------- /SDL/sdlc/Makefile: -------------------------------------------------------------------------------- 1 | IDRIS := idris2 2 | MACHINE := $(shell $(CC) -dumpmachine) 3 | 4 | ifneq (, $(findstring darwin, $(MACHINE))) 5 | OS :=darwin 6 | else ifneq (, $(findstring cygwin, $(MACHINE))) 7 | OS :=windows 8 | else ifneq (, $(findstring mingw, $(MACHINE))) 9 | OS :=windows 10 | else ifneq (, $(findstring windows, $(MACHINE))) 11 | OS :=windows 12 | else 13 | OS :=unix 14 | endif 15 | 16 | ifeq ($(OS), darwin) 17 | SHLIB_SUFFIX :=dylib 18 | else ifeq ($(OS), windows) 19 | SHLIB_SUFFIX :=dll 20 | else 21 | SHLIB_SUFFIX :=so 22 | endif 23 | 24 | LIBTARGET = libidrissdl.$(SHLIB_SUFFIX) 25 | # TODO: Work out how to get the right install directory without hard coding 26 | # the version number! 27 | INSTALLDIR = `${IDRIS} --libdir`/sdl-0.1/lib 28 | 29 | HDRS = idris_sdl.h 30 | OBJS = idris_sdl.o 31 | 32 | SDL_LIBS := `sdl2-config --libs` 33 | SDL_FLAGS := `sdl2-config --cflags` 34 | 35 | CFLAGS = $(SDL_FLAGS) 36 | 37 | $(LIBTARGET): $(OBJS) 38 | echo $(SDL_LIBS) 39 | $(CC) -o $(LIBTARGET) -shared $(OBJS) $(SDL_LIBS) $(SDL_FLAGS) 40 | 41 | clean: 42 | rm -f $(OBJS) $(LIBTARGET) 43 | 44 | install: 45 | @if ! [ -d $(INSTALLDIR) ]; then mkdir -p $(INSTALLDIR); fi 46 | install $(LIBTARGET) $(HDRS) $(INSTALLDIR) 47 | 48 | .PHONY: install clean 49 | -------------------------------------------------------------------------------- /SDL/sdlc/idris_sdl.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "idris_sdl.h" 3 | 4 | void* simple_createWindow(char* title, int x, int y, int width, int height) { 5 | SDL_Init(SDL_INIT_EVERYTHING); 6 | SDL_Window* win = SDL_CreateWindow(title, x, y, width, height, SDL_WINDOW_SHOWN); 7 | return (void*)win; 8 | } 9 | 10 | void* simple_createRenderer(void* w) { 11 | SDL_Window* win = w; 12 | SDL_Renderer* ren = SDL_CreateRenderer(win, -1, 0); 13 | return (void*)ren; 14 | } 15 | 16 | void sdl_setRenderDrawColor(void* x, int r, int g, int b, int a) { 17 | SDL_Renderer* ren = x; 18 | SDL_SetRenderDrawColor(ren, r, g, b, a); 19 | } 20 | 21 | void sdl_renderClear(void* r) { 22 | SDL_Renderer* ren = r; 23 | SDL_RenderClear(ren); 24 | } 25 | 26 | void sdl_renderPresent(void* r) { 27 | SDL_Renderer* ren = r; 28 | SDL_RenderPresent(ren); 29 | } 30 | 31 | -------------------------------------------------------------------------------- /SDL/sdlc/idris_sdl.h: -------------------------------------------------------------------------------- 1 | #ifndef __IDRIS_SDL_H 2 | #define __IDRIS_SDL_H 3 | 4 | #include 5 | 6 | void* simple_createWindow(char* title, int x, int y, int width, int height); 7 | void* make_renderer(void* win); 8 | void sdl_setRenderDrawColor(void* ren, int r, int g, int b, int a); 9 | void sdl_renderClear(void* ren); 10 | void sdl_renderPresent(void* ren); 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /SDL/src/SDL.idr: -------------------------------------------------------------------------------- 1 | module SDL 2 | 3 | sdl : String -> String 4 | sdl f = "C:" ++ f ++ ",libidrissdl" 5 | 6 | data SDLWindow : Type where 7 | MkWindow : AnyPtr -> SDLWindow 8 | 9 | data SDLRenderer : Type where 10 | MkRenderer : AnyPtr -> SDLRenderer 11 | 12 | %foreign sdl "simple_createWindow" 13 | prim_createWindow : String -> Int -> Int -> Int -> Int -> AnyPtr 14 | 15 | export 16 | createWindow : HasIO io => String -> Int -> Int -> Int -> Int -> io SDLWindow 17 | createWindow title x y w h 18 | = pure (MkWindow (prim_createWindow title x y w h)) 19 | 20 | %foreign sdl "simple_createRenderer" 21 | prim_createRenderer : AnyPtr -> AnyPtr 22 | 23 | export 24 | createRenderer : HasIO io => SDLWindow -> io SDLRenderer 25 | createRenderer (MkWindow win) 26 | = pure (MkRenderer (prim_createRenderer win)) 27 | 28 | %foreign sdl "sdl_setRenderDrawColor" 29 | prim_setRenderDrawColor : AnyPtr -> Int -> Int -> Int -> Int -> PrimIO () 30 | 31 | export 32 | sdl_setRenderDrawColor : HasIO io => 33 | SDLRenderer -> Int -> Int -> Int -> Int -> io () 34 | sdl_setRenderDrawColor (MkRenderer ren) r g b a 35 | = primIO $ prim_setRenderDrawColor ren r g b a 36 | 37 | %foreign sdl "sdl_renderClear" 38 | prim_renderClear : AnyPtr -> PrimIO () 39 | 40 | export 41 | sdl_renderClear : HasIO io => SDLRenderer -> io () 42 | sdl_renderClear (MkRenderer ren) = primIO $ prim_renderClear ren 43 | 44 | %foreign sdl "sdl_renderPresent" 45 | prim_renderPresent : AnyPtr -> PrimIO () 46 | 47 | export 48 | sdl_renderPresent : HasIO io => SDLRenderer -> io () 49 | sdl_renderPresent (MkRenderer ren) = primIO $ prim_renderPresent ren 50 | 51 | %foreign sdl "SDL_Delay" 52 | prim_delay : Int -> PrimIO () 53 | 54 | export 55 | sdlDelay : HasIO io => Int -> io () 56 | sdlDelay d = primIO $ prim_delay d 57 | 58 | %foreign sdl "SDL_Quit" 59 | prim_quit : PrimIO () 60 | 61 | export 62 | sdlQuit : HasIO io => io () 63 | sdlQuit = primIO $ prim_quit 64 | --------------------------------------------------------------------------------