diff options
author | Hanspeter Portner <dev@open-music-kontrollers.ch> | 2019-04-06 21:35:09 +0200 |
---|---|---|
committer | Hanspeter Portner <dev@open-music-kontrollers.ch> | 2019-04-06 21:35:09 +0200 |
commit | 3bd51e7f0a6493c052007754146dc6defd6040b2 (patch) | |
tree | 04af2d6805caea648faeb26a19974908b8622a5c | |
parent | 4258e0f80a6ece809ecdbee6d3ca47be1ed6b9a7 (diff) | |
parent | 50388a2cd1b7d0e664dd994e5b49a5376cf2b26d (diff) | |
download | monitors.lv2-3bd51e7f0a6493c052007754146dc6defd6040b2.tar.xz |
Merge commit '50388a2cd1b7d0e664dd994e5b49a5376cf2b26d'
-rw-r--r-- | canvas.lv2/canvas.lv2/idisp.h | 166 | ||||
-rw-r--r-- | canvas.lv2/canvas.lv2/lv2_extensions.h | 174 | ||||
-rw-r--r-- | canvas.lv2/canvas.lv2/render.h | 2 | ||||
-rw-r--r-- | canvas.lv2/canvas.lv2/render_cairo.h | 38 | ||||
-rw-r--r-- | canvas.lv2/canvas.lv2/render_nanovg.h | 14 |
5 files changed, 379 insertions, 15 deletions
diff --git a/canvas.lv2/canvas.lv2/idisp.h b/canvas.lv2/canvas.lv2/idisp.h new file mode 100644 index 0000000..afe7371 --- /dev/null +++ b/canvas.lv2/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/canvas.lv2/lv2_extensions.h b/canvas.lv2/canvas.lv2/lv2_extensions.h new file mode 100644 index 0000000..64fc3bc --- /dev/null +++ b/canvas.lv2/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/canvas.lv2/render.h b/canvas.lv2/canvas.lv2/render.h index af539aa..b809804 100644 --- a/canvas.lv2/canvas.lv2/render.h +++ b/canvas.lv2/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/canvas.lv2/render_cairo.h b/canvas.lv2/canvas.lv2/render_cairo.h index 86c3ec9..a41c72c 100644 --- a/canvas.lv2/canvas.lv2/render_cairo.h +++ b/canvas.lv2/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/canvas.lv2/render_nanovg.h b/canvas.lv2/canvas.lv2/render_nanovg.h index 3051afa..7df0661 100644 --- a/canvas.lv2/canvas.lv2/render_nanovg.h +++ b/canvas.lv2/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 |