aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHanspeter Portner <dev@open-music-kontrollers.ch>2021-03-03 23:06:34 +0100
committerHanspeter Portner <dev@open-music-kontrollers.ch>2021-03-03 23:06:34 +0100
commitcc13dac856e80208bdbf2b3bd641c13230d76b27 (patch)
treefc7e46af67c5156947968769124787c8130eafdd
parent5d37b14fc69e9073027066d8c30ed8edba14d757 (diff)
parent9ea55367360e28ba4273f248ed9056f07b0eaf78 (diff)
downloadsynthpod-cc13dac856e80208bdbf2b3bd641c13230d76b27.tar.xz
Merge commit '9ea55367360e28ba4273f248ed9056f07b0eaf78'
-rw-r--r--subprojects/d2tk/VERSION2
-rw-r--r--subprojects/d2tk/d2tk/base.h49
-rw-r--r--subprojects/d2tk/d2tk/config.h.in2
-rw-r--r--subprojects/d2tk/d2tk/util.h11
-rw-r--r--subprojects/d2tk/example/example.c119
-rwxr-xr-xsubprojects/d2tk/linenoise/example.c3
-rwxr-xr-xsubprojects/d2tk/linenoise/linenoise.c26
-rwxr-xr-xsubprojects/d2tk/linenoise/linenoise.h2
-rw-r--r--subprojects/d2tk/meson.build29
-rw-r--r--subprojects/d2tk/meson_options.txt4
-rw-r--r--subprojects/d2tk/src/base_internal.h5
-rw-r--r--subprojects/d2tk/src/base_lineedit.c239
-rw-r--r--subprojects/d2tk/src/base_pty.c286
-rw-r--r--subprojects/d2tk/src/core.c4
-rw-r--r--subprojects/d2tk/src/util_spawn.c31
15 files changed, 495 insertions, 317 deletions
diff --git a/subprojects/d2tk/VERSION b/subprojects/d2tk/VERSION
index 5617b801..0e3cfd94 100644
--- a/subprojects/d2tk/VERSION
+++ b/subprojects/d2tk/VERSION
@@ -1 +1 @@
-0.1.1215
+0.1.1241
diff --git a/subprojects/d2tk/d2tk/base.h b/subprojects/d2tk/d2tk/base.h
index da07debe..c37582c5 100644
--- a/subprojects/d2tk/d2tk/base.h
+++ b/subprojects/d2tk/d2tk/base.h
@@ -25,6 +25,7 @@
#include <d2tk/core.h>
#include <utf8.h/utf8.h>
+#include <linenoise.h>
#ifdef __cplusplus
extern "C" {
@@ -42,10 +43,16 @@ typedef struct _d2tk_flowmatrix_node_t d2tk_flowmatrix_node_t;
typedef struct _d2tk_flowmatrix_arc_t d2tk_flowmatrix_arc_t;
typedef struct _d2tk_pane_t d2tk_pane_t;
typedef struct _d2tk_pty_t d2tk_pty_t;
-typedef struct _d2tk_lineedit_t d2tk_lineedit_t;
typedef struct _d2tk_base_t d2tk_base_t;
+typedef struct _d2tk_lineedit_filter_t d2tk_lineedit_filter_t;
-typedef int (*d2tk_base_pty_cb_t)(void *data);
+typedef int (*d2tk_base_pty_cb_t)(void *data, int fd_in, int fd_out);
+
+struct _d2tk_lineedit_filter_t {
+ linenoiseCompletionCallback *completion_cb;
+ linenoiseHintsCallback *hints_cb;
+ linenoiseFreeHintsCallback *free_hints_cb;
+};
struct _d2tk_pos_t {
d2tk_coord_t x;
@@ -158,7 +165,8 @@ typedef enum _d2tk_flag_t {
D2TK_FLAG_INACTIVE = (1 << 10),
D2TK_FLAG_SEPARATOR_X = (1 << 11),
D2TK_FLAG_SEPARATOR_Y = (1 << 12),
- D2TK_FLAG_PTY_REINIT = (1 << 13)
+ D2TK_FLAG_PTY_REINIT = (1 << 13),
+ D2TK_FLAG_PTY_NOMOUSE = (1 << 14)
} d2tk_flag_t;
#define D2TK_ID_IDX(IDX) ( ((d2tk_id_t)__LINE__ << 16) | (IDX) )
@@ -176,7 +184,6 @@ extern const size_t d2tk_flowmatrix_node_sz;
extern const size_t d2tk_flowmatrix_arc_sz;
extern const size_t d2tk_pane_sz;
extern const size_t d2tk_pty_sz;
-extern const size_t d2tk_lineedit_sz;
D2TK_API d2tk_table_t *
d2tk_table_begin(const d2tk_rect_t *rect, unsigned N, unsigned M,
@@ -521,37 +528,13 @@ d2tk_pty_get_max_blue(d2tk_pty_t *pty);
d2tk_pty_not_end((PTY)); \
(PTY) = d2tk_pty_next((PTY)))
-D2TK_API d2tk_lineedit_t *
-d2tk_lineedit_begin(d2tk_base_t *base, d2tk_id_t id, const char *fill,
- d2tk_coord_t height, const d2tk_rect_t *rect, d2tk_flag_t flags,
- d2tk_lineedit_t *lineedit);
-
-D2TK_API bool
-d2tk_lineedit_not_end(d2tk_lineedit_t *lineedit);
-
-D2TK_API d2tk_lineedit_t *
-d2tk_lineedit_next(d2tk_lineedit_t *lineedit);
-
D2TK_API d2tk_state_t
-d2tk_lineedit_get_state(d2tk_lineedit_t *lineedit);
-
-D2TK_API const char *
-d2tk_lineedit_acquire_line(d2tk_lineedit_t *lineedit);
-
-D2TK_API void
-d2tk_lineedit_release_line(d2tk_lineedit_t *lineedit);
-
-D2TK_API char *
-d2tk_lineedit_acquire_fill(d2tk_lineedit_t *lineedit, size_t *fill_len);
-
-D2TK_API void
-d2tk_lineedit_release_fill(d2tk_lineedit_t *lineedit);
+d2tk_base_lineedit(d2tk_base_t *base, d2tk_id_t id, size_t line_len,
+ char *line, const d2tk_lineedit_filter_t *filter,
+ const d2tk_rect_t *rect, d2tk_flag_t flags);
-#define D2TK_BASE_LINEEDIT(BASE, ID, FILL, HEIGHT, RECT, FLAGS, LINEEDIT) \
- for(d2tk_lineedit_t *(LINEEDIT) = d2tk_lineedit_begin((BASE), (ID), (FILL), (HEIGHT), \
- (RECT), (FLAGS), alloca(d2tk_lineedit_sz)); \
- d2tk_lineedit_not_end((LINEEDIT)); \
- (LINEEDIT) = d2tk_lineedit_next((LINEEDIT)))
+#define d2tk_base_lineedit_is_changed(...) \
+ d2tk_state_is_changed(d2tk_base_lineedit(__VA_ARGS__))
#if D2TK_EVDEV
D2TK_API d2tk_state_t
diff --git a/subprojects/d2tk/d2tk/config.h.in b/subprojects/d2tk/d2tk/config.h.in
index 8d90c873..e8be9232 100644
--- a/subprojects/d2tk/d2tk/config.h.in
+++ b/subprojects/d2tk/d2tk/config.h.in
@@ -1,6 +1,4 @@
#define D2TK_EVDEV @D2TK_EVDEV@
#define D2TK_INPUT_1_15 @D2TK_INPUT_1_15@
#define D2TK_FONTCONFIG @D2TK_FONTCONFIG@
-#define D2TK_VFORK @D2TK_VFORK@
-#define D2TK_CLONE @D2TK_CLONE@
#define D2TK_DEBUG @D2TK_DEBUG@
diff --git a/subprojects/d2tk/d2tk/util.h b/subprojects/d2tk/d2tk/util.h
index 72fa2a75..f8eebf82 100644
--- a/subprojects/d2tk/d2tk/util.h
+++ b/subprojects/d2tk/d2tk/util.h
@@ -25,8 +25,19 @@ extern "C" {
#include "config.h"
#include <d2tk/d2tk.h>
+/****f* util/d2tk_util_spawn
+ * SYNOPSIS
+ */
D2TK_API int
d2tk_util_spawn(char **argv);
+/*
+ * FUNCTION
+ * If condition is false, makes a longjump back to wrapping function start.
+ * INPUTS
+ * - jit Pointer to opaque jit structure
+ * - condition Condition, whether to longjump or not
+ ****
+ */
D2TK_API int
d2tk_util_kill(int *kid);
diff --git a/subprojects/d2tk/example/example.c b/subprojects/d2tk/example/example.c
index 6041cb4c..9da7b3d7 100644
--- a/subprojects/d2tk/example/example.c
+++ b/subprojects/d2tk/example/example.c
@@ -54,6 +54,7 @@ typedef enum _bar_t {
BAR_UTF8,
BAR_CUSTOM,
BAR_COPYPASTE,
+ BAR_LINEEDIT,
BAR_PTY,
BAR_SPAWN,
#if !defined(_WIN32) && !defined(__APPLE__)
@@ -82,6 +83,7 @@ static const char *bar_lbl [BAR_MAX] = {
[BAR_CUSTOM] = "Custom",
[BAR_COPYPASTE] = "Copy&Paste",
[BAR_UTF8] = "UTF-8",
+ [BAR_LINEEDIT] = "Lineedit",
[BAR_PTY] = "PTY",
[BAR_SPAWN] = "Spawn",
#if !defined(_WIN32) && !defined(__APPLE__)
@@ -892,7 +894,7 @@ static inline void
_render_c_frame(d2tk_base_t *base, const d2tk_rect_t *rect)
{
#define N 4
- static bool val [N];
+ static bool val [N*N];
D2TK_BASE_TABLE(rect, N, N, D2TK_FLAG_TABLE_REL, tab)
{
@@ -1012,6 +1014,78 @@ _render_c_copypaste(d2tk_frontend_t *frontend, d2tk_base_t *base,
}
}
+static void
+_completion(const char *buf, linenoiseCompletions *lc)
+{
+ if(!strcasecmp(buf, ":"))
+ {
+ linenoiseAddCompletion(lc, ":author");
+ linenoiseAddCompletion(lc, ":class");
+ };
+}
+
+static char *
+_hints(const char *buf, int *color, int *bold)
+{
+ if(!strcasecmp(buf, ":"))
+ {
+ *color = 35;
+ *bold = 0;
+ return " search-category (author|class)";
+ }
+ else if(!strcasecmp(buf, ":author"))
+ {
+ *color = 35;
+ *bold = 0;
+ return " author-name";
+ }
+ else if(!strcasecmp(buf, ":class"))
+ {
+ *color = 35;
+ *bold = 0;
+ return " class-name";
+ }
+
+ return NULL;
+}
+
+static const d2tk_lineedit_filter_t filter = {
+ .completion_cb = _completion,
+ .hints_cb = _hints,
+ .free_hints_cb = NULL
+};
+
+static inline void
+_render_c_lineedit(d2tk_base_t *base, const d2tk_rect_t *rect)
+{
+ static char entry [16] [512] = {
+ "h0", "h1", "h2", "h3",
+ "h4", "h5", "h6", "h7",
+ "h8", "h9", "hA", "hB",
+ "hC", "hD", "hE", "hF"
+ };
+
+ static d2tk_coord_t vfrac [16] = {
+ 1, 1, 1, 1,
+ 1, 1, 1, 1,
+ 1, 1, 1, 1,
+ 1, 1, 1, 1
+ };
+
+ D2TK_BASE_LAYOUT(rect, 16, vfrac, D2TK_FLAG_LAYOUT_Y_REL, vlay)
+ {
+ const d2tk_rect_t *vrect = d2tk_layout_get_rect(vlay);
+ const d2tk_coord_t k = d2tk_layout_get_index(vlay);
+ const d2tk_id_t id = D2TK_ID_IDX(k);
+
+ if(d2tk_base_lineedit_is_changed(base, id, sizeof(entry), entry[k], &filter,
+ vrect, D2TK_FLAG_PTY_NOMOUSE))
+ {
+ fprintf(stderr, "line: %s\n", entry[k]);
+ }
+ }
+}
+
static inline void
_render_c_pty(d2tk_base_t *base, const d2tk_rect_t *rect)
{
@@ -1024,11 +1098,10 @@ _render_c_pty(d2tk_base_t *base, const d2tk_rect_t *rect)
static uint32_t last_red = 0x0;;
static uint32_t last_green = 0x0;;
static uint32_t last_blue = 0x0;;
- static char entry [512] = "fill";
- static d2tk_coord_t hfrac [3] = { 1, 1, 1 };
+ static d2tk_coord_t hfrac [2] = { 1, 1 };
- D2TK_BASE_LAYOUT(rect, 3, hfrac, D2TK_FLAG_LAYOUT_X_REL, hlay)
+ D2TK_BASE_LAYOUT(rect, 2, hfrac, D2TK_FLAG_LAYOUT_X_REL, hlay)
{
const d2tk_rect_t *hrect = d2tk_layout_get_rect(hlay);
const d2tk_coord_t x = d2tk_layout_get_index(hlay);
@@ -1037,7 +1110,8 @@ _render_c_pty(d2tk_base_t *base, const d2tk_rect_t *rect)
{
case 0:
{
- D2TK_BASE_PTY(base, D2TK_ID, NULL, argv, HEIGHT, hrect, D2TK_FLAG_NONE, pty)
+ D2TK_BASE_PTY(base, D2TK_ID, NULL, argv, HEIGHT, hrect,
+ D2TK_FLAG_PTY_NOMOUSE, pty)
{
const uint32_t max_red = d2tk_pty_get_max_red(pty);
const uint32_t max_green = d2tk_pty_get_max_green(pty);
@@ -1062,39 +1136,12 @@ _render_c_pty(d2tk_base_t *base, const d2tk_rect_t *rect)
} break;
case 1:
{
- D2TK_BASE_PTY(base, D2TK_ID, NULL, argv, HEIGHT, hrect, D2TK_FLAG_NONE, pty)
+ D2TK_BASE_PTY(base, D2TK_ID, NULL, argv, HEIGHT, hrect,
+ D2TK_FLAG_PTY_NOMOUSE, pty)
{
// nothing to do
}
} break;
- case 2:
- {
- D2TK_BASE_LINEEDIT(base, D2TK_ID, entry, HEIGHT, hrect, D2TK_FLAG_NONE, lineedit)
- {
- const d2tk_state_t state = d2tk_lineedit_get_state(lineedit);
-
- if(d2tk_state_is_enter(state))
- {
- const char *line;
- if( (line = d2tk_lineedit_acquire_line(lineedit)) )
- {
- fprintf(stderr, "line: %s\n", line);
- snprintf(entry, sizeof(entry), "%s", line);
-
- d2tk_lineedit_release_line(lineedit);
- }
-
- size_t fill_len = 0;
- char *fill = NULL;
- if( (fill = d2tk_lineedit_acquire_fill(lineedit, &fill_len)) )
- {
- snprintf(fill, fill_len, "%s", entry);
-
- d2tk_lineedit_release_fill(lineedit);
- }
- }
- }
- } break;
}
}
@@ -1475,6 +1522,10 @@ d2tk_example_run(d2tk_frontend_t *frontend, d2tk_base_t *base,
{
_render_c_copypaste(frontend, base, vrect);
} break;
+ case BAR_LINEEDIT:
+ {
+ _render_c_lineedit(base, vrect);
+ } break;
case BAR_PTY:
{
_render_c_pty(base, vrect);
diff --git a/subprojects/d2tk/linenoise/example.c b/subprojects/d2tk/linenoise/example.c
index 0ba43aec..adbf1bd7 100755
--- a/subprojects/d2tk/linenoise/example.c
+++ b/subprojects/d2tk/linenoise/example.c
@@ -1,6 +1,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <unistd.h>
#include "linenoise.h"
#define UTF8
@@ -40,7 +41,7 @@ int main(int argc, char **argv) {
char *line;
char *prgname = argv[0];
- linenoiseApp *app = linenoiseAppNew();
+ linenoiseApp *app = linenoiseAppNew(STDIN_FILENO, STDOUT_FILENO);
if(!app)
{
diff --git a/subprojects/d2tk/linenoise/linenoise.c b/subprojects/d2tk/linenoise/linenoise.c
index e32d9f28..e7d8b16d 100755
--- a/subprojects/d2tk/linenoise/linenoise.c
+++ b/subprojects/d2tk/linenoise/linenoise.c
@@ -141,6 +141,9 @@ struct _linenoiseApp {
int history_max_len;
int history_len;
char **history;
+
+ int fd_in;
+ int fd_out;
};
/* The linenoiseState structure represents the state during line editing.
@@ -321,7 +324,7 @@ static int isUnsupportedTerm(void) {
static int enableRawMode(linenoiseApp *app, int fd) {
struct termios raw;
- if (!isatty(STDIN_FILENO)) goto fatal;
+ if (!isatty(app->fd_in)) goto fatal;
if (tcgetattr(fd,&app->orig_termios) == -1) goto fatal;
raw = app->orig_termios; /* modify the original mode */
@@ -417,7 +420,7 @@ failed:
/* Clear the screen. Used to handle ctrl+l */
void linenoiseClearScreen(linenoiseApp *app __attribute__((unused))) {
- if (write(STDOUT_FILENO,"\x1b[H\x1b[2J",7) <= 0) {
+ if (write(app->fd_out,"\x1b[H\x1b[2J",7) <= 0) {
/* nothing to do, just to avoid warning. */
}
}
@@ -1128,13 +1131,13 @@ void linenoisePrintKeyCodes(linenoiseApp *app) {
printf("Linenoise key codes debugging mode.\n"
"Press keys to see scan codes. Type 'quit' at any time to exit.\n");
- if (enableRawMode(app, STDIN_FILENO) == -1) return;
+ if (enableRawMode(app, app->fd_in) == -1) return;
memset(quit,' ',4);
while(1) {
char c;
int nread;
- nread = read(STDIN_FILENO,&c,1);
+ nread = read(app->fd_in,&c,1);
if (nread <= 0) continue;
memmove(quit,quit+1,sizeof(quit)-1); /* shift string to left. */
quit[sizeof(quit)-1] = c; /* Insert current char on the right. */
@@ -1145,7 +1148,7 @@ void linenoisePrintKeyCodes(linenoiseApp *app) {
printf("\r"); /* Go left edge manually, we are in raw mode. */
fflush(stdout);
}
- disableRawMode(app, STDIN_FILENO);
+ disableRawMode(app, app->fd_in);
}
/* This function calls the line editing function linenoiseEdit() using
@@ -1158,9 +1161,9 @@ static int linenoiseRaw(linenoiseApp *app, char *buf, size_t buflen, const char
return -1;
}
- if (enableRawMode(app, STDIN_FILENO) == -1) return -1;
- count = linenoiseEdit(app, STDIN_FILENO, STDOUT_FILENO, buf, buflen, prompt);
- disableRawMode(app, STDIN_FILENO);
+ if (enableRawMode(app, app->fd_in) == -1) return -1;
+ count = linenoiseEdit(app, app->fd_in, app->fd_out, buf, buflen, prompt);
+ disableRawMode(app, app->fd_in);
printf("\n");
return count;
}
@@ -1210,7 +1213,7 @@ char *linenoise(linenoiseApp *app, const char *prompt) {
char buf[LINENOISE_MAX_LINE];
int count;
- if (!isatty(STDIN_FILENO)) {
+ if (!isatty(app->fd_in)) {
/* Not a tty: read from file / pipe. In this mode we don't want any
* limit to the line size, so we call a function to handle that. */
return linenoiseNoTTY();
@@ -1364,7 +1367,7 @@ int linenoiseHistoryLoad(linenoiseApp *app, const char *filename) {
}
linenoiseApp *
-linenoiseAppNew()
+linenoiseAppNew(int fd_in, int fd_out)
{
linenoiseApp *app = calloc(1, sizeof(linenoiseApp));
@@ -1380,6 +1383,9 @@ linenoiseAppNew()
app->nextCharLen = defaultNextCharLen;
app->readCode = defaultReadCode;
+ app->fd_in = fd_in;
+ app->fd_out = fd_out;
+
return app;
}
diff --git a/subprojects/d2tk/linenoise/linenoise.h b/subprojects/d2tk/linenoise/linenoise.h
index 0558e2a9..643ba10f 100755
--- a/subprojects/d2tk/linenoise/linenoise.h
+++ b/subprojects/d2tk/linenoise/linenoise.h
@@ -45,7 +45,7 @@ extern "C" {
typedef struct _linenoiseApp linenoiseApp;
-linenoiseApp *linenoiseAppNew();
+linenoiseApp *linenoiseAppNew(int fd_in, int fd_out);
void linenoiseAppFree(linenoiseApp *app);
typedef struct linenoiseCompletions {
diff --git a/subprojects/d2tk/meson.build b/subprojects/d2tk/meson.build
index 038a47e7..58a2d69c 100644
--- a/subprojects/d2tk/meson.build
+++ b/subprojects/d2tk/meson.build
@@ -10,6 +10,7 @@ static_link = false #meson.is_cross_build()
build_debug_overlay = get_option('build-debug-overlay')
build_examples = get_option('build-examples')
build_tests = get_option('build-tests')
+build_doc = get_option('build-doc')
use_backend_cairo = get_option('use-backend-cairo')
use_backend_nanovg = get_option('use-backend-nanovg')
@@ -29,11 +30,15 @@ fc_list = find_program('fc-list',
check_for_font = find_program('check_for_font',
native : true,
required : use_fontconfig)
+robodoc = find_program('robodoc',
+ native : true,
+ required : build_doc)
cc = meson.get_compiler('c')
# mandatory dependencies
m_dep = cc.find_library('m')
+thread_dep = dependency('threads')
# dependencies for backend_cairo/frontend_pugl
freetype_dep = dependency('freetype2',
@@ -101,7 +106,7 @@ fontconfig_dep = dependency('fontconfig',
static : static_link,
required : use_fontconfig)
-deps = [m_dep, evdev_dep, util_dep, vterm_dep, fontconfig_dep]
+deps = [m_dep, thread_dep, evdev_dep, util_dep, vterm_dep, fontconfig_dep]
links = []
pugl_inc = include_directories(join_paths('pugl', 'include'))
@@ -177,18 +182,6 @@ else
conf_data.set('D2TK_FONTCONFIG', 0)
endif
-if cc.has_function('vfork')
- conf_data.set('D2TK_VFORK', 1)
-else
- conf_data.set('D2TK_VFORK', 0)
-endif
-
-if cc.has_function('clone')
- conf_data.set('D2TK_CLONE', 1)
-else
- conf_data.set('D2TK_CLONE', 0)
-endif
-
example_srcs = [
join_paths('example', 'example.c')
]
@@ -428,3 +421,13 @@ if build_tests
test('FiraCode-Bold.ttf', check_for_font, args : ['FiraCode-Bold.ttf'])
endif
endif
+
+if build_doc
+ run_command('rm', '-rf', 'doc')
+
+ run_command(robodoc,
+ '--src', './d2tk',
+ '--doc', 'doc',
+ '--multidoc', '--troff', '--nosort', '--nodesc', '--cmode',
+ '--compress', 'gzip')
+endif
diff --git a/subprojects/d2tk/meson_options.txt b/subprojects/d2tk/meson_options.txt
index 00192a77..242cbe03 100644
--- a/subprojects/d2tk/meson_options.txt
+++ b/subprojects/d2tk/meson_options.txt
@@ -10,6 +10,10 @@ option('build-tests',
type : 'boolean',
value : true,
yield : true)
+option('build-doc',
+ type : 'boolean',
+ value : false,
+ yield : true)
option('use-backend-cairo',
type : 'feature',
diff --git a/subprojects/d2tk/src/base_internal.h b/subprojects/d2tk/src/base_internal.h
index 46637402..0ece0bf7 100644
--- a/subprojects/d2tk/src/base_internal.h
+++ b/subprojects/d2tk/src/base_internal.h
@@ -144,3 +144,8 @@ _d2tk_base_clear_chars(d2tk_base_t *base);
d2tk_state_t
_d2tk_base_tooltip_draw(d2tk_base_t *base, ssize_t lbl_len, const char *lbl,
d2tk_coord_t h);
+
+d2tk_pty_t *
+d2tk_pty_begin_state(d2tk_base_t *base, d2tk_id_t id, d2tk_state_t state,
+ d2tk_base_pty_cb_t cb, void *data, d2tk_coord_t height,
+ const d2tk_rect_t *rect, d2tk_flag_t flags, d2tk_pty_t *pty);
diff --git a/subprojects/d2tk/src/base_lineedit.c b/subprojects/d2tk/src/base_lineedit.c
index 182cfafe..dc741a44 100644
--- a/subprojects/d2tk/src/base_lineedit.c
+++ b/subprojects/d2tk/src/base_lineedit.c
@@ -19,82 +19,57 @@
#include "base_internal.h"
-#include <linenoise.h>
#include <encodings/utf8.h>
+#define FONT_CODE_REGULAR "FiraCode:regular"
+
typedef struct _d2tk_atom_body_lineedit_t d2tk_atom_body_lineedit_t;
-typedef struct _d2tk_lineedit_t d2tk_lineedit_t;
struct _d2tk_atom_body_lineedit_t {
- atomic_flag lock;
- char fill [512];
- char line [512];
-};
-
-struct _d2tk_lineedit_t {
- d2tk_state_t state;
- d2tk_atom_body_lineedit_t *body;
+ atomic_uintptr_t filter;
+ atomic_uintptr_t line;
+ atomic_uintptr_t fill;
};
const size_t d2tk_atom_body_lineedit_sz = sizeof(d2tk_atom_body_lineedit_t);
-const size_t d2tk_lineedit_sz = sizeof(d2tk_lineedit_t);
-
-static void
-_completion(const char *buf, linenoiseCompletions *lc)
-{
- if(!strcasecmp(buf, ":"))
- {
- linenoiseAddCompletion(lc, ":author");
- linenoiseAddCompletion(lc, ":class");
- };
-}
static char *
-_hints(const char *buf, int *color, int *bold)
+_atomic_get(atomic_uintptr_t *ptr)
{
- if(!strcasecmp(buf, ":"))
- {
- *color = 35;
- *bold = 0;
- return " search-category (author|class)";
- }
- else if(!strcasecmp(buf, ":author"))
- {
- *color = 35;
- *bold = 0;
- return " author-name";
- }
- else if(!strcasecmp(buf, ":class"))
- {
- *color = 35;
- *bold = 0;
- return " class-name";
- }
+ uintptr_t desired = 0;
+ char *old = (char *)atomic_exchange(ptr, desired);
- return NULL;
+ return old;
}
static void
-_body_lock(d2tk_atom_body_lineedit_t *body)
+_atomic_set(atomic_uintptr_t *ptr, const char *new)
{
- while(atomic_flag_test_and_set(&body->lock))
- {}
+ uintptr_t desired = new
+ ? (uintptr_t)strdup(new)
+ : 0;
+ char *old = (char *)atomic_exchange(ptr, desired);
+
+ if(old)
+ {
+ free(old);
+ }
}
static void
-_body_unlock(d2tk_atom_body_lineedit_t *body)
+_atomic_clr(atomic_uintptr_t *ptr)
{
- atomic_flag_clear(&body->lock);
+ _atomic_set(ptr, 0);
}
static int
-_entry(void *data)
+_entry(void *data, int file_in, int file_out)
{
- static const char *prompt = "> ";
+ static const char *prompt = "◆";
d2tk_atom_body_lineedit_t *body = data;
- char fill [512] = "";
+ char entry [2048] = "";
- linenoiseApp *app = linenoiseAppNew();
+ linenoiseApp *app = linenoiseAppNew(file_in, file_out);
if(!app)
{
return 1;
@@ -102,27 +77,42 @@ _entry(void *data)
linenoiseSetMultiLine(app, 0);
linenoiseHistorySetMaxLen(app, 32);
- linenoiseSetFill(app, fill);
+ linenoiseSetFill(app, entry);
+
+ d2tk_lineedit_filter_t *filter = (d2tk_lineedit_filter_t *)atomic_load(&body->filter);
+ if(filter)
+ {
+ if(filter->completion_cb)
+ {
+ linenoiseSetCompletionCallback(app, filter->completion_cb);
+ }
+
+ if(filter->hints_cb)
+ {
+ linenoiseSetHintsCallback(app, filter->hints_cb);
+ }
+
+ if(filter->free_hints_cb)
+ {
+ linenoiseSetFreeHintsCallback(app, filter->free_hints_cb);
+ }
+ }
- linenoiseSetCompletionCallback(app, _completion);
- linenoiseSetHintsCallback(app, _hints);
linenoiseSetEncodingFunctions(app, linenoiseUtf8PrevCharLen,
linenoiseUtf8NextCharLen, linenoiseUtf8ReadCode);
- _body_lock(body);
- snprintf(fill, sizeof(fill), "%s", body->fill);
- _body_unlock(body);
+ char *fill = _atomic_get(&body->fill);
+ if(fill)
+ {
+ snprintf(entry, sizeof(entry), "%s", fill);
+ free(fill);
+ }
char *line;
while( (line= linenoise(app, prompt)) )
{
- _body_lock(body);
- snprintf(body->line, sizeof(body->line), "%s", line);
- _body_unlock(body);
-
- _body_lock(body);
- snprintf(fill, sizeof(fill), "%s", body->fill);
- _body_unlock(body);
+ _atomic_set(&body->line, line);
+ snprintf(entry, sizeof(entry), "%s", line);
linenoiseHistoryAdd(app, line);
linenoiseFree(app, line);
@@ -134,80 +124,87 @@ _entry(void *data)
return 0;
}
-D2TK_API d2tk_lineedit_t *
-d2tk_lineedit_begin(d2tk_base_t *base, d2tk_id_t id, const char *fill,
- d2tk_coord_t height, const d2tk_rect_t *rect, d2tk_flag_t flags,
- d2tk_lineedit_t *lineedit)
+static int
+_lineedit_event(d2tk_atom_event_type_t event, void *data)
{
- memset(lineedit, 0x0, sizeof(d2tk_lineedit_t));
-
- lineedit->body = _d2tk_base_get_atom(base, id, D2TK_ATOM_LINEEDIT,
- NULL);
+ d2tk_atom_body_lineedit_t *body = data;
- if(fill)
+ switch(event)
{
- _body_lock(lineedit->body);
- snprintf(lineedit->body->fill, sizeof(lineedit->body->fill), "%s", fill);
- _body_unlock(lineedit->body);
+ case D2TK_ATOM_EVENT_DEINIT:
+ {
+ _atomic_clr(&body->line);
+ _atomic_clr(&body->fill);
+ } break;
+
+ case D2TK_ATOM_EVENT_FD:
+ // fall-through
+ case D2TK_ATOM_EVENT_NONE:
+ // fall-through
+ default:
+ {
+ // nothing to do
+ } break;
}
- const d2tk_id_t subid = (1ULL << 32) | id;
-
- d2tk_pty_t *pty = d2tk_pty_begin(base, subid, _entry, lineedit->body, height, rect,
- flags, alloca(d2tk_pty_sz));
-
- lineedit->state = d2tk_pty_get_state(pty);
-
- return lineedit;
+ return 0;
}
-D2TK_API bool
-d2tk_lineedit_not_end(d2tk_lineedit_t *lineedit)
+D2TK_API d2tk_state_t
+d2tk_base_lineedit(d2tk_base_t *base, d2tk_id_t id, size_t line_len,
+ char *line, const d2tk_lineedit_filter_t *filter,
+ const d2tk_rect_t *rect, d2tk_flag_t flags)
{
- return lineedit ? true : false;
-}
+ static const float mul = 0.5f;
-D2TK_API d2tk_lineedit_t *
-d2tk_lineedit_next(d2tk_lineedit_t *lineedit __attribute__((unused)))
-{
- return NULL;
-}
+ const d2tk_id_t subid = (1ULL << 32) | id;
+ d2tk_atom_body_lineedit_t *body = _d2tk_base_get_atom(base, subid,
+ D2TK_ATOM_LINEEDIT, _lineedit_event);
-D2TK_API d2tk_state_t
-d2tk_lineedit_get_state(d2tk_lineedit_t *lineedit)
-{
- return lineedit->state;
-}
+ atomic_store(&body->filter, (uintptr_t)filter);
+ _atomic_set(&body->fill, line);
+
+ d2tk_state_t state = d2tk_base_is_active_hot(base, id, rect, D2TK_FLAG_NONE);
-D2TK_API const char *
-d2tk_lineedit_acquire_line(d2tk_lineedit_t *lineedit)
-{
- _body_lock(lineedit->body);
+ if(d2tk_state_is_focused(state))
+ {
+ const d2tk_coord_t dh = rect->h * mul / 2;
- return lineedit->body->line;
-}
+ d2tk_rect_t bnd;
+ d2tk_rect_shrink_y(&bnd, rect, dh);
-D2TK_API void
-d2tk_lineedit_release_line(d2tk_lineedit_t *lineedit)
-{
- _body_unlock(lineedit->body);
-}
+ d2tk_pty_t *pty = d2tk_pty_begin_state(base, id, state, _entry, body,
+ bnd.h, &bnd, flags, alloca(d2tk_pty_sz));
-D2TK_API char *
-d2tk_lineedit_acquire_fill(d2tk_lineedit_t *lineedit, size_t *fill_len)
-{
- _body_lock(lineedit->body);
+ state = d2tk_pty_get_state(pty);
- if(fill_len)
- {
- *fill_len = sizeof(lineedit->body->fill);
+ char *old = _atomic_get(&body->line);
+ if(old)
+ {
+ if(line)
+ {
+ snprintf(line, line_len, "%s", old);
+ state |= D2TK_STATE_CHANGED;
+ }
+
+ free(old);
+ }
}
+ else
+ {
+ const d2tk_style_t *old_style = d2tk_base_get_style(base);
+ d2tk_style_t style = *old_style;
+ style.font_face = FONT_CODE_REGULAR;
+ d2tk_base_set_style(base, &style);
- return lineedit->body->fill;
-}
+ char lbl [512];
+ const size_t lbl_len = snprintf(lbl, sizeof(lbl), "◇%s", line);
-D2TK_API void
-d2tk_lineedit_release_fill(d2tk_lineedit_t *lineedit)
-{
- _body_unlock(lineedit->body);
+ state = d2tk_base_label(base, lbl_len, lbl, mul, rect,
+ D2TK_ALIGN_MIDDLE | D2TK_ALIGN_LEFT);
+
+ d2tk_base_set_style(base, old_style);
+ }
+
+ return state;
}
diff --git a/subprojects/d2tk/src/base_pty.c b/subprojects/d2tk/src/base_pty.c
index adfb9e4f..6267ed47 100644
--- a/subprojects/d2tk/src/base_pty.c
+++ b/subprojects/d2tk/src/base_pty.c
@@ -27,6 +27,8 @@
#include <limits.h>
#include <sys/wait.h>
#include <sys/mman.h>
+#include <pthread.h>
+#include <stdatomic.h>
#include "base_internal.h"
@@ -50,6 +52,8 @@ typedef struct _col_t col_t;
typedef struct _cell_t cell_t;
typedef struct _d2tk_atom_body_pty_t d2tk_atom_body_pty_t;
typedef struct _d2tk_pty_t d2tk_pty_t;
+typedef struct _thread_data_t thread_data_t;
+typedef struct _clone_data_t clone_data_t;
struct _col_t {
uint8_t r;
@@ -68,6 +72,19 @@ struct _cell_t {
uint32_t bg;
};
+struct _thread_data_t {
+ int slave;
+ d2tk_base_pty_cb_t cb;
+ void *data;
+ atomic_bool running;
+};
+
+struct _clone_data_t {
+ int master;
+ int slave;
+ void *data;
+};
+
struct _d2tk_atom_body_pty_t {
d2tk_coord_t height;
@@ -78,6 +95,9 @@ struct _d2tk_atom_body_pty_t {
int fd;
pid_t kid;
+ thread_data_t thread_data;
+ bool is_threaded;
+
VTerm *vterm;
VTermScreen *screen;
VTermState *state;
@@ -147,16 +167,36 @@ _term_read(d2tk_atom_body_pty_t *vpty,
return count;
}
+static inline void
+_term_clear(d2tk_atom_body_pty_t *vpty)
+{
+ vpty->kid = 0;
+ atomic_store(&vpty->thread_data.running, false);;
+}
+
static inline int
-_term_done(d2tk_atom_body_pty_t *vpty)
+_term_done_thread(d2tk_atom_body_pty_t *vpty)
{
- if(vpty->kid == 0)
+ if(atomic_load(&vpty->thread_data.running))
{
- return 1;
+ return 0;
}
+ pthread_join(vpty->kid, NULL);
+
+ _term_clear(vpty);
+ return 1;
+}
+
+static inline int
+_term_done_fork(d2tk_atom_body_pty_t *vpty)
+{
int stat = 0;
const int kid = waitpid(vpty->kid, NULL, WNOHANG);
+#if D2TK_DEBUG == 1
+ fprintf(stderr, "[%s] waitpid of child with pid %d: %d (%d)\n",
+ __func__, vpty->kid, kid, stat);
+#endif
if(kid == -1)
{
@@ -171,19 +211,36 @@ _term_done(d2tk_atom_body_pty_t *vpty)
// has exited
if(WIFSIGNALED(stat))
{
+#if D2TK_DEBUG == 1
fprintf(stderr, "[%s] child with pid %d has exited with signal %d\n",
__func__, vpty->kid, WTERMSIG(stat));
+#endif
}
else if(WIFEXITED(stat))
{
+#if D2TK_DEBUG == 1
fprintf(stderr, "[%s] child with pid %d has exited with status %d\n",
__func__, vpty->kid, WEXITSTATUS(stat));
+#endif
}
- vpty->kid = 0;
+ _term_clear(vpty);
return 1;
}
+static inline int
+_term_done(d2tk_atom_body_pty_t *vpty)
+{
+ if(vpty->kid == 0)
+ {
+ return 1;
+ }
+
+ return vpty->is_threaded
+ ? _term_done_thread(vpty)
+ : _term_done_fork(vpty);
+}
+
static void
_term_output(const char *buf, size_t len, void *data)
{
@@ -268,15 +325,6 @@ static const VTermScreenCallbacks screen_callbacks = {
.resize = _screen_resize
};
-typedef struct _clone_data_t clone_data_t;
-
-struct _clone_data_t {
- int master;
- int slave;
- d2tk_base_pty_cb_t cb;
- void *data;
-};
-
static int
_clone(void *data)
{
@@ -296,26 +344,34 @@ _clone(void *data)
signal(SIGSTOP, SIG_DFL);
signal(SIGCONT, SIG_DFL);
- if(clone_data->cb)
+ char **argv = (char **)clone_data->data;
+
+ /* clone environment */
+ unsigned envc = 0;
+ for(char **env = environ; *env; env++)
{
- return clone_data->cb(clone_data->data);
+ envc++;
}
- char **argv = (char **)clone_data->data;
+ const size_t envs = envc + 2; // TERM + sentinel
+ char **envp = alloca(envs*sizeof(char *));
- char envh [PATH_MAX];
- char envu [PATH_MAX];
- char *home = getenv("HOME");
- char *user = getenv("USER");
- snprintf(envh, sizeof(envh), "HOME=%s", home ? home : "");
- snprintf(envu, sizeof(envu), "USER=%s", user ? user : "");
-
- char *envp [] = {
- "TERM=xterm-256color",
- envh,
- envu,
- NULL
- };
+ envc = 0;
+ for(char **env = environ; *env; env++)
+ {
+ if(strstr(*env, "TERM=") == *env)
+ {
+ /* ignore parent TERM */
+ }
+ else
+ {
+ envp[envc++] = *env;
+ }
+ }
+
+ /* add child TERM and sentinel */
+ envp[envc++] = "TERM=xterm-256color";
+ envp[envc] = NULL;
execvpe(argv[0], argv, envp);
_exit(EXIT_FAILURE);
@@ -323,46 +379,68 @@ _clone(void *data)
return 0;
}
+static void *
+_thread(void *data)
+{
+ thread_data_t *thread_data = data;
+
+ thread_data->cb(thread_data->data, thread_data->slave, thread_data->slave);
+
+ atomic_store(&thread_data->running, false);
+
+ close(thread_data->slave);
+
+ return NULL;
+}
+
static int
-_forkpty(int *amaster, char *name, const struct termios *termp,
- const struct winsize *winp, d2tk_base_pty_cb_t cb, void *data)
+_threadpty(int *amaster, const struct termios *termp, const struct winsize *winp,
+ d2tk_base_pty_cb_t cb, void *data, thread_data_t *thread_data)
{
- clone_data_t clone_data = {
- .master = 0,
- .slave = 0,
- .cb = cb,
- .data = data
- };
-
- if(openpty(&clone_data.master, &clone_data.slave, name, termp, winp) == -1)
+ pthread_t thread = 0;
+ int thread_data_master = 0;
+
+ thread_data->slave = 0,
+ thread_data->cb = cb,
+ thread_data->data = data,
+ atomic_store(&thread_data->running, false);
+
+ if(openpty(&thread_data_master, &thread_data->slave, NULL, termp, winp) == -1)
{
- return -1;
+ return -1;
}
-#if D2TK_CLONE == 1
-# define STACK_SIZE (1024 * 1024)
- uint8_t *stack = mmap(NULL, STACK_SIZE, PROT_READ | PROT_WRITE,
- MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, -1, 0);
- if(stack == MAP_FAILED)
+ atomic_store(&thread_data->running, true);
+
+ if(pthread_create(&thread, NULL, _thread, thread_data) != 0)
{
- close(clone_data.master);
- close(clone_data.slave);
+ close(thread_data_master);
+ close(thread_data->slave);
+ atomic_store(&thread_data->running, false);
return -1;
}
- uint8_t *stack_top = stack + STACK_SIZE;
- int flags = CLONE_FS | CLONE_IO | CLONE_VM | SIGCHLD;
- if(cb == NULL)
+ *amaster = thread_data_master;
+
+ return thread;
+}
+
+static int
+_forkpty(int *amaster, const struct termios *termp, const struct winsize *winp,
+ void *data)
+{
+ clone_data_t clone_data = {
+ .master = 0,
+ .slave = 0,
+ .data = data
+ };
+
+ if(openpty(&clone_data.master, &clone_data.slave, NULL, termp, winp) == -1)
{
- flags |= CLONE_VFORK;
+ return -1;
}
- const int pid = clone(_clone, stack_top, flags, &clone_data);
-# undef STACK_SIZE
-#elif D2TK_VFORK == 1
+
const int pid = vfork();
-#else
-# error "support for clone or vfork required"
-#endif
switch(pid)
{
@@ -372,12 +450,10 @@ _forkpty(int *amaster, char *name, const struct termios *termp,
close(clone_data.slave);
} return -1;
-#if D2TK_CLONE == 0
case 0: //child
{
// everything is done in _clone
} return _clone(&clone_data);
-#endif
default: // parent
{
@@ -391,6 +467,7 @@ static int
_term_init(d2tk_atom_body_pty_t *vpty, d2tk_base_pty_cb_t cb, void *data,
d2tk_coord_t height, d2tk_coord_t ncols, d2tk_coord_t nrows)
{
+ vpty->is_threaded = cb ? true : false;
vpty->height = height;
vpty->nrows = nrows;
vpty->ncols = ncols;
@@ -457,14 +534,19 @@ _term_init(d2tk_atom_body_pty_t *vpty, d2tk_base_pty_cb_t cb, void *data,
.ws_ypixel = 0
};
- vpty->kid = _forkpty(&vpty->fd, NULL, &termios, &winsize, cb, data);
+ vpty->kid =vpty->is_threaded
+ ? _threadpty(&vpty->fd, &termios, &winsize, cb, data, &vpty->thread_data)
+ : _forkpty(&vpty->fd, &termios, &winsize, data);
+
if(vpty->kid == -1)
{
- vpty->kid = 0;
+ _term_clear(vpty);
return 1;
}
+#if D2TK_DEBUG == 1
fprintf(stderr, "[%s] child with pid %i has spawned\n", __func__, vpty->kid);
+#endif
fcntl(vpty->fd, F_SETFL, fcntl(vpty->fd, F_GETFL) | O_NONBLOCK);
@@ -488,24 +570,31 @@ _term_fd(d2tk_atom_body_pty_t *vpty)
}
static int
-_term_deinit(d2tk_atom_body_pty_t *vpty)
+_term_deinit_thread(d2tk_atom_body_pty_t *vpty)
{
- if(!vpty)
+ if(vpty->kid != 0)
{
- return 1;
- }
+ // send CTRL-C
+ vterm_keyboard_unichar(vpty->vterm, 0x3, VTERM_MOD_NONE);
- if(vpty->fd)
- {
- close(vpty->fd);
+ pthread_join(vpty->kid, NULL);
- vpty->fd = 0;
+ _term_clear(vpty);
}
+ return 0;
+}
+
+static int
+_term_deinit_fork(d2tk_atom_body_pty_t *vpty)
+{
if(vpty->kid != 0)
{
while(true)
{
+ // send CTRL-C
+ vterm_keyboard_unichar(vpty->vterm, 0x3, VTERM_MOD_NONE);
+
usleep(1000);;
kill(vpty->kid, SIGINT);
@@ -530,20 +619,46 @@ _term_deinit(d2tk_atom_body_pty_t *vpty)
// has exited
if(WIFSIGNALED(stat))
{
+#if D2TK_DEBUG == 1
fprintf(stderr, "[%s] child with pid %d has exited with signal %d\n",
__func__, vpty->kid, WTERMSIG(stat));
+#endif
}
else if(WIFEXITED(stat))
{
+#if D2TK_DEBUG == 1
fprintf(stderr, "[%s] child with pid %d has exited with status %d\n",
__func__, vpty->kid, WEXITSTATUS(stat));
+#endif
}
- vpty->kid = 0;
+ _term_clear(vpty);
break;
}
}
+ return 0;
+}
+
+static int
+_term_deinit(d2tk_atom_body_pty_t *vpty)
+{
+ if(!vpty)
+ {
+ return 1;
+ }
+
+ const int ret = vpty->is_threaded
+ ? _term_deinit_thread(vpty)
+ : _term_deinit_fork(vpty);
+
+ if(vpty->fd)
+ {
+ close(vpty->fd);
+
+ vpty->fd = 0;
+ }
+
if(vpty->vterm)
{
vterm_free(vpty->vterm);
@@ -551,7 +666,7 @@ _term_deinit(d2tk_atom_body_pty_t *vpty)
memset(vpty, 0x0, sizeof(d2tk_atom_body_pty_t));
- return 0;
+ return ret;
}
static int
@@ -816,11 +931,8 @@ _term_input(d2tk_atom_body_pty_t *vpty)
static inline d2tk_state_t
_term_behave(d2tk_base_t *base, d2tk_atom_body_pty_t *vpty,
- d2tk_id_t id, const d2tk_rect_t *rect)
+ d2tk_state_t state, d2tk_flag_t flags, const d2tk_rect_t *rect)
{
- const d2tk_state_t state = d2tk_base_is_active_hot(base, id, rect,
- D2TK_FLAG_NONE);
-
VTermModifier mod = VTERM_MOD_NONE;
if(d2tk_state_is_focused(state))
@@ -903,6 +1015,11 @@ _term_behave(d2tk_base_t *base, d2tk_atom_body_pty_t *vpty,
vterm_state_focus_out(vpty->state);
}
+ if(flags & D2TK_FLAG_PTY_NOMOUSE)
+ {
+ return state;
+ }
+
if(d2tk_state_is_hot(state))
{
d2tk_coord_t mx, my;
@@ -1031,9 +1148,10 @@ _term_draw(d2tk_base_t *base, d2tk_atom_body_pty_t *vpty,
}
}
-D2TK_API d2tk_pty_t *
-d2tk_pty_begin(d2tk_base_t *base, d2tk_id_t id, d2tk_base_pty_cb_t cb, void *data,
- d2tk_coord_t height, const d2tk_rect_t *rect, d2tk_flag_t flags, d2tk_pty_t *pty)
+d2tk_pty_t *
+d2tk_pty_begin_state(d2tk_base_t *base, d2tk_id_t id, d2tk_state_t state,
+ d2tk_base_pty_cb_t cb, void *data, d2tk_coord_t height,
+ const d2tk_rect_t *rect, d2tk_flag_t flags, d2tk_pty_t *pty)
{
memset(pty, 0x0, sizeof(d2tk_pty_t));
@@ -1076,7 +1194,7 @@ d2tk_pty_begin(d2tk_base_t *base, d2tk_id_t id, d2tk_base_pty_cb_t cb, void *dat
_term_resize(vpty, ncols, nrows);
- pty->state = _term_behave(base, vpty, id, rect);
+ pty->state = _term_behave(base, vpty, state, flags, rect);
_term_input(vpty);
@@ -1101,6 +1219,16 @@ d2tk_pty_begin(d2tk_base_t *base, d2tk_id_t id, d2tk_base_pty_cb_t cb, void *dat
return pty;
}
+D2TK_API d2tk_pty_t *
+d2tk_pty_begin(d2tk_base_t *base, d2tk_id_t id, d2tk_base_pty_cb_t cb, void *data,
+ d2tk_coord_t height, const d2tk_rect_t *rect, d2tk_flag_t flags, d2tk_pty_t *pty)
+{
+ const d2tk_state_t state = d2tk_base_is_active_hot(base, id, rect,
+ D2TK_FLAG_NONE);
+
+ return d2tk_pty_begin_state(base, id, state, cb, data, height, rect, flags, pty);
+}
+
D2TK_API bool
d2tk_pty_not_end(d2tk_pty_t *pty)
{
diff --git a/subprojects/d2tk/src/core.c b/subprojects/d2tk/src/core.c
index 3e9ee4be..5383776e 100644
--- a/subprojects/d2tk/src/core.c
+++ b/subprojects/d2tk/src/core.c
@@ -1049,8 +1049,8 @@ d2tk_core_bbox_pop(d2tk_core_t *core, ssize_t ref)
com->size = len - sizeof(d2tk_com_t);
// hash over instructions exclusive position
- com->body->bbox.hash = d2tk_hash(&com->body->bbox.clip.w,
- len - offsetof(d2tk_clip_t, w));
+ const size_t hash_len = com->size - offsetof(d2tk_body_bbox_t, clip) - offsetof(d2tk_clip_t, w);
+ com->body->bbox.hash = d2tk_hash(&com->body->bbox.clip.w, hash_len);
core->ref.x = 0;
core->ref.y = 0;
diff --git a/subprojects/d2tk/src/util_spawn.c b/subprojects/d2tk/src/util_spawn.c
index 44b4e9b5..28aff32d 100644
--- a/subprojects/d2tk/src/util_spawn.c
+++ b/subprojects/d2tk/src/util_spawn.c
@@ -52,41 +52,24 @@ d2tk_util_spawn(char **argv)
.argv = argv
};
-#if D2TK_CLONE == 1
-# define STACK_SIZE (1024 * 1024)
- uint8_t *stack = mmap(NULL, STACK_SIZE, PROT_READ | PROT_WRITE,
- MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, -1, 0);
- if(stack == MAP_FAILED)
- {
- return -1;
- }
-
- uint8_t *stack_top = stack + STACK_SIZE;
- const int flags = CLONE_FS | CLONE_IO | CLONE_VFORK | CLONE_VM | SIGCHLD;
- const int pid = clone(_clone, stack_top, flags, &clone_data);
-# undef STACK_SIZE
-#elif D2TK_VFORK == 1
const int pid = vfork();
-#else
-# error "support for clone or vfork required"
-#endif
-
switch(pid)
{
case -1:
{
+ // nothing to do
} return -1;
-#if D2TK_CLONE == 0
case 0: //child
{
// everything is done in _clone
} return _clone(&clone_data);
-#endif
default: // parent
{
+#if D2TK_DEBUG == 1
fprintf(stderr, "[%s] child with pid %i has spawned\n", __func__, pid);
+#endif
} return pid;
}
}
@@ -124,13 +107,17 @@ d2tk_util_kill(int *kid)
// has exited
if(WIFSIGNALED(stat))
{
+#if D2TK_DEBUG == 1
fprintf(stderr, "[%s] child with pid %d has exited with signal %d\n",
__func__, *kid, WTERMSIG(stat));
+#endif
}
else if(WIFEXITED(stat))
{
+#if D2TK_DEBUG == 1
fprintf(stderr, "[%s] child with pid %d has exited with status %d\n",
__func__, *kid, WEXITSTATUS(stat));
+#endif
}
*kid = -1;
@@ -164,13 +151,17 @@ d2tk_util_wait(int *kid)
// has exited
if(WIFSIGNALED(stat))
{
+#if D2TK_DEBUG == 1
fprintf(stderr, "[%s] child with pid %d has exited with signal %d\n",
__func__, *kid, WTERMSIG(stat));
+#endif
}
else if(WIFEXITED(stat))
{
+#if D2TK_DEBUG == 1
fprintf(stderr, "[%s] child with pid %d has exited with status %d\n",
__func__, *kid, WEXITSTATUS(stat));
+#endif
}
*kid = -1;