aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHanspeter Portner <dev@open-music-kontrollers.ch>2019-12-12 21:00:41 +0100
committerHanspeter Portner <dev@open-music-kontrollers.ch>2019-12-12 21:00:41 +0100
commit79e9620b9fd5a255a79756d03cc19847b883eeec (patch)
tree1b52d2a9b213f983e4e33019e4677e629eef3bd5
parent37b0e88b07655eb7c93adbf74ffa9fa8694fdaf1 (diff)
downloadd2tk-79e9620b9fd5a255a79756d03cc19847b883eeec.tar.xz
base: prototype deinit mechanisms for atoms.
-rw-r--r--VERSION2
-rw-r--r--d2tk/base.h2
-rw-r--r--meson.build1
-rw-r--r--src/base.c25
-rw-r--r--src/base_flowmatrix.c2
-rw-r--r--src/base_internal.h9
-rw-r--r--src/base_pane.c2
-rw-r--r--src/base_pty.c78
-rw-r--r--src/base_scrollbar.c2
-rw-r--r--src/frontend_pugl.c11
10 files changed, 100 insertions, 34 deletions
diff --git a/VERSION b/VERSION
index d0e2ef6..00b303b 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-0.1.911
+0.1.913
diff --git a/d2tk/base.h b/d2tk/base.h
index 38c5b59..7f54af3 100644
--- a/d2tk/base.h
+++ b/d2tk/base.h
@@ -619,7 +619,7 @@ d2tk_base_pre(d2tk_base_t *base);
D2TK_API void
d2tk_base_post(d2tk_base_t *base);
-D2TK_API void
+D2TK_API bool
d2tk_base_set_again(d2tk_base_t *base);
D2TK_API void
diff --git a/meson.build b/meson.build
index 1821271..08e3515 100644
--- a/meson.build
+++ b/meson.build
@@ -94,6 +94,7 @@ lib_srcs = [
if vterm_dep.found()
conf_data.set('D2TK_PTY', 1)
lib_srcs += join_paths('src', 'base_pty.c')
+ deps += thread_dep
deps += util_dep
else
conf_data.set('D2TK_PTY', 0)
diff --git a/src/base.c b/src/base.c
index deb8900..864c891 100644
--- a/src/base.c
+++ b/src/base.c
@@ -88,7 +88,8 @@ _d2tk_flip_clear_old(d2tk_flip_t *flip)
}
void *
-_d2tk_base_get_atom(d2tk_base_t *base, d2tk_id_t id, d2tk_atom_type_t type)
+_d2tk_base_get_atom(d2tk_base_t *base, d2tk_id_t id, d2tk_atom_type_t type,
+ d2tk_atom_deinit_t deinit)
{
for(unsigned i = 0, idx = (id + i*i) & _D2TK_MASK_ATOMS;
i < _D2TK_MAX_ATOM;
@@ -105,6 +106,7 @@ _d2tk_base_get_atom(d2tk_base_t *base, d2tk_id_t id, d2tk_atom_type_t type)
{
atom->id = id;
atom->type = type;
+ atom->deinit = deinit;
size_t len;
switch(atom->type)
@@ -139,6 +141,11 @@ _d2tk_base_get_atom(d2tk_base_t *base, d2tk_id_t id, d2tk_atom_type_t type)
if(len == 0)
{
+ if(atom->deinit)
+ {
+ atom->deinit(atom->body);
+ atom->deinit = NULL;
+ }
free(atom->body);
atom->body = 0;
}
@@ -706,6 +713,8 @@ d2tk_base_new(const d2tk_core_driver_t *driver, void *data)
return NULL;
}
+ atomic_init(&base->again, false);
+
base->core = d2tk_core_new(driver, data);
return base;
@@ -726,6 +735,11 @@ d2tk_base_free(d2tk_base_t *base)
atom->id = 0;
atom->type = 0;
+ if(atom->deinit)
+ {
+ atom->deinit(atom->body);
+ atom->deinit = NULL;
+ }
free(atom->body);
atom->body = NULL;
}
@@ -744,9 +758,6 @@ d2tk_base_pre(d2tk_base_t *base)
base->mouse.dx = (int32_t)base->mouse.x - base->mouse.ox;
base->mouse.dy = (int32_t)base->mouse.y - base->mouse.oy;
- // reset again flag
- base->again = false;
-
// reset clear-focus flag
base->clear_focus = false;
@@ -785,16 +796,16 @@ d2tk_base_clear_focus(d2tk_base_t *base)
base->clear_focus = true;
}
-D2TK_API void
+D2TK_API bool
d2tk_base_set_again(d2tk_base_t *base)
{
- base->again = true;
+ return atomic_exchange(&base->again, true);
}
D2TK_API bool
d2tk_base_get_again(d2tk_base_t *base)
{
- return base->again;
+ return atomic_exchange(&base->again, false);
}
D2TK_API void
diff --git a/src/base_flowmatrix.c b/src/base_flowmatrix.c
index b8d65a1..0edc1c5 100644
--- a/src/base_flowmatrix.c
+++ b/src/base_flowmatrix.c
@@ -161,7 +161,7 @@ d2tk_flowmatrix_begin(d2tk_base_t *base, const d2tk_rect_t *rect, d2tk_id_t id,
flowmatrix->base = base;
flowmatrix->id = id;
flowmatrix->rect = rect;
- flowmatrix->atom_body = _d2tk_base_get_atom(base, id, D2TK_ATOM_FLOW);
+ flowmatrix->atom_body = _d2tk_base_get_atom(base, id, D2TK_ATOM_FLOW, NULL);
flowmatrix->scale = exp2f(flowmatrix->atom_body->exponent); //FIXME cache this instead
flowmatrix->cx = flowmatrix->rect->x + flowmatrix->rect->w / 2
- flowmatrix->atom_body->x * flowmatrix->scale;
diff --git a/src/base_internal.h b/src/base_internal.h
index f9f471f..955a85b 100644
--- a/src/base_internal.h
+++ b/src/base_internal.h
@@ -15,6 +15,8 @@
* http://www.perlfoundation.org/artistic_license_2_0.
*/
+#include <stdatomic.h>
+
#include <d2tk/base.h>
#include <d2tk/hash.h>
#include "core_internal.h"
@@ -24,6 +26,7 @@
typedef struct _d2tk_flip_t d2tk_flip_t;
typedef struct _d2tk_atom_t d2tk_atom_t;
+typedef void (*d2tk_atom_deinit_t)(void *data);
typedef enum _d2tk_atom_type_t {
D2TK_ATOM_NONE,
@@ -46,6 +49,7 @@ struct _d2tk_atom_t {
d2tk_id_t id;
d2tk_atom_type_t type;
void *body;
+ d2tk_atom_deinit_t deinit;
};
struct _d2tk_base_t {
@@ -88,7 +92,7 @@ struct _d2tk_base_t {
const d2tk_style_t *style;
- bool again;
+ atomic_bool again;
bool clear_focus;
bool focused;
@@ -105,7 +109,8 @@ extern const size_t d2tk_atom_body_pty_sz;
#endif
void *
-_d2tk_base_get_atom(d2tk_base_t *base, d2tk_id_t id, d2tk_atom_type_t type);
+_d2tk_base_get_atom(d2tk_base_t *base, d2tk_id_t id, d2tk_atom_type_t type,
+ d2tk_atom_deinit_t deinit);
d2tk_state_t
_d2tk_base_is_active_hot_vertical_scroll(d2tk_base_t *base);
diff --git a/src/base_pane.c b/src/base_pane.c
index 6eba8e1..07b6b5d 100644
--- a/src/base_pane.c
+++ b/src/base_pane.c
@@ -124,7 +124,7 @@ d2tk_pane_begin(d2tk_base_t *base, const d2tk_rect_t *rect, d2tk_id_t id,
pane->k = 0;
pane->rect[0] = *rect;
pane->rect[1] = *rect;
- pane->atom_body = _d2tk_base_get_atom(base, id, D2TK_ATOM_PANE);
+ pane->atom_body = _d2tk_base_get_atom(base, id, D2TK_ATOM_PANE, NULL);
float *fraction = &pane->atom_body->fraction;
d2tk_rect_t sub = *rect;
diff --git a/src/base_pty.c b/src/base_pty.c
index acb1f03..6ff3875 100644
--- a/src/base_pty.c
+++ b/src/base_pty.c
@@ -22,7 +22,9 @@
#include <fcntl.h>
#include <vterm.h>
#include <pty.h>
+#include <pthread.h>
#include <sys/wait.h>
+#include <poll.h>
#include "base_internal.h"
@@ -57,6 +59,9 @@ struct _d2tk_atom_body_pty_t {
int fd;
pid_t kid;
+ atomic_bool done;
+ pthread_t thread;
+
VTerm *vterm;
VTermScreen *screen;
VTermState *state;
@@ -67,12 +72,46 @@ struct _d2tk_atom_body_pty_t {
int cursor_shape;
bool again;
+ d2tk_base_t *base;
cell_t cells [NROWS_MAX][NCOLS_MAX];
};
const size_t d2tk_atom_body_pty_sz = sizeof(d2tk_atom_body_pty_t);
+static void *
+_term_thread(void *data)
+{
+ d2tk_atom_body_pty_t *vpty = data;
+
+ struct pollfd fds = {
+ .fd = vpty->fd,
+ .events = POLLIN
+ };
+
+ while(!atomic_load(&vpty->done))
+ {
+ switch(poll(&fds, 1, 1000))
+ {
+ case -1:
+ {
+ //printf("[%s] error: %s\n", __func__, strerror(errno));
+ } break;
+ case 0:
+ {
+ //printf("[%s] timeout\n", __func__);
+ } break;
+ default:
+ {
+ //printf("[%s] ready\n", __func__);
+ d2tk_base_set_again(vpty->base);
+ } break;
+ }
+ }
+
+ return NULL;
+}
+
static inline uint32_t
_term_dark(d2tk_atom_body_pty_t *vpty)
{
@@ -308,6 +347,9 @@ _term_init(d2tk_atom_body_pty_t *vpty, char **argv, d2tk_coord_t height,
vterm_screen_set_callbacks(vpty->screen, &screen_callbacks, vpty);
vterm_screen_reset(vpty->screen, 1);
+ atomic_init(&vpty->done, false);
+ pthread_create(&vpty->thread, NULL, _term_thread, vpty);
+
return 0;
}
@@ -319,10 +361,13 @@ _term_deinit(d2tk_atom_body_pty_t *vpty)
return;
}
+ atomic_store(&vpty->done, true);
+ pthread_join(vpty->thread, NULL);
+
kill(vpty->kid, SIGINT);
kill(vpty->kid, SIGTERM);
kill(vpty->kid, SIGQUIT);
- waitpid(vpty->kid, NULL, 0);
+ waitpid(vpty->kid, NULL, WNOHANG); //FIXME should also work without nohang
vterm_free(vpty->vterm);
@@ -506,19 +551,6 @@ _term_behave(d2tk_base_t *base, d2tk_atom_body_pty_t *vpty,
VTermModifier mod = VTERM_MOD_NONE;
- if(d2tk_base_get_modmask(base, D2TK_MODMASK_SHIFT, false))
- {
- mod |= VTERM_MOD_SHIFT;
- }
- if(d2tk_base_get_modmask(base, D2TK_MODMASK_ALT, false))
- {
- mod |= VTERM_MOD_ALT;
- }
- if(d2tk_base_get_modmask(base, D2TK_MODMASK_CTRL, false))
- {
- mod |= VTERM_MOD_CTRL;
- }
-
if(d2tk_state_is_focused(state))
{
if(d2tk_base_get_keymask(base, D2TK_KEYMASK_ENTER, true))
@@ -593,6 +625,19 @@ _term_behave(d2tk_base_t *base, d2tk_atom_body_pty_t *vpty,
}
}
+ if(d2tk_base_get_modmask(base, D2TK_MODMASK_SHIFT, false))
+ {
+ mod |= VTERM_MOD_SHIFT;
+ }
+ if(d2tk_base_get_modmask(base, D2TK_MODMASK_ALT, false))
+ {
+ mod |= VTERM_MOD_ALT;
+ }
+ if(d2tk_base_get_modmask(base, D2TK_MODMASK_CTRL, false))
+ {
+ mod |= VTERM_MOD_CTRL;
+ }
+
if(d2tk_state_is_hot(state))
{
d2tk_coord_t mx, my;
@@ -720,7 +765,8 @@ D2TK_API d2tk_state_t
d2tk_base_pty(d2tk_base_t *base, d2tk_id_t id, char **argv, d2tk_coord_t height,
const d2tk_rect_t *rect)
{
- d2tk_atom_body_pty_t *vpty = _d2tk_base_get_atom(base, id, D2TK_ATOM_PTY);
+ d2tk_atom_body_pty_t *vpty = _d2tk_base_get_atom(base, id, D2TK_ATOM_PTY,
+ (d2tk_atom_deinit_t)_term_deinit);
d2tk_state_t state = D2TK_STATE_NONE;
const d2tk_coord_t width = height / 2;
@@ -733,6 +779,8 @@ d2tk_base_pty(d2tk_base_t *base, d2tk_id_t id, char **argv, d2tk_coord_t height,
{
fprintf(stderr, "[%s] _term_init failed\n", __func__);
}
+
+ vpty->base = base; //FIXME put somewhere else
}
const d2tk_style_t *old_style = d2tk_base_get_style(base);
diff --git a/src/base_scrollbar.c b/src/base_scrollbar.c
index e561fa3..c98b038 100644
--- a/src/base_scrollbar.c
+++ b/src/base_scrollbar.c
@@ -49,7 +49,7 @@ d2tk_scrollbar_begin(d2tk_base_t *base, const d2tk_rect_t *rect, d2tk_id_t id,
scrollbar->num[1] = num[1];
scrollbar->rect = rect;
scrollbar->sub = *rect;
- scrollbar->atom_body = _d2tk_base_get_atom(base, id, D2TK_ATOM_SCROLL);
+ scrollbar->atom_body = _d2tk_base_get_atom(base, id, D2TK_ATOM_SCROLL, NULL);
const d2tk_coord_t s = 10; //FIXME
diff --git a/src/frontend_pugl.c b/src/frontend_pugl.c
index 22340a0..6a5c655 100644
--- a/src/frontend_pugl.c
+++ b/src/frontend_pugl.c
@@ -68,11 +68,6 @@ _d2tk_pugl_expose(d2tk_pugl_t *dpugl)
dpugl->config->expose(dpugl->config->data, w, h);
d2tk_base_post(base);
-
- if(d2tk_base_get_again(base))
- {
- puglPostRedisplay(dpugl->view);
- }
}
static void
@@ -399,6 +394,7 @@ _d2tk_pugl_event_func(PuglView *view, const PuglEvent *e)
case PUGL_TEXT:
{
d2tk_base_append_utf8(base, e->text.character);
+
puglPostRedisplay(dpugl->view);
} break;
case PUGL_NOTHING:
@@ -413,6 +409,11 @@ _d2tk_pugl_event_func(PuglView *view, const PuglEvent *e)
D2TK_API int
d2tk_pugl_step(d2tk_pugl_t *dpugl)
{
+ if(d2tk_base_get_again(dpugl->base))
+ {
+ puglPostRedisplay(dpugl->view);
+ }
+
const PuglStatus stat = puglDispatchEvents(dpugl->world);
(void)stat;