31 #ifndef LVTK_EXTRA_HPP
32 #define LVTK_EXTRA_HPP
34 #if defined (LVTK_EXTRA_ENABLED)
36 #include <lvtk/types.hpp>
50 LVTK_MIXIN_CLASS NoUserResize {
59 static void map_feature_handlers(feature_handler_map& hmap) {
60 hmap[
"http://ll-plugins.nongnu.org/lv2/dev/ui#noUserResize"] =
61 &I<Derived>::handle_feature;
65 static void handle_feature(
void* instance,
void* data) {
66 Derived* d =
reinterpret_cast<Derived*
>(instance);
67 I<Derived>* e =
static_cast<I<Derived>*
>(d);
73 std::clog<<
" [LV2::NoUserResize] Validation "
74 <<(this->m_ok ?
"succeeded" :
"failed")<<
"."<<std::endl;
92 LVTK_MIXIN_CLASS FixedSize {
101 static void map_feature_handlers(feature_handler_map& hmap) {
102 hmap[
"http://ll-plugins.nongnu.org/lv2/dev/ui#fixedSize"] =
103 &I<Derived>::handle_feature;
107 static void handle_feature(
void* instance,
void* data) {
108 Derived* d =
reinterpret_cast<Derived*
>(instance);
109 I<Derived>* e =
static_cast<I<Derived>*
>(d);
115 std::clog<<
" [LV2::FixedSize] Validation "
116 <<(this->m_ok ?
"succeeded" :
"failed")<<
"."<<std::endl;
135 LVTK_MIXIN_CLASS WriteOSC {
143 I() : m_osc_type(0) {
144 m_buffer = lv2_event_buffer_new(
sizeof(LV2_Event) + 256, 0);
148 Derived* d =
static_cast<Derived*
>(
this);
150 uri_to_id(LVTK_EVENT_URI,
"http://lv2plug.in/ns/ext/osc#OscEvent");
151 m_event_buffer_format = d->
152 uri_to_id(LVTK_UI_URI,
"http://lv2plug.in/ns/extensions/ui#Events");
153 return !Required || (m_osc_type && m_event_buffer_format);
158 bool write_osc(uint32_t port,
const char* path,
const char* types, ...) {
162 lv2_event_buffer_reset(m_buffer, 0, m_buffer->data);
163 LV2_Event_Iterator iter;
164 lv2_event_begin(&iter, m_buffer);
167 uint32_t size = lv2_osc_event_vsize(path, types, ap);
172 bool success = lv2_osc_buffer_vappend(&iter, 0, 0, m_osc_type,
173 path, types, size, ap);
176 static_cast<Derived*
>(
this)->
177 write(port, m_buffer->header_size + m_buffer->capacity,
178 m_event_buffer_format, m_buffer);
185 uint32_t m_event_buffer_format;
186 LV2_Event_Buffer* m_buffer;
200 LVTK_MIXIN_CLASS Presets {
208 I() : m_hdesc(0), m_host_support(false) { }
211 static void map_feature_handlers(feature_handler_map& hmap) {
212 hmap[LVTK_UI_PRESETS_URI] = &I<Derived>::handle_feature;
216 static void handle_feature(
void* instance,
void* data) {
217 Derived* d =
reinterpret_cast<Derived*
>(instance);
218 I<Derived>* e =
static_cast<I<Derived>*
>(d);
219 e->m_hdesc =
static_cast<LV2UI_Presets_Feature*
>(data);
220 e->m_ok = (e->m_hdesc != 0);
221 e->m_host_support = (e->m_hdesc != 0);
226 std::clog<<
" [LV2::Presets] Validation "
227 <<(this->m_ok ?
"succeeded" :
"failed")<<
"."<<std::endl;
237 void preset_added(uint32_t number,
246 void preset_removed(uint32_t number) {
253 void presets_cleared() {
263 void current_preset_changed(uint32_t number) {
270 static void const* extension_data(
char const* uri) {
271 static LV2UI_Presets_GDesc desc = { &_preset_added,
274 &_current_preset_changed };
275 if (!std::strcmp(uri, LVTK_UI_PRESETS_URI))
284 void change_preset(uint32_t preset) {
287 std::clog<<
"[LV2::Presets] change_preset("<<preset<<
")"
290 m_hdesc->change_preset(static_cast<Derived*>(
this)->controller(),
293 else if (LVTK_DEBUG) {
294 std::clog<<
"[LV2::Presets] change_preset("<<preset<<
")"
295 <<
" --- Function not provided by host!"<<std::endl;
302 void save_preset(uint32_t preset,
char const* name) {
305 std::clog<<
"[LV2::Presets] save_preset("<<preset<<
", \""
306 <<name<<
"\")"<<std::endl;
308 m_hdesc->save_preset(static_cast<Derived*>(
this)->controller(),
311 else if (LVTK_DEBUG) {
312 std::clog<<
"[LV2::Presets] save_preset("<<preset<<
", \""
314 <<
" --- Function not provided by host!"<<std::endl;
320 bool host_supports_presets()
const {
321 return m_host_support;
326 static void _preset_added(LV2UI_Handle gui,
330 std::clog<<
"[LV2::Presets] Host called preset_added("
331 <<number<<
", \""<<name<<
"\")."<<std::endl;
333 static_cast<Derived*
>(gui)->preset_added(number, name);
336 static void _preset_removed(LV2UI_Handle gui,
339 std::clog<<
"[LV2::Presets] Host called preset_removed("
340 <<number<<
")."<<std::endl;
342 static_cast<Derived*
>(gui)->preset_removed(number);
345 static void _presets_cleared(LV2UI_Handle gui) {
347 std::clog<<
"[LV2::Presets] Host called presets_cleared()."
350 static_cast<Derived*
>(gui)->presets_cleared();
353 static void _current_preset_changed(LV2UI_Handle gui,
356 std::clog<<
"[LV2::Presets] Host called current_preset_changed("
357 <<number<<
")."<<std::endl;
359 static_cast<Derived*
>(gui)->current_preset_changed(number);
362 LV2UI_Presets_Feature* m_hdesc;
377 LVTK_MIXIN_CLASS FixedBufSize {
385 I() : m_buffer_size(0) { }
388 static void map_feature_handlers(feature_handler_map& hmap) {
389 hmap[
"http://tapas.affenbande.org/lv2/ext/fixed-buffersize"] =
390 &I<Derived>::handle_feature;
394 static void handle_feature(
void* instance,
void* data) {
395 Derived* d =
reinterpret_cast<Derived*
>(instance);
396 I<Derived>* fe =
static_cast<I<Derived>*
>(d);
397 fe->m_buffer_size = *
reinterpret_cast<uint32_t*
>(data);
399 std::clog<<
" [LV2::FixedBufSize] Host set buffer size to "
400 <<fe->m_buffer_size<<std::endl;
407 std::clog<<
" [LV2::FixedBufSize] Validation "
408 <<(this->m_ok ?
"succeeded" :
"failed")<<
"."<<std::endl;
418 uint32_t get_buffer_size()
const {
return m_buffer_size; }
420 uint32_t m_buffer_size;
433 LVTK_MIXIN_CLASS FixedP2BufSize {
441 I() : m_buffer_size(0) { }
444 static void map_feature_handlers(feature_handler_map& hmap) {
445 hmap[
"http://tapas.affenbande.org/lv2/ext/power-of-two-buffersize"] =
446 &I<Derived>::handle_feature;
450 static void handle_feature(
void* instance,
void* data) {
451 Derived* d =
reinterpret_cast<Derived*
>(instance);
452 I<Derived>* fe =
static_cast<I<Derived>*
>(d);
453 fe->m_buffer_size = *
reinterpret_cast<uint32_t*
>(data);
455 std::clog<<
" [LV2::FixedP2BufSize] Host set buffer size to "
456 <<fe->m_buffer_size<<std::endl;
463 std::clog<<
" [LV2::FixedP2BufSize] Validation "
464 <<(this->m_ok ?
"succeeded" :
"failed")<<
"."<<std::endl;
474 uint32_t get_buffer_size()
const {
return m_buffer_size; }
476 uint32_t m_buffer_size;
489 LVTK_MIXIN_CLASS SaveRestore {
498 static void map_feature_handlers(feature_handler_map& hmap) {
499 hmap[LVTK_SAVERESTORE_URI] = &I<Derived>::handle_feature;
503 static void handle_feature(
void* instance,
void* data) {
504 Derived* d =
reinterpret_cast<Derived*
>(instance);
505 I<Derived>* fe =
static_cast<I<Derived>*
>(d);
511 std::clog<<
" [LV2::SaveRestore] Validation "
512 <<(this->m_ok ?
"succeeded" :
"failed")<<
"."<<std::endl;
518 static const void* extension_data(
const char* uri) {
519 if (!std::strcmp(uri, LVTK_SAVERESTORE_URI)) {
520 static LV2SR_Descriptor srdesc = { &I<Derived>::_save,
521 &I<Derived>::_restore };
539 char* save(
const char* directory, LV2SR_File*** files) {
return 0; }
547 char* restore(
const LV2SR_File** files) {
return 0; }
553 static char* _save(LV2_Handle h,
554 const char* directory, LV2SR_File*** files) {
556 std::clog<<
"[LV2::SaveRestore] Host called save().\n"
557 <<
" directory: \""<<directory<<
"\""<<std::endl;
559 return reinterpret_cast<Derived*
>(h)->save(directory, files);
564 static char* _restore(LV2_Handle h,
const LV2SR_File** files) {
566 std::clog<<
"[LV2::SaveRestore] Host called restore().\n"
568 for (LV2SR_File
const** f = files; (*f) != 0; ++f)
569 std::clog<<
" \""<<(*f)->name<<
"\" -> \""<<(*f)->path<<
"\"\n";
570 std::clog<<std::flush;
572 return reinterpret_cast<Derived*
>(h)->restore(files);
586 LVTK_MIXIN_CLASS MsgContext {
595 static void map_feature_handlers(feature_handler_map& hmap) {
596 hmap[LVTK_CONTEXT_MESSAGE] = &I<Derived>::handle_feature;
600 static void handle_feature(
void* instance,
void* data) {
601 Derived* d =
reinterpret_cast<Derived*
>(instance);
602 I<Derived>* fe =
static_cast<I<Derived>*
>(d);
608 std::clog<<
" [LV2::MsgContext] Validation "
609 <<(this->m_ok ?
"succeeded" :
"failed")<<
"."<<std::endl;
615 static const void* extension_data(
const char* uri) {
616 if (!std::strcmp(uri, LVTK_CONTEXT_MESSAGE)) {
617 static LVTK_Blocking_Context desc = { &I<Derived>::_blocking_run,
618 &I<Derived>::_connect_port };
628 bool blocking_run(uint8_t* outputs_written) {
return false; }
634 static bool _blocking_run(LV2_Handle h, uint8_t* outputs_written) {
636 std::clog<<
"[LV2::MsgContext] Host called blocking_run()."<<std::endl;
637 return reinterpret_cast<Derived*
>(h)->blocking_run(outputs_written);
642 static void _connect_port(LV2_Handle h, uint32_t port,
void* buffer) {
643 reinterpret_cast<Derived*
>(h)->connect_port(port, buffer);
Definition: feature.hpp:34