ExTermbox v1.0.2 ExTermbox.Bindings View Source
Provides the low-level bindings to the termbox library. This module loads the
NIFs defined in c_src/
and thinly wraps the C interface.
For event-handling, it's recommended to use the ExTermbox.EventManager
API
instead of the raw interface exposed here.
For more complex applications, it's recommended to use the high-level rendering API provided by Ratatouille (a terminal UI kit based on the bindings here). Ratatouille manages things like initialization, updates and shutdown automatically, and provides a declarative, HTML-like interface for rendering content to the screen. See the repo for details:
https://github.com/ndreynolds/ratatouille
See also the termbox header file for additional documentation of the functions here:
https://github.com/nsf/termbox/blob/master/src/termbox.h
Note that the "NIF
Event Polling
The event polling API differs slightly from the termbox API in order to make it in the Erlang ecosystem. Instead of blocking poll calls, it uses asynchronous message passing to deliver events to the caller.
It's recommended to use the ExTermbox.EventManager
gen_server to subscribe
to terminal events instead of using these bindings directly. It supports
multiple subscriptions and more gracefully handles errors.
Implementation Notes
In the start_polling/1
NIF, an OS-level thread is created which performs the
blocking event polling (i.e., a select
call). This allows the NIF to return
quickly and avoid causing the scheduler too much trouble. It would be very bad
to block the scheduler thread until an event is received.
While using threads solves this problem, it unfortunately also introduces new ones. The bindings implement some locking mechanisms to try to coordinate threading logic and prevent polling from occurring simultaneously, but this sort of logic is hard to get right (one of the reasons we use Elixir/Erlang). No issues are currently known, but please report any you happen to encounter.
Timeouts
You might have noticed that there's no binding for tb_peek_event
(which
accepts a timeout). That's because it's easy enough to implement a timeout
ourselves with start_polling/1
and receive
with after
, e.g.:
{:ok, _resource} = Bindings.start_polling(self())
receive do
{:event, event} ->
# handle the event...
after
1_000 ->
:ok = Bindings.stop_polling(self())
# do something else...
end
Link to this section Summary
Functions
Changes the attributes of the cell at the specified position in the internal
back buffer. Prefer using put_cell/1
, which supports passing an
ExTermbox.Cell
struct.
Clears the internal back buffer, setting the foreground and background to the
defaults, or those specified by set_clear_attributes/2
.
Returns {:ok, height}
where height
is the height of the terminal window in
characters.
Initializes the termbox library. Must be called before any other bindings are called.
Synchronizes the internal back buffer and the terminal.
Puts a cell in the internal back buffer at the cell's position. Note that this is
implemented in terms of change_cell/5
.
Sets or retrieves the input mode (see ExTermbox.Constants.input_modes/0
).
See the termbox source
for additional documentation.
Sets or retrieves the output mode (see ExTermbox.Constants.output_modes/0
).
See the termbox source
for additional documentation.
Sets the default foreground and background colors used when clear/0
is
called.
Sets the position of the cursor to the coordinates (x, y)
, or hide the
cursor by passing ExTermbox.Constants.hide_cursor/0
for both x and y.
Finalizes the termbox library. Should be called when the terminal application is exited, and before your program or OTP application stops.
Starts polling for terminal events asynchronously. The function accepts a PID
as argument and returns immediately. When an event is received, it's sent to
the specified process. It continues polling until either stop_polling/0
or
shutdown/0
is called. An error is returned when this function is called
again before polling has been stopped.
Cancels a previous call to start_polling/1
and blocks until polling has
stopped. The polling loop checks every 10 ms for a stop condition, so calls
can take up to 10 ms to return.
Returns {:ok, width}
where width
is the width of the terminal window in
characters.
Link to this section Functions
change_cell(x, y, ch, fg, bg)
View Sourcechange_cell( non_neg_integer(), non_neg_integer(), non_neg_integer(), ExTermbox.Constants.color(), ExTermbox.Constants.color() ) :: :ok | {:error, :not_running}
Changes the attributes of the cell at the specified position in the internal
back buffer. Prefer using put_cell/1
, which supports passing an
ExTermbox.Cell
struct.
Returns :ok
if successful. If termbox was not initialized, returns
{:error, :not_running}
(call init/0
first).
Clears the internal back buffer, setting the foreground and background to the
defaults, or those specified by set_clear_attributes/2
.
Returns :ok
if successful. If termbox was not initialized, returns
{:error, :not_running}
(call init/0
first).
Returns {:ok, height}
where height
is the height of the terminal window in
characters.
If termbox was not initialized, returns {:error, :not_running}
(call
init/0
first).
Initializes the termbox library. Must be called before any other bindings are called.
Returns :ok
on success and otherwise one of the following errors:
{:error, :already_running} - the library was already initialized. *
` - where code is an integer error code from termbox.
Synchronizes the internal back buffer and the terminal.
Returns :ok
if successful. If termbox was not initialized, returns
{:error, :not_running}
(call init/0
first).
put_cell(cell)
View Sourceput_cell(ExTermbox.Cell.t()) :: :ok | {:error, :not_running}
Puts a cell in the internal back buffer at the cell's position. Note that this is
implemented in terms of change_cell/5
.
Returns :ok
if successful. If termbox was not initialized, returns
{:error, :not_running}
(call init/0
first).
select_input_mode(mode)
View Sourceselect_input_mode(ExTermbox.Constants.input_mode()) :: {:ok, integer()} | {:error, :not_running}
Sets or retrieves the input mode (see ExTermbox.Constants.input_modes/0
).
See the termbox source
for additional documentation.
Returns {:ok, input_mode}
when successful, where input_mode
is an integer
representing the current mode. If termbox was not initialized, returns
{:error, :not_running}
(call init/0
first).
select_output_mode(mode)
View Sourceselect_output_mode(ExTermbox.Constants.output_mode()) :: {:ok, integer()} | {:error, :not_running}
Sets or retrieves the output mode (see ExTermbox.Constants.output_modes/0
).
See the termbox source
for additional documentation.
Returns {:ok, output_mode}
when successful, where output_mode
is an
integer representing the current mode. If termbox was not initialized, returns
{:error, :not_running}
(call init/0
first).
set_clear_attributes(fg, bg)
View Sourceset_clear_attributes(ExTermbox.Constants.color(), ExTermbox.Constants.color()) :: :ok | {:error, :not_running}
Sets the default foreground and background colors used when clear/0
is
called.
Returns :ok
if successful. If termbox was not initialized, returns
{:error, :not_running}
(call init/0
first).
set_cursor(x, y)
View Sourceset_cursor(non_neg_integer(), non_neg_integer()) :: :ok | {:error, :not_running}
Sets the position of the cursor to the coordinates (x, y)
, or hide the
cursor by passing ExTermbox.Constants.hide_cursor/0
for both x and y.
Returns :ok
if successful. If termbox was not initialized, returns
{:error, :not_running}
(call init/0
first).
Finalizes the termbox library. Should be called when the terminal application is exited, and before your program or OTP application stops.
Returns :ok
on success and otherwise one of the following errors:
{:error, :not_running} - the library can not be shut down because it is not initialized. *
- where
code` is an integer error code from termbox.
Starts polling for terminal events asynchronously. The function accepts a PID
as argument and returns immediately. When an event is received, it's sent to
the specified process. It continues polling until either stop_polling/0
or
shutdown/0
is called. An error is returned when this function is called
again before polling has been stopped.
If successful, returns {:ok, resource}
, where resource
is an Erlang
resource object representing a handle for the poll thread. Otherwise, one of
the following errors is returned:
{:error, :not_running} - termbox should be initialized before events are polled. *
- [
start_polling/1`](#start_polling/1) was previously called and has not been since stopped.
stop_polling()
View Sourcestop_polling() :: :ok | {:error, :not_running | :not_polling}
Cancels a previous call to start_polling/1
and blocks until polling has
stopped. The polling loop checks every 10 ms for a stop condition, so calls
can take up to 10 ms to return.
This can be useful, for example, if the start_polling/1
recipient process
dies and the polling needs to be restarted by another process.
Returns :ok
on success and otherwise one of the following errors:
{:error, :not_running} - termbox should be initialized before any polling functions are called. *
- polling cannot be stopped because it was already stopped or never started.
Returns {:ok, width}
where width
is the width of the terminal window in
characters.
If termbox was not initialized, returns {:error, :not_running}
(call
init/0
first).