From 551ba602e3123a4efdf2fb32d0e32a0c5506503a Mon Sep 17 00:00:00 2001 From: David Robillard Date: Thu, 2 Aug 2012 22:13:57 +0000 Subject: Pass parent widget to suil_instance_new. git-svn-id: http://svn.drobilla.net/lad/trunk/jalv@4600 a436a847-0d15-0410-975c-d299462d15a1 --- NEWS | 1 + src/jalv.c | 102 +++++++++++++++++++++++++++------------------------- src/jalv_console.c | 5 ++- src/jalv_gtk.c | 30 +++++++++------- src/jalv_gtkmm2.cpp | 17 +++++---- src/jalv_internal.h | 12 +++++-- src/jalv_qt4.cpp | 16 +++++---- 7 files changed, 103 insertions(+), 80 deletions(-) diff --git a/NEWS b/NEWS index 7fbb883..e5319b0 100644 --- a/NEWS +++ b/NEWS @@ -7,6 +7,7 @@ jalv (9999) unstable; * Notify plugins of Jack transport changes by sending events (an atom:Blank with properties from the LV2 time extension) * Add Gtk3 UI + * Port to Windows -- David Robillard diff --git a/src/jalv.c b/src/jalv.c index a6fbae1..d17ffb1 100644 --- a/src/jalv.c +++ b/src/jalv.c @@ -107,17 +107,15 @@ uri_to_id(LV2_URI_Map_Callback_Data callback_data, static LV2_URI_Map_Feature uri_map = { NULL, &uri_to_id }; static LV2_Feature uri_map_feature = { NS_EXT "uri-map", &uri_map }; -static LV2_Feature map_feature = { NS_EXT "urid#map", NULL }; -static LV2_Feature unmap_feature = { NS_EXT "urid#unmap", NULL }; -static LV2_Feature instance_feature = { NS_EXT "instance-access", NULL }; +static LV2_Feature map_feature = { LV2_URID__map, NULL }; +static LV2_Feature unmap_feature = { LV2_URID__unmap, NULL }; static LV2_Feature make_path_feature = { LV2_STATE__makePath, NULL }; static LV2_Feature schedule_feature = { LV2_WORKER__schedule, NULL }; static LV2_Feature log_feature = { LV2_LOG__log, NULL }; static LV2_Feature buf_size_feature = { LV2_BUF_SIZE__access, NULL }; -const LV2_Feature* features[10] = { +const LV2_Feature* features[9] = { &uri_map_feature, &map_feature, &unmap_feature, - &instance_feature, &make_path_feature, &schedule_feature, &log_feature, @@ -572,6 +570,48 @@ jack_session_cb(jack_session_event_t* event, void* arg) } #endif /* JALV_JACK_SESSION */ +void +jalv_ui_instantiate(Jalv* jalv, const char* native_ui_type, void* parent) +{ + jalv->ui_host = suil_host_new(jalv_ui_write, NULL, NULL, NULL); + + const LV2_Feature parent_feature = { + LV2_UI__parent, parent + }; + const LV2_Feature instance_feature = { + NS_EXT "instance-access", lilv_instance_get_handle(jalv->instance) + }; + const LV2_Feature* ui_features[] = { + &uri_map_feature, &map_feature, &unmap_feature, + &instance_feature, + &log_feature, + &parent_feature, + NULL + }; + + jalv->ui_instance = suil_instance_new( + jalv->ui_host, + &jalv, + native_ui_type, + lilv_node_as_uri(lilv_plugin_get_uri(jalv->plugin)), + lilv_node_as_uri(lilv_ui_get_uri(jalv->ui)), + lilv_node_as_uri(jalv->ui_type), + lilv_uri_to_path(lilv_node_as_uri(lilv_ui_get_bundle_uri(jalv->ui))), + lilv_uri_to_path(lilv_node_as_uri(lilv_ui_get_binary_uri(jalv->ui))), + ui_features); + + /* Set initial control values on UI */ + if (jalv->ui_instance) { + for (uint32_t i = 0; i < jalv->num_ports; ++i) { + if (jalv->ports[i].type == TYPE_CONTROL) { + suil_instance_port_event(jalv->ui_instance, i, + sizeof(float), 0, + &jalv->ports[i].control); + } + } + } +} + bool jalv_ui_is_resizable(Jalv* jalv) { @@ -852,15 +892,16 @@ main(int argc, char** argv) } /* Get a plugin UI */ - LilvNode* native_ui_type = jalv_native_ui_type(&jalv); - const LilvNode* ui_type = NULL; - jalv.ui = NULL; - if (!jalv.opts.generic_ui && native_ui_type) { + const char* native_ui_type_uri = jalv_native_ui_type(&jalv); + if (!jalv.opts.generic_ui && native_ui_type_uri) { + const LilvNode* native_ui_type = lilv_new_uri(jalv.world, native_ui_type_uri); jalv.uis = lilv_plugin_get_uis(jalv.plugin); LILV_FOREACH(uis, u, jalv.uis) { const LilvUI* this_ui = lilv_uis_get(jalv.uis, u); - if (lilv_ui_is_supported( - this_ui, suil_ui_supported, native_ui_type, &ui_type)) { + if (lilv_ui_is_supported(this_ui, + suil_ui_supported, + native_ui_type, + &jalv.ui_type)) { // TODO: Multiple UI support jalv.ui = this_ui; break; @@ -973,9 +1014,6 @@ main(int argc, char** argv) jalv_apply_state(&jalv, state); } - /* Set instance for instance-access extension */ - instance_feature.data = lilv_instance_get_handle(jalv.instance); - /* Set Jack callbacks */ jack_set_process_callback(jalv.jack_client, &jack_process_cb, (void*)(&jalv)); @@ -999,39 +1037,8 @@ main(int argc, char** argv) jalv.sample_rate = jack_get_sample_rate(jalv.jack_client); jalv.play_state = JALV_RUNNING; - SuilHost* ui_host = NULL; - if (jalv.ui) { - /* Instantiate UI */ - ui_host = suil_host_new(jalv_ui_write, NULL, NULL, NULL); - - jalv.has_ui = true; - jalv.ui_instance = suil_instance_new( - ui_host, - &jalv, - lilv_node_as_uri(native_ui_type), - lilv_node_as_uri(lilv_plugin_get_uri(jalv.plugin)), - lilv_node_as_uri(lilv_ui_get_uri(jalv.ui)), - lilv_node_as_uri(ui_type), - lilv_uri_to_path(lilv_node_as_uri(lilv_ui_get_bundle_uri(jalv.ui))), - lilv_uri_to_path(lilv_node_as_uri(lilv_ui_get_binary_uri(jalv.ui))), - features); - - if (!jalv.ui_instance) { - die("Failed to instantiate plugin.\n"); - } - - /* Set initial control values for UI */ - for (uint32_t i = 0; i < jalv.num_ports; ++i) { - if (jalv.ports[i].type == TYPE_CONTROL) { - suil_instance_port_event(jalv.ui_instance, i, - sizeof(float), 0, - &jalv.ports[i].control); - } - } - } - /* Run UI (or prompt at console) */ - jalv_open_ui(&jalv, jalv.ui_instance); + jalv_open_ui(&jalv); /* Wait for finish signal from UI or signal handler */ zix_sem_wait(&exit_sem); @@ -1060,12 +1067,11 @@ main(int argc, char** argv) free(jalv.ports); jack_ringbuffer_free(jalv.ui_events); jack_ringbuffer_free(jalv.plugin_events); - lilv_node_free(native_ui_type); for (LilvNode** n = (LilvNode**)&jalv.nodes; *n; ++n) { lilv_node_free(*n); } symap_free(jalv.symap); - suil_host_free(ui_host); + suil_host_free(jalv.ui_host); sratom_free(jalv.sratom); lilv_uis_free(jalv.uis); lilv_world_free(world); diff --git a/src/jalv_console.c b/src/jalv_console.c index 5508532..fe47ea3 100644 --- a/src/jalv_console.c +++ b/src/jalv_console.c @@ -86,15 +86,14 @@ jalv_init(int* argc, char*** argv, JalvOptions* opts) return 0; } -LilvNode* +const char* jalv_native_ui_type(Jalv* jalv) { return NULL; } int -jalv_open_ui(Jalv* jalv, - SuilInstance* instance) +jalv_open_ui(Jalv* jalv) { #ifdef JALV_JACK_SESSION printf("\nPress Ctrl-C to quit: "); diff --git a/src/jalv_gtk.c b/src/jalv_gtk.c index f385efa..32d361c 100644 --- a/src/jalv_gtk.c +++ b/src/jalv_gtk.c @@ -94,15 +94,13 @@ jalv_init(int* argc, char*** argv, JalvOptions* opts) return !err; } -LilvNode* +const char* jalv_native_ui_type(Jalv* jalv) { #if GTK_MAJOR_VERSION == 2 - return lilv_new_uri(jalv->world, - "http://lv2plug.in/ns/extensions/ui#GtkUI"); + return "http://lv2plug.in/ns/extensions/ui#GtkUI"; #elif GTK_MAJOR_VERSION == 3 - return lilv_new_uri(jalv->world, - "http://lv2plug.in/ns/extensions/ui#Gtk3UI"); + return "http://lv2plug.in/ns/extensions/ui#Gtk3UI"; #else return NULL; #endif @@ -544,8 +542,7 @@ build_control_widget(Jalv* jalv, GtkWidget* window) } int -jalv_open_ui(Jalv* jalv, - SuilInstance* instance) +jalv_open_ui(Jalv* jalv) { GtkWidget* window = gtk_window_new(GTK_WINDOW_TOPLEVEL); jalv->window = window; @@ -597,11 +594,20 @@ jalv_open_ui(Jalv* jalv, g_signal_connect(G_OBJECT(save_preset), "activate", G_CALLBACK(on_save_preset_activate), jalv); - if (instance && !jalv->opts.generic_ui) { - GtkWidget* alignment = gtk_alignment_new(0.5, 0.5, 1.0, 1.0); - GtkWidget* widget = (GtkWidget*)suil_instance_get_widget(instance); + /* Create/show alignment to contain UI (whether custom or generic) */ + GtkWidget* alignment = gtk_alignment_new(0.5, 0.5, 1.0, 1.0); + gtk_box_pack_start(GTK_BOX(vbox), alignment, TRUE, TRUE, 0); + gtk_widget_show(alignment); + + /* Attempt to instantiate custom UI if necessary */ + if (jalv->ui && !jalv->opts.generic_ui) { + jalv_ui_instantiate(jalv, jalv_native_ui_type(jalv), alignment); + } + + if (jalv->ui_instance) { + GtkWidget* widget = (GtkWidget*)suil_instance_get_widget( + jalv->ui_instance); - gtk_box_pack_start(GTK_BOX(vbox), alignment, TRUE, TRUE, 0); gtk_container_add(GTK_CONTAINER(alignment), widget); gtk_window_set_resizable(GTK_WINDOW(window), jalv_ui_is_resizable(jalv)); gtk_widget_show_all(vbox); @@ -613,7 +619,7 @@ jalv_open_ui(Jalv* jalv, gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW(scroll_win), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); - gtk_box_pack_start(GTK_BOX(vbox), scroll_win, TRUE, TRUE, 0); + gtk_container_add(GTK_CONTAINER(alignment), scroll_win); gtk_widget_show_all(vbox); GtkRequisition controls_size, box_size; diff --git a/src/jalv_gtkmm2.cpp b/src/jalv_gtkmm2.cpp index 14e41c7..4e31d17 100644 --- a/src/jalv_gtkmm2.cpp +++ b/src/jalv_gtkmm2.cpp @@ -29,11 +29,10 @@ jalv_init(int* argc, char*** argv, JalvOptions* opts) return 0; } -LilvNode* +const char* jalv_native_ui_type(Jalv* jalv) { - return lilv_new_uri(jalv->world, - "http://lv2plug.in/ns/extensions/ui#GtkUI"); + return "http://lv2plug.in/ns/extensions/ui#GtkUI"; } int @@ -59,13 +58,17 @@ jalv_ui_port_event(Jalv* jalv, } int -jalv_open_ui(Jalv* jalv, - SuilInstance* instance) +jalv_open_ui(Jalv* jalv) { Gtk::Window* window = new Gtk::Window(); - if (instance) { - GtkWidget* widget = (GtkWidget*)suil_instance_get_widget(instance); + if (jalv->ui) { + jalv_ui_instantiate(jalv, jalv_native_ui_type(jalv), NULL); + } + + if (jalv->ui_instance) { + GtkWidget* widget = (GtkWidget*)suil_instance_get_widget( + jalv->ui_instance); Gtk::Widget* widgetmm = Glib::wrap(widget); window->add(*Gtk::manage(widgetmm)); widgetmm->show_all(); diff --git a/src/jalv_internal.h b/src/jalv_internal.h index e4bea12..fee0451 100644 --- a/src/jalv_internal.h +++ b/src/jalv_internal.h @@ -160,7 +160,9 @@ typedef struct { const LilvPlugin* plugin; ///< Plugin class (RDF data) LilvUIs* uis; ///< All plugin UIs (RDF data) const LilvUI* ui; ///< Plugin UI (RDF data) + const LilvNode* ui_type; ///< Plugin UI type (unwrapped) LilvInstance* instance; ///< Plugin instance (shared library) + SuilHost* ui_host; ///< Plugin UI host support SuilInstance* ui_instance; ///< Plugin UI instance (shared library) void* window; ///< Window (if applicable) struct Port* ports; ///< Port array of size num_ports @@ -188,12 +190,16 @@ jalv_create_ports(Jalv* jalv); struct Port* jalv_port_by_symbol(Jalv* jalv, const char* sym); -LilvNode* +const char* jalv_native_ui_type(Jalv* jalv); int -jalv_open_ui(Jalv* jalv, - SuilInstance* instance); +jalv_open_ui(Jalv* jalv); + +void +jalv_ui_instantiate(Jalv* jalv, + const char* native_ui_type, + void* parent); bool jalv_ui_is_resizable(Jalv* jalv); diff --git a/src/jalv_qt4.cpp b/src/jalv_qt4.cpp index 4798b45..34ab8e4 100644 --- a/src/jalv_qt4.cpp +++ b/src/jalv_qt4.cpp @@ -32,11 +32,10 @@ jalv_init(int* argc, char*** argv, JalvOptions* opts) return 0; } -LilvNode* +const char* jalv_native_ui_type(Jalv* jalv) { - return lilv_new_uri(jalv->world, - "http://lv2plug.in/ns/extensions/ui#Qt4UI"); + return "http://lv2plug.in/ns/extensions/ui#Qt4UI"; } int @@ -73,11 +72,14 @@ private: }; int -jalv_open_ui(Jalv* jalv, - SuilInstance* instance) +jalv_open_ui(Jalv* jalv) { - if (instance) { - QWidget* widget = (QWidget*)suil_instance_get_widget(instance); + if (jalv->ui) { + jalv_ui_instantiate(jalv, jalv_native_ui_type(jalv), NULL); + } + + if (jalv->ui_instance) { + QWidget* widget = (QWidget*)suil_instance_get_widget(jalv->ui_instance); widget->show(); } else { QPushButton* button = new QPushButton("Close"); -- cgit v1.2.1