aboutsummaryrefslogtreecommitdiff
path: root/sherlock_nk.c
diff options
context:
space:
mode:
Diffstat (limited to 'sherlock_nk.c')
-rw-r--r--sherlock_nk.c158
1 files changed, 126 insertions, 32 deletions
diff --git a/sherlock_nk.c b/sherlock_nk.c
index ae7bd11..65233b5 100644
--- a/sherlock_nk.c
+++ b/sherlock_nk.c
@@ -22,6 +22,7 @@
#include <limits.h>
#include <sherlock.h>
+#include <osc.lv2/util.h>
#define NK_PUGL_IMPLEMENTATION
#include <sherlock_nk.h>
@@ -183,21 +184,47 @@ _empty(struct nk_context *ctx)
nk_text(ctx, NULL, 0, NK_TEXT_RIGHT);
}
-void
-_clear(plughandle_t *handle)
+static void
+_clear_items(plughandle_t *handle)
{
- atom_ser_t *ser = &handle->ser;
- struct nk_str *str = &handle->str;
-
- if(_ser_realloc(ser, 1024))
+ if(handle->items)
{
- lv2_atom_forge_set_sink(&handle->mem, _sink, _deref, ser);
- lv2_atom_forge_tuple(&handle->mem, &handle->frame);
+ for(int i = 0; i < handle->n_item; i++)
+ {
+ item_t *itm = handle->items[i];
+
+ if(itm)
+ free(itm);
+ }
+
+ free(handle->items);
+ handle->items = NULL;
}
- handle->count = 0;
+ handle->n_item = 0;
+}
+
+static item_t *
+_append_item(plughandle_t *handle, item_type_t type, size_t sz)
+{
+ handle->items = realloc(handle->items, (handle->n_item + 1)*sizeof(item_t *));
+ handle->items[handle->n_item] = malloc(sizeof(item_t) + sz);
+
+ item_t *itm = handle->items[handle->n_item];
+ itm->type = type;
+
+ handle->n_item += 1;
+
+ return itm;
+}
+
+void
+_clear(plughandle_t *handle)
+{
+ _clear_items(handle);
+ nk_str_clear(&handle->str);
handle->selected = NULL;
- nk_str_clear(str);
+ handle->counter = 0;
}
void
@@ -244,7 +271,6 @@ instantiate(const LV2UI_Descriptor *descriptor, const char *plugin_uri,
handle->event_transfer = handle->map->map(handle->map->handle, LV2_ATOM__eventTransfer);
lv2_atom_forge_init(&handle->forge, handle->map);
- lv2_atom_forge_init(&handle->mem, handle->map);
lv2_osc_urid_init(&handle->osc_urid, handle->map);
handle->write_function = write_function;
@@ -257,8 +283,7 @@ instantiate(const LV2UI_Descriptor *descriptor, const char *plugin_uri,
return NULL;
}
- if( !(handle->urid.count = props_register(&handle->props, &stat_count, &handle->state.count, &handle->stash.count))
- || !(handle->urid.overwrite = props_register(&handle->props, &stat_overwrite, &handle->state.overwrite, &handle->stash.overwrite))
+ if( !(handle->urid.overwrite = props_register(&handle->props, &stat_overwrite, &handle->state.overwrite, &handle->stash.overwrite))
|| !(handle->urid.block = props_register(&handle->props, &stat_block, &handle->state.block, &handle->stash.block))
|| !(handle->urid.follow = props_register(&handle->props, &stat_follow, &handle->state.follow, &handle->stash.follow)) )
{
@@ -280,16 +305,19 @@ instantiate(const LV2UI_Descriptor *descriptor, const char *plugin_uri,
cfg->data = handle;
if(!strcmp(plugin_uri, SHERLOCK_MIDI_INSPECTOR_URI))
{
+ handle->type = SHERLOCK_MIDI_INSPECTOR,
cfg->width = 600 * scale;
cfg->expose = _midi_inspector_expose;
}
else if(!strcmp(plugin_uri, SHERLOCK_ATOM_INSPECTOR_URI))
{
+ handle->type = SHERLOCK_ATOM_INSPECTOR,
cfg->width = 1200 * scale;
cfg->expose = _atom_inspector_expose;
}
else if(!strcmp(plugin_uri, SHERLOCK_OSC_INSPECTOR_URI))
{
+ handle->type = SHERLOCK_OSC_INSPECTOR,
cfg->width = 600 * scale;
cfg->expose = _osc_inspector_expose;
}
@@ -329,11 +357,9 @@ cleanup(LV2UI_Handle instance)
sratom_free(handle->sratom);
+ _clear_items(handle);
nk_str_free(&handle->str);
- atom_ser_t *ser = &handle->ser;
- _ser_free(ser);
-
nk_pugl_hide(&handle->win);
nk_pugl_shutdown(&handle->win);
@@ -341,6 +367,36 @@ cleanup(LV2UI_Handle instance)
}
static void
+_osc_bundle(plughandle_t *handle, const LV2_Atom_Object *obj);
+
+static void
+_osc_packet(plughandle_t *handle, const LV2_Atom_Object *obj)
+{
+ if(lv2_osc_is_message_type(&handle->osc_urid, obj->body.otype))
+ {
+ _append_item(handle, ITEM_TYPE_NONE, 0);
+ }
+ else if(lv2_osc_is_bundle_type(&handle->osc_urid, obj->body.otype))
+ {
+ _append_item(handle, ITEM_TYPE_NONE, 0);
+ _osc_bundle(handle, obj);
+ }
+}
+
+static void
+_osc_bundle(plughandle_t *handle, const LV2_Atom_Object *obj)
+{
+ const LV2_Atom_Object *timetag = NULL;
+ const LV2_Atom_Tuple *items = NULL;
+ lv2_osc_bundle_get(&handle->osc_urid, obj, &timetag, &items);
+
+ LV2_ATOM_TUPLE_FOREACH(items, item)
+ {
+ _osc_packet(handle, (const LV2_Atom_Object *)item);
+ }
+}
+
+static void
port_event(LV2UI_Handle instance, uint32_t i, uint32_t size, uint32_t urid,
const void *buf)
{
@@ -374,32 +430,70 @@ port_event(LV2UI_Handle instance, uint32_t i, uint32_t size, uint32_t urid,
}
case 2:
{
- bool append = true;
-
if(handle->state.block)
- append = false;
-
- if(handle->count > handle->state.count)
{
- if(handle->state.overwrite)
- _clear(handle);
- else
- append = false;
+ break;
}
- if(append)
+ if( (handle->n_item > MAX_LINES) && handle->state.overwrite)
{
- const LV2_Atom *atom = buf;
- const uint32_t sz = lv2_atom_total_size(atom);
+ _clear(handle);
+ }
- lv2_atom_forge_write(&handle->mem, atom, sz);
+ const LV2_Atom *atom = buf;
+ const LV2_Atom_Tuple *tup = (const LV2_Atom_Tuple *)atom;
+ const LV2_Atom_Long *offset = (const LV2_Atom_Long *)lv2_atom_tuple_begin(tup);
+ const LV2_Atom_Int *nsamples = (const LV2_Atom_Int *)lv2_atom_tuple_next(&offset->atom);
+ const LV2_Atom_Sequence *seq = (const LV2_Atom_Sequence *)lv2_atom_tuple_next(&nsamples->atom);
- if(handle->state.follow)
- handle->bottom = true; // signal scrolling to bottom
+ // append frame
+ {
+ item_t *itm = _append_item(handle, ITEM_TYPE_FRAME, 0);
+ itm->frame.offset = offset->body;
+ itm->frame.counter = handle->counter++;
+ itm->frame.nsamples = nsamples->body;
+ }
- nk_pugl_post_redisplay(&handle->win);
+ LV2_ATOM_SEQUENCE_FOREACH(seq, ev)
+ {
+ const size_t ev_sz = sizeof(LV2_Atom_Event) + ev->body.size;
+ item_t *itm = _append_item(handle, ITEM_TYPE_EVENT, ev_sz);
+ memcpy(&itm->event.ev, ev, ev_sz);
+
+ switch(handle->type)
+ {
+ case SHERLOCK_ATOM_INSPECTOR:
+ {
+ if(handle->state.follow)
+ {
+ handle->selected = &itm->event.ev.body;
+ handle->ttl_dirty = true;
+ }
+ } break;
+ case SHERLOCK_OSC_INSPECTOR:
+ {
+ // bundles may span over multiple lines
+ const LV2_Atom_Object *obj = (const LV2_Atom_Object *)&ev->body;
+ if(lv2_osc_is_bundle_type(&handle->osc_urid, obj->body.otype))
+ {
+ _osc_bundle(handle, obj);
+ }
+ } break;
+ case SHERLOCK_MIDI_INSPECTOR:
+ {
+ // sysex messages may span over multiple lines
+ const uint8_t *msg = LV2_ATOM_BODY_CONST(&ev->body);
+ if( (msg[0] == 0xf0) && (ev->body.size > 4) )
+ {
+ for(uint32_t j = 4; j < ev->body.size; j += 4)
+ _append_item(handle, ITEM_TYPE_NONE, 0); // place holder
+ }
+ } break;
+ }
}
+ nk_pugl_post_redisplay(&handle->win);
+
break;
}
}