@@ -369,7 +369,7 @@ const CarlaCachedPluginInfo* carla_get_cached_plugin_info(PluginType ptype, uint | |||
// features | |||
info.hints = 0x0; | |||
if (lilvPlugin.get_uis().size() > 0) | |||
if (lilvPlugin.get_uis().size() > 0 || lilvPlugin.get_modgui_resources_directory().as_uri() != nullptr) | |||
info.hints |= CB::PLUGIN_HAS_CUSTOM_UI; | |||
{ | |||
@@ -1699,6 +1699,27 @@ lilv_ui_get_binary_uri(const LilvUI* ui); | |||
/** | |||
Custom calls | |||
*/ | |||
LILV_API LilvNode* | |||
lilv_plugin_get_modgui_resources_directory(const LilvPlugin* plugin); | |||
LILV_API LilvNode* | |||
lilv_plugin_get_modgui_stylesheet(const LilvPlugin* plugin); | |||
LILV_API LilvNode* | |||
lilv_plugin_get_modgui_icon_template(const LilvPlugin* plugin); | |||
LILV_API LilvNode* | |||
lilv_plugin_get_modgui_settings_template(const LilvPlugin* plugin); | |||
LILV_API LilvNode* | |||
lilv_plugin_get_modgui_template_data(const LilvPlugin* plugin); | |||
LILV_API LilvNode* | |||
lilv_plugin_get_modgui_screenshot(const LilvPlugin* plugin); | |||
LILV_API LilvNode* | |||
lilv_plugin_get_modgui_thumbnail(const LilvPlugin* plugin); | |||
LILV_API const LilvNodes* | |||
lilv_ui_get_supported_features(const LilvUI* ui); | |||
@@ -234,6 +234,13 @@ struct Plugin { | |||
LILV_WRAP0(Nodes, plugin, get_extension_data); | |||
LILV_WRAP0(UIs, plugin, get_uis); | |||
LILV_WRAP1(Nodes, plugin, get_related, Node, type); | |||
LILV_WRAP0(Node, plugin, get_modgui_resources_directory); | |||
LILV_WRAP0(Node, plugin, get_modgui_stylesheet); | |||
LILV_WRAP0(Node, plugin, get_modgui_icon_template); | |||
LILV_WRAP0(Node, plugin, get_modgui_settings_template); | |||
LILV_WRAP0(Node, plugin, get_modgui_template_data); | |||
LILV_WRAP0(Node, plugin, get_modgui_screenshot); | |||
LILV_WRAP0(Node, plugin, get_modgui_thumbnail); | |||
inline Port get_port_by_index(unsigned index) { | |||
return Port(me, lilv_plugin_get_port_by_index(me, index)); | |||
@@ -31,6 +31,7 @@ | |||
#define NS_DOAP (const uint8_t*)"http://usefulinc.com/ns/doap#" | |||
#define NS_FOAF (const uint8_t*)"http://xmlns.com/foaf/0.1/" | |||
#define NS_MOD (const uint8_t*)"http://portalmod.com/ns/modgui#" | |||
/** Ownership of `uri` is taken */ | |||
LilvPlugin* | |||
@@ -908,6 +909,131 @@ lilv_plugin_get_author_homepage(const LilvPlugin* plugin) | |||
return NULL; | |||
} | |||
static const SordNode* | |||
lilv_plugin_get_modgui(const LilvPlugin* p) | |||
{ | |||
lilv_plugin_load_if_necessary(p); | |||
SordNode* mod_gui = sord_new_uri( | |||
p->world->world, NS_MOD "gui"); | |||
SordIter* gui = lilv_world_query_internal( | |||
p->world, | |||
p->plugin_uri->node, | |||
mod_gui, | |||
NULL); | |||
sord_node_free(p->world->world, mod_gui); | |||
if (sord_iter_end(gui)) { | |||
sord_iter_free(gui); | |||
return NULL; | |||
} | |||
const SordNode* Gui = sord_iter_get_node(gui, SORD_OBJECT); | |||
sord_iter_free(gui); | |||
return Gui; | |||
} | |||
LILV_API LilvNode* | |||
lilv_plugin_get_modgui_resources_directory(const LilvPlugin* plugin) | |||
{ | |||
const SordNode* modgui = lilv_plugin_get_modgui(plugin); | |||
if (modgui) { | |||
SordWorld* sworld = plugin->world->world; | |||
SordNode* modgui_res = sord_new_uri(sworld, NS_MOD "resourcesDirectory"); | |||
LilvNode* ret = lilv_plugin_get_one(plugin, modgui, modgui_res); | |||
sord_node_free(sworld, modgui_res); | |||
return ret; | |||
} | |||
return NULL; | |||
} | |||
LILV_API LilvNode* | |||
lilv_plugin_get_modgui_stylesheet(const LilvPlugin* plugin) | |||
{ | |||
const SordNode* modgui = lilv_plugin_get_modgui(plugin); | |||
if (modgui) { | |||
SordWorld* sworld = plugin->world->world; | |||
SordNode* modgui_style = sord_new_uri(sworld, NS_MOD "stylesheet"); | |||
LilvNode* ret = lilv_plugin_get_one(plugin, modgui, modgui_style); | |||
sord_node_free(sworld, modgui_style); | |||
return ret; | |||
} | |||
return NULL; | |||
} | |||
LILV_API LilvNode* | |||
lilv_plugin_get_modgui_icon_template(const LilvPlugin* plugin) | |||
{ | |||
const SordNode* modgui = lilv_plugin_get_modgui(plugin); | |||
if (modgui) { | |||
SordWorld* sworld = plugin->world->world; | |||
SordNode* modgui_tmpl = sord_new_uri(sworld, NS_MOD "iconTemplate"); | |||
LilvNode* ret = lilv_plugin_get_one(plugin, modgui, modgui_tmpl); | |||
sord_node_free(sworld, modgui_tmpl); | |||
return ret; | |||
} | |||
return NULL; | |||
} | |||
LILV_API LilvNode* | |||
lilv_plugin_get_modgui_settings_template(const LilvPlugin* plugin) | |||
{ | |||
const SordNode* modgui = lilv_plugin_get_modgui(plugin); | |||
if (modgui) { | |||
SordWorld* sworld = plugin->world->world; | |||
SordNode* modgui_tmpl = sord_new_uri(sworld, NS_MOD "settingsTemplate"); | |||
LilvNode* ret = lilv_plugin_get_one(plugin, modgui, modgui_tmpl); | |||
sord_node_free(sworld, modgui_tmpl); | |||
return ret; | |||
} | |||
return NULL; | |||
} | |||
LILV_API LilvNode* | |||
lilv_plugin_get_modgui_template_data(const LilvPlugin* plugin) | |||
{ | |||
const SordNode* modgui = lilv_plugin_get_modgui(plugin); | |||
if (modgui) { | |||
SordWorld* sworld = plugin->world->world; | |||
SordNode* modgui_tmpl = sord_new_uri(sworld, NS_MOD "templateData"); | |||
LilvNode* ret = lilv_plugin_get_one(plugin, modgui, modgui_tmpl); | |||
sord_node_free(sworld, modgui_tmpl); | |||
return ret; | |||
} | |||
return NULL; | |||
} | |||
LILV_API LilvNode* | |||
lilv_plugin_get_modgui_screenshot(const LilvPlugin* plugin) | |||
{ | |||
const SordNode* modgui = lilv_plugin_get_modgui(plugin); | |||
if (modgui) { | |||
SordWorld* sworld = plugin->world->world; | |||
SordNode* modgui_scr = sord_new_uri(sworld, NS_MOD "screenshot"); | |||
LilvNode* ret = lilv_plugin_get_one(plugin, modgui, modgui_scr); | |||
sord_node_free(sworld, modgui_scr); | |||
return ret; | |||
} | |||
return NULL; | |||
} | |||
LILV_API LilvNode* | |||
lilv_plugin_get_modgui_thumbnail(const LilvPlugin* plugin) | |||
{ | |||
const SordNode* modgui = lilv_plugin_get_modgui(plugin); | |||
if (modgui) { | |||
SordWorld* sworld = plugin->world->world; | |||
SordNode* modgui_thumb = sord_new_uri(sworld, NS_MOD "thumbnail"); | |||
LilvNode* ret = lilv_plugin_get_one(plugin, modgui, modgui_thumb); | |||
sord_node_free(sworld, modgui_thumb); | |||
return ret; | |||
} | |||
return NULL; | |||
} | |||
LILV_API bool | |||
lilv_plugin_is_replaced(const LilvPlugin* plugin) | |||
{ | |||
@@ -221,6 +221,7 @@ typedef uint32_t LV2_Property; | |||
#define LV2_UI_X11 7 | |||
#define LV2_UI_EXTERNAL 8 | |||
#define LV2_UI_OLD_EXTERNAL 9 | |||
#define LV2_UI_MOD 10 | |||
#define LV2_IS_UI_GTK2(x) ((x) == LV2_UI_GTK2) | |||
#define LV2_IS_UI_GTK3(x) ((x) == LV2_UI_GTK3) | |||
@@ -231,6 +232,7 @@ typedef uint32_t LV2_Property; | |||
#define LV2_IS_UI_X11(x) ((x) == LV2_UI_X11) | |||
#define LV2_IS_UI_EXTERNAL(x) ((x) == LV2_UI_EXTERNAL) | |||
#define LV2_IS_UI_OLD_EXTERNAL(x) ((x) == LV2_UI_OLD_EXTERNAL) | |||
#define LV2_IS_UI_MOD(x) ((x) == LV2_UI_MOD) | |||
// Plugin Types | |||
#define LV2_PLUGIN_DELAY 0x000001 | |||
@@ -92,6 +92,7 @@ | |||
#define NS_rdf "http://www.w3.org/1999/02/22-rdf-syntax-ns#" | |||
#define NS_rdfs "http://www.w3.org/2000/01/rdf-schema#" | |||
#define NS_llmm "http://ll-plugins.nongnu.org/lv2/ext/midimap#" | |||
#define NS_mod "http://portalmod.com/ns/modgui#" | |||
#define LV2_MIDI_Map__CC "http://ll-plugins.nongnu.org/lv2/namespace#CC" | |||
#define LV2_MIDI_Map__NRPN "http://ll-plugins.nongnu.org/lv2/namespace#NRPN" | |||
@@ -363,9 +364,7 @@ public: | |||
rdf_type (new_uri(NS_rdf "type")), | |||
rdfs_label (new_uri(NS_rdfs "label")), | |||
needsInit(true) | |||
{ | |||
} | |||
needsInit(true) {} | |||
static Lv2WorldClass& getInstance() | |||
{ | |||
@@ -1265,11 +1264,13 @@ const LV2_RDF_Descriptor* lv2_rdf_new(const LV2_URI uri, const bool loadPresets) | |||
// ------------------------------------------------------------------- | |||
// Set Plugin UIs | |||
{ | |||
const bool hasMODGui(lilvPlugin.get_modgui_resources_directory().as_uri() != nullptr); | |||
Lilv::UIs lilvUIs(lilvPlugin.get_uis()); | |||
if (lilvUIs.size() > 0) | |||
if (lilvUIs.size() > 0 || hasMODGui) | |||
{ | |||
rdfDescriptor->UICount = lilvUIs.size(); | |||
rdfDescriptor->UICount = lilvUIs.size() + (hasMODGui ? 1 : 0); | |||
rdfDescriptor->UIs = new LV2_RDF_UI[rdfDescriptor->UICount]; | |||
uint32_t h = 0; | |||
@@ -1389,6 +1390,29 @@ const LV2_RDF_Descriptor* lv2_rdf_new(const LV2_URI uri, const bool loadPresets) | |||
lilv_nodes_free(const_cast<LilvNodes*>(lilvExtensionDataNodes.me)); | |||
} | |||
} | |||
for (; hasMODGui;) | |||
{ | |||
CARLA_SAFE_ASSERT_BREAK(h == rdfDescriptor->UICount-1); | |||
LV2_RDF_UI* const rdfUI(&rdfDescriptor->UIs[h++]); | |||
// ------------------------------------------------------- | |||
// Set UI Type | |||
rdfUI->Type = LV2_UI_MOD; | |||
// ------------------------------------------------------- | |||
// Set UI Information | |||
if (const char* const resDir = lilvPlugin.get_modgui_resources_directory().as_uri()) | |||
rdfUI->URI = carla_strdup(lilv_uri_to_path(resDir)); | |||
if (rdfDescriptor->Bundle != nullptr) | |||
rdfUI->Bundle = carla_strdup(rdfDescriptor->Bundle); | |||
break; | |||
} | |||
} | |||
lilv_nodes_free(const_cast<LilvNodes*>(lilvUIs.me)); | |||