aboutsummaryrefslogtreecommitdiff
path: root/canvas.c
diff options
context:
space:
mode:
Diffstat (limited to 'canvas.c')
-rw-r--r--canvas.c141
1 files changed, 95 insertions, 46 deletions
diff --git a/canvas.c b/canvas.c
index cc3c311..4d06252 100644
--- a/canvas.c
+++ b/canvas.c
@@ -25,6 +25,8 @@
#include <cairo/cairo.h>
+#define MAX_GRAPH_BUF 0x10000
+
typedef struct _plughandle_t plughandle_t;
struct _plughandle_t {
@@ -37,6 +39,11 @@ struct _plughandle_t {
const LV2_Atom_Sequence *control;
LV2_Atom_Sequence *notify;
+ LV2_URID patch_Get;
+ LV2_URID patch_Set;
+ LV2_URID patch_property;
+ LV2_URID patch_value;
+
atomic_flag lock;
LV2_Inline_Display *queue_draw;
@@ -46,9 +53,11 @@ struct _plughandle_t {
cairo_t *ctx;
} cairo;
+ LV2_Canvas canvas;
+
union {
- LV2_Atom_Tuple tup;
- uint8_t buf [0x10000];
+ LV2_Atom_Tuple graph;
+ uint8_t buf [MAX_GRAPH_BUF];
};
};
@@ -105,16 +114,23 @@ instantiate(const LV2_Descriptor* descriptor, double rate,
return NULL;
}
+ handle->patch_Get = handle->map->map(handle->map->handle, LV2_PATCH__Get);
+ handle->patch_Set = handle->map->map(handle->map->handle, LV2_PATCH__Set);
+ handle->patch_property = handle->map->map(handle->map->handle, LV2_PATCH__property);
+ handle->patch_value = handle->map->map(handle->map->handle, LV2_PATCH__value);
+
if(handle->log)
lv2_log_logger_init(&handle->logger, handle->map, handle->log);
lv2_atom_forge_init(&handle->forge, handle->map);
- handle->tup.atom.size = 0;
- handle->tup.atom.type = handle->forge.Tuple;
+ handle->graph.atom.size = 0;
+ handle->graph.atom.type = handle->forge.Tuple;
_init_lock(&handle->lock);
+ lv2_canvas_init(&handle->canvas, handle->map);
+
return handle;
}
@@ -141,18 +157,83 @@ run(LV2_Handle instance, uint32_t nsamples)
{
plughandle_t *handle = instance;
- const uint32_t sz = lv2_atom_total_size(&handle->control->atom);
- memcpy(handle->notify, handle->control, sz);
+ const uint32_t capacity = handle->notify->atom.size;
+ lv2_atom_forge_set_buffer(&handle->forge, (uint8_t *)handle->notify, capacity);
+ LV2_Atom_Forge_Frame frame;
+ LV2_Atom_Forge_Ref ref = lv2_atom_forge_sequence_head(&handle->forge, &frame, 0);
- if(_try_lock(&handle->lock))
+ LV2_ATOM_SEQUENCE_FOREACH(handle->control, ev)
{
- //FIXME
+ const LV2_Atom_Object *obj = (const LV2_Atom_Object *)&ev->body;
- _unlock_lock(&handle->lock);
-
- if(handle->queue_draw)
- handle->queue_draw->queue_draw(handle->queue_draw->handle);
+ if(lv2_atom_forge_is_object_type(&handle->forge, obj->atom.type))
+ {
+ if(obj->body.otype == handle->patch_Get)
+ {
+ const LV2_Atom_URID *property = NULL;
+
+ lv2_atom_object_get(obj, handle->patch_property, &property, 0);
+
+ if( property
+ && (property->atom.type == handle->forge.URID)
+ && (property->body == handle->canvas.urid.Canvas_graph) )
+ {
+ LV2_Atom_Forge_Frame obj_frame;
+ if(ref)
+ ref = lv2_atom_forge_frame_time(&handle->forge, ev->time.frames);
+ if(ref)
+ ref = lv2_atom_forge_object(&handle->forge, &obj_frame, 0, handle->patch_Set);
+ if(ref)
+ ref = lv2_atom_forge_key(&handle->forge, handle->patch_property);
+ if(ref)
+ ref = lv2_atom_forge_urid(&handle->forge, handle->canvas.urid.Canvas_graph);
+ if(ref)
+ ref = lv2_atom_forge_key(&handle->forge, handle->patch_value);
+ if(ref)
+ ref = lv2_atom_forge_write(&handle->forge, &handle->graph, lv2_atom_total_size(&handle->graph.atom));
+ if(ref)
+ lv2_atom_forge_pop(&handle->forge, &obj_frame);
+ }
+ }
+ else if(obj->body.otype == handle->patch_Set)
+ {
+ const LV2_Atom_URID *property = NULL;
+ const LV2_Atom_Tuple *graph = NULL;
+
+ lv2_atom_object_get(obj, handle->patch_property, &property,
+ handle->patch_value, &graph, 0);
+
+ if( property
+ && (property->atom.type == handle->forge.URID)
+ && (property->body == handle->canvas.urid.Canvas_graph)
+ && graph
+ && (graph->atom.type == handle->forge.Tuple) )
+ {
+ const uint32_t sz = lv2_atom_total_size(&graph->atom);
+
+ if( (sz <= MAX_GRAPH_BUF) && _try_lock(&handle->lock))
+ {
+ memcpy(&handle->graph, graph, sz);
+
+ _unlock_lock(&handle->lock);
+
+ if(handle->queue_draw)
+ handle->queue_draw->queue_draw(handle->queue_draw->handle);
+ }
+
+ if(ref)
+ ref = lv2_atom_forge_frame_time(&handle->forge, ev->time.frames);
+ if(ref)
+ ref = lv2_atom_forge_write(&handle->forge, obj, lv2_atom_total_size(&obj->atom));
+ }
+ }
+ }
}
+
+ if(ref)
+ lv2_atom_forge_pop(&handle->forge, &frame);
+ else
+ lv2_atom_sequence_clear(handle->notify);
}
static inline LV2_Inline_Display_Image_Surface *
@@ -225,44 +306,12 @@ _render(LV2_Handle instance, uint32_t w, uint32_t h)
if(!surf)
return NULL;
- // save state
- cairo_save(handle->cairo.ctx);
-
- // clear surface
- cairo_set_operator(handle->cairo.ctx, CAIRO_OPERATOR_CLEAR);
- cairo_paint(handle->cairo.ctx);
-
- // default attributes
- cairo_set_operator(handle->cairo.ctx, CAIRO_OPERATOR_SOURCE);
- cairo_set_font_size(handle->cairo.ctx, 0.1);
- cairo_set_line_width(handle->cairo.ctx, 0.01);
- cairo_set_source_rgba(handle->cairo.ctx, 1.0, 1.0, 1.0, 1.0);
-
_spin_lock(&handle->lock);
- LV2_ATOM_TUPLE_FOREACH(&handle->tup, itm)
- {
- if(lv2_atom_forge_is_object_type(&handle->forge, itm->type))
- ;//_render_cmd(handle, handle->cairo.ctx, (const LV2_Atom_Object *)itm);
- }
+ lv2_canvas_render(&handle->canvas, handle->cairo.ctx, &handle->forge, &handle->graph);
_unlock_lock(&handle->lock);
- //FIXME
- {
- cairo_translate(handle->cairo.ctx, 0.5, 0.5);
- cairo_rotate(handle->cairo.ctx, M_PI/4);
- cairo_rectangle(handle->cairo.ctx, -0.3, -0.3, 0.6, 0.6);
- cairo_set_source_rgba(handle->cairo.ctx, 0.8, 0.8, 0.0, 1.0);
- cairo_fill(handle->cairo.ctx);
- }
-
- // save state
- cairo_restore(handle->cairo.ctx);
-
- // flush
- cairo_surface_flush(handle->cairo.surface);
-
return surf;
}
@@ -294,7 +343,7 @@ extension_data(const char *uri)
}
const LV2_Descriptor canvas_canvas = {
- .URI = CANVAS_CANVAS_URI,
+ .URI = CANVAS_PREFIX"canvas",
.instantiate = instantiate,
.connect_port = connect_port,
.activate = NULL,