1
0
Fork 0
forked from fun/fun

Very basic Notcurses support. There are bugs! (0.37.45)

This commit is contained in:
Johannes Findeisen 2026-01-03 21:11:26 +01:00
commit fd582f4d3a
30 changed files with 465 additions and 5 deletions

27
src/vm/notcurses/clear.c Normal file
View file

@ -0,0 +1,27 @@
/**
* This file is part of the Fun programming language.
* https://fun-lang.xyz/
*
* Copyright 2025 Johannes Findeisen <you@hanez.org>
* Licensed under the terms of the Apache-2.0 license.
* https://opensource.org/license/apache-2-0
*
* Added: 2026-01-03
*/
/* NC_CLEAR */
case OP_NC_CLEAR: {
#ifdef FUN_WITH_NOTCURSES
if (_fun_nc && _fun_nc_std) {
ncplane_erase(_fun_nc_std);
notcurses_render(_fun_nc);
push_value(vm, make_int(0));
} else {
push_value(vm, make_int(-1));
}
#else
(void)_fun_nc; (void)_fun_nc_std;
push_value(vm, make_int(-1));
#endif
break;
}

23
src/vm/notcurses/common.h Normal file
View file

@ -0,0 +1,23 @@
/**
* This file is part of the Fun programming language.
* https://fun-lang.xyz/
*
* Copyright 2025 Johannes Findeisen <you@hanez.org>
* Licensed under the terms of the Apache-2.0 license.
* https://opensource.org/license/apache-2-0
*
* Added: 2026-01-03
*/
/* Common helpers/state for Notcurses TUI ops */
#pragma once
#include "value.h"
/* Forward declarations to avoid depending on the notcurses headers unless enabled */
struct notcurses;
struct ncplane;
/* Shared static state within vm.c translation unit (header is included into vm.c at file scope) */
static struct notcurses* _fun_nc = NULL;
static struct ncplane* _fun_nc_std = NULL;

View file

@ -0,0 +1,39 @@
/**
* This file is part of the Fun programming language.
* https://fun-lang.xyz/
*
* Copyright 2025 Johannes Findeisen <you@hanez.org>
* Licensed under the terms of the Apache-2.0 license.
* https://opensource.org/license/apache-2-0
*
* Added: 2026-01-03
*/
/* NC_DRAW_TEXT */
case OP_NC_DRAW_TEXT: {
Value textv = pop_value(vm);
Value xv = pop_value(vm);
Value yv = pop_value(vm);
int x = (xv.type == VAL_INT ? (int)xv.i : (xv.type == VAL_FLOAT ? (int)xv.d : 0));
int y = (yv.type == VAL_INT ? (int)yv.i : (yv.type == VAL_FLOAT ? (int)yv.d : 0));
char *text = value_to_string_alloc(&textv);
free_value(textv);
free_value(xv);
free_value(yv);
#ifdef FUN_WITH_NOTCURSES
if (_fun_nc && _fun_nc_std && text) {
ncplane_putstr_yx(_fun_nc_std, y, x, text);
notcurses_render(_fun_nc);
free(text);
push_value(vm, make_int(0));
} else {
if (text) free(text);
push_value(vm, make_int(-1));
}
#else
(void)_fun_nc; (void)_fun_nc_std;
if (text) free(text);
push_value(vm, make_int(-1));
#endif
break;
}

43
src/vm/notcurses/getch.c Normal file
View file

@ -0,0 +1,43 @@
/**
* This file is part of the Fun programming language.
* https://fun-lang.xyz/
*
* Copyright 2025 Johannes Findeisen <you@hanez.org>
* Licensed under the terms of the Apache-2.0 license.
* https://opensource.org/license/apache-2-0
*
* Added: 2026-01-03
*/
/* NC_GETCH */
case OP_NC_GETCH: {
Value to_ms_v = pop_value(vm);
int timeout_ms = (to_ms_v.type == VAL_INT ? (int)to_ms_v.i : (to_ms_v.type == VAL_FLOAT ? (int)to_ms_v.d : 0));
free_value(to_ms_v);
#ifdef FUN_WITH_NOTCURSES
if (_fun_nc) {
/* For simplicity, use blocking get for now when timeout<=0 */
if (timeout_ms <= 0) {
ncinput ni;
uint32_t id = notcurses_get_blocking(_fun_nc, &ni);
push_value(vm, make_int((int)id));
} else {
/* Polling approximation: render then nonblocking get once */
ncinput ni;
uint32_t id = notcurses_get_nblock(_fun_nc, &ni);
if (id == 0) {
/* no input available now: return -1 to indicate timeout */
push_value(vm, make_int(-1));
} else {
push_value(vm, make_int((int)id));
}
}
} else {
push_value(vm, make_int(-1));
}
#else
(void)_fun_nc; (void)_fun_nc_std; (void)timeout_ms;
push_value(vm, make_int(-1));
#endif
break;
}

27
src/vm/notcurses/init.c Normal file
View file

@ -0,0 +1,27 @@
/**
* This file is part of the Fun programming language.
* https://fun-lang.xyz/
*
* Copyright 2025 Johannes Findeisen <you@hanez.org>
* Licensed under the terms of the Apache-2.0 license.
* https://opensource.org/license/apache-2-0
*
* Added: 2026-01-03
*/
/* NC_INIT */
case OP_NC_INIT: {
#ifdef FUN_WITH_NOTCURSES
if (_fun_nc) { push_value(vm, make_int(1)); break; }
struct notcurses_options opts = {0};
_fun_nc = notcurses_core_init(&opts, NULL);
if (!_fun_nc) { push_value(vm, make_int(0)); break; }
_fun_nc_std = notcurses_stdplane(_fun_nc);
push_value(vm, make_int(1));
#else
(void)_fun_nc; (void)_fun_nc_std;
fprintf(stderr, "Notcurses support disabled at build time. Reconfigure with -DFUN_WITH_NOTCURSES=ON.\n");
push_value(vm, make_int(0));
#endif
break;
}

View file

@ -0,0 +1,25 @@
/**
* This file is part of the Fun programming language.
* https://fun-lang.xyz/
*
* Copyright 2025 Johannes Findeisen <you@hanez.org>
* Licensed under the terms of the Apache-2.0 license.
* https://opensource.org/license/apache-2-0
*
* Added: 2026-01-03
*/
/* NC_SHUTDOWN */
case OP_NC_SHUTDOWN: {
#ifdef FUN_WITH_NOTCURSES
if (_fun_nc) {
notcurses_stop(_fun_nc);
_fun_nc = NULL;
_fun_nc_std = NULL;
}
#else
(void)_fun_nc; (void)_fun_nc_std;
#endif
push_value(vm, make_int(0));
break;
}