Changeset 557f9d42 in ingen


Ignore:
Timestamp:
10/24/15 15:14:06 (22 months ago)
Author:
David Robillard <d@…>
Branches:
master, groups, nodeless, parallel, parameters, sequencefix
Children:
a742608
Parents:
e4d549a
Message:

Fix LV2 UIs that send during instantiation

git-svn-id: http://svn.drobilla.net/lad/trunk/ingen@5780 a436a847-0d15-0410-975c-d299462d15a1

Files:
4 edited

Legend:

Unmodified
Added
Removed
  • ingen/client/PluginUI.hpp

    r3353177 r557f9d42  
    4343    ~PluginUI(); 
    4444 
     45    /** Create a UI for the given block and plugin. 
     46     * 
     47     * This does not actually instantiate the UI itself, so signals can be 
     48     * connected first.  The caller should connect to signal_property_changed, 
     49     * then call instantiate(). 
     50     */ 
    4551    static SPtr<PluginUI> create(Ingen::World*          world, 
    4652                                 SPtr<const BlockModel> block, 
    4753                                 const LilvPlugin*      plugin); 
     54 
     55    /** Instantiate the UI. 
     56     * 
     57     * If true is returned, instantiation was successfull and the widget can be 
     58     * obtained with get_widget(). Otherwise, instantiation failed, so there is 
     59     * no widget and the UI can not be used. 
     60     */ 
     61    bool instantiate(); 
    4862 
    4963    SuilWidget get_widget(); 
     
    7286    PluginUI(Ingen::World*          world, 
    7387             SPtr<const BlockModel> block, 
    74              const LilvNode*        ui_node); 
     88             LilvUIs*               uis, 
     89             const LilvUI*          ui, 
     90             const LilvNode*        ui_type); 
    7591 
    7692    Ingen::World*          _world; 
    7793    SPtr<const BlockModel> _block; 
    7894    SuilInstance*          _instance; 
     95    LilvUIs*               _uis; 
     96    const LilvUI*          _ui; 
    7997    LilvNode*              _ui_node; 
     98    LilvNode*              _ui_type; 
    8099    std::set<uint32_t>     _subscribed_ports; 
    81100 
  • src/client/PluginUI.cpp

    r3b22d3c r557f9d42  
    147147PluginUI::PluginUI(Ingen::World*          world, 
    148148                   SPtr<const BlockModel> block, 
    149                    const LilvNode*        ui_node) 
     149                   LilvUIs*               uis, 
     150                   const LilvUI*          ui, 
     151                   const LilvNode*        ui_type) 
    150152    : _world(world) 
    151153    , _block(block) 
    152154    , _instance(NULL) 
    153     , _ui_node(lilv_node_duplicate(ui_node)) 
     155    , _uis(uis) 
     156    , _ui(ui) 
     157    , _ui_node(lilv_node_duplicate(lilv_ui_get_uri(ui))) 
     158    , _ui_type(lilv_node_duplicate(ui_type)) 
    154159{ 
    155160} 
     
    162167    suil_instance_free(_instance); 
    163168    lilv_node_free(_ui_node); 
     169    lilv_node_free(_ui_type); 
     170    lilv_uis_free(_uis); 
    164171} 
    165172 
     
    203210 
    204211    // Create the PluginUI, but don't instantiate yet 
    205     SPtr<PluginUI> ret(new PluginUI(world, block, lilv_ui_get_uri(ui))); 
     212    SPtr<PluginUI> ret(new PluginUI(world, block, uis, ui, ui_type)); 
    206213    ret->_features = world->lv2_features().lv2_features( 
    207214        world, const_cast<BlockModel*>(block.get())); 
     215 
     216    return ret; 
     217} 
     218 
     219bool 
     220PluginUI::instantiate() 
     221{ 
     222    const URIs&       uris       = _world->uris(); 
     223    const std::string plugin_uri = _block->plugin()->uri(); 
    208224 
    209225    /* Subscribe (enable broadcast) for any requested port notifications.  This 
    210226       must be done before instantiation so responses to any events sent by the 
    211227       UI's init() will be sent back to this client. */ 
    212     LilvWorld* lworld              = world->lilv_world(); 
     228    LilvWorld* lworld              = _world->lilv_world(); 
    213229    LilvNode*  ui_portNotification = lilv_new_uri(lworld, LV2_UI__portNotification); 
    214230    LilvNode*  ui_plugin           = lilv_new_uri(lworld, LV2_UI__plugin); 
    215231    LilvNodes* notes               = lilv_world_find_nodes( 
    216         lworld, lilv_ui_get_uri(ui), ui_portNotification, NULL); 
     232        lworld, lilv_ui_get_uri(_ui), ui_portNotification, NULL); 
    217233    LILV_FOREACH(nodes, n, notes) { 
    218234        const LilvNode* note = lilv_nodes_get(notes, n); 
    219235        const LilvNode* sym  = lilv_world_get(lworld, note, uris.lv2_symbol, NULL); 
    220236        const LilvNode* plug = lilv_world_get(lworld, note, ui_plugin, NULL); 
    221         if (plug && !lilv_node_is_uri(plug)) { 
    222             world->log().error(fmt("%1% UI has non-URI ui:plugin\n") 
    223                                % block->plugin()->uri().c_str()); 
    224             continue; 
    225         } 
    226         if (plug && strcmp(lilv_node_as_uri(plug), block->plugin()->uri().c_str())) { 
    227             continue;  // Notification is for another plugin 
    228         } 
    229         if (sym) { 
    230             uint32_t index = lv2_ui_port_index(ret.get(), lilv_node_as_string(sym)); 
     237        if (!plug) { 
     238            _world->log().error(fmt("%1% UI %2% notification missing plugin\n") 
     239                                % plugin_uri % lilv_node_as_string(_ui_node)); 
     240        } else if (!sym) { 
     241            _world->log().error(fmt("%1% UI %2% notification missing symbol\n") 
     242                                % plugin_uri % lilv_node_as_string(_ui_node)); 
     243        } else if (!lilv_node_is_uri(plug)) { 
     244            _world->log().error(fmt("%1% UI %2% notification has non-URI plugin\n") 
     245                                % plugin_uri % lilv_node_as_string(_ui_node)); 
     246        } else if (strcmp(lilv_node_as_uri(plug), plugin_uri.c_str())) { 
     247            // Notification is valid and for this plugin 
     248            uint32_t index = lv2_ui_port_index(this, lilv_node_as_string(sym)); 
    231249            if (index != LV2UI_INVALID_PORT_INDEX) { 
    232                 lv2_ui_subscribe(ret.get(), index, 0, NULL); 
    233                 ret->_subscribed_ports.insert(index); 
     250                lv2_ui_subscribe(this, index, 0, NULL); 
     251                _subscribed_ports.insert(index); 
    234252            } 
    235253        } 
     
    239257    lilv_node_free(ui_portNotification); 
    240258 
    241     const char* bundle_uri  = lilv_node_as_uri(lilv_ui_get_bundle_uri(ui)); 
    242     const char* binary_uri  = lilv_node_as_uri(lilv_ui_get_binary_uri(ui)); 
     259    const char* bundle_uri  = lilv_node_as_uri(lilv_ui_get_bundle_uri(_ui)); 
     260    const char* binary_uri  = lilv_node_as_uri(lilv_ui_get_binary_uri(_ui)); 
    243261    char*       bundle_path = lilv_file_uri_parse(bundle_uri, NULL); 
    244262    char*       binary_path = lilv_file_uri_parse(binary_uri, NULL); 
    245263 
    246264    // Instantiate the actual plugin UI via Suil 
    247     SuilInstance* instance = suil_instance_new( 
     265    _instance = suil_instance_new( 
    248266        PluginUI::ui_host, 
    249         ret.get(), 
    250         lilv_node_as_uri(gtk_ui), 
    251         lilv_node_as_uri(lilv_plugin_get_uri(plugin)), 
    252         lilv_node_as_uri(lilv_ui_get_uri(ui)), 
    253         lilv_node_as_uri(ui_type), 
     267        this, 
     268        LV2_UI__GtkUI, 
     269        plugin_uri.c_str(), 
     270        lilv_node_as_uri(lilv_ui_get_uri(_ui)), 
     271        lilv_node_as_uri(_ui_type), 
    254272        bundle_path, 
    255273        binary_path, 
    256         ret->_features->array()); 
     274        _features->array()); 
    257275 
    258276    lilv_free(binary_path); 
    259277    lilv_free(bundle_path); 
    260     lilv_node_free(gtk_ui); 
    261  
    262     if (!instance) { 
    263         world->log().error("Failed to instantiate LV2 UI\n"); 
     278 
     279    if (!_instance) { 
     280        _world->log().error("Failed to instantiate LV2 UI\n"); 
    264281        // Cancel any subscriptions 
    265         for (uint32_t i : ret->_subscribed_ports) { 
    266             lv2_ui_unsubscribe(ret.get(), i, 0, NULL); 
    267         } 
    268         return SPtr<PluginUI>(); 
    269     } 
    270  
    271     ret->_instance = instance; 
    272  
    273     return ret; 
     282        for (uint32_t i : _subscribed_ports) { 
     283            lv2_ui_unsubscribe(this, i, 0, NULL); 
     284        } 
     285        return false; 
     286    } 
     287 
     288    return true; 
    274289} 
    275290 
     
    286301                     const void* buffer) 
    287302{ 
    288     suil_instance_port_event( 
    289         _instance, port_index, buffer_size, format, buffer); 
     303    if (_instance) { 
     304        suil_instance_port_event( 
     305            _instance, port_index, buffer_size, format, buffer); 
     306    } else { 
     307        _world->log().warn("LV2 UI port event with no instance\n"); 
     308    } 
    290309} 
    291310 
  • src/gui/App.cpp

    r85a9454 r557f9d42  
    235235       went as planned here and fire the signal ourselves as if the server 
    236236       feedback came back immediately. */ 
    237     _client->signal_property_change().emit(subject, key, value); 
     237    if (key != uris().ingen_activity) { 
     238        _client->signal_property_change().emit(subject, key, value); 
     239    } 
    238240} 
    239241 
  • src/gui/NodeModule.cpp

    rdc6bde3 r557f9d42  
    236236                sigc::mem_fun(app(), &App::set_property)); 
    237237 
    238             GtkWidget* c_widget = (GtkWidget*)_plugin_ui->get_widget(); 
    239             _gui_widget = Glib::wrap(c_widget); 
    240  
    241             Gtk::Container* container = new Gtk::EventBox(); 
    242             container->set_name("IngenEmbeddedUI"); 
    243             container->set_border_width(4.0); 
    244             container->add(*_gui_widget); 
    245             Ganv::Module::embed(container); 
     238            if (!_plugin_ui->instantiate()) { 
     239                app().log().error("Failed to instantiate LV2 UI\n"); 
     240            } else { 
     241                GtkWidget* c_widget = (GtkWidget*)_plugin_ui->get_widget(); 
     242                _gui_widget = Glib::wrap(c_widget); 
     243 
     244                Gtk::Container* container = new Gtk::EventBox(); 
     245                container->set_name("IngenEmbeddedUI"); 
     246                container->set_border_width(4.0); 
     247                container->add(*_gui_widget); 
     248                Ganv::Module::embed(container); 
     249            } 
    246250        } else { 
    247251            app().log().error("Failed to create LV2 UI\n"); 
Note: See TracChangeset for help on using the changeset viewer.