diff --git a/extra/curses/authors.txt b/extra/curses/authors.txt new file mode 100644 index 0000000000..7c1b2f2279 --- /dev/null +++ b/extra/curses/authors.txt @@ -0,0 +1 @@ +Doug Coleman diff --git a/extra/curses/curses-tests.factor b/extra/curses/curses-tests.factor new file mode 100644 index 0000000000..21463b207b --- /dev/null +++ b/extra/curses/curses-tests.factor @@ -0,0 +1,18 @@ +! Copyright (C) 2009 Doug Coleman. +! See http://factorcode.org/license.txt for BSD license. +USING: accessors curses kernel threads tools.test ; +IN: curses.tests + +: hello-curses ( -- ) + [ + curses-window new + "mainwin" >>name + add-curses-window + + "mainwin" "hi" curses-printf + + 2000000 sleep + ] with-curses ; + +[ +] [ hello-curses ] unit-test diff --git a/extra/curses/curses.factor b/extra/curses/curses.factor new file mode 100644 index 0000000000..f11b26333b --- /dev/null +++ b/extra/curses/curses.factor @@ -0,0 +1,155 @@ +! Copyright (C) 2008 Doug Coleman. +! See http://factorcode.org/license.txt for BSD license. +USING: accessors alien.c-types alien.strings assocs byte-arrays +combinators continuations destructors fry io.encodings.8-bit +io io.encodings.string io.encodings.utf8 kernel math +namespaces prettyprint sequences +strings threads curses.ffi ; +IN: curses + +SYMBOL: curses-windows +SYMBOL: current-window + +: ERR -1 ; inline +: FALSE 0 ; inline +: TRUE 1 ; inline +: >BOOLEAN ( n -- TRUE/FALSE ) >boolean TRUE FALSE ? ; inline + +ERROR: duplicate-window window ; +ERROR: unnamed-window window ; +ERROR: window-not-found window ; +ERROR: curses-failed ; + +: get-window ( string -- window ) + dup curses-windows get at* + [ nip ] [ drop window-not-found ] if ; + +: window-ptr ( string -- window ) get-window ptr>> ; + +: curses-error ( n -- ) ERR = [ curses-failed ] when ; + +: with-curses ( quot -- ) + H{ } clone curses-windows [ + initscr curses-error + [ + curses-windows get values [ dispose ] each + nocbreak curses-error + echo curses-error + endwin curses-error + ] [ ] cleanup + ] with-variable ; inline + +: with-window ( name quot -- ) + [ window-ptr current-window ] dip with-variable ; inline + +TUPLE: curses-window + name + parent-name + ptr + { lines integer initial: 0 } + { columns integer initial: 0 } + { y integer initial: 0 } + { x integer initial: 0 } + + { cbreak initial: t } + { echo initial: t } + { raw initial: f } + + { scrollok initial: t } + { leaveok initial: f } + + idcok idlok immedok + { keypad initial: f } ; + +M: curses-window dispose ( window -- ) + ptr>> delwin curses-error ; + +> [ unnamed-window ] unless* + curses-windows get 2dup key? + [ duplicate-window ] [ set-at ] if ; + +: delete-window ( window -- ) + curses-windows get 2dup key? + [ delete-at ] [ drop window-not-found ] if ; + +: window-params ( window -- lines columns y x ) + { [ lines>> ] [ columns>> ] [ y>> ] [ x>> ] } cleave ; + +: setup-window ( window -- ) + { + [ + dup + dup parent-name>> [ + window-ptr swap window-params derwin + ] [ + window-params newwin + ] if* [ curses-error ] keep >>ptr drop + ] + [ cbreak>> [ cbreak ] [ nocbreak ] if curses-error ] + [ echo>> [ echo ] [ noecho ] if curses-error ] + [ raw>> [ raw ] [ noraw ] if curses-error ] + [ [ ptr>> ] [ scrollok>> >BOOLEAN ] bi scrollok curses-error ] + [ [ ptr>> ] [ leaveok>> >BOOLEAN ] bi leaveok curses-error ] + [ [ ptr>> ] [ keypad>> >BOOLEAN ] bi keypad curses-error ] + [ add-window ] + } cleave ; + +PRIVATE> + +: add-curses-window ( window -- ) + [ setup-window ] [ ] [ dispose ] cleanup ; + +: (curses-window-refresh) ( window-ptr -- ) wrefresh curses-error ; +: wnrefresh ( window -- ) window-ptr (curses-window-refresh) ; +: curses-refresh ( -- ) current-window get (curses-window-refresh) ; + +: (curses-wprint) ( window-ptr string -- ) + waddstr curses-error ; + +: curses-nwrite ( window string -- ) + [ window-ptr ] dip (curses-wprint) ; + +: curses-wprint ( window string -- ) + [ window-ptr dup ] dip (curses-wprint) "\n" (curses-wprint) ; + +: curses-printf ( window string -- ) + [ window-ptr dup dup ] dip (curses-wprint) + "\n" (curses-wprint) + (curses-window-refresh) ; + +: curses-writef ( window string -- ) + [ window-ptr dup ] dip (curses-wprint) (curses-window-refresh) ; + +: (curses-read) ( window-ptr n encoding -- string ) + [ [ tuck ] keep wgetnstr curses-error ] dip alien>string ; + +: curses-read ( window n -- string ) + utf8 [ window-ptr ] 2dip (curses-read) ; + +: curses-erase ( window -- ) window-ptr werase curses-error ; + +: move-cursor ( window-name y x -- ) + [ + window-ptr + { + [ ] + [ (curses-window-refresh) ] + [ c-window-_curx ] + [ c-window-_cury ] + } cleave + ] 2dip mvcur curses-error (curses-window-refresh) ; + +: delete-line ( window-name y -- ) + [ window-ptr dup ] dip + 0 wmove curses-error wdeleteln curses-error ; + +: insert-blank-line ( window-name y -- ) + [ window-ptr dup ] dip + 0 wmove curses-error winsertln curses-error ; + +: insert-line ( window-name y string -- ) + [ dupd insert-blank-line ] dip + curses-writef ; diff --git a/extra/curses/ffi/ffi.factor b/extra/curses/ffi/ffi.factor new file mode 100644 index 0000000000..8d4a7ddb4b --- /dev/null +++ b/extra/curses/ffi/ffi.factor @@ -0,0 +1,231 @@ +! Copyright (C) 2008 Doug Coleman. +! See http://factorcode.org/license.txt for BSD license. +USING: accessors alien alien.syntax combinators kernel system ; +IN: curses.ffi + +<< "curses" { + { [ os winnt? ] [ "libcurses.dll" ] } + { [ os macosx? ] [ "libcurses.dylib" ] } + { [ os unix? ] [ "libcurses.so" ] } +} cond "cdecl" add-library >> + +TYPEDEF: void* WINDOW* +TYPEDEF: void* SCREEN* +TYPEDEF: void* va_list + +TYPEDEF: uint chtype +TYPEDEF: chtype attr_t +TYPEDEF: short NCURSES_SIZE_T +TYPEDEF: ushort wchar_t + +: CCHARW_MAX 5 ; inline + +C-STRUCT: cchar_t + { "attr_t" "attr" } + { { "wchar_t" CCHARW_MAX } "chars" } ; + +C-STRUCT: pdat + { "NCURSES_SIZE_T" "_pad_y" } + { "NCURSES_SIZE_T" "_pad_x" } + { "NCURSES_SIZE_T" "_pad_top" } + { "NCURSES_SIZE_T" "_pad_left" } + { "NCURSES_SIZE_T" "_pad_bottom" } + { "NCURSES_SIZE_T" "_pad_right" } ; + +C-STRUCT: c-window + { "NCURSES_SIZE_T" "_cury" } + { "NCURSES_SIZE_T" "_curx" } + + { "NCURSES_SIZE_T" "_maxy" } + { "NCURSES_SIZE_T" "_maxx" } + { "NCURSES_SIZE_T" "_begy" } + { "NCURSES_SIZE_T" "_begx" } + + { "short" " _flags" } + + { "attr_t" "_attrs" } + { "chtype" "_bkgd" } + + { "bool" "_notimeout" } + { "bool" "_clear" } + { "bool" "_leaveok" } + { "bool" "_scroll" } + { "bool" "_idlok" } + { "bool" "_idcok" } + { "bool" "_immed" } + { "bool" "_sync" } + { "bool" "_use_keypad" } + { "int" "_delay" } + + { "char*" "_line" } + { "NCURSES_SIZE_T" "_regtop" } + { "NCURSES_SIZE_T" "_regbottom" } + + { "int" "_parx" } + { "int" "_pary" } + { "WINDOW*" "_parent" } + + { "pdat" "_pad" } + + { "NCURSES_SIZE_T" "_yoffset" } + + { "cchar_t" "_bkgrnd" } ; + +LIBRARY: curses + +: stdscr ( -- alien ) + "stdscr" "curses" library dll>> dlsym ; + +FUNCTION: WINDOW* initscr ( ) ; +FUNCTION: int endwin ( ) ; +FUNCTION: bool isendwin ( ) ; +FUNCTION: SCREEN* newterm ( char* type, FILE* outfd, FILE* infd ) ; +FUNCTION: SCREEN* set_term ( SCREEN* new ) ; +FUNCTION: void delscreen ( SCREEN* sp ) ; + +FUNCTION: int def_prog_mode ( ) ; +FUNCTION: int def_shell_mode ( ) ; +FUNCTION: int reset_prog_mode ( ) ; +FUNCTION: int reset_shell_mode ( ) ; +FUNCTION: int resetty ( ) ; +FUNCTION: int savetty ( ) ; +FUNCTION: int ripoffline ( int line, void* callback ) ; +FUNCTION: int curs_set ( int visibility ) ; +FUNCTION: int napms ( int ms ) ; + +FUNCTION: WINDOW* newwin ( int nlines, int ncols, int begin_y, int begin_x ) ; +FUNCTION: int delwin ( WINDOW* win ) ; +FUNCTION: int mvwin ( WINDOW* win, int y, int x ) ; +FUNCTION: WINDOW* subwin ( WINDOW* orig, int nlines, int ncols, int begin_y, int begin_x ) ; +FUNCTION: WINDOW* derwin ( WINDOW* orig, int nlines, int ncols, int begin_y, int begin_x ) ; +FUNCTION: int mvderwin ( WINDOW* win, int par_y, int par_x ) ; +FUNCTION: WINDOW* dupwin ( WINDOW* win ) ; +FUNCTION: void wsyncup ( WINDOW* win ) ; +FUNCTION: int syncok ( WINDOW* win, bool bf ) ; +FUNCTION: void wcursyncup ( WINDOW* win ) ; +FUNCTION: void wsyncdown ( WINDOW* win ) ; + +FUNCTION: int cbreak ( ) ; +FUNCTION: int nocbreak ( ) ; +FUNCTION: int echo ( ) ; +FUNCTION: int noecho ( ) ; +FUNCTION: int halfdelay ( int tenths ) ; +FUNCTION: int intrflush ( WINDOW* win, bool bf ) ; +FUNCTION: int keypad ( WINDOW* win, bool bf ) ; +FUNCTION: int meta ( WINDOW* win, bool bf ) ; +FUNCTION: int nodelay ( WINDOW* win, bool bf ) ; +FUNCTION: int raw ( ) ; +FUNCTION: int noraw ( ) ; +FUNCTION: void noqiflush ( ) ; +FUNCTION: void qiflush ( ) ; +FUNCTION: int notimeout ( WINDOW* win, bool bf ) ; +FUNCTION: void timeout ( int delay ) ; +FUNCTION: void wtimeout ( WINDOW* win, int delay ) ; +FUNCTION: int typeahead ( int fd ) ; + +FUNCTION: int clearok ( WINDOW* win, bool bf ) ; +FUNCTION: int idlok ( WINDOW* win, bool bf ) ; +FUNCTION: void idcok ( WINDOW* win, bool bf ) ; +FUNCTION: void immedok ( WINDOW* win, bool bf ) ; +FUNCTION: int leaveok ( WINDOW* win, bool bf ) ; +FUNCTION: int setscrreg ( int top, int bot ) ; +FUNCTION: int wsetscrreg ( WINDOW* win, int top, int bot ) ; +FUNCTION: int scrollok ( WINDOW* win, bool bf ) ; +FUNCTION: int nl ( ) ; +FUNCTION: int nonl ( ) ; + +FUNCTION: int erase ( ) ; +FUNCTION: int werase ( WINDOW* win ) ; +FUNCTION: int clear ( ) ; +FUNCTION: int wclear ( WINDOW* win ) ; +FUNCTION: int clrtobot ( ) ; +FUNCTION: int wclrtobot ( WINDOW* win ) ; +FUNCTION: int clrtoeol ( ) ; +FUNCTION: int wclrtoeol ( WINDOW* win ) ; + +FUNCTION: int refresh ( ) ; +FUNCTION: int wrefresh ( WINDOW* win ) ; +FUNCTION: int wnoutrefresh ( WINDOW* win ) ; +FUNCTION: int doupdate ( ) ; +FUNCTION: int redrawwin ( WINDOW* win ) ; +FUNCTION: int wredrawln ( WINDOW* win, int beg_line, int num_lines ) ; + +FUNCTION: int getch ( ) ; +FUNCTION: int wgetch ( WINDOW* win ) ; +FUNCTION: int mvgetch ( int y, int x ) ; +FUNCTION: int mvwgetch ( WINDOW* win, int y, int x ) ; +FUNCTION: int ungetch ( int ch ) ; +FUNCTION: int has_key ( int ch ) ; + +FUNCTION: int getstr ( char* str ) ; +FUNCTION: int getnstr ( char* str, int n ) ; +FUNCTION: int wgetstr ( WINDOW* win, char* str ) ; +FUNCTION: int wgetnstr ( WINDOW* win, char* str, int n ) ; +FUNCTION: int mvgetstr ( int y, int x, char* str ) ; +FUNCTION: int mvwgetstr ( WINDOW* win, int y, int x, char* str ) ; +FUNCTION: int mvgetnstr ( int y, int x, char* str, int n ) ; +FUNCTION: int mvwgetnstr ( WINDOW* win, int y, int x, char* str, int n ) ; + +FUNCTION: int printw ( char* fmt, int lol ) ; +FUNCTION: int wprintw ( WINDOW* win, char* fmt, int lol ) ; +FUNCTION: int mvprintw ( int y, int x, char* fmt, int lol ) ; +FUNCTION: int mvwprintw ( WINDOW* win, int y, int x, char* fmt, int lol ) ; +FUNCTION: int vwprintw ( WINDOW* win, char* fmt, va_list varglist ) ; +FUNCTION: int vw_printw ( WINDOW* win, char* fmt, va_list varglist ) ; + +FUNCTION: int move ( int y, int x ) ; +FUNCTION: int wmove ( WINDOW* win, int y, int x ) ; + + +FUNCTION: int scroll ( WINDOW* win ) ; +FUNCTION: int scrl ( int n ) ; +FUNCTION: int wscrl ( WINDOW* win, int n ) ; + + ! int setupterm(char *term, int fildes, int *errret); + ! int setterm(char *term); + ! TERMINAL *set_curterm(TERMINAL *nterm); + ! int del_curterm(TERMINAL *oterm); + ! int restartterm(const char *term, int fildes, int *errret); + ! char *tparm(char *str, ...); + ! int tputs(const char *str, int affcnt, int (*putc)(int)); + ! int putp(const char *str); + ! int vidputs(chtype attrs, int (*putc)(int)); + ! int vidattr(chtype attrs); + ! int vid_puts(attr_t attrs, short pair, void *opts, int (*putc)(char)); + ! int vid_attr(attr_t attrs, short pair, void *opts); +FUNCTION: int mvcur ( int oldrow, int oldcol, int newrow, int newcol ) ; + ! int tigetflag(char *capname); + ! int tigetnum(char *capname); + ! char *tigetstr(char *capname); + +FUNCTION: int touchwin ( WINDOW* win ) ; +FUNCTION: int touchline ( WINDOW* win, int start, int count ) ; +FUNCTION: int untouchwin ( WINDOW* win ) ; +FUNCTION: int wtouchln ( WINDOW* win, int y, int n, int changed ) ; +FUNCTION: bool is_linetouched ( WINDOW* win, int line ) ; +FUNCTION: bool is_wintouched ( WINDOW* win ) ; + +FUNCTION: int insch ( chtype ch ) ; +FUNCTION: int winsch ( WINDOW* win, chtype ch ) ; +FUNCTION: int mvinsch ( int y, int x, chtype ch ) ; +FUNCTION: int mvwinsch ( WINDOW* win, int y, int x, chtype ch ) ; +FUNCTION: int delch ( ) ; +FUNCTION: int wdelch ( WINDOW* win ) ; +FUNCTION: int mvdelch ( int y, int x ) ; +FUNCTION: int mvwdelch ( WINDOW* win, int y, int x ) ; + +FUNCTION: int deleteln ( ) ; +FUNCTION: int wdeleteln ( WINDOW* win ) ; +FUNCTION: int insdelln ( int n ) ; +FUNCTION: int winsdelln ( WINDOW* win, int n ) ; +FUNCTION: int insertln ( ) ; +FUNCTION: int winsertln ( WINDOW* win ) ; + +FUNCTION: int addstr ( char* str ) ; +FUNCTION: int addnstr ( char* str, int n ) ; +FUNCTION: int waddstr ( WINDOW* win, char* str ) ; +FUNCTION: int waddnstr ( WINDOW* win, char* str, int n ) ; +FUNCTION: int mvaddstr ( int y, int x, char* str ) ; +FUNCTION: int mvaddnstr ( int y, int x, char* str, int n ) ; +FUNCTION: int mvwaddstr ( WINDOW* win, int y, int x, char* str ) ; +FUNCTION: int mvwaddnstr ( WINDOW* win, int y, int x, char* str, int n ) ; diff --git a/extra/curses/ffi/tags.txt b/extra/curses/ffi/tags.txt new file mode 100644 index 0000000000..6bf68304bb --- /dev/null +++ b/extra/curses/ffi/tags.txt @@ -0,0 +1 @@ +unportable diff --git a/extra/curses/summary.txt b/extra/curses/summary.txt new file mode 100644 index 0000000000..0eb839c524 --- /dev/null +++ b/extra/curses/summary.txt @@ -0,0 +1 @@ +ncurses binding diff --git a/extra/curses/tags.txt b/extra/curses/tags.txt new file mode 100644 index 0000000000..6bf68304bb --- /dev/null +++ b/extra/curses/tags.txt @@ -0,0 +1 @@ +unportable