CL-TERMBOX is a set of cffi bindings to the tiny TERMBOX library for terminal output.
libtermbox
is a simplistic text-mode library for building user-interfaces based on a rectangular grid of character cells, supporting keyboard and mouse input.
CL-TERMBOX is a hand-built set of CFFI bindings, providing a verbatim low-level set of bindings, and a very thin lisp wrapper. Currently, only linux bindings are loaded. If you need to get it working on another machine, please open an issue or a pull request.
All C names are converted to Lisp conventions by removing the tb_
prefix and replacing underscores with dashes. All low-level C bindings have a &
suffix; Lisp layer functions has no such suffix. In many cases, Lisp layer simply invokes the binding.
Low-level calls are not exported and should be accessed with a TB::
prefix (and a &
suffix). High-level functions are exported, and should be accessed with a TB:
prefix. See package.lisp
file for all exports.
A few bindings are low-level only and have no high-level wrapper:
tb::blit&
is available, but is deprecated.tb::put-cell&
stores a cell via a pointer parameter, and the Lisp use-case is unclear.tb::cell-buffer&
returns a pointer to the buffer, and the use-case is unclear.- utf/unicode functions deal with foreign pointers and the Lisp use-case is unclear.
tb::poll-event&
andtb::peek-event&
return a raw foreign structure. Generally, the application will pre-allocate an event record and pass it to the poll/peek routine to be filled. Upon return, the application typically needs a couple of values, so translating the entire structure to Lisp is unwise. A custom extractor is probably a better solution.
CL-TERMBOX runs in a real terminal. In order to use these bindings, Lisp must be started in a shell, and not from Emacs. However, if Lisp is running SWANK, Emacs can connect to it.
SBCL:sbcl --eval "(progn (ql:quickload '(:swank) :silent t))" --eval "(progn (swank:create-server :port 4006 :dont-close t)(loop (sleep 10000)))"
Roswell: ros run -e "(progn (ql:quickload '(:swank) :silent t))" -e "(progn (swank:create-server :port 4006 :dont-close t) (loop (sleep 10000))) "
Connect to it from Emacs with slime-connect
, entering the same port (4006 in this case).
In some cases swank may work better with :style :fd-handler
.
Now, call (tb:init)
to connect to the terminal. When done, call (tb:shutdown)
.
Make sure you set an output mode that makes sense. My terminal defaults to a mode in which colors were off by one.
A minimal error trap around init and shutdown will report TB-ERROR but keep in mind that shutting down more than once will result in a SIGABRT.