aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Hanspeter Portner <dev@open-music-kontrollers.ch>2019-04-06 21:40:03 +0200
committerGravatar Hanspeter Portner <dev@open-music-kontrollers.ch>2019-04-06 21:40:03 +0200
commite95c7a66caaa54a50b5aa71bc5e7d59a1e4d7e07 (patch)
tree397163290ba3e8b3627919c84b3c26a486d53d1a
parent4c278f549c06f055e6a78b9872895189fb7e21ca (diff)
downloadsynthpod-e95c7a66caaa54a50b5aa71bc5e7d59a1e4d7e07.tar.xz
Squashed 'canvas.lv2/' changes from 3259ea1e..054228e5
054228e5 add inline_display wrapper. 01fbfd95 fix pedantic compiler warnings. git-subtree-dir: canvas.lv2 git-subtree-split: 054228e51c47fdf3c050a40190c29c74839fe245
-rw-r--r--canvas.lv2/idisp.h166
-rw-r--r--canvas.lv2/lv2_extensions.h174
-rw-r--r--canvas.lv2/render.h2
-rw-r--r--canvas.lv2/render_cairo.h38
-rw-r--r--canvas.lv2/render_nanovg.h14
5 files changed, 379 insertions, 15 deletions
diff --git a/canvas.lv2/idisp.h b/canvas.lv2/idisp.h
new file mode 100644
index 0000000..afe7371
--- /dev/null
+++ b/canvas.lv2/idisp.h
@@ -0,0 +1,166 @@
+/*
+ * Copyright (c) 2016 Hanspeter Portner (dev@open-music-kontrollers.ch)
+ *
+ * This is free software: you can redistribute it and/or modify
+ * it under the terms of the Artistic License 2.0 as published by
+ * The Perl Foundation.
+ *
+ * This source is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * Artistic License 2.0 for more details.
+ *
+ * You should have received a copy of the Artistic License 2.0
+ * along the source as a COPYING file. If not, obtain it from
+ * http://www.perlfoundation.org/artistic_license_2_0.
+ */
+
+#ifndef _LV2_CANVAS_IDISP_H
+#define _LV2_CANVAS_IDISP_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define LV2_CANVAS_RENDER_CAIRO
+#include <canvas.lv2/render.h>
+#include <canvas.lv2/lv2_extensions.h>
+
+typedef struct _LV2_Canvas_Idisp LV2_Canvas_Idisp;
+
+struct _LV2_Canvas_Idisp {
+ LV2_Inline_Display *queue_draw;
+ LV2_Canvas canvas;
+ LV2_Inline_Display_Image_Surface image_surface;
+ struct {
+ cairo_surface_t *surface;
+ cairo_t *ctx;
+ } cairo;
+};
+
+static inline LV2_Inline_Display_Image_Surface *
+_lv2_canvas_idisp_surf_init(LV2_Canvas_Idisp *idisp, int w, int h)
+{
+ LV2_Inline_Display_Image_Surface *surf = &idisp->image_surface;
+
+ surf->width = w;
+ surf->height = w > h ? h : w; // try to use 1:1 ratio
+ surf->stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, surf->width);
+ surf->data = realloc(surf->data, surf->stride * surf->height);
+ if(!surf->data)
+ {
+ return NULL;
+ }
+
+ idisp->cairo.surface = cairo_image_surface_create_for_data(
+ surf->data, CAIRO_FORMAT_ARGB32, surf->width, surf->height, surf->stride);
+
+ if(idisp->cairo.surface)
+ {
+ cairo_surface_set_device_scale(idisp->cairo.surface, surf->width, surf->height);
+
+ idisp->cairo.ctx = cairo_create(idisp->cairo.surface);
+ if(idisp->cairo.ctx)
+ {
+ cairo_select_font_face(idisp->cairo.ctx, "cairo:monospace",
+ CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
+ }
+ }
+
+ return surf;
+}
+
+static inline void
+_lv2_canvas_idisp_surf_deinit(LV2_Canvas_Idisp *idisp)
+{
+ LV2_Inline_Display_Image_Surface *surf = &idisp->image_surface;
+
+ if(idisp->cairo.ctx)
+ {
+ cairo_destroy(idisp->cairo.ctx);
+ idisp->cairo.ctx = NULL;
+ }
+
+ if(idisp->cairo.surface)
+ {
+ cairo_surface_finish(idisp->cairo.surface);
+ cairo_surface_destroy(idisp->cairo.surface);
+ idisp->cairo.surface = NULL;
+ }
+
+ if(surf->data)
+ {
+ free(surf->data);
+ surf->data = NULL;
+ }
+}
+
+static inline LV2_Inline_Display_Image_Surface *
+lv2_canvas_idisp_surf_configure(LV2_Canvas_Idisp *idisp,
+ uint32_t w, uint32_t h, float aspect_ratio)
+{
+ LV2_Inline_Display_Image_Surface *surf = &idisp->image_surface;
+ int W;
+ int H;
+
+ if(aspect_ratio < 1.f)
+ {
+ W = h * aspect_ratio;
+ H = h;
+ }
+ else if(aspect_ratio > 1.f)
+ {
+ W = w;
+ H = w / aspect_ratio;
+ }
+ else // aspect_ratio == 0.f
+ {
+ W = w;
+ H = h;
+ }
+
+ if( (surf->width != W) || (surf->height != H) || !surf->data)
+ {
+ _lv2_canvas_idisp_surf_deinit(idisp);
+ surf = _lv2_canvas_idisp_surf_init(idisp, W, H);
+ }
+
+ return surf;
+}
+
+static inline void
+lv2_canvas_idisp_init(LV2_Canvas_Idisp *idisp, LV2_Inline_Display *queue_draw,
+ LV2_URID_Map *map)
+{
+ lv2_canvas_init(&idisp->canvas, map);
+ idisp->queue_draw = queue_draw;
+}
+
+static inline void
+lv2_canvas_idisp_deinit(LV2_Canvas_Idisp *idisp)
+{
+ _lv2_canvas_idisp_surf_deinit(idisp);
+}
+
+static inline void
+lv2_canvas_idisp_queue_draw(LV2_Canvas_Idisp *idisp)
+{
+ if(idisp->queue_draw)
+ {
+ idisp->queue_draw->queue_draw(idisp->queue_draw->handle);
+ }
+}
+
+static inline bool
+lv2_canvas_idisp_render_body(LV2_Canvas_Idisp *idisp, uint32_t type,
+ uint32_t size, const LV2_Atom *body)
+{
+ return lv2_canvas_render_body(&idisp->canvas, idisp->cairo.ctx,
+ type, size, body);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _LV2_CANVAS_IDISP_H
diff --git a/canvas.lv2/lv2_extensions.h b/canvas.lv2/lv2_extensions.h
new file mode 100644
index 0000000..64fc3bc
--- /dev/null
+++ b/canvas.lv2/lv2_extensions.h
@@ -0,0 +1,174 @@
+/*
+ Copyright 2016 Robin Gareus <robin@gareus.org>
+
+ Permission to use, copy, modify, and/or distribute this software for any
+ purpose with or without fee is hereby granted, provided that the above
+ copyright notice and this permission notice appear in all copies.
+
+ THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+*/
+
+#ifndef _ardour_lv2_extensions_h_
+#define _ardour_lv2_extensions_h_
+
+#include "lv2/lv2plug.in/ns/lv2core/lv2.h"
+
+/**
+ @defgroup inlinedisplay Inline-Display
+
+ Support for displaying a miniaturized generic view
+ directly in the host's Mixer Window.
+
+ @{
+*/
+
+#define LV2_INLINEDISPLAY_URI "http://harrisonconsoles.com/lv2/inlinedisplay"
+#define LV2_INLINEDISPLAY_PREFIX LV2_INLINEDISPLAY_URI "#"
+#define LV2_INLINEDISPLAY__interface LV2_INLINEDISPLAY_PREFIX "interface"
+#define LV2_INLINEDISPLAY__queue_draw LV2_INLINEDISPLAY_PREFIX "queue_draw"
+
+/** Opaque handle for LV2_Inline_Display::queue_draw() */
+typedef void* LV2_Inline_Display_Handle;
+
+/** raw image pixmap format is ARGB32,
+ * the data pointer is owned by the plugin and must be valid
+ * from the first call to render until cleanup.
+ */
+typedef struct {
+ unsigned char *data;
+ int width;
+ int height;
+ int stride;
+} LV2_Inline_Display_Image_Surface;
+
+/** a LV2 Feature provided by the Host to the plugin */
+typedef struct {
+ /** Opaque host data */
+ LV2_Inline_Display_Handle handle;
+ /** Request from run() that the host should call render() at a later time
+ * to update the inline display */
+ void (*queue_draw)(LV2_Inline_Display_Handle handle);
+} LV2_Inline_Display;
+
+/**
+ * Plugin Inline-Display Interface.
+ */
+typedef struct {
+ /**
+ * The render method. This is called by the host in a non-realtime context,
+ * usually the main GUI thread.
+ * The data pointer is owned by the plugin and must be valid
+ * from the first call to render until cleanup.
+ *
+ * @param instance The LV2 instance
+ * @param w the max available width
+ * @param h the max available height
+ * @return pointer to a LV2_Inline_Display_Image_Surface or NULL
+ */
+ LV2_Inline_Display_Image_Surface* (*render)(LV2_Handle instance, uint32_t w, uint32_t h);
+} LV2_Inline_Display_Interface;
+
+/**
+ @}
+*/
+
+/**
+ @defgroup automate Self-Automation
+
+ Support for plugins to write automation data via Atom Events
+
+ @{
+*/
+
+#define LV2_AUTOMATE_URI "http://ardour.org/lv2/automate"
+#define LV2_AUTOMATE_URI_PREFIX LV2_AUTOMATE_URI "#"
+/** an lv2:optionalFeature */
+#define LV2_AUTOMATE_URI__can_write LV2_AUTOMATE_URI_PREFIX "canWriteAutomatation"
+/** atom:supports */
+#define LV2_AUTOMATE_URI__control LV2_AUTOMATE_URI_PREFIX "automationControl"
+/** lv2:portProperty */
+#define LV2_AUTOMATE_URI__controlled LV2_AUTOMATE_URI_PREFIX "automationControlled"
+#define LV2_AUTOMATE_URI__controller LV2_AUTOMATE_URI_PREFIX "automationController"
+
+/** atom messages */
+#define LV2_AUTOMATE_URI__event LV2_AUTOMATE_URI_PREFIX "event"
+#define LV2_AUTOMATE_URI__setup LV2_AUTOMATE_URI_PREFIX "setup"
+#define LV2_AUTOMATE_URI__finalize LV2_AUTOMATE_URI_PREFIX "finalize"
+#define LV2_AUTOMATE_URI__start LV2_AUTOMATE_URI_PREFIX "start"
+#define LV2_AUTOMATE_URI__end LV2_AUTOMATE_URI_PREFIX "end"
+#define LV2_AUTOMATE_URI__parameter LV2_AUTOMATE_URI_PREFIX "parameter"
+#define LV2_AUTOMATE_URI__value LV2_AUTOMATE_URI_PREFIX "value"
+
+/**
+ @}
+*/
+
+/**
+ @defgroup license License-Report
+
+ Allow for commercial LV2 to report their
+ licensing status.
+
+ @{
+*/
+
+#define LV2_PLUGINLICENSE_URI "http://harrisonconsoles.com/lv2/license"
+#define LV2_PLUGINLICENSE_PREFIX LV2_PLUGINLICENSE_URI "#"
+#define LV2_PLUGINLICENSE__interface LV2_PLUGINLICENSE_PREFIX "interface"
+
+typedef struct _LV2_License_Interface {
+ /* @return -1 if no license is needed; 0 if unlicensed, 1 if licensed */
+ int (*is_licensed)(LV2_Handle instance);
+ /* @return a string copy of the licensee name if licensed, or NULL, the caller needs to free this */
+ char* (*licensee)(LV2_Handle instance);
+ /* @return a URI identifying the plugin-bundle or plugin for which a given license is valid */
+ const char* (*product_uri)(LV2_Handle instance);
+ /* @return human readable product name for the URI */
+ const char* (*product_name)(LV2_Handle instance);
+ /* @return link to website or webstore */
+ const char* (*store_url)(LV2_Handle instance);
+} LV2_License_Interface;
+
+/**
+ @}
+*/
+
+/**
+ @defgroup plugin provided bypass
+
+ A port with the designation "processing#enable" must
+ control a plugin's internal bypass mode.
+
+ If the port value is larger than zero the plugin processes
+ normally.
+
+ If the port value is zero, the plugin is expected to bypass
+ all signals unmodified.
+
+ The plugin is responsible for providing a click-free transition
+ between the states.
+
+ (values less than zero are reserved for future use:
+ e.g click-free insert/removal of latent plugins.
+ Generally values <= 0 are to be treated as bypassed.)
+
+ lv2:designation <http://ardour.org/lv2/processing#enable> ;
+
+ @{
+*/
+
+#define LV2_PROCESSING_URI "http://ardour.org/lv2/processing"
+#define LV2_PROCESSING_URI_PREFIX LV2_PROCESSING_URI "#"
+#define LV2_PROCESSING_URI__enable LV2_PROCESSING_URI_PREFIX "enable"
+
+/**
+ @}
+*/
+
+#endif
diff --git a/canvas.lv2/render.h b/canvas.lv2/render.h
index af539aa..b809804 100644
--- a/canvas.lv2/render.h
+++ b/canvas.lv2/render.h
@@ -84,4 +84,4 @@ _lv2_canvas_render_get_type(const LV2_Atom *body, LV2_URID type)
# include <canvas.lv2/render_cairo.h>
#endif
-#endif // CANVAS_IMPLEMENTATION
+#endif // _LV2_CANVAS_RENDER_H
diff --git a/canvas.lv2/render_cairo.h b/canvas.lv2/render_cairo.h
index 86c3ec9..a41c72c 100644
--- a/canvas.lv2/render_cairo.h
+++ b/canvas.lv2/render_cairo.h
@@ -30,7 +30,8 @@ extern "C" {
static inline void
_lv2_canvas_render_beginPath(void *data,
- LV2_Canvas_URID *urid, const LV2_Atom *body)
+ LV2_Canvas_URID *urid __attribute__((unused)),
+ const LV2_Atom *body __attribute__((unused)))
{
cairo_t *ctx = data;
cairo_new_sub_path(ctx);
@@ -38,7 +39,8 @@ _lv2_canvas_render_beginPath(void *data,
static inline void
_lv2_canvas_render_closePath(void *data,
- LV2_Canvas_URID *urid, const LV2_Atom *body)
+ LV2_Canvas_URID *urid __attribute__((unused)),
+ const LV2_Atom *body __attribute__((unused)))
{
cairo_t *ctx = data;
cairo_close_path(ctx);
@@ -235,7 +237,8 @@ _lv2_canvas_render_miterLimit(void *data,
static inline void
_lv2_canvas_render_stroke(void *data,
- LV2_Canvas_URID *urid, const LV2_Atom *body)
+ LV2_Canvas_URID *urid __attribute__((unused)),
+ const LV2_Atom *body __attribute__((unused)))
{
cairo_t *ctx = data;
cairo_stroke(ctx);
@@ -243,7 +246,8 @@ _lv2_canvas_render_stroke(void *data,
static inline void
_lv2_canvas_render_fill(void *data,
- LV2_Canvas_URID *urid, const LV2_Atom *body)
+ LV2_Canvas_URID *urid __attribute__((unused)),
+ const LV2_Atom *body __attribute__((unused)))
{
cairo_t *ctx = data;
cairo_fill(ctx);
@@ -251,7 +255,8 @@ _lv2_canvas_render_fill(void *data,
static inline void
_lv2_canvas_render_clip(void *data,
- LV2_Canvas_URID *urid, const LV2_Atom *body)
+ LV2_Canvas_URID *urid __attribute__((unused)),
+ const LV2_Atom *body __attribute__((unused)))
{
cairo_t *ctx = data;
cairo_clip(ctx);
@@ -259,7 +264,8 @@ _lv2_canvas_render_clip(void *data,
static inline void
_lv2_canvas_render_save(void *data,
- LV2_Canvas_URID *urid, const LV2_Atom *body)
+ LV2_Canvas_URID *urid __attribute__((unused)),
+ const LV2_Atom *body __attribute__((unused)))
{
cairo_t *ctx = data;
cairo_save(ctx);
@@ -267,7 +273,8 @@ _lv2_canvas_render_save(void *data,
static inline void
_lv2_canvas_render_restore(void *data,
- LV2_Canvas_URID *urid, const LV2_Atom *body)
+ LV2_Canvas_URID *urid __attribute__((unused)),
+ const LV2_Atom *body __attribute__((unused)))
{
cairo_t *ctx = data;
cairo_restore(ctx);
@@ -336,7 +343,8 @@ _lv2_canvas_render_transform(void *data,
static inline void
_lv2_canvas_render_reset(void *data,
- LV2_Canvas_URID *urid, const LV2_Atom *body)
+ LV2_Canvas_URID *urid __attribute__((unused)),
+ const LV2_Atom *body __attribute__((unused)))
{
cairo_t *ctx = data;
cairo_identity_matrix(ctx);
@@ -512,11 +520,12 @@ lv2_canvas_init(LV2_Canvas *canvas, LV2_URID_Map *map)
}
static inline bool
-lv2_canvas_render(LV2_Canvas *canvas, cairo_t *ctx, const LV2_Atom_Tuple *tup)
+lv2_canvas_render_body(LV2_Canvas *canvas, cairo_t *ctx, uint32_t type,
+ uint32_t size, const LV2_Atom *body)
{
LV2_Canvas_URID *urid = &canvas->urid;
- if(!tup || (tup->atom.type != urid->forge.Tuple) )
+ if(!body || (type != urid->forge.Tuple) )
return false;
// save state
@@ -532,7 +541,7 @@ lv2_canvas_render(LV2_Canvas *canvas, cairo_t *ctx, const LV2_Atom_Tuple *tup)
cairo_set_line_width(ctx, 0.01);
cairo_set_source_rgba(ctx, 1.0, 1.0, 1.0, 1.0);
- LV2_ATOM_TUPLE_FOREACH(tup, itm)
+ LV2_ATOM_TUPLE_BODY_FOREACH(body, size, itm)
{
if(lv2_atom_forge_is_object_type(&urid->forge, itm->type))
{
@@ -561,6 +570,13 @@ lv2_canvas_render(LV2_Canvas *canvas, cairo_t *ctx, const LV2_Atom_Tuple *tup)
return true;
}
+static inline bool
+lv2_canvas_render(LV2_Canvas *canvas, cairo_t *ctx, const LV2_Atom_Tuple *tup)
+{
+ return lv2_canvas_render_body(canvas, ctx, tup->atom.type, tup->atom.size,
+ LV2_ATOM_BODY_CONST(&tup->atom));
+}
+
#ifdef __cplusplus
}
#endif
diff --git a/canvas.lv2/render_nanovg.h b/canvas.lv2/render_nanovg.h
index 3051afa..7df0661 100644
--- a/canvas.lv2/render_nanovg.h
+++ b/canvas.lv2/render_nanovg.h
@@ -533,11 +533,12 @@ lv2_canvas_init(LV2_Canvas *canvas, LV2_URID_Map *map)
}
static inline bool
-lv2_canvas_render(LV2_Canvas *canvas, NVGcontext *ctx, const LV2_Atom_Tuple *tup)
+lv2_canvas_render_body(LV2_Canvas *canvas, cairo_t *ctx, uint32_t type,
+ uint32_t size, const LV2_Atom *body)
{
LV2_Canvas_URID *urid = &canvas->urid;
- if(!tup || (tup->atom.type != urid->forge.Tuple) )
+ if(!body || (type != urid->forge.Tuple) )
return false;
// save state
@@ -554,7 +555,7 @@ lv2_canvas_render(LV2_Canvas *canvas, NVGcontext *ctx, const LV2_Atom_Tuple *tup
nvgStrokeColor(ctx, nvgRGBA(0xff, 0xff, 0xff, 0xff));
nvgFillColor(ctx, nvgRGBA(0xff, 0xff, 0xff, 0xff));
- LV2_ATOM_TUPLE_FOREACH(tup, itm)
+ LV2_ATOM_TUPLE_BODY_FOREACH(body, size, itm)
{
if(lv2_atom_forge_is_object_type(&urid->forge, itm->type))
{
@@ -579,6 +580,13 @@ lv2_canvas_render(LV2_Canvas *canvas, NVGcontext *ctx, const LV2_Atom_Tuple *tup
return true;
}
+static inline bool
+lv2_canvas_render(LV2_Canvas *canvas, NVGcontext *ctx, const LV2_Atom_Tuple *tup)
+{
+ return lv2_canvas_render_body(canvas, ctx, tup->atom.type, tup->atom.size,
+ LV2_ATOM_BODY_CONST(&tup->atom));
+}
+
#ifdef __cplusplus
}
#endif