From a06305e2c8068f0519f25ab3d0eddf7278d6ba7c Mon Sep 17 00:00:00 2001 From: David Robillard Date: Sun, 23 Sep 2007 18:51:21 +0000 Subject: Support for plugin UIs in separate bundles. Fix some memory leaks. Better/more future proof UI interface. git-svn-id: http://svn.drobilla.net/lad/slv2@772 a436a847-0d15-0410-975c-d299462d15a1 --- slv2/Makefile.am | 2 ++ slv2/plugin.h | 18 +++------------ slv2/pluginuiinstance.h | 2 +- slv2/slv2.h | 2 ++ slv2/types.h | 6 ++++- slv2/value.h | 26 +-------------------- src/Makefile.am | 2 ++ src/plugin.c | 61 ++++++++++++++++++++++++++++++++++++++----------- src/pluginuiinstance.c | 5 +++- src/slv2_internal.h | 25 ++++++++++++-------- src/value.c | 20 ++-------------- src/world.c | 3 ++- utils/lv2_inspect.c | 30 +++++++++++++----------- 13 files changed, 105 insertions(+), 97 deletions(-) diff --git a/slv2/Makefile.am b/slv2/Makefile.am index 9c0aa21..a3f9a0d 100644 --- a/slv2/Makefile.am +++ b/slv2/Makefile.am @@ -7,6 +7,8 @@ slv2include_HEADERS = \ plugin.h \ pluginclass.h \ pluginclasses.h \ + pluginui.h \ + pluginuis.h \ pluginuiinstance.h \ plugininstance.h \ plugins.h \ diff --git a/slv2/plugin.h b/slv2/plugin.h index 224a450..97d830f 100644 --- a/slv2/plugin.h +++ b/slv2/plugin.h @@ -201,7 +201,7 @@ slv2_plugin_get_value_for_subject(SLV2Plugin p, * understand all the LV2 Properties associated with that plugin (if this is * not what you want, see slv2_plugin_get_hints). * - * Return value must be freed by caller with slv2_value_free. + * Return value must be freed by caller with slv2_values_free. * * Time = Query */ @@ -214,7 +214,7 @@ slv2_plugin_get_properties(SLV2Plugin p); * LV2 Hints are suggestions that may be useful for a host. LV2 Hints may be * ignored and the plugin will still function correctly. * - * Return value must be freed by caller with slv2_value_free. + * Return value must be freed by caller with slv2_values_free. * * Time = Query */ @@ -352,22 +352,10 @@ slv2_plugin_get_port_by_symbol(SLV2Plugin plugin, * * Time = Query */ -SLV2Values +SLV2PluginUIs slv2_plugin_get_uis(SLV2Plugin plugin); -/** Get the URI for a UI library. - * - * \param plugin The plugin that the UI is for. - * \param ui A UI identifier as returned by slv2_plugin_get_uis() (with type SLV2_VALUE_UI). - * - * Time = Query - */ -SLV2Value -slv2_plugin_get_ui_library_uri(SLV2Plugin plugin, - SLV2Value ui); - - /** @} */ #ifdef __cplusplus diff --git a/slv2/pluginuiinstance.h b/slv2/pluginuiinstance.h index 48b915e..0a3d8d7 100644 --- a/slv2/pluginuiinstance.h +++ b/slv2/pluginuiinstance.h @@ -73,7 +73,7 @@ typedef struct _SLV2UIInstance { */ SLV2UIInstance slv2_plugin_ui_instantiate(SLV2Plugin plugin, - SLV2Value gui, + SLV2PluginUI gui, LV2UI_Write_Function write_function, LV2UI_Command_Function command_function, LV2UI_Program_Change_Function program_function, diff --git a/slv2/slv2.h b/slv2/slv2.h index 64c40c6..dbb98e3 100644 --- a/slv2/slv2.h +++ b/slv2/slv2.h @@ -28,6 +28,8 @@ extern "C" { #include #include #include +#include +#include #include #include #include diff --git a/slv2/types.h b/slv2/types.h index 53a27c6..b906899 100644 --- a/slv2/types.h +++ b/slv2/types.h @@ -109,7 +109,11 @@ typedef void* SLV2Values; /** A plugin UI */ -typedef void* SLV2UI; +typedef struct _SLV2PluginUI* SLV2PluginUI; + + +/** A collection of plugin UIs. */ +typedef void* SLV2PluginUIs; #ifdef __cplusplus diff --git a/slv2/value.h b/slv2/value.h index 47bb1ff..d3ea1c4 100644 --- a/slv2/value.h +++ b/slv2/value.h @@ -73,8 +73,7 @@ slv2_value_is_uri(SLV2Value value); /** Return this value as a URI string, e.g. "http://example.org/foo". * - * Valid to call only if slv2_value_is_uri(\a value) or - * slv2_value_is_ui(\a value) returns true. + * Valid to call only if slv2_value_is_uri(\a value) returns true. * Returned value is owned by \a value and must not be freed by caller. * * Time = O(1) @@ -172,29 +171,6 @@ int slv2_value_as_int(SLV2Value value); -/** Return whether this value is a GUI (URI and type). - * - * If this returns true, slv2_value_as_uri will return the URI of the GUI, - * and slv2_value_as_ui_type will return the SLV2UIType (which can be - * used to find the URI of the corresponding GUI spec itself, with - * slv2_ui_type_get_uri). - * - * Time = O(1) - */ -bool -slv2_value_is_ui(SLV2Value value); - - -/** Return \a value as an SLV2UIType. - * - * Valid to call only if slv2_value_is_ui(\a value) returns true. - * - * Time = O(1) - */ -SLV2UIType -slv2_value_as_ui_type(SLV2Value value); - - /** @} */ #ifdef __cplusplus diff --git a/src/Makefile.am b/src/Makefile.am index c32a0a1..99b07b2 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -7,6 +7,8 @@ libslv2_la_SOURCES = \ plugin.c \ pluginclass.c \ pluginclasses.c \ + pluginui.c \ + pluginuis.c \ pluginuiinstance.c \ plugininstance.c \ plugins.c \ diff --git a/src/plugin.c b/src/plugin.c index 51ae77e..758b256 100644 --- a/src/plugin.c +++ b/src/plugin.c @@ -29,6 +29,7 @@ #include #include #include +#include /* private */ @@ -239,6 +240,8 @@ slv2_plugin_load(SLV2Plugin p) const char* slv2_plugin_get_uri(SLV2Plugin p) { + assert(p); + assert(p->plugin_uri); return (const char*)librdf_uri_as_string(p->plugin_uri); } @@ -246,6 +249,8 @@ slv2_plugin_get_uri(SLV2Plugin p) const char* slv2_plugin_get_bundle_uri(SLV2Plugin p) { + assert(p); + assert(p->bundle_uri); return (const char*)librdf_uri_as_string(p->bundle_uri); } @@ -253,6 +258,8 @@ slv2_plugin_get_bundle_uri(SLV2Plugin p) const char* slv2_plugin_get_library_uri(SLV2Plugin p) { + assert(p); + assert(p->binary_uri); return (const char*)librdf_uri_as_string(p->binary_uri); } @@ -559,28 +566,54 @@ slv2_plugin_get_port_by_symbol(SLV2Plugin p, } -SLV2Values +SLV2PluginUIs slv2_plugin_get_uis(SLV2Plugin plugin) { - if (!plugin->rdf) - slv2_plugin_load(plugin); + const char* const query_str = + "PREFIX guiext: \n" + "SELECT DISTINCT ?uri ?type ?binary WHERE {\n" + "<> guiext:gui ?uri .\n" + "?uri a ?type ;\n" + " guiext:binary ?binary .\n" + "}\n"; + + librdf_query_results* results = slv2_plugin_query(plugin, query_str); + + SLV2PluginUIs result = slv2_plugin_uis_new(); + + while (!librdf_query_results_finished(results)) { + librdf_node* uri_node = librdf_query_results_get_binding_value(results, 0); + librdf_node* type_node = librdf_query_results_get_binding_value(results, 1); + librdf_node* binary_node = librdf_query_results_get_binding_value(results, 2); - SLV2Values result = slv2_plugin_get_value(plugin, SLV2_URI, - "http://ll-plugins.nongnu.org/lv2/ext/gui/dev/1#gui"); + SLV2PluginUI ui = slv2_plugin_ui_new(plugin->world, + librdf_node_get_uri(uri_node), + librdf_node_get_uri(type_node), + librdf_node_get_uri(binary_node)); - for (int i=0; i < raptor_sequence_size(result); ++i) { - SLV2Value val = (SLV2Value)raptor_sequence_get_at(result, i); - val->type = SLV2_VALUE_UI; - val->val.ui_type_val = SLV2_UI_TYPE_GTK2; + raptor_sequence_push(result, ui); + + librdf_free_node(uri_node); + librdf_free_node(type_node); + librdf_free_node(binary_node); + + librdf_query_results_next(results); } - return result; -} + librdf_free_query_results(results); + if (slv2_plugin_uis_size(result) > 0) { + return result; + } else { + slv2_plugin_uis_free(result); + return NULL; + } +} +#if 0 SLV2Value slv2_plugin_get_ui_library_uri(SLV2Plugin plugin, - SLV2Value ui) + SLV2Value ui) { assert(ui->type == SLV2_VALUE_UI); @@ -606,7 +639,7 @@ slv2_plugin_get_ui_library_uri(SLV2Plugin plugin, return value; } - +#endif const char* slv2_ui_type_get_uri(SLV2UIType type) @@ -622,6 +655,7 @@ void* slv2_plugin_load_ui(SLV2Plugin plugin, SLV2Value ui) { +#if 0 SLV2Value lib_uri = slv2_plugin_get_ui_library_uri(plugin, ui); if (!lib_uri) @@ -629,6 +663,7 @@ slv2_plugin_load_ui(SLV2Plugin plugin, //LV2UI_Handle handle = // +#endif return NULL; } diff --git a/src/pluginuiinstance.c b/src/pluginuiinstance.c index ee6de5b..be06217 100644 --- a/src/pluginuiinstance.c +++ b/src/pluginuiinstance.c @@ -33,7 +33,7 @@ SLV2UIInstance slv2_plugin_ui_instantiate(SLV2Plugin plugin, - SLV2Value ui, + SLV2PluginUI ui, LV2UI_Write_Function write_function, LV2UI_Command_Function command_function, LV2UI_Program_Change_Function program_function, @@ -41,6 +41,7 @@ slv2_plugin_ui_instantiate(SLV2Plugin plugin, LV2UI_Controller controller, const LV2_Host_Feature* const* host_features) { +#if 0 assert(ui->type == SLV2_VALUE_UI); if (ui->val.ui_type_val != SLV2_UI_TYPE_GTK2) @@ -139,6 +140,8 @@ slv2_plugin_ui_instantiate(SLV2Plugin plugin, free((LV2_Host_Feature**)host_features); return result; +#endif + return NULL; } diff --git a/src/slv2_internal.h b/src/slv2_internal.h index 1a34699..57343fe 100644 --- a/src/slv2_internal.h +++ b/src/slv2_internal.h @@ -98,7 +98,7 @@ struct _InstanceImpl { }; -/* ********* GUI Instance ********* */ +/* ********* UI Instance ********* */ struct _SLV2UIInstanceImpl { void* lib_handle; const LV2UI_Descriptor* lv2ui_descriptor; @@ -169,13 +169,22 @@ void slv2_world_load_file(SLV2World world, librdf_uri* file_uri); -/* ********* GUI ********* */ +/* ********* Plugin UI ********* */ -struct _SLV2UI { - SLV2UIType type; - char* uri; +struct _SLV2PluginUI { + librdf_uri* uri; + librdf_uri* bundle_uri; + librdf_uri* binary_uri; + SLV2Values types; }; +SLV2PluginUIs slv2_plugin_uis_new(); +SLV2PluginUI +slv2_plugin_ui_new(SLV2World world, + librdf_uri* uri, + librdf_uri* type_uri, + librdf_uri* binary_uri); +void slv2_plugin_ui_free(SLV2PluginUI ui); /* ********* Value ********* */ @@ -186,16 +195,14 @@ typedef enum _SLV2ValueType { SLV2_VALUE_STRING, SLV2_VALUE_INT, SLV2_VALUE_FLOAT, - SLV2_VALUE_UI } SLV2ValueType; struct _SLV2Value { SLV2ValueType type; char* str_val; ///< always present union { - int int_val; - float float_val; - SLV2UIType ui_type_val; + int int_val; + float float_val; } val; }; diff --git a/src/value.c b/src/value.c index c18074f..33f0020 100644 --- a/src/value.c +++ b/src/value.c @@ -90,7 +90,6 @@ slv2_value_get_turtle_token(SLV2Value value) char* result = NULL; switch (value->type) { - case SLV2_VALUE_UI: case SLV2_VALUE_URI: len = strlen(value->str_val) + 3; result = calloc(len, sizeof(char)); @@ -119,14 +118,14 @@ slv2_value_get_turtle_token(SLV2Value value) bool slv2_value_is_uri(SLV2Value value) { - return (value->type == SLV2_VALUE_URI || value->type == SLV2_VALUE_UI); + return (value->type == SLV2_VALUE_URI); } const char* slv2_value_as_uri(SLV2Value value) { - assert(slv2_value_is_uri(value) || slv2_value_is_ui(value)); + assert(slv2_value_is_uri(value)); return value->str_val; } @@ -185,18 +184,3 @@ slv2_value_as_float(SLV2Value value) return (float)value->val.int_val; } - -bool -slv2_value_is_ui(SLV2Value value) -{ - return (value->type == SLV2_VALUE_UI); -} - - -SLV2UIType -slv2_value_as_ui_type(SLV2Value value) -{ - assert(slv2_value_is_ui(value)); - return value->val.ui_type_val; -} - diff --git a/src/world.c b/src/world.c index 07f39a5..052dadf 100644 --- a/src/world.c +++ b/src/world.c @@ -236,6 +236,7 @@ slv2_world_load_bundle(SLV2World world, const char* bundle_uri_str) } librdf_free_stream(results); + free(q); /* Query statement: ?specification a lv2:Specification */ q = librdf_new_statement_from_nodes(world->world, @@ -269,6 +270,7 @@ slv2_world_load_bundle(SLV2World world, const char* bundle_uri_str) } librdf_free_stream(results); + free(q); /* Join the temporary model to the main model */ librdf_stream* manifest_stream = librdf_model_as_stream(manifest_model); @@ -276,7 +278,6 @@ slv2_world_load_bundle(SLV2World world, const char* bundle_uri_str) librdf_free_stream(manifest_stream); librdf_free_model(manifest_model); - free(q); librdf_free_storage(manifest_storage); librdf_free_uri(manifest_uri); librdf_free_uri(bundle_uri); diff --git a/utils/lv2_inspect.c b/utils/lv2_inspect.c index ee52b9b..b229c8e 100644 --- a/utils/lv2_inspect.c +++ b/utils/lv2_inspect.c @@ -126,24 +126,27 @@ print_plugin(SLV2Plugin p) printf("\tBundle: %s\n", slv2_plugin_get_bundle_uri(p)); printf("\tBinary: %s\n", slv2_plugin_get_library_uri(p)); - SLV2Values ui = slv2_plugin_get_uis(p); - if (slv2_values_size(ui) > 0) { - printf("\tGUI:\n"); - for (unsigned i=0; i < slv2_values_size(ui); ++i) { - printf("\t\t%s\n", slv2_value_as_uri(slv2_values_get_at(ui, i))); + SLV2PluginUIs uis = slv2_plugin_get_uis(p); + if (slv2_values_size(uis) > 0) { + printf("\tGUI: "); + for (unsigned i=0; i < slv2_plugin_uis_size(uis); ++i) { + SLV2PluginUI ui = slv2_plugin_uis_get_at(uis, i); + printf("%s\n", slv2_plugin_ui_get_uri(ui)); + + const char* binary = slv2_plugin_ui_get_binary_uri(ui); - SLV2Value binary = slv2_plugin_get_ui_library_uri(p, slv2_values_get_at(ui, i)); - - printf("\t\t\tType: %s\n", slv2_ui_type_get_uri(slv2_value_as_ui_type( - slv2_values_get_at(ui, i)))); + SLV2Values types = slv2_plugin_ui_get_types(ui); + for (unsigned i=0; i < slv2_values_size(types); ++i) { + printf("\t\t\tType: %s\n", slv2_value_as_uri(slv2_values_get_at(types, i))); + } if (binary) - printf("\t\t\tBinary: %s\n", slv2_value_as_uri(binary)); - - slv2_value_free(binary); + printf("\t\t\tBinary: %s\n", binary); + + printf("\t\t\tBundle: %s\n", slv2_plugin_ui_get_bundle_uri(ui)); } } - slv2_values_free(ui); + slv2_plugin_uis_free(uis); //SLV2Values ui = slv2_plugin_get_value_for_subject(p, // ""); @@ -183,6 +186,7 @@ print_plugin(SLV2Plugin p) printf("%s\n", slv2_value_as_uri(slv2_values_get_at(hints, i))); } printf("\n"); + slv2_values_free(hints); /* Ports */ -- cgit v1.2.1