aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHanspeter Portner <dev@open-music-kontrollers.ch>2017-02-27 15:00:31 +0100
committerHanspeter Portner <dev@open-music-kontrollers.ch>2017-02-27 15:00:31 +0100
commit1823c3b9ccbb7345c4f5f7cddeb9b5f48f4d7b03 (patch)
tree26b8f723291e18b2d94024c612cfc14ce42a5e82
parent15f1847a5b0b4d59a79bd6a8b26c222d0a133406 (diff)
downloadcanvas.lv2-1823c3b9ccbb7345c4f5f7cddeb9b5f48f4d7b03.tar.xz
implement mouse event feedback.
-rw-r--r--VERSION2
-rw-r--r--canvas.lv2/canvas.h106
-rw-r--r--test/canvas.c208
-rw-r--r--test/canvas.ttl6
-rw-r--r--test/canvas_ui.c194
5 files changed, 438 insertions, 78 deletions
diff --git a/VERSION b/VERSION
index b2e22fd..94f0727 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-0.1.325
+0.1.327
diff --git a/canvas.lv2/canvas.h b/canvas.lv2/canvas.h
index 40c1b6a..56e6fb7 100644
--- a/canvas.lv2/canvas.h
+++ b/canvas.lv2/canvas.h
@@ -26,44 +26,56 @@ extern "C" {
#include <lv2/lv2plug.in/ns/ext/atom/atom.h>
#include <lv2/lv2plug.in/ns/ext/atom/forge.h>
-#define CANVAS_URI "http://open-music-kontrollers.ch/lv2/canvas"
-#define CANVAS_PREFIX CANVAS_URI"#"
-
-#define CANVAS__graph CANVAS_PREFIX"graph"
-#define CANVAS__body CANVAS_PREFIX"body"
-
-#define CANVAS__BeginPath CANVAS_PREFIX"BeginPath"
-#define CANVAS__ClosePath CANVAS_PREFIX"ClosePath"
-#define CANVAS__Arc CANVAS_PREFIX"Arc"
-#define CANVAS__CurveTo CANVAS_PREFIX"CurveTo"
-#define CANVAS__LineTo CANVAS_PREFIX"LineTo"
-#define CANVAS__MoveTo CANVAS_PREFIX"MoveTo"
-#define CANVAS__Rectangle CANVAS_PREFIX"Rectangle"
-#define CANVAS__Style CANVAS_PREFIX"Style"
-#define CANVAS__LineWidth CANVAS_PREFIX"LineWidth"
-#define CANVAS__LineDash CANVAS_PREFIX"LineDash"
-#define CANVAS__LineCap CANVAS_PREFIX"LineCap"
-#define CANVAS__LineJoin CANVAS_PREFIX"LineJoin"
-#define CANVAS__MiterLimit CANVAS_PREFIX"MiterLimig"
-#define CANVAS__Stroke CANVAS_PREFIX"Stroke"
-#define CANVAS__Fill CANVAS_PREFIX"Fill"
-#define CANVAS__Clip CANVAS_PREFIX"Clip"
-#define CANVAS__Save CANVAS_PREFIX"Save"
-#define CANVAS__Restore CANVAS_PREFIX"Restore"
-#define CANVAS__Translate CANVAS_PREFIX"Translate"
-#define CANVAS__Scale CANVAS_PREFIX"Scale"
-#define CANVAS__Rotate CANVAS_PREFIX"Rotate"
-#define CANVAS__Reset CANVAS_PREFIX"Reset"
-#define CANVAS__FontSize CANVAS_PREFIX"FontSize"
-#define CANVAS__FillText CANVAS_PREFIX"FillText"
-
-#define CANVAS__lineCapButt CANVAS_PREFIX"lineCapButt"
-#define CANVAS__lineCapRound CANVAS_PREFIX"lineCapRound"
-#define CANVAS__lineCapSquare CANVAS_PREFIX"lineCapSquare"
-
-#define CANVAS__lineJoinMiter CANVAS_PREFIX"lineJoinMiter"
-#define CANVAS__lineJoinRound CANVAS_PREFIX"lineJoinRound"
-#define CANVAS__lineJoinBevel CANVAS_PREFIX"lineJoinBevel"
+#define CANVAS_URI "http://open-music-kontrollers.ch/lv2/canvas"
+#define CANVAS_PREFIX CANVAS_URI"#"
+
+#define CANVAS__graph CANVAS_PREFIX"graph"
+#define CANVAS__body CANVAS_PREFIX"body"
+
+// Graph properties and attributes
+#define CANVAS__BeginPath CANVAS_PREFIX"BeginPath"
+#define CANVAS__ClosePath CANVAS_PREFIX"ClosePath"
+#define CANVAS__Arc CANVAS_PREFIX"Arc"
+#define CANVAS__CurveTo CANVAS_PREFIX"CurveTo"
+#define CANVAS__LineTo CANVAS_PREFIX"LineTo"
+#define CANVAS__MoveTo CANVAS_PREFIX"MoveTo"
+#define CANVAS__Rectangle CANVAS_PREFIX"Rectangle"
+#define CANVAS__Style CANVAS_PREFIX"Style"
+#define CANVAS__LineWidth CANVAS_PREFIX"LineWidth"
+#define CANVAS__LineDash CANVAS_PREFIX"LineDash"
+#define CANVAS__LineCap CANVAS_PREFIX"LineCap"
+#define CANVAS__LineJoin CANVAS_PREFIX"LineJoin"
+#define CANVAS__MiterLimit CANVAS_PREFIX"MiterLimig"
+#define CANVAS__Stroke CANVAS_PREFIX"Stroke"
+#define CANVAS__Fill CANVAS_PREFIX"Fill"
+#define CANVAS__Clip CANVAS_PREFIX"Clip"
+#define CANVAS__Save CANVAS_PREFIX"Save"
+#define CANVAS__Restore CANVAS_PREFIX"Restore"
+#define CANVAS__Translate CANVAS_PREFIX"Translate"
+#define CANVAS__Scale CANVAS_PREFIX"Scale"
+#define CANVAS__Rotate CANVAS_PREFIX"Rotate"
+#define CANVAS__Reset CANVAS_PREFIX"Reset"
+#define CANVAS__FontSize CANVAS_PREFIX"FontSize"
+#define CANVAS__FillText CANVAS_PREFIX"FillText"
+
+#define CANVAS__lineCapButt CANVAS_PREFIX"lineCapButt"
+#define CANVAS__lineCapRound CANVAS_PREFIX"lineCapRound"
+#define CANVAS__lineCapSquare CANVAS_PREFIX"lineCapSquare"
+
+#define CANVAS__lineJoinMiter CANVAS_PREFIX"lineJoinMiter"
+#define CANVAS__lineJoinRound CANVAS_PREFIX"lineJoinRound"
+#define CANVAS__lineJoinBevel CANVAS_PREFIX"lineJoinBevel"
+
+// Input properties and attributes
+
+#define CANVAS__mouseButtonLeft CANVAS_PREFIX"mouseButtonLeft"
+#define CANVAS__mouseButtonMiddle CANVAS_PREFIX"mouseButtonMiddle"
+#define CANVAS__mouseButtonRight CANVAS_PREFIX"mouseButtonRight"
+#define CANVAS__mouseWheelX CANVAS_PREFIX"mouseWheelX"
+#define CANVAS__mouseWheelY CANVAS_PREFIX"mouseWheelY"
+#define CANVAS__mousePositionX CANVAS_PREFIX"mousePositionX"
+#define CANVAS__mousePositionY CANVAS_PREFIX"mousePositionY"
+#define CANVAS__mouseFocus CANVAS_PREFIX"mouseFocus"
typedef struct _LV2_Canvas_URID LV2_Canvas_URID;
@@ -104,6 +116,15 @@ struct _LV2_Canvas_URID {
LV2_URID Canvas_lineJoinRound;
LV2_URID Canvas_lineJoinBevel;
+ LV2_URID Canvas_mouseButtonLeft;
+ LV2_URID Canvas_mouseButtonMiddle;
+ LV2_URID Canvas_mouseButtonRight;
+ LV2_URID Canvas_mouseWheelX;
+ LV2_URID Canvas_mouseWheelY;
+ LV2_URID Canvas_mousePositionX;
+ LV2_URID Canvas_mousePositionY;
+ LV2_URID Canvas_mouseFocus;
+
LV2_Atom_Forge forge;
};
@@ -146,6 +167,15 @@ lv2_canvas_urid_init(LV2_Canvas_URID *urid, LV2_URID_Map *map)
urid->Canvas_lineJoinRound = map->map(map->handle, CANVAS__lineJoinRound);
urid->Canvas_lineJoinBevel = map->map(map->handle, CANVAS__lineJoinBevel);
+ urid->Canvas_mouseButtonLeft = map->map(map->handle, CANVAS__mouseButtonLeft);
+ urid->Canvas_mouseButtonMiddle = map->map(map->handle, CANVAS__mouseButtonMiddle);
+ urid->Canvas_mouseButtonRight = map->map(map->handle, CANVAS__mouseButtonRight);
+ urid->Canvas_mouseWheelX = map->map(map->handle, CANVAS__mouseWheelX);
+ urid->Canvas_mouseWheelY = map->map(map->handle, CANVAS__mouseWheelY);
+ urid->Canvas_mousePositionX = map->map(map->handle, CANVAS__mousePositionX);
+ urid->Canvas_mousePositionY = map->map(map->handle, CANVAS__mousePositionY);
+ urid->Canvas_mouseFocus = map->map(map->handle, CANVAS__mouseFocus);
+
lv2_atom_forge_init(&urid->forge, map);
}
diff --git a/test/canvas.c b/test/canvas.c
index 4087844..7a53e76 100644
--- a/test/canvas.c
+++ b/test/canvas.c
@@ -18,8 +18,11 @@
#include <stdlib.h>
#include <stdio.h>
#include <stdatomic.h>
+#include <inttypes.h>
#include <lv2/lv2plug.in/ns/ext/patch/patch.h>
+#include <lv2/lv2plug.in/ns/ext/log/log.h>
+#include <lv2/lv2plug.in/ns/ext/log/logger.h>
#include <canvas.lv2/forge.h>
#include <canvas.lv2/render.h>
@@ -35,14 +38,20 @@ typedef struct _plughandle_t plughandle_t;
struct _plughandle_t {
LV2_URID_Map *map;
LV2_Atom_Forge forge;
+ LV2_Atom_Forge forge_through;
+
+ LV2_Log_Log *log;
+ LV2_Log_Logger logger;
const LV2_Atom_Sequence *control;
LV2_Atom_Sequence *notify;
LV2_URID patch_Get;
LV2_URID patch_Set;
+ LV2_URID patch_Put;
LV2_URID patch_property;
LV2_URID patch_value;
+ LV2_URID patch_body;
atomic_flag lock;
@@ -153,6 +162,8 @@ instantiate(const LV2_Descriptor* descriptor, double rate,
handle->map = features[i]->data;
else if(!strcmp(features[i]->URI, LV2_INLINEDISPLAY__queue_draw))
handle->queue_draw = features[i]->data;
+ else if(!strcmp(features[i]->URI, LV2_LOG__log))
+ handle->log = features[i]->data;
}
if(!handle->map)
@@ -163,10 +174,15 @@ instantiate(const LV2_Descriptor* descriptor, double rate,
return NULL;
}
+ if(handle->log)
+ lv2_log_logger_init(&handle->logger, handle->map, handle->log);
+
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_Put = handle->map->map(handle->map->handle, LV2_PATCH__Put);
handle->patch_property = handle->map->map(handle->map->handle, LV2_PATCH__property);
handle->patch_value = handle->map->map(handle->map->handle, LV2_PATCH__value);
+ handle->patch_body = handle->map->map(handle->map->handle, LV2_PATCH__body);
lv2_atom_forge_init(&handle->forge, handle->map);
@@ -220,6 +236,8 @@ run(LV2_Handle instance, uint32_t nsamples)
LV2_ATOM_SEQUENCE_FOREACH(handle->control, ev)
{
const LV2_Atom_Object *obj = (const LV2_Atom_Object *)&ev->body;
+ const uint32_t szo = lv2_atom_total_size(&obj->atom);
+ bool route = false;
if(lv2_atom_forge_is_object_type(&handle->forge, obj->atom.type))
{
@@ -227,7 +245,8 @@ run(LV2_Handle instance, uint32_t nsamples)
{
const LV2_Atom_URID *property = NULL;
- lv2_atom_object_get(obj, handle->patch_property, &property, 0);
+ lv2_atom_object_get(obj, handle->patch_property, &property,
+ 0);
if( property
&& (property->atom.type == handle->forge.URID)
@@ -255,37 +274,190 @@ run(LV2_Handle instance, uint32_t nsamples)
else if(obj->body.otype == handle->patch_Set)
{
const LV2_Atom_URID *property = NULL;
- const LV2_Atom_Tuple *graph = NULL;
+ const LV2_Atom *value = NULL;
lv2_atom_object_get(obj, handle->patch_property, &property,
- handle->patch_value, &graph, 0);
+ handle->patch_value, &value,
+ 0);
if( property
&& (property->atom.type == handle->forge.URID)
- && (property->body == handle->canvas.urid.Canvas_graph)
- && graph
- && (graph->atom.type == handle->forge.Tuple) )
+ && value)
{
- const uint32_t szo = lv2_atom_total_size(&obj->atom);
- const uint32_t szg = lv2_atom_total_size(&graph->atom);
+ if( (property->body == handle->canvas.urid.Canvas_graph)
+ && (value->type == handle->forge.Tuple) )
+ {
+ const LV2_Atom_Tuple *graph = (const LV2_Atom_Tuple *)value;
+ const uint32_t szg = lv2_atom_total_size(&graph->atom);
+
+ if( (szg <= MAX_GRAPH_BUF)
+ && _try_lock(&handle->lock) )
+ {
+ memcpy(&handle->graph, graph, szg);
+
+ _unlock(&handle->lock);
- if( (szg <= MAX_GRAPH_BUF)
- && _try_lock(&handle->lock) )
+ if(handle->queue_draw)
+ handle->queue_draw->queue_draw(handle->queue_draw->handle);
+ }
+
+ route = true;
+ }
+ else if( (property->body == handle->canvas.urid.Canvas_mouseButtonLeft)
+ && (value->type == handle->forge.Bool) )
{
- memcpy(&handle->graph, graph, szg);
+ if(handle->log)
+ {
+ lv2_log_trace(&handle->logger, "\tcanvas:mouseButtonLeft: %"PRIi32"\n",
+ ((const LV2_Atom_Bool *)value)->body);
+ }
- _unlock(&handle->lock);
+ route = true;
+ }
+ else if( (property->body == handle->canvas.urid.Canvas_mouseButtonMiddle)
+ && (value->type == handle->forge.Bool) )
+ {
+ if(handle->log)
+ {
+ lv2_log_trace(&handle->logger, "\tcanvas:mouseButtonMiddle: %"PRIi32"\n",
+ ((const LV2_Atom_Bool *)value)->body);
+ }
- if(handle->queue_draw)
- handle->queue_draw->queue_draw(handle->queue_draw->handle);
+ route = true;
}
+ else if( (property->body == handle->canvas.urid.Canvas_mouseButtonRight)
+ && (value->type == handle->forge.Bool) )
+ {
+ if(handle->log)
+ {
+ lv2_log_trace(&handle->logger, "\tcanvas:mouseButtonRight: %"PRIi32"\n",
+ ((const LV2_Atom_Bool *)value)->body);
+ }
- if(ref)
- ref = lv2_atom_forge_frame_time(&handle->forge, ev->time.frames);
- if(ref)
- ref = lv2_atom_forge_write(&handle->forge, obj, szo);
+ route = true;
+ }
+ else if( (property->body == handle->canvas.urid.Canvas_mousePositionX)
+ && (value->type == handle->forge.Double) )
+ {
+ if(handle->log)
+ {
+ lv2_log_trace(&handle->logger, "\tcanvas:mousePositionX: %lf\n",
+ ((const LV2_Atom_Double *)value)->body);
+ }
+
+ route = true;
+ }
+ else if( (property->body == handle->canvas.urid.Canvas_mousePositionY)
+ && (value->type == handle->forge.Double) )
+ {
+ if(handle->log)
+ {
+ lv2_log_trace(&handle->logger, "\tcanvas:mousePositionY: %lf\n",
+ ((const LV2_Atom_Double *)value)->body);
+ }
+
+ route = true;
+ }
+ else if( (property->body == handle->canvas.urid.Canvas_mouseWheelX)
+ && (value->type == handle->forge.Double) )
+ {
+ if(handle->log)
+ {
+ lv2_log_trace(&handle->logger, "\tcanvas:mouseWheelX: %lf\n",
+ ((const LV2_Atom_Double *)value)->body);
+ }
+
+ route = true;
+ }
+ else if( (property->body == handle->canvas.urid.Canvas_mouseWheelY)
+ && (value->type == handle->forge.Double) )
+ {
+ if(handle->log)
+ {
+ lv2_log_trace(&handle->logger, "\tcanvas:mouseWheelY: %lf\n",
+ ((const LV2_Atom_Double *)value)->body);
+ }
+
+ route = true;
+ }
+ else if( (property->body == handle->canvas.urid.Canvas_mouseFocus)
+ && (value->type == handle->forge.Bool) )
+ {
+ if(handle->log)
+ {
+ lv2_log_trace(&handle->logger, "\tcanvas:mouseFocus: %"PRIi32"\n",
+ ((const LV2_Atom_Bool *)value)->body);
+ }
+
+ route = true;
+ }
}
}
+ else if(obj->body.otype == handle->patch_Put)
+ {
+ const LV2_Atom_Object *body = NULL;
+
+ lv2_atom_object_get(obj, handle->patch_body, &body,
+ 0);
+
+ if( body
+ && lv2_atom_forge_is_object_type(&handle->forge, body->atom.type) )
+ {
+ const LV2_Atom_Bool *l = NULL;
+ const LV2_Atom_Bool *m = NULL;
+ const LV2_Atom_Bool *r = NULL;
+ const LV2_Atom_Double *dx = NULL;
+ const LV2_Atom_Double *dy = NULL;
+ const LV2_Atom_Double *x = NULL;
+ const LV2_Atom_Double *y = NULL;
+ const LV2_Atom_Bool *f = NULL;
+
+ lv2_atom_object_get(body,
+ handle->canvas.urid.Canvas_mouseButtonLeft, &l,
+ handle->canvas.urid.Canvas_mouseButtonMiddle, &m,
+ handle->canvas.urid.Canvas_mouseButtonRight, &r,
+ handle->canvas.urid.Canvas_mouseWheelX, &dx,
+ handle->canvas.urid.Canvas_mouseWheelY, &dy,
+ handle->canvas.urid.Canvas_mousePositionX, &x,
+ handle->canvas.urid.Canvas_mousePositionY, &y,
+ handle->canvas.urid.Canvas_mouseFocus, &f,
+ 0);
+
+ if(handle->log)
+ {
+ lv2_log_trace(&handle->logger, "{\n");
+ if(l && (l->atom.type == handle->forge.Bool) )
+ lv2_log_trace(&handle->logger, "\tcanvas:mousebuttonLeft: %"PRIi32"\n", l->body);
+ if(m && (m->atom.type == handle->forge.Bool) )
+ lv2_log_trace(&handle->logger, "\tcanvas:mousebuttonMiddle: %"PRIi32"\n", m->body);
+ if(r && (r->atom.type == handle->forge.Bool) )
+ lv2_log_trace(&handle->logger, "\tcanvas:mousebuttonRight: %"PRIi32"\n", r->body);
+ if(x && (x->atom.type == handle->forge.Double) )
+ lv2_log_trace(&handle->logger, "\tcanvas:mousePositionX: %lf\n", x->body);
+ if(y && (y->atom.type == handle->forge.Double) )
+ lv2_log_trace(&handle->logger, "\tcanvas:mousePositionY: %lf\n", y->body);
+ if(dx && (dx->atom.type == handle->forge.Double) )
+ lv2_log_trace(&handle->logger, "\tcanvas:mouseWheelX: %lf\n", dx->body);
+ if(dy && (dy->atom.type == handle->forge.Double) )
+ lv2_log_trace(&handle->logger, "\tcanvas:mouseWheelY: %lf\n", dy->body);
+ if(f && (f->atom.type == handle->forge.Bool) )
+ lv2_log_trace(&handle->logger, "\tcanvas:mouseFocus: %"PRIi32"\n", f->body);
+ lv2_log_trace(&handle->logger, "}\n");
+ }
+
+ if( x && (x->atom.type == handle->forge.Double)
+ && y && (y->atom.type == handle->forge.Double) )
+ route = true; // a valid input event at least sets x and y
+ }
+ }
+ }
+
+ if(route) // should we route to UI?
+ {
+ if(ref)
+ ref = lv2_atom_forge_frame_time(&handle->forge, ev->time.frames);
+ if(ref)
+ ref = lv2_atom_forge_write(&handle->forge, obj, szo);
}
}
diff --git a/test/canvas.ttl b/test/canvas.ttl
index fa76918..aa28b8a 100644
--- a/test/canvas.ttl
+++ b/test/canvas.ttl
@@ -18,6 +18,8 @@
@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
@prefix atom: <http://lv2plug.in/ns/ext/atom#> .
@prefix urid: <http://lv2plug.in/ns/ext/urid#> .
+@prefix log: <http://lv2plug.in/ns/ext/log#> .
+@prefix patch: <http://lv2plug.in/ns/ext/patch#> .
@prefix idisp: <http://harrisonconsoles.com/lv2/inlinedisplay#> .
@prefix lic: <http://opensource.org/licenses/> .
@@ -52,13 +54,14 @@ canvas:canvas
doap:license lic:Artistic-2.0 ;
lv2:project proj:canvas ;
lv2:requiredFeature urid:map ;
- lv2:optionalFeature lv2:isLive, lv2:hardRTCapable, idisp:queue_draw ;
+ lv2:optionalFeature lv2:isLive, lv2:hardRTCapable, idisp:queue_draw, log:log ;
lv2:extensionData idisp:interface ;
lv2:port [
a lv2:InputPort ,
atom:AtomPort ;
atom:bufferType atom:Sequence ;
+ atom:supports patch:Message ;
lv2:index 0 ;
lv2:symbol "control" ;
lv2:name "Control" ;
@@ -67,6 +70,7 @@ canvas:canvas
a lv2:OutputPort ,
atom:AtomPort ;
atom:bufferType atom:Sequence ;
+ atom:supports patch:Message ;
lv2:index 1 ;
lv2:symbol "notify" ;
lv2:name "Notify" ;
diff --git a/test/canvas_ui.c b/test/canvas_ui.c
index 61b4b88..e99c368 100644
--- a/test/canvas_ui.c
+++ b/test/canvas_ui.c
@@ -42,28 +42,44 @@ struct _plughandle_t {
LV2_URID patch_Get;
LV2_URID patch_Set;
+ LV2_URID patch_Put;
LV2_URID patch_property;
LV2_URID patch_value;
+ LV2_URID patch_body;
LV2_URID atom_eventTransfer;
LV2_Atom_Tuple *graph;
LV2UI_Write_Function writer;
LV2UI_Controller controller;
-};
-static inline void
-_refresh(plughandle_t *handle)
-{
union {
LV2_Atom atom;
- uint8_t buf [128];
+ uint8_t buf [512];
} dst;
+};
- lv2_atom_forge_set_buffer(&handle->forge, dst.buf, 128);
- LV2_Atom_Forge_Ref ref;
+static inline void
+_event_request(plughandle_t *handle)
+{
+ lv2_atom_forge_set_buffer(&handle->forge, handle->dst.buf, 512);
+}
+static inline void
+_event_commit(plughandle_t *handle)
+{
+ const uint32_t sz = lv2_atom_total_size(&handle->dst.atom);
+ handle->writer(handle->controller, 0, sz, handle->atom_eventTransfer, &handle->dst.atom);
+}
+
+static inline void
+_refresh(plughandle_t *handle)
+{
LV2_Atom_Forge_Frame obj_frame;
+ LV2_Atom_Forge_Ref ref;
+
+ _event_request(handle);
+
ref = lv2_atom_forge_object(&handle->forge, &obj_frame, 0, handle->patch_Get);
if(ref)
ref = lv2_atom_forge_key(&handle->forge, handle->patch_property);
@@ -72,8 +88,33 @@ _refresh(plughandle_t *handle)
if(ref)
lv2_atom_forge_pop(&handle->forge, &obj_frame);
- const uint32_t sz = lv2_atom_total_size(&dst.atom);
- handle->writer(handle->controller, 0, sz, handle->atom_eventTransfer, &dst.atom);
+ if(ref)
+ _event_commit(handle);
+}
+
+static inline LV2_Atom_Forge_Ref
+_input_request(plughandle_t *handle, LV2_Atom_Forge_Frame frame [2])
+{
+ LV2_Atom_Forge_Ref ref;
+
+ _event_request(handle);
+
+ ref = lv2_atom_forge_object(&handle->forge, &frame[0], 0, handle->patch_Put);
+ if(ref)
+ ref = lv2_atom_forge_key(&handle->forge, handle->patch_body);
+ if(ref)
+ ref = lv2_atom_forge_object(&handle->forge, &frame[1], 0, 0);
+
+ return ref;
+}
+
+static inline void
+_input_commit(plughandle_t *handle, LV2_Atom_Forge_Frame frame [2])
+{
+ lv2_atom_forge_pop(&handle->forge, &frame[1]);
+ lv2_atom_forge_pop(&handle->forge, &frame[0]);
+
+ _event_commit(handle);
}
static inline void
@@ -110,15 +151,30 @@ _configure(plughandle_t *handle, const PuglEventConfigure *e)
}
static void
+_relative_position(PuglView *view, double xa, double ya, double *xr, double *yr)
+{
+ int width;
+ int height;
+
+ puglGetSize(view, &width, &height);
+
+ *xr = (double)xa / width;
+ *yr = (double)ya / height;
+}
+
+static void
_event_func(PuglView *view, const PuglEvent *e)
{
plughandle_t *handle = puglGetHandle(view);
+ LV2_Atom_Forge_Ref ref;
+ LV2_Atom_Forge_Frame frame [2];
switch(e->type)
{
case PUGL_CONFIGURE:
{
_configure(handle, (const PuglEventConfigure *)e);
+
puglPostRedisplay(handle->view);
} break;
case PUGL_EXPOSE:
@@ -129,30 +185,126 @@ _event_func(PuglView *view, const PuglEvent *e)
{
_close(handle);
} break;
- case PUGL_ENTER_NOTIFY:
- // fall-through
- case PUGL_LEAVE_NOTIFY:
- // fall-through
+
case PUGL_FOCUS_IN:
// fall-through
case PUGL_FOCUS_OUT:
{
puglPostRedisplay(handle->view);
- } break;
+ } break;
+
+ case PUGL_ENTER_NOTIFY:
+ case PUGL_LEAVE_NOTIFY:
+ {
+ double x, y;
+ _relative_position(view, e->crossing.x, e->crossing.y, &x, &y);
+
+ ref = _input_request(handle, frame);
+ if(ref)
+ ref = lv2_atom_forge_key(&handle->forge, handle->canvas.urid.Canvas_mousePositionX);
+ if(ref)
+ ref = lv2_atom_forge_double(&handle->forge, x);
+ if(ref)
+ ref = lv2_atom_forge_key(&handle->forge, handle->canvas.urid.Canvas_mousePositionY);
+ if(ref)
+ ref = lv2_atom_forge_double(&handle->forge, y);
+ if(ref)
+ ref = lv2_atom_forge_key(&handle->forge, handle->canvas.urid.Canvas_mouseFocus);
+ if(ref)
+ ref = lv2_atom_forge_bool(&handle->forge, e->type == PUGL_ENTER_NOTIFY ? 1 : 0);
+ if(ref)
+ _input_commit(handle, frame);
+
+ puglPostRedisplay(handle->view);
+ } break;
- case PUGL_NOTHING:
- // fall-through
case PUGL_BUTTON_PRESS:
- // fall-through
case PUGL_BUTTON_RELEASE:
- // fall-through
+ {
+ double x, y;
+ _relative_position(view, e->button.x, e->button.y, &x, &y);
+
+ ref = _input_request(handle, frame);
+ if(ref)
+ ref = lv2_atom_forge_key(&handle->forge, handle->canvas.urid.Canvas_mousePositionX);
+ if(ref)
+ ref = lv2_atom_forge_double(&handle->forge, x);
+ if(ref)
+ ref = lv2_atom_forge_key(&handle->forge, handle->canvas.urid.Canvas_mousePositionY);
+ if(ref)
+ ref = lv2_atom_forge_double(&handle->forge, y);
+ LV2_URID button_urid;
+ switch(e->button.button)
+ {
+ case 3:
+ button_urid = handle->canvas.urid.Canvas_mouseButtonRight;
+ break;
+ case 2:
+ button_urid = handle->canvas.urid.Canvas_mouseButtonMiddle;
+ break;
+ case 1:
+ default:
+ button_urid = handle->canvas.urid.Canvas_mouseButtonLeft;
+ break;
+ }
+ if(ref)
+ ref = lv2_atom_forge_key(&handle->forge, button_urid);
+ if(ref)
+ ref = lv2_atom_forge_bool(&handle->forge, e->type == PUGL_BUTTON_PRESS ? 1 : 0);
+ if(ref)
+ _input_commit(handle, frame);
+ } break;
+
+ case PUGL_MOTION_NOTIFY:
+ {
+ double x, y;
+ _relative_position(view, e->motion.x, e->motion.y, &x, &y);
+
+ ref = _input_request(handle, frame);
+ if(ref)
+ ref = lv2_atom_forge_key(&handle->forge, handle->canvas.urid.Canvas_mousePositionX);
+ if(ref)
+ ref = lv2_atom_forge_double(&handle->forge, x);
+ if(ref)
+ ref = lv2_atom_forge_key(&handle->forge, handle->canvas.urid.Canvas_mousePositionY);
+ if(ref)
+ ref = lv2_atom_forge_double(&handle->forge, y);
+ if(ref)
+ _input_commit(handle, frame);
+ } break;
+
+ case PUGL_SCROLL:
+ {
+ double x, y;
+ _relative_position(view, e->scroll.x, e->scroll.y, &x, &y);
+
+ ref = _input_request(handle, frame);
+ if(ref)
+ ref = lv2_atom_forge_key(&handle->forge, handle->canvas.urid.Canvas_mousePositionX);
+ if(ref)
+ ref = lv2_atom_forge_double(&handle->forge, x);
+ if(ref)
+ ref = lv2_atom_forge_key(&handle->forge, handle->canvas.urid.Canvas_mousePositionY);
+ if(ref)
+ ref = lv2_atom_forge_double(&handle->forge, y);
+ if(ref)
+ ref = lv2_atom_forge_key(&handle->forge, handle->canvas.urid.Canvas_mouseWheelX);
+ if(ref)
+ ref = lv2_atom_forge_double(&handle->forge, e->scroll.dx);
+ if(ref)
+ ref = lv2_atom_forge_key(&handle->forge, handle->canvas.urid.Canvas_mouseWheelY);
+ if(ref)
+ ref = lv2_atom_forge_double(&handle->forge, e->scroll.dy);
+ if(ref)
+ _input_commit(handle, frame);
+ } break;
+
case PUGL_KEY_PRESS:
// fall-through
case PUGL_KEY_RELEASE:
// fall-through
- case PUGL_MOTION_NOTIFY:
+ case PUGL_NOTHING:
// fall-through
- case PUGL_SCROLL:
{
// nothing
} break;
@@ -200,8 +352,10 @@ instantiate(const LV2UI_Descriptor *descriptor, const char *plugin_uri,
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_Put = handle->map->map(handle->map->handle, LV2_PATCH__Put);
handle->patch_property = handle->map->map(handle->map->handle, LV2_PATCH__property);
handle->patch_value = handle->map->map(handle->map->handle, LV2_PATCH__value);
+ handle->patch_body = handle->map->map(handle->map->handle, LV2_PATCH__body);
handle->atom_eventTransfer= handle->map->map(handle->map->handle, LV2_ATOM__eventTransfer);
handle->view = puglInit(NULL, NULL);