| @@ -1270,13 +1270,11 @@ class VstPlugin : public CarlaPlugin | |||
| #ifdef VESTIGE_HEADER | |||
| if (effect && effect->ptr1) | |||
| #else | |||
| if (effect && effect->resvd1) | |||
| #endif | |||
| { | |||
| #ifdef VESTIGE_HEADER | |||
| self = (VstPlugin*)effect->ptr1; | |||
| #else | |||
| if (effect && effect->resvd1) | |||
| { | |||
| self = (VstPlugin*)get_pointer(effect->resvd1); | |||
| #endif | |||
| if (self->unique1 != self->unique2) | |||
| @@ -1,5 +1,5 @@ | |||
| /* | |||
| * Carla UI bridge code | |||
| * Carla bridge code | |||
| * Copyright (C) 2011-2012 Filipe Coelho <falktx@gmail.com> | |||
| * | |||
| * This program is free software; you can redistribute it and/or modify | |||
| @@ -15,11 +15,14 @@ | |||
| * For a full copy of the GNU General Public License see the COPYING file | |||
| */ | |||
| #ifndef CARLA_BRIDGE_UI_H | |||
| #define CARLA_BRIDGE_UI_H | |||
| #ifndef CARLA_BRIDGE_H | |||
| #define CARLA_BRIDGE_H | |||
| #include "carla_includes.h" | |||
| #ifdef BUILD_BRIDGE_UI | |||
| #include "carla_lib_includes.h" | |||
| #endif | |||
| #include <cstdio> | |||
| #include <cstdlib> | |||
| @@ -58,12 +61,11 @@ struct QuequeBridgeMessage { | |||
| // ------------------------------------------------------------------------- | |||
| class UiData | |||
| class ClientData | |||
| { | |||
| public: | |||
| UiData(const char* ui_title) | |||
| ClientData(const char* ui_title) | |||
| { | |||
| m_lib = nullptr; | |||
| m_filename = nullptr; | |||
| m_title = strdup(ui_title); | |||
| @@ -74,9 +76,13 @@ public: | |||
| QuequeBridgeMessages[i].value2 = 0; | |||
| QuequeBridgeMessages[i].value3 = 0.0; | |||
| } | |||
| #ifdef BUILD_BRIDGE_UI | |||
| m_lib = nullptr; | |||
| #endif | |||
| } | |||
| virtual ~UiData() | |||
| virtual ~ClientData() | |||
| { | |||
| if (m_filename) | |||
| free(m_filename); | |||
| @@ -170,13 +176,16 @@ public: | |||
| virtual void note_on(uint8_t note, uint8_t velocity) = 0; | |||
| virtual void note_off(uint8_t note) = 0; | |||
| #ifdef BUILD_BRIDGE_UI | |||
| // gui | |||
| virtual void* get_widget() const = 0; | |||
| virtual bool is_resizable() const = 0; | |||
| virtual bool needs_reparent() const = 0; | |||
| #endif | |||
| // --------------------------------------------------------------------- | |||
| #ifdef BUILD_BRIDGE_UI | |||
| bool lib_open(const char* filename) | |||
| { | |||
| m_lib = ::lib_open(filename); | |||
| @@ -202,19 +211,23 @@ public: | |||
| { | |||
| return ::lib_error(m_filename ? m_filename : ""); | |||
| } | |||
| #endif | |||
| // --------------------------------------------------------------------- | |||
| private: | |||
| void* m_lib; | |||
| char* m_filename; | |||
| char* m_title; | |||
| QMutex m_lock; | |||
| QuequeBridgeMessage QuequeBridgeMessages[MAX_BRIDGE_MESSAGES]; | |||
| #ifdef BUILD_BRIDGE_UI | |||
| void* m_lib; | |||
| #endif | |||
| }; | |||
| // ------------------------------------------------------------------------- | |||
| extern UiData* ui; | |||
| extern ClientData* client; | |||
| #endif // CARLA_BRIDGE_UI_H | |||
| #endif // CARLA_BRIDGE_H | |||
| @@ -15,21 +15,16 @@ | |||
| * For a full copy of the GNU General Public License see the COPYING file | |||
| */ | |||
| #include "carla_bridge.h" | |||
| #include "carla_bridge_osc.h" | |||
| #include "carla_midi.h" | |||
| #include <QtCore/QString> | |||
| #ifdef BUILD_BRIDGE_PLUGIN | |||
| #include "carla_plugin.h" | |||
| extern void plugin_bridge_show_gui(bool yesno); | |||
| extern void plugin_bridge_quit(); | |||
| static const size_t client_name_len = 13; | |||
| static const char* const client_name = "plugin-bridge"; | |||
| #define CARLA_PLUGIN CarlaBackend::CarlaPlugins[0] | |||
| #else | |||
| #include "carla_bridge_ui.h" | |||
| extern int osc_handle_lv2_event_transfer(lo_arg** argv); | |||
| static const size_t client_name_len = 13; | |||
| static const char* const client_name = "lv2-ui-bridge"; | |||
| #endif | |||
| @@ -168,8 +163,8 @@ int osc_handle_configure(lo_arg** argv) | |||
| const char* key = (const char*)&argv[0]->s; | |||
| const char* value = (const char*)&argv[1]->s; | |||
| if (CARLA_PLUGIN) | |||
| CARLA_PLUGIN->set_custom_data(CarlaBackend::CUSTOM_DATA_STRING, key, value, false); | |||
| //if (CARLA_PLUGIN) | |||
| // CARLA_PLUGIN->set_custom_data(CarlaBackend::CUSTOM_DATA_STRING, key, value, false); | |||
| #else | |||
| Q_UNUSED(argv); | |||
| #endif | |||
| @@ -182,15 +177,8 @@ int osc_handle_control(lo_arg** argv) | |||
| int rindex = argv[0]->i; | |||
| float value = argv[1]->f; | |||
| qDebug("osc_handle_control(%i, %f)", rindex, value); | |||
| #ifdef BUILD_BRIDGE_PLUGIN | |||
| if (CARLA_PLUGIN) | |||
| CARLA_PLUGIN->set_parameter_value_by_rindex(rindex, value, true, true, false); | |||
| #else | |||
| if (ui) | |||
| ui->queque_message(BRIDGE_MESSAGE_PARAMETER, rindex, 0, value); | |||
| #endif | |||
| if (client) | |||
| client->queque_message(BRIDGE_MESSAGE_PARAMETER, rindex, 0, value); | |||
| return 0; | |||
| } | |||
| @@ -199,16 +187,8 @@ int osc_handle_program(lo_arg** argv) | |||
| { | |||
| int index = argv[0]->i; | |||
| if (index >= 0) | |||
| { | |||
| #ifdef BUILD_BRIDGE_PLUGIN | |||
| if (CARLA_PLUGIN && index < (int32_t)CARLA_PLUGIN->prog_count()) | |||
| CARLA_PLUGIN->set_program(index, false, true, true, true); | |||
| #else | |||
| if (ui) | |||
| ui->queque_message(BRIDGE_MESSAGE_PROGRAM, index, 0, 0.0); | |||
| #endif | |||
| } | |||
| if (client) | |||
| client->queque_message(BRIDGE_MESSAGE_PROGRAM, index, 0, 0.0); | |||
| return 0; | |||
| } | |||
| @@ -218,16 +198,8 @@ int osc_handle_midi_program(lo_arg** argv) | |||
| int bank = argv[0]->i; | |||
| int program = argv[1]->i; | |||
| if (bank >= 0 && program >= 0) | |||
| { | |||
| #ifdef BUILD_BRIDGE_PLUGIN | |||
| if (CARLA_PLUGIN) | |||
| CARLA_PLUGIN->set_midi_program_by_id(bank, program, false, true, true, true); | |||
| #else | |||
| if (ui) | |||
| ui->queque_message(BRIDGE_MESSAGE_MIDI_PROGRAM, bank, program, 0.0); | |||
| #endif | |||
| } | |||
| if (client) | |||
| client->queque_message(BRIDGE_MESSAGE_MIDI_PROGRAM, bank, program, 0.0); | |||
| return 0; | |||
| } | |||
| @@ -244,25 +216,17 @@ int osc_handle_midi(lo_arg** argv) | |||
| if (MIDI_IS_STATUS_NOTE_OFF(status)) | |||
| { | |||
| uint8_t note = data[2]; | |||
| #ifdef BUILD_BRIDGE_PLUGIN | |||
| if (CARLA_PLUGIN) | |||
| CARLA_PLUGIN->send_midi_note(false, note, 0, false, true, true); | |||
| #else | |||
| if (ui) | |||
| ui->queque_message(BRIDGE_MESSAGE_NOTE_OFF, note, 0, 0.0); | |||
| #endif | |||
| if (client) | |||
| client->queque_message(BRIDGE_MESSAGE_NOTE_OFF, note, 0, 0.0); | |||
| } | |||
| else if (MIDI_IS_STATUS_NOTE_ON(status)) | |||
| { | |||
| uint8_t note = data[2]; | |||
| uint8_t velo = data[3]; | |||
| #ifdef BUILD_BRIDGE_PLUGIN | |||
| if (CARLA_PLUGIN) | |||
| CARLA_PLUGIN->send_midi_note(true, note, velo, false, true, true); | |||
| #else | |||
| if (ui) | |||
| ui->queque_message(BRIDGE_MESSAGE_NOTE_ON, note, velo, 0.0); | |||
| #endif | |||
| if (client) | |||
| client->queque_message(BRIDGE_MESSAGE_NOTE_ON, note, velo, 0.0); | |||
| } | |||
| return 0; | |||
| @@ -270,36 +234,24 @@ int osc_handle_midi(lo_arg** argv) | |||
| int osc_handle_show() | |||
| { | |||
| #ifdef BUILD_BRIDGE_PLUGIN | |||
| plugin_bridge_show_gui(true); | |||
| #else | |||
| if (ui) | |||
| ui->queque_message(BRIDGE_MESSAGE_SHOW_GUI, 1, 0, 0.0); | |||
| #endif | |||
| if (client) | |||
| client->queque_message(BRIDGE_MESSAGE_SHOW_GUI, 1, 0, 0.0); | |||
| return 0; | |||
| } | |||
| int osc_handle_hide() | |||
| { | |||
| #ifdef BUILD_BRIDGE_PLUGIN | |||
| plugin_bridge_show_gui(false); | |||
| #else | |||
| if (ui) | |||
| ui->queque_message(BRIDGE_MESSAGE_SHOW_GUI, 0, 0, 0.0); | |||
| #endif | |||
| if (client) | |||
| client->queque_message(BRIDGE_MESSAGE_SHOW_GUI, 0, 0, 0.0); | |||
| return 0; | |||
| } | |||
| int osc_handle_quit() | |||
| { | |||
| #ifdef BUILD_BRIDGE_PLUGIN | |||
| plugin_bridge_quit(); | |||
| #else | |||
| if (ui) | |||
| ui->queque_message(BRIDGE_MESSAGE_QUIT, 0, 0, 0.0); | |||
| #endif | |||
| if (client) | |||
| client->queque_message(BRIDGE_MESSAGE_QUIT, 0, 0, 0.0); | |||
| return 0; | |||
| } | |||
| @@ -41,6 +41,8 @@ void osc_send_bridge_midi_program_info(int index, int bank, int program, const c | |||
| void osc_send_bridge_update(); | |||
| #else | |||
| // ui-bridge only | |||
| //int osc_handle_lv2_atom_transfer(lo_arg** argv); | |||
| int osc_handle_lv2_event_transfer(lo_arg** argv); | |||
| //void osc_send_lv2_atom_transfer(); | |||
| void osc_send_lv2_event_transfer(const char* type, const char* key, const char* value); | |||
| #endif | |||
| @@ -15,8 +15,8 @@ | |||
| * For a full copy of the GNU General Public License see the COPYING file | |||
| */ | |||
| #include "carla_bridge.h" | |||
| #include "carla_bridge_osc.h" | |||
| #include "carla_bridge_ui.h" | |||
| #ifdef BRIDGE_LV2_X11 | |||
| #error X11 UI uses Qt4 | |||
| @@ -26,7 +26,7 @@ | |||
| #include <QtCore/QSettings> | |||
| static GtkWidget* window = nullptr; | |||
| static QSettings settings("Cadence", "Carla-UIs"); | |||
| static QSettings settings("Cadence", "Carla-Gtk2UIs"); | |||
| // ------------------------------------------------------------------------- | |||
| @@ -34,20 +34,27 @@ gint last_x, last_y, last_width, last_height; | |||
| void save_window_settings() | |||
| { | |||
| settings.setValue(QString("%1/pos_x").arg(ui->get_title()), last_x); | |||
| settings.setValue(QString("%1/pos_y").arg(ui->get_title()), last_y); | |||
| settings.setValue(QString("%1/width").arg(ui->get_title()), last_width); | |||
| settings.setValue(QString("%1/height").arg(ui->get_title()), last_height); | |||
| settings.sync(); | |||
| if (client) | |||
| { | |||
| settings.setValue(QString("%1/pos_x").arg(client->get_title()), last_x); | |||
| settings.setValue(QString("%1/pos_y").arg(client->get_title()), last_y); | |||
| settings.setValue(QString("%1/width").arg(client->get_title()), last_width); | |||
| settings.setValue(QString("%1/height").arg(client->get_title()), last_height); | |||
| settings.sync(); | |||
| } | |||
| } | |||
| // ------------------------------------------------------------------------- | |||
| gboolean gtk_ui_recheck(void*) | |||
| { | |||
| gtk_window_get_position(GTK_WINDOW(window), &last_x, &last_y); | |||
| gtk_window_get_size(GTK_WINDOW(window), &last_width, &last_height); | |||
| return ui->run_messages(); | |||
| if (window) | |||
| { | |||
| gtk_window_get_position(GTK_WINDOW(window), &last_x, &last_y); | |||
| gtk_window_get_size(GTK_WINDOW(window), &last_width, &last_height); | |||
| } | |||
| return client ? client->run_messages() : false; | |||
| } | |||
| void gtk_ui_destroy(GtkWidget*, void*) | |||
| @@ -67,27 +74,27 @@ void toolkit_init() | |||
| void toolkit_loop() | |||
| { | |||
| window = gtk_window_new(GTK_WINDOW_TOPLEVEL); | |||
| gtk_container_add(GTK_CONTAINER(window), (GtkWidget*)ui->get_widget()); | |||
| gtk_container_add(GTK_CONTAINER(window), (GtkWidget*)client->get_widget()); | |||
| g_timeout_add(50, gtk_ui_recheck, nullptr); | |||
| g_signal_connect(window, "destroy", G_CALLBACK(gtk_ui_destroy), nullptr); | |||
| gtk_window_set_resizable(GTK_WINDOW(window), ui->is_resizable()); | |||
| gtk_window_set_title(GTK_WINDOW(window), ui->get_title()); | |||
| gtk_window_set_resizable(GTK_WINDOW(window), client->is_resizable()); | |||
| gtk_window_set_title(GTK_WINDOW(window), client->get_title()); | |||
| gtk_window_get_position(GTK_WINDOW(window), &last_x, &last_y); | |||
| gtk_window_get_size(GTK_WINDOW(window), &last_width, &last_height); | |||
| if (settings.contains(QString("%1/pos_x").arg(ui->get_title()))) | |||
| if (settings.contains(QString("%1/pos_x").arg(client->get_title()))) | |||
| { | |||
| last_x = settings.value(QString("%1/pos_x").arg(ui->get_title()), last_x).toInt(); | |||
| last_y = settings.value(QString("%1/pos_y").arg(ui->get_title()), last_y).toInt(); | |||
| last_x = settings.value(QString("%1/pos_x").arg(client->get_title()), last_x).toInt(); | |||
| last_y = settings.value(QString("%1/pos_y").arg(client->get_title()), last_y).toInt(); | |||
| gtk_window_move(GTK_WINDOW(window), last_x, last_y); | |||
| if (ui->is_resizable()) | |||
| if (client->is_resizable()) | |||
| { | |||
| last_width = settings.value(QString("%1/width").arg(ui->get_title()), last_width).toInt(); | |||
| last_height = settings.value(QString("%1/height").arg(ui->get_title()), last_height).toInt(); | |||
| last_width = settings.value(QString("%1/width").arg(client->get_title()), last_width).toInt(); | |||
| last_height = settings.value(QString("%1/height").arg(client->get_title()), last_height).toInt(); | |||
| gtk_window_resize(GTK_WINDOW(window), last_width, last_height); | |||
| } | |||
| } | |||
| @@ -100,9 +107,10 @@ void toolkit_loop() | |||
| void toolkit_quit() | |||
| { | |||
| save_window_settings(); | |||
| if (window) | |||
| { | |||
| save_window_settings(); | |||
| gtk_widget_destroy(window); | |||
| gtk_main_quit(); | |||
| } | |||
| @@ -15,8 +15,8 @@ | |||
| * For a full copy of the GNU General Public License see the COPYING file | |||
| */ | |||
| #include "carla_bridge.h" | |||
| #include "carla_bridge_osc.h" | |||
| #include "carla_bridge_ui.h" | |||
| #include "carla_midi.h" | |||
| #include "lv2_rdf.h" | |||
| @@ -26,7 +26,7 @@ | |||
| #include <QtGui/QDialog> | |||
| #endif | |||
| UiData* ui = nullptr; | |||
| ClientData* client = nullptr; | |||
| // ------------------------------------------------------------------------- | |||
| @@ -62,10 +62,10 @@ const uint32_t CARLA_URI_MAP_ID_COUNT = 12; | |||
| // ------------------------------------------------------------------------- | |||
| class Lv2UiData : public UiData | |||
| class Lv2UiData : public ClientData | |||
| { | |||
| public: | |||
| Lv2UiData(const char* ui_title) : UiData(ui_title) | |||
| Lv2UiData(const char* ui_title) : ClientData(ui_title) | |||
| { | |||
| handle = nullptr; | |||
| widget = nullptr; | |||
| @@ -89,7 +89,9 @@ public: | |||
| for (uint32_t i=0; i < lv2_feature_count+1; i++) | |||
| features[i] = nullptr; | |||
| // Initialize features | |||
| // ----------------------------------------------------------------- | |||
| // initialize features | |||
| LV2_Event_Feature* Event_Feature = new LV2_Event_Feature; | |||
| Event_Feature->callback_data = this; | |||
| Event_Feature->lv2_event_ref = carla_lv2_event_ref; | |||
| @@ -222,86 +224,95 @@ public: | |||
| bool init(const char* plugin_uri, const char* ui_uri) | |||
| { | |||
| // ----------------------------------------------------------------- | |||
| // get plugin from lv2_rdf (lilv) | |||
| Lv2World.init(); | |||
| rdf_descriptor = lv2_rdf_new(plugin_uri); | |||
| if (rdf_descriptor) | |||
| if (! rdf_descriptor) | |||
| return false; | |||
| // ----------------------------------------------------------------- | |||
| // find requested UI | |||
| for (uint32_t i=0; i < rdf_descriptor->UICount; i++) | |||
| { | |||
| for (uint32_t i=0; i < rdf_descriptor->UICount; i++) | |||
| if (strcmp(rdf_descriptor->UIs[i].URI, ui_uri) == 0) | |||
| { | |||
| if (strcmp(rdf_descriptor->UIs[i].URI, ui_uri) == 0) | |||
| { | |||
| rdf_ui_descriptor = &rdf_descriptor->UIs[i]; | |||
| break; | |||
| } | |||
| rdf_ui_descriptor = &rdf_descriptor->UIs[i]; | |||
| break; | |||
| } | |||
| } | |||
| if (! rdf_ui_descriptor) | |||
| return false; | |||
| // ----------------------------------------------------------------- | |||
| // open DLL | |||
| if (! lib_open(rdf_ui_descriptor->Binary)) | |||
| return false; | |||
| // ----------------------------------------------------------------- | |||
| // get DLL main entry | |||
| LV2UI_DescriptorFunction ui_descfn = (LV2UI_DescriptorFunction)lib_symbol("lv2ui_descriptor"); | |||
| if (! ui_descfn) | |||
| return false; | |||
| // ----------------------------------------------------------- | |||
| // get descriptor that matches URI | |||
| uint32_t i = 0; | |||
| while ((descriptor = ui_descfn(i++))) | |||
| { | |||
| if (strcmp(descriptor->URI, ui_uri) == 0) | |||
| break; | |||
| } | |||
| if (! descriptor) | |||
| return false; | |||
| // ----------------------------------------------------------- | |||
| // initialize UI | |||
| handle = descriptor->instantiate(descriptor, plugin_uri, rdf_ui_descriptor->Bundle, carla_lv2_ui_write_function, this, &widget, features); | |||
| if (! handle) | |||
| return false; | |||
| // ----------------------------------------------------------- | |||
| // check if not resizable | |||
| if (rdf_ui_descriptor && lib_open(rdf_ui_descriptor->Binary)) | |||
| #ifndef BRIDGE_LV2_X11 | |||
| for (uint32_t i=0; i < rdf_ui_descriptor->FeatureCount; i++) | |||
| { | |||
| if (strcmp(rdf_ui_descriptor->Features[i].URI, LV2_UI__fixedSize) == 0 || strcmp(rdf_ui_descriptor->Features[i].URI, LV2_UI__noUserResize) == 0) | |||
| { | |||
| LV2UI_DescriptorFunction ui_descfn = (LV2UI_DescriptorFunction)lib_symbol("lv2ui_descriptor"); | |||
| m_resizable = false; | |||
| break; | |||
| } | |||
| } | |||
| #endif | |||
| // ----------------------------------------------------------- | |||
| // check for programs extension | |||
| if (ui_descfn) | |||
| if (descriptor->extension_data) | |||
| { | |||
| for (uint32_t i=0; i < rdf_ui_descriptor->ExtensionCount; i++) | |||
| { | |||
| if (strcmp(rdf_ui_descriptor->Extensions[i], LV2_PROGRAMS__UIInterface) == 0) | |||
| { | |||
| uint32_t i = 0; | |||
| while ((descriptor = ui_descfn(i++))) | |||
| { | |||
| if (strcmp(descriptor->URI, ui_uri) == 0) | |||
| break; | |||
| } | |||
| if (descriptor) | |||
| { | |||
| handle = descriptor->instantiate(descriptor, | |||
| plugin_uri, | |||
| rdf_ui_descriptor->Bundle, | |||
| carla_lv2_ui_write_function, | |||
| this, | |||
| &widget, | |||
| features); | |||
| if (handle) | |||
| { | |||
| // Check if not resizable | |||
| for (uint32_t i=0; i < rdf_ui_descriptor->FeatureCount; i++) | |||
| { | |||
| if (strcmp(rdf_ui_descriptor->Features[i].URI, LV2_UI__fixedSize) == 0 || strcmp(rdf_ui_descriptor->Features[i].URI, LV2_UI__noUserResize) == 0) | |||
| { | |||
| m_resizable = false; | |||
| break; | |||
| } | |||
| } | |||
| // Check for programs extension | |||
| if (descriptor->extension_data) | |||
| { | |||
| for (uint32_t i=0; i < rdf_ui_descriptor->ExtensionCount; i++) | |||
| { | |||
| if (strcmp(rdf_ui_descriptor->Extensions[i], LV2_PROGRAMS__UIInterface) == 0) | |||
| { | |||
| programs = (LV2_Programs_UI_Interface*)descriptor->extension_data(LV2_PROGRAMS__UIInterface); | |||
| break; | |||
| } | |||
| } | |||
| } | |||
| return true; | |||
| } | |||
| else | |||
| qCritical("Lv2UiData::init(%s, %s) - ui failed no initiliaze", plugin_uri, ui_uri); | |||
| } | |||
| else | |||
| qCritical("Lv2UiData::init(%s, %s) - ui descriptor mismatch", plugin_uri, ui_uri); | |||
| programs = (LV2_Programs_UI_Interface*)descriptor->extension_data(LV2_PROGRAMS__UIInterface); | |||
| break; | |||
| } | |||
| else | |||
| qCritical("Lv2UiData::init(%s, %s) - Failed to find ui entry point", plugin_uri, ui_uri); | |||
| } | |||
| else | |||
| qCritical("Lv2UiData::init(%s, %s) - Failed to find ui", plugin_uri, ui_uri); | |||
| } | |||
| else | |||
| qCritical("Lv2UiData::init(%s, %s) - Failed to find plugin", plugin_uri, ui_uri); | |||
| return false; | |||
| return true; | |||
| } | |||
| void close() | |||
| @@ -447,7 +458,10 @@ public: | |||
| return nullptr; | |||
| } | |||
| // TODO - finish lv2-features and import here from main backend code | |||
| // ----------------- Event Feature --------------------------------------------------- | |||
| static uint32_t carla_lv2_event_ref(LV2_Event_Callback_Data callback_data, LV2_Event* event) | |||
| { | |||
| qDebug("carla_lv2_event_ref(%p, %p)", callback_data, event); | |||
| @@ -461,6 +475,7 @@ public: | |||
| } | |||
| // ----------------- Logs Feature ---------------------------------------------------- | |||
| static int carla_lv2_log_vprintf(LV2_Log_Handle handle, LV2_URID type, const char* fmt, va_list ap) | |||
| { | |||
| qDebug("carla_lv2_log_vprintf(%p, %i, %s, ...)", handle, type, fmt); | |||
| @@ -505,6 +520,7 @@ public: | |||
| } | |||
| // ----------------- Programs Feature ------------------------------------------------ | |||
| static void carla_lv2_program_changed(LV2_Programs_Handle handle, int32_t index) | |||
| { | |||
| qDebug("Lv2Plugin::carla_lv2_program_changed(%p, %i)", handle, index); | |||
| @@ -514,6 +530,7 @@ public: | |||
| } | |||
| // ----------------- State Feature --------------------------------------------------- | |||
| static char* carla_lv2_state_make_path(LV2_State_Make_Path_Handle handle, const char* path) | |||
| { | |||
| qDebug("carla_lv2_state_make_path(%p, %p)", handle, path); | |||
| @@ -533,6 +550,7 @@ public: | |||
| } | |||
| // ----------------- URI-Map Feature --------------------------------------- | |||
| static uint32_t carla_lv2_uri_to_id(LV2_URI_Map_Callback_Data data, const char* map, const char* uri) | |||
| { | |||
| qDebug("carla_lv2_uri_to_id(%p, %s, %s)", data, map, uri); | |||
| @@ -540,6 +558,7 @@ public: | |||
| } | |||
| // ----------------- URID Feature ------------------------------------------ | |||
| static LV2_URID carla_lv2_urid_map(LV2_URID_Map_Handle handle, const char* uri) | |||
| { | |||
| qDebug("carla_lv2_urid_map(%p, %s)", handle, uri); | |||
| @@ -625,6 +644,7 @@ public: | |||
| } | |||
| // ----------------- UI Port-Map Feature --------------------------------------------- | |||
| static uint32_t carla_lv2_ui_port_map(LV2UI_Feature_Handle handle, const char* symbol) | |||
| { | |||
| qDebug("Lv2Plugin::carla_lv2_ui_port_map(%p, %s)", handle, symbol); | |||
| @@ -644,6 +664,7 @@ public: | |||
| } | |||
| // ----------------- UI Resize Feature ------------------------------------- | |||
| static int carla_lv2_ui_resize(LV2UI_Feature_Handle data, int width, int height) | |||
| { | |||
| qDebug("carla_lv2_ui_resized(%p, %i, %i)", data, width, height); | |||
| @@ -659,6 +680,7 @@ public: | |||
| } | |||
| // ----------------- UI Extension ------------------------------------------ | |||
| static void carla_lv2_ui_write_function(LV2UI_Controller controller, uint32_t port_index, uint32_t buffer_size, uint32_t format, const void* buffer) | |||
| { | |||
| qDebug("carla_lv2_ui_write_function(%p, %i, %i, %i, %p)", controller, port_index, buffer_size, format, buffer); | |||
| @@ -729,7 +751,7 @@ int osc_handle_lv2_event_transfer(lo_arg** argv) | |||
| const char* type = (const char*)&argv[0]->s; | |||
| const char* key = (const char*)&argv[1]->s; | |||
| const char* value = (const char*)&argv[2]->s; | |||
| ((Lv2UiData*)ui)->handle_event_transfer(type, key, value); | |||
| ((Lv2UiData*)client)->handle_event_transfer(type, key, value); | |||
| return 0; | |||
| } | |||
| @@ -738,8 +760,8 @@ int main(int argc, char* argv[]) | |||
| #if 1 | |||
| if (argc != 5) | |||
| { | |||
| qCritical("%s: bad arguments", argv[0]); | |||
| return 1; | |||
| qCritical("%s: bad arguments", argv[0]); | |||
| return 1; | |||
| } | |||
| const char* osc_url = argv[1]; | |||
| @@ -757,7 +779,7 @@ int main(int argc, char* argv[]) | |||
| toolkit_init(); | |||
| // Init LV2-UI | |||
| ui = new Lv2UiData(ui_title); | |||
| client = new Lv2UiData(ui_title); | |||
| // Init OSC | |||
| osc_init(osc_url); | |||
| @@ -765,7 +787,7 @@ int main(int argc, char* argv[]) | |||
| // Load UI | |||
| int ret; | |||
| if (ui->init(plugin_uri, ui_uri)) | |||
| if (client->init(plugin_uri, ui_uri)) | |||
| { | |||
| toolkit_loop(); | |||
| ret = 0; | |||
| @@ -781,14 +803,14 @@ int main(int argc, char* argv[]) | |||
| osc_close(); | |||
| // Close LV2-UI | |||
| ui->close(); | |||
| client->close(); | |||
| // Close toolkit | |||
| if (! ret) | |||
| toolkit_quit(); | |||
| delete ui; | |||
| ui = nullptr; | |||
| delete client; | |||
| client = nullptr; | |||
| return ret; | |||
| } | |||
| @@ -15,8 +15,8 @@ | |||
| * For a full copy of the GNU General Public License see the COPYING file | |||
| */ | |||
| #include "carla_bridge.h" | |||
| #include "carla_bridge_osc.h" | |||
| #include "carla_bridge_ui.h" | |||
| #include <QtCore/QSettings> | |||
| #include <QtCore/QTimer> | |||
| @@ -26,7 +26,11 @@ | |||
| #include <QtGui/QVBoxLayout> | |||
| static QDialog* window = nullptr; | |||
| static QSettings settings("Cadence", "Carla-UIs"); | |||
| #ifdef BRIDGE_LV2_X11 | |||
| static QSettings settings("Cadence", "Carla-X11UIs"); | |||
| #else | |||
| static QSettings settings("Cadence", "Carla-Qt4UIs"); | |||
| #endif | |||
| // ------------------------------------------------------------------------- | |||
| @@ -40,8 +44,8 @@ public: | |||
| void timerEvent(QTimerEvent*) | |||
| { | |||
| if (ui) | |||
| ui->run_messages(); | |||
| if (client) | |||
| client->run_messages(); | |||
| } | |||
| }; | |||
| @@ -56,9 +60,9 @@ void toolkit_init() | |||
| void toolkit_loop() | |||
| { | |||
| if (ui->needs_reparent()) | |||
| if (client->needs_reparent()) | |||
| { | |||
| window = (QDialog*)ui->get_widget(); | |||
| window = (QDialog*)client->get_widget(); | |||
| window->resize(10, 10); | |||
| } | |||
| else | |||
| @@ -67,7 +71,7 @@ void toolkit_loop() | |||
| window->resize(10, 10); | |||
| window->setLayout(new QVBoxLayout(window)); | |||
| QWidget* widget = (QWidget*)ui->get_widget(); | |||
| QWidget* widget = (QWidget*)client->get_widget(); | |||
| window->layout()->addWidget(widget); | |||
| window->layout()->setContentsMargins(0, 0, 0, 0); | |||
| window->adjustSize(); | |||
| @@ -79,21 +83,21 @@ void toolkit_loop() | |||
| checker.start(50); | |||
| QObject::connect(window, SIGNAL(finished(int)), app, SLOT(quit())); | |||
| if (! ui->is_resizable()) | |||
| if (! client->is_resizable()) | |||
| window->setFixedSize(window->width(), window->height()); | |||
| window->setWindowTitle(ui->get_title()); | |||
| window->setWindowTitle(client->get_title()); | |||
| if (settings.contains(QString("%1/pos_x").arg(ui->get_title()))) | |||
| if (settings.contains(QString("%1/pos_x").arg(client->get_title()))) | |||
| { | |||
| int pos_x = settings.value(QString("%1/pos_x").arg(ui->get_title()), window->x()).toInt(); | |||
| int pos_y = settings.value(QString("%1/pos_y").arg(ui->get_title()), window->y()).toInt(); | |||
| int pos_x = settings.value(QString("%1/pos_x").arg(client->get_title()), window->x()).toInt(); | |||
| int pos_y = settings.value(QString("%1/pos_y").arg(client->get_title()), window->y()).toInt(); | |||
| window->move(pos_x, pos_y); | |||
| if (ui->is_resizable()) | |||
| if (client->is_resizable()) | |||
| { | |||
| int width = settings.value(QString("%1/width").arg(ui->get_title()), window->width()).toInt(); | |||
| int height = settings.value(QString("%1/height").arg(ui->get_title()), window->height()).toInt(); | |||
| int width = settings.value(QString("%1/width").arg(client->get_title()), window->width()).toInt(); | |||
| int height = settings.value(QString("%1/height").arg(client->get_title()), window->height()).toInt(); | |||
| window->resize(width, height); | |||
| } | |||
| } | |||
| @@ -108,24 +112,29 @@ void toolkit_quit() | |||
| { | |||
| if (window) | |||
| { | |||
| settings.setValue(QString("%1/pos_x").arg(ui->get_title()), window->x()); | |||
| settings.setValue(QString("%1/pos_y").arg(ui->get_title()), window->y()); | |||
| settings.setValue(QString("%1/width").arg(ui->get_title()), window->width()); | |||
| settings.setValue(QString("%1/height").arg(ui->get_title()), window->height()); | |||
| settings.sync(); | |||
| if (client) | |||
| { | |||
| settings.setValue(QString("%1/pos_x").arg(client->get_title()), window->x()); | |||
| settings.setValue(QString("%1/pos_y").arg(client->get_title()), window->y()); | |||
| settings.setValue(QString("%1/width").arg(client->get_title()), window->width()); | |||
| settings.setValue(QString("%1/height").arg(client->get_title()), window->height()); | |||
| settings.sync(); | |||
| } | |||
| window->close(); | |||
| delete window; | |||
| window = nullptr; | |||
| } | |||
| if (app) | |||
| { | |||
| app->quit(); | |||
| if (! app->closingDown()) | |||
| app->quit(); | |||
| delete app; | |||
| app = nullptr; | |||
| } | |||
| app = nullptr; | |||
| window = nullptr; | |||
| } | |||
| void toolkit_window_show() | |||
| @@ -142,9 +151,9 @@ void toolkit_window_hide() | |||
| void toolkit_window_resize(int width, int height) | |||
| { | |||
| if (window) | |||
| if (client && window) | |||
| { | |||
| if (ui->is_resizable()) | |||
| if (client->is_resizable()) | |||
| window->resize(width, height); | |||
| else | |||
| window->setFixedSize(width, height); | |||
| @@ -15,38 +15,32 @@ | |||
| * For a full copy of the GNU General Public License see the COPYING file | |||
| */ | |||
| #include "carla_vst_includes.h" | |||
| #include "carla_bridge.h" | |||
| #include "carla_bridge_osc.h" | |||
| #include "carla_bridge_ui.h" | |||
| #include "carla_midi.h" | |||
| #include "carla_vst_includes.h" | |||
| #include <QtGui/QDialog> | |||
| UiData* ui = nullptr; | |||
| ClientData* client = nullptr; | |||
| // ------------------------------------------------------------------------- | |||
| #define FAKE_SAMPLE_RATE 44100.0 | |||
| #define FAKE_BUFFER_SIZE 512 | |||
| class VstUiData : public UiData | |||
| class VstUiData : public ClientData | |||
| { | |||
| public: | |||
| VstUiData(const char* ui_title) : UiData(ui_title) | |||
| VstUiData(const char* ui_title) : ClientData(ui_title) | |||
| { | |||
| effect = nullptr; | |||
| widget = new QDialog; | |||
| // make UI valid | |||
| unique1 = unique2 = random(); | |||
| } | |||
| ~VstUiData() | |||
| { | |||
| // UI is no longer valid | |||
| unique1 = 0; | |||
| unique2 = 1; | |||
| } | |||
| // --------------------------------------------------------------------- | |||
| @@ -54,48 +48,63 @@ public: | |||
| bool init(const char* binary, const char*) | |||
| { | |||
| if (lib_open(binary)) | |||
| // ----------------------------------------------------------------- | |||
| // open DLL | |||
| if ( !lib_open(binary)) | |||
| return false; | |||
| // ----------------------------------------------------------------- | |||
| // get DLL main entry | |||
| VST_Function vstfn = (VST_Function)lib_symbol("VSTPluginMain"); | |||
| if (! vstfn) | |||
| { | |||
| VST_Function vstfn = (VST_Function)lib_symbol("VSTPluginMain"); | |||
| vstfn = (VST_Function)lib_symbol("main"); | |||
| if (! vstfn) | |||
| vstfn = (VST_Function)lib_symbol("main"); | |||
| return false; | |||
| } | |||
| if (vstfn) | |||
| { | |||
| effect = vstfn(VstHostCallback); | |||
| // ----------------------------------------------------------------- | |||
| // initialize plugin | |||
| if (effect && effect->magic == kEffectMagic) | |||
| { | |||
| effect->dispatcher(effect, effOpen, 0, 0, nullptr, 0.0f); | |||
| effect = vstfn(VstHostCallback); | |||
| if (! effect || effect->magic != kEffectMagic) | |||
| return false; | |||
| // ----------------------------------------------------------------- | |||
| // initialize VST stuff | |||
| effect->dispatcher(effect, effOpen, 0, 0, nullptr, 0.0f); | |||
| #if ! VST_FORCE_DEPRECATED | |||
| effect->dispatcher(effect, effSetBlockSizeAndSampleRate, 0, FAKE_BUFFER_SIZE, nullptr, FAKE_SAMPLE_RATE); | |||
| effect->dispatcher(effect, effSetBlockSizeAndSampleRate, 0, FAKE_BUFFER_SIZE, nullptr, FAKE_SAMPLE_RATE); | |||
| #endif | |||
| effect->dispatcher(effect, effSetSampleRate, 0, 0, nullptr, FAKE_SAMPLE_RATE); | |||
| effect->dispatcher(effect, effSetBlockSize, 0, FAKE_BUFFER_SIZE, nullptr, 0.0f); | |||
| effect->dispatcher(effect, effEditOpen, 0, 0, (void*)widget->winId(), 0.0f); | |||
| effect->user = this; | |||
| #ifndef ERect | |||
| struct ERect { | |||
| short top; | |||
| short left; | |||
| short bottom; | |||
| short right; | |||
| }; | |||
| effect->dispatcher(effect, effSetSampleRate, 0, 0, nullptr, FAKE_SAMPLE_RATE); | |||
| effect->dispatcher(effect, effSetBlockSize, 0, FAKE_BUFFER_SIZE, nullptr, 0.0f); | |||
| effect->dispatcher(effect, effEditOpen, 0, 0, (void*)widget->winId(), 0.0f); | |||
| #ifdef VESTIGE_HEADER | |||
| effect->ptr1 = this; | |||
| #else | |||
| effect->resvd1 = (intptr_t)this; | |||
| #endif | |||
| ERect* vst_rect; | |||
| if (effect->dispatcher(effect, effEditGetRect, 0, 0, &vst_rect, 0.0f)) | |||
| { | |||
| int width = vst_rect->right - vst_rect->left; | |||
| int height = vst_rect->bottom - vst_rect->top; | |||
| widget->setFixedSize(width, height); | |||
| return true; | |||
| } | |||
| } | |||
| } | |||
| // ----------------------------------------------------------------- | |||
| // initialize gui stuff | |||
| ERect* vstRect; | |||
| if (effect->dispatcher(effect, effEditGetRect, 0, 0, &vstRect, 0.0f)) | |||
| { | |||
| int width = vstRect->right - vstRect->left; | |||
| int height = vstRect->bottom - vstRect->top; | |||
| widget->setFixedSize(width, height); | |||
| return true; | |||
| } | |||
| return false; | |||
| } | |||
| @@ -147,20 +156,6 @@ public: | |||
| static intptr_t VstHostCallback(AEffect* effect, int32_t opcode, int32_t index, intptr_t value, void* ptr, float opt) | |||
| { | |||
| #if DEBUG | |||
| qDebug("VstHostCallback() - code: %s, index: %i, value: " P_INTPTR ", opt: %f", VstOpcode2str(opcode), index, value, opt); | |||
| #endif | |||
| // Check if 'user' points to this UI | |||
| VstUiData* self = nullptr; | |||
| if (effect && effect->user) | |||
| { | |||
| self = (VstUiData*)effect->user; | |||
| if (self->unique1 != self->unique2) | |||
| self = nullptr; | |||
| } | |||
| switch (opcode) | |||
| { | |||
| case audioMasterAutomate: | |||
| @@ -179,20 +174,17 @@ public: | |||
| break; | |||
| case audioMasterGetTime: | |||
| { | |||
| static VstTimeInfo timeInfo; | |||
| memset(&timeInfo, 0, sizeof(VstTimeInfo)); | |||
| timeInfo.sampleRate = 44100; | |||
| static VstTimeInfo_R timeInfo; | |||
| memset(&timeInfo, 0, sizeof(VstTimeInfo_R)); | |||
| timeInfo.sampleRate = FAKE_SAMPLE_RATE; | |||
| return (intptr_t)&timeInfo; | |||
| } | |||
| case audioMasterProcessEvents: | |||
| if (self && ptr) | |||
| if (client && ptr) | |||
| { | |||
| int32_t i; | |||
| const VstEvents* const events = (VstEvents*)ptr; | |||
| for (i=0; i < events->numEvents; i++) | |||
| for (int32_t i=0; i < events->numEvents; i++) | |||
| { | |||
| const VstMidiEvent* const midi_event = (VstMidiEvent*)events->events[i]; | |||
| @@ -218,8 +210,8 @@ public: | |||
| #endif | |||
| case audioMasterSizeWindow: | |||
| if (self) | |||
| self->queque_message(BRIDGE_MESSAGE_RESIZE_GUI, index, value, 0.0f); | |||
| if (client) | |||
| client->queque_message(BRIDGE_MESSAGE_RESIZE_GUI, index, value, 0.0f); | |||
| return 1; | |||
| case audioMasterGetSampleRate: | |||
| @@ -290,7 +282,7 @@ public: | |||
| return kVstLangEnglish; | |||
| case audioMasterUpdateDisplay: | |||
| osc_send_configure("reloadprograms", ""); | |||
| //osc_send_configure("reloadprograms", ""); | |||
| break; | |||
| default: | |||
| @@ -304,18 +296,16 @@ public: | |||
| } | |||
| private: | |||
| long unique1; | |||
| AEffect* effect; | |||
| QDialog* widget; | |||
| long unique2; | |||
| }; | |||
| int main(int argc, char* argv[]) | |||
| { | |||
| if (argc != 4) | |||
| { | |||
| qCritical("%s: bad arguments", argv[0]); | |||
| return 1; | |||
| qCritical("%s: bad arguments", argv[0]); | |||
| return 1; | |||
| } | |||
| const char* osc_url = argv[1]; | |||
| @@ -326,7 +316,7 @@ int main(int argc, char* argv[]) | |||
| toolkit_init(); | |||
| // Init VST-UI | |||
| ui = new VstUiData(ui_title); | |||
| client = new VstUiData(ui_title); | |||
| // Init OSC | |||
| osc_init(osc_url); | |||
| @@ -334,7 +324,7 @@ int main(int argc, char* argv[]) | |||
| // Load UI | |||
| int ret; | |||
| if (ui->init(binary, nullptr)) | |||
| if (client->init(binary, nullptr)) | |||
| { | |||
| toolkit_loop(); | |||
| ret = 0; | |||
| @@ -350,14 +340,14 @@ int main(int argc, char* argv[]) | |||
| osc_close(); | |||
| // Close VST-UI | |||
| ui->close(); | |||
| client->close(); | |||
| // Close toolkit | |||
| if (! ret) | |||
| toolkit_quit(); | |||
| delete ui; | |||
| ui = nullptr; | |||
| delete client; | |||
| client = nullptr; | |||
| return ret; | |||
| } | |||
| @@ -15,8 +15,8 @@ SOURCES = \ | |||
| ../carla_bridge_ui-gtk2.cpp | |||
| HEADERS = \ | |||
| ../carla_bridge.h \ | |||
| ../carla_bridge_osc.h \ | |||
| ../carla_bridge_ui.h \ | |||
| ../../carla-backend/carla_midi.h \ | |||
| ../../carla-includes/carla_includes.h \ | |||
| ../../carla-includes/carla_lib_includes.h \ | |||
| @@ -15,8 +15,8 @@ SOURCES = \ | |||
| ../carla_bridge_ui-qt4.cpp | |||
| HEADERS = \ | |||
| ../carla_bridge.h \ | |||
| ../carla_bridge_osc.h \ | |||
| ../carla_bridge_ui.h \ | |||
| ../../carla-backend/carla_midi.h \ | |||
| ../../carla-includes/carla_includes.h \ | |||
| ../../carla-includes/carla_lib_includes.h \ | |||
| @@ -15,8 +15,8 @@ SOURCES = \ | |||
| ../carla_bridge_ui-qt4.cpp | |||
| HEADERS = \ | |||
| ../carla_bridge.h \ | |||
| ../carla_bridge_osc.h \ | |||
| ../carla_bridge_ui.h \ | |||
| ../../carla-backend/carla_midi.h \ | |||
| ../../carla-includes/carla_includes.h \ | |||
| ../../carla-includes/carla_lib_includes.h \ | |||
| @@ -11,12 +11,12 @@ VERSION = 0.5.0 | |||
| SOURCES = \ | |||
| ../carla_bridge_osc.cpp \ | |||
| ../carla_bridge_ui-lv2.cpp \ | |||
| ../carla_bridge_ui-vst.cpp \ | |||
| ../carla_bridge_ui-qt4.cpp | |||
| HEADERS = \ | |||
| ../carla_bridge.h \ | |||
| ../carla_bridge_osc.h \ | |||
| ../carla_bridge_ui.h \ | |||
| ../../carla-backend/carla_midi.h \ | |||
| ../../carla-includes/carla_includes.h \ | |||
| ../../carla-includes/carla_lib_includes.h \ | |||