factor/extra/curses/curses.factor

271 lines
7.5 KiB
Factor
Raw Normal View History

! Copyright (C) 2008 Doug Coleman.
! See http://factorcode.org/license.txt for BSD license.
USING: accessors alien.c-types alien.strings assocs byte-arrays
2009-10-21 11:09:24 -04:00
classes.struct combinators continuations destructors
2009-10-20 07:57:24 -04:00
fry io io.encodings.8-bit io.encodings.string io.encodings.utf8
io.streams.c kernel libc locals math memoize multiline
namespaces prettyprint sequences strings threads ;
IN: curses
2009-10-21 11:09:24 -04:00
QUALIFIED-WITH: curses.ffi ffi
SYMBOL: current-window
2009-10-20 07:57:24 -04:00
CONSTANT: COLOR_BLACK 0
CONSTANT: COLOR_RED 1
CONSTANT: COLOR_GREEN 2
CONSTANT: COLOR_YELLO 3
CONSTANT: COLOR_BLUE 4
CONSTANT: COLOR_MAGEN 5
CONSTANT: COLOR_CYAN 6
CONSTANT: COLOR_WHITE 7
2009-10-21 13:36:41 -04:00
CONSTANT: A_NORMAL 0
CONSTANT: A_ATTRIBUTES -256
CONSTANT: A_CHARTEXT 255
CONSTANT: A_COLOR 65280
CONSTANT: A_STANDOUT 65536
CONSTANT: A_UNDERLINE 131072
CONSTANT: A_REVERSE 262144
CONSTANT: A_BLINK 524288
CONSTANT: A_DIM 1048576
CONSTANT: A_BOLD 2097152
CONSTANT: A_ALTCHARSET 4194304
CONSTANT: A_INVIS 8388608
CONSTANT: A_PROTECT 16777216
CONSTANT: A_HORIZONTAL 33554432
CONSTANT: A_LEFT 67108864
CONSTANT: A_LOW 134217728
CONSTANT: A_RIGHT 268435456
CONSTANT: A_TOP 536870912
CONSTANT: A_VERTICAL 1073741824
ERROR: curses-failed ;
ERROR: unsupported-curses-terminal ;
2009-10-21 11:09:24 -04:00
<PRIVATE
: >BOOLEAN ( ? -- TRUE/FALSE ) ffi:TRUE ffi:FALSE ? ; inline
: curses-pointer-error ( ptr/f -- ptr )
dup [ curses-failed ] unless ; inline
: curses-error ( n -- ) ffi:ERR = [ curses-failed ] when ;
PRIVATE>
: curses-ok? ( -- ? )
{ 0 1 2 } [ isatty 0 = not ] all? ;
2009-10-20 07:57:24 -04:00
TUPLE: curses-window < disposable
ptr
2009-10-20 07:57:24 -04:00
parent-window
{ 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
2009-10-20 07:57:24 -04:00
{ keypad initial: t }
2009-10-20 07:57:24 -04:00
{ encoding initial: utf8 } ;
2009-10-20 07:57:24 -04:00
: <curses-window> ( -- window )
curses-window new-disposable ;
2009-10-20 07:57:24 -04:00
M: curses-window dispose* ( window -- )
2009-10-21 11:09:24 -04:00
ptr>> ffi:delwin curses-error ;
2009-10-20 07:57:24 -04:00
<PRIVATE
: window-params ( window -- lines columns y x )
{ [ lines>> ] [ columns>> ] [ y>> ] [ x>> ] } cleave ;
2009-10-20 07:57:24 -04:00
: set-cbreak/raw ( cbreak raw -- )
2009-10-21 11:09:24 -04:00
[ drop ffi:raw ] [
[ ffi:cbreak ] [ ffi:nocbreak ] if
2009-10-20 07:57:24 -04:00
] if curses-error ;
: apply-options ( window -- )
{
2009-10-20 07:57:24 -04:00
[ [ cbreak>> ] [ raw>> ] bi set-cbreak/raw ]
2009-10-21 11:09:24 -04:00
[ echo>> [ ffi:echo ] [ ffi:noecho ] if curses-error ]
[ [ ptr>> ] [ scrollok>> >BOOLEAN ] bi ffi:scrollok curses-error ]
[ [ ptr>> ] [ leaveok>> >BOOLEAN ] bi ffi:leaveok curses-error ]
[ [ ptr>> ] [ keypad>> >BOOLEAN ] bi ffi:keypad curses-error ]
} cleave ;
2009-10-20 07:57:24 -04:00
SYMBOL: n-registered-colors
MEMO: register-color ( fg bg -- n )
2009-10-21 11:09:24 -04:00
[ n-registered-colors get ] 2dip ffi:init_pair curses-error
2009-10-20 07:57:24 -04:00
n-registered-colors [ get ] [ inc ] bi ;
2009-10-21 11:09:24 -04:00
: init-colors ( -- )
ffi:has_colors [
1 n-registered-colors set
\ register-color reset-memoized
ffi:start_color curses-error
] when ;
PRIVATE>
2009-10-20 07:57:24 -04:00
: setup-window ( window -- window )
[
dup
dup parent-window>> [
2009-10-21 11:09:24 -04:00
ptr>> swap window-params ffi:derwin
2009-10-20 07:57:24 -04:00
] [
2009-10-21 11:09:24 -04:00
window-params ffi:newwin
2009-10-20 07:57:24 -04:00
] if* [ curses-error ] keep >>ptr &dispose
] [ apply-options ] bi ;
: with-window ( window quot -- )
[ current-window ] dip with-variable ; inline
: with-curses ( window quot -- )
curses-ok? [ unsupported-curses-terminal ] unless
[
2009-10-21 13:36:41 -04:00
'[
2009-10-21 11:09:24 -04:00
ffi:initscr curses-pointer-error
2009-10-20 07:57:24 -04:00
>>ptr dup apply-options
2009-10-21 13:36:41 -04:00
ffi:erase curses-error
init-colors
_ with-window
] [ ffi:endwin curses-error ] [ ] cleanup
2009-10-20 07:57:24 -04:00
] with-destructors ; inline
2009-10-20 07:58:19 -04:00
TUPLE: curses-terminal < disposable
infd outfd ptr ;
: <curses-terminal> ( infd outfd ptr -- curses-terminal )
curses-terminal new-disposable
swap >>ptr
swap >>outfd
swap >>infd ;
M: curses-terminal dispose
[ outfd>> fclose ] [ infd>> fclose ]
2009-10-21 11:09:24 -04:00
[ ptr>> ffi:delscreen ] tri ;
2009-10-20 07:58:19 -04:00
: init-terminal ( terminal -- curses-terminal )
"xterm-color" swap [ "rb" fopen ] [ "wb" fopen ] bi
2009-10-21 11:09:24 -04:00
[ ffi:newterm curses-pointer-error ] 2keep <curses-terminal> ;
2009-10-20 07:58:19 -04:00
: start-remote-curses ( terminal window -- curses-terminal )
[
init-terminal
2009-10-21 11:09:24 -04:00
ffi:initscr curses-pointer-error drop
dup ptr>> ffi:set_term curses-pointer-error drop
2009-10-20 07:58:19 -04:00
] dip apply-options ;
2009-10-20 07:57:24 -04:00
<PRIVATE
2009-10-21 11:09:24 -04:00
: (wcrefresh) ( window-ptr -- ) ffi:wrefresh curses-error ; inline
: (wcwrite) ( string window-ptr -- ) swap ffi:waddstr curses-error ; inline
2009-10-21 11:09:24 -04:00
:: (wcread) ( n encoding window-ptr -- string )
2009-10-20 07:57:24 -04:00
[
n 1 + malloc &free :> str
2009-10-21 11:09:24 -04:00
window-ptr str n ffi:wgetnstr curses-error
2009-10-20 07:57:24 -04:00
str encoding alien>string
] with-destructors ; inline
2009-10-21 11:09:24 -04:00
: (wcmove) ( y x window-ptr -- )
-rot ffi:wmove curses-error ; inline
2009-10-21 11:09:24 -04:00
: (winsert-blank-line) ( y window-ptr -- )
[ 0 swap (wcmove) ]
[ ffi:winsertln curses-error ] bi ; inline
2009-10-21 11:09:24 -04:00
: (waddch) ( ch window-ptr -- )
swap ffi:waddch curses-error ; inline
2009-10-21 11:09:24 -04:00
: (wgetch) ( window -- key )
ffi:wgetch [ curses-error ] keep ; inline
2009-10-21 13:36:41 -04:00
: (wattroff) ( attribute window-ptr -- )
swap ffi:wattroff curses-error ; inline
: (wattron) ( attribute window-ptr -- )
swap ffi:wattron curses-error ; inline
2009-10-20 07:57:24 -04:00
PRIVATE>
2009-10-21 11:09:24 -04:00
: wcrefresh ( window -- ) ptr>> (wcrefresh) ;
: crefresh ( -- ) current-window get wcrefresh ;
: wcnl ( window -- ) [ "\n" ] dip ptr>> (wcwrite) ;
: cnl ( -- ) current-window get wcnl ;
2009-10-21 13:36:41 -04:00
: wcwrite ( string window -- ) ptr>> (wcwrite) ;
: cwrite ( string -- ) current-window get wcwrite ;
2009-10-21 11:09:24 -04:00
: wcprint ( string window -- )
ptr>> [ (wcwrite) ] [ "\n" swap (wcwrite) ] bi ;
: cprint ( string -- ) current-window get wcprint ;
: wcprintf ( string window -- )
ptr>> [ (wcwrite) ] [ "\n" swap (wcwrite) ]
[ (wcrefresh) ] tri ;
2009-10-21 13:36:41 -04:00
: cprintf ( string -- ) current-window get wcprintf ;
2009-10-21 11:09:24 -04:00
: wcwritef ( string window -- )
ptr>> [ (wcwrite) ] [ (wcrefresh) ] bi ;
: cwritef ( string -- ) current-window get wcwritef ;
: wcread ( n window -- string )
[ encoding>> ] [ ptr>> ] bi (wcread) ;
: curses-read ( n -- string ) current-window get wcread ;
: wgetch ( window -- key ) ptr>> (wgetch) ;
: getch ( -- key ) current-window get wgetch ;
: waddch ( ch window -- ) ptr>> (waddch) ;
: addch ( ch -- ) current-window get waddch ;
: werase ( window -- ) ptr>> ffi:werase curses-error ;
: erase ( -- ) current-window get werase ;
: wcmove ( y x window -- )
ptr>> [ (wcmove) ] [ (wcrefresh) ] bi ;
: cmove ( y x -- ) current-window get wcmove ;
: wdelete-line ( y window -- )
ptr>> [ 0 swap (wcmove) ] [ ffi:wdeleteln curses-error ] bi ;
: delete-line ( y -- ) current-window get wdelete-line ;
: winsert-blank-line ( y window -- )
ptr>> (winsert-blank-line) ;
2009-10-20 07:57:24 -04:00
: insert-blank-line ( y -- )
2009-10-21 11:09:24 -04:00
current-window get winsert-blank-line ;
2009-10-20 07:57:24 -04:00
2009-10-21 11:09:24 -04:00
: winsert-line ( string y window -- )
ptr>> [ (winsert-blank-line) ] [ (wcwrite) ] bi ;
2009-10-20 07:57:24 -04:00
: insert-line ( string y -- )
2009-10-21 11:09:24 -04:00
current-window get winsert-line ;
2009-10-20 07:57:24 -04:00
2009-10-21 13:36:41 -04:00
: wattron ( attribute window -- ) ptr>> (wattron) ;
: attron ( attribute -- ) current-window get wattron ;
: wattroff ( attribute window -- ) ptr>> (wattroff) ;
: attroff ( attribute -- ) current-window get wattroff ;
: wall-attroff ( window -- ) [ A_NORMAL ] dip wattroff ;
: all-attroff ( -- ) current-window get wall-attroff ;
2009-10-21 11:09:24 -04:00
: wccolor ( foreground background window -- )
[
2009-10-20 07:57:24 -04:00
2dup [ COLOR_WHITE = ] [ COLOR_BLACK = ] bi* and
2009-10-21 11:09:24 -04:00
[ 2drop 0 ] [ register-color ] if ffi:COLOR_PAIR
2009-10-21 13:36:41 -04:00
] dip ptr>> (wattron) ;
2009-10-21 11:09:24 -04:00
: ccolor ( foreground background -- )
current-window get wccolor ;