Current section
Files
Jump to
Current section
Files
src/termbox2_nif.c
#define TB_IMPL
#include "erl_nif.h"
#include "termbox2.h"
int tui_init = 0;
char *buf;
static ERL_NIF_TERM ex_start(ErlNifEnv *env, int argc,
const ERL_NIF_TERM argv[]) {
buf = enif_alloc(1024 + 1);
tb_init();
// tb_set_output_mode(TB_OUTPUT_256);
tui_init = 1;
// pthread_create(&event_handler_pt, NULL, event_handler_pthread_routine,
// NULL);
return enif_make_int(env, 0);
}
static ERL_NIF_TERM ex_stop(ErlNifEnv *env, int argc,
const ERL_NIF_TERM argv[]) {
tui_init = 0;
tb_shutdown();
enif_free(buf);
return enif_make_int(env, 0);
}
static ERL_NIF_TERM present(ErlNifEnv *env, int argc,
const ERL_NIF_TERM argv[]) {
tb_present();
return enif_make_int(env, 0);
}
static ERL_NIF_TERM clear_region(ErlNifEnv *env, int argc,
const ERL_NIF_TERM argv[]) {
int x, y, width, height;
enif_get_int(env, argv[0], &x);
enif_get_int(env, argv[1], &y);
enif_get_int(env, argv[2], &width);
enif_get_int(env, argv[3], &height);
for (int i = x; i < x + width; ++i) {
for (int j = y; j < y + height; ++j) {
tb_set_cell(i, j, ' ', TB_DEFAULT, TB_DEFAULT);
}
}
return enif_make_int(env, 0);
}
static ERL_NIF_TERM clear(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
tb_clear();
return enif_make_int(env, 0);
}
static ERL_NIF_TERM width(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
return enif_make_int(env, tb_width());
}
static ERL_NIF_TERM height(ErlNifEnv *env, int argc,
const ERL_NIF_TERM argv[]) {
return enif_make_int(env, tb_height());
}
static ERL_NIF_TERM poll(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
int timeout;
struct tb_event event = {0};
enif_get_int(env, argv[0], &timeout);
int result = tb_peek_event(&event, timeout);
if (result == TB_OK) {
ErlNifEnv *env = enif_alloc_env();
ERL_NIF_TERM result = enif_make_tuple2(
env, enif_make_atom(env, "event"),
enif_make_tuple8(
env, enif_make_uint(env, event.type),
enif_make_uint(env, event.mod), enif_make_uint(env, event.key),
enif_make_uint(env, event.ch), enif_make_int(env, event.w),
enif_make_int(env, event.h), enif_make_int(env, event.x),
enif_make_int(env, event.y)));
return result;
} else {
return enif_make_atom(env, "none");
}
}
static ERL_NIF_TERM tb2_puts(ErlNifEnv *env, int argc,
const ERL_NIF_TERM argv[]) {
int x, y, attr;
enif_get_int(env, argv[0], &x);
enif_get_int(env, argv[1], &y);
enif_get_int(env, argv[2], &attr);
ErlNifBinary bin;
// NOTE: Cody helped here, chatgpt not so much
enif_inspect_binary(env, argv[3], &bin);
int len = bin.size;
if (len > tb_width() - x) {
len = tb_width() - x;
}
memcpy(buf, bin.data, len);
buf[len] = '\0';
if (x >= 0 && x < tb_width() && y >= 0 && y < tb_height()) {
tb_print(x, y, TB_DEFAULT | attr, TB_DEFAULT, buf);
}
// tb_printf(x, y, TB_DEFAULT | TB_BOLD, TB_DEFAULT, buf);
return enif_make_int(env, 0);
}
static ErlNifFunc nif_funcs[] = {{"present", 0, present, 0},
{"clear", 0, clear, 0},
{"clear_region", 4, clear_region, 0},
{"width", 0, width, 0},
{"height", 0, height, 0},
{"ex_start", 0, ex_start, 0},
{"ex_stop", 0, ex_stop, 0},
{"poll", 1, poll, 0},
{"puts", 4, tb2_puts, 0}};
ERL_NIF_INIT(Elixir.ElementTui.TermBox2Ex, nif_funcs, NULL, NULL, NULL, NULL)