@@ -1476,17 +1476,17 @@ void CarlaEngine::osc_send_bridge_midi_count(const int32_t ins, const int32_t ou | |||||
} | } | ||||
} | } | ||||
void CarlaEngine::osc_send_bridge_param_count(const int32_t ins, const int32_t outs, const int32_t total) | |||||
void CarlaEngine::osc_send_bridge_parameter_count(const int32_t ins, const int32_t outs, const int32_t total) | |||||
{ | { | ||||
qDebug("CarlaEngine::osc_send_bridge_param_count(%i, %i, %i)", ins, outs, total); | |||||
qDebug("CarlaEngine::osc_send_bridge_parameter_count(%i, %i, %i)", ins, outs, total); | |||||
Q_ASSERT(m_oscData); | Q_ASSERT(m_oscData); | ||||
Q_ASSERT(total >= 0 && total >= ins + outs); | Q_ASSERT(total >= 0 && total >= ins + outs); | ||||
if (m_oscData && m_oscData->target) | if (m_oscData && m_oscData->target) | ||||
{ | { | ||||
char target_path[strlen(m_oscData->path)+20]; | |||||
char target_path[strlen(m_oscData->path)+24]; | |||||
strcpy(target_path, m_oscData->path); | strcpy(target_path, m_oscData->path); | ||||
strcat(target_path, "/bridge_param_count"); | |||||
strcat(target_path, "/bridge_parameter_count"); | |||||
lo_send(m_oscData->target, target_path, "iii", ins, outs, total); | lo_send(m_oscData->target, target_path, "iii", ins, outs, total); | ||||
} | } | ||||
} | } | ||||
@@ -1585,7 +1585,7 @@ void CarlaEngine::osc_send_bridge_param_ranges(const int32_t index, const double | |||||
void CarlaEngine::osc_send_bridge_program_info(const int32_t index, const char* const name) | void CarlaEngine::osc_send_bridge_program_info(const int32_t index, const char* const name) | ||||
{ | { | ||||
//qDebug("CarlaEngine::osc_send_bridge_program_info(%i, \"%s\")", index, name); | |||||
qDebug("CarlaEngine::osc_send_bridge_program_info(%i, \"%s\")", index, name); | |||||
Q_ASSERT(m_oscData); | Q_ASSERT(m_oscData); | ||||
if (m_oscData && m_oscData->target) | if (m_oscData && m_oscData->target) | ||||
@@ -1610,6 +1610,62 @@ void CarlaEngine::osc_send_bridge_midi_program_info(const int32_t index, const i | |||||
lo_send(m_oscData->target, target_path, "iiis", index, bank, program, label); | lo_send(m_oscData->target, target_path, "iiis", index, bank, program, label); | ||||
} | } | ||||
} | } | ||||
void CarlaEngine::osc_send_bridge_set_parameter_value(const int32_t index, const double value) | |||||
{ | |||||
qDebug("CarlaEngine::osc_send_bridge_set_parameter_value(%i, %g)", index, value); | |||||
Q_ASSERT(m_oscData); | |||||
if (m_oscData && m_oscData->target) | |||||
{ | |||||
char target_path[strlen(m_oscData->path)+27]; | |||||
strcpy(target_path, m_oscData->path); | |||||
strcat(target_path, "/bridge_set_parameter_value"); | |||||
lo_send(m_oscData->target, target_path, "id", index, value); | |||||
} | |||||
} | |||||
void CarlaEngine::osc_send_bridge_set_default_value(const int32_t index, const double value) | |||||
{ | |||||
qDebug("CarlaEngine::osc_send_bridge_set_default_value(%i, %g)", index, value); | |||||
Q_ASSERT(m_oscData); | |||||
if (m_oscData && m_oscData->target) | |||||
{ | |||||
char target_path[strlen(m_oscData->path)+27]; | |||||
strcpy(target_path, m_oscData->path); | |||||
strcat(target_path, "/bridge_set_default_value"); | |||||
lo_send(m_oscData->target, target_path, "id", index, value); | |||||
} | |||||
} | |||||
void CarlaEngine::osc_send_bridge_set_program(const int32_t index) | |||||
{ | |||||
qDebug("CarlaEngine::osc_send_bridge_set_program(%i)", index); | |||||
Q_ASSERT(m_oscData); | |||||
if (m_oscData && m_oscData->target) | |||||
{ | |||||
char target_path[strlen(m_oscData->path)+27]; | |||||
strcpy(target_path, m_oscData->path); | |||||
strcat(target_path, "/bridge_set_program"); | |||||
lo_send(m_oscData->target, target_path, "i", index); | |||||
} | |||||
} | |||||
void CarlaEngine::osc_send_bridge_set_midi_program(const int32_t index) | |||||
{ | |||||
qDebug("CarlaEngine::osc_send_bridge_set_midi_program(%i)", index); | |||||
Q_ASSERT(m_oscData); | |||||
if (m_oscData && m_oscData->target) | |||||
{ | |||||
char target_path[strlen(m_oscData->path)+27]; | |||||
strcpy(target_path, m_oscData->path); | |||||
strcat(target_path, "/bridge_set_midi_program"); | |||||
lo_send(m_oscData->target, target_path, "i", index); | |||||
} | |||||
} | |||||
#endif | #endif | ||||
CARLA_BACKEND_END_NAMESPACE | CARLA_BACKEND_END_NAMESPACE |
@@ -267,7 +267,7 @@ public: | |||||
#ifdef BUILD_BRIDGE | #ifdef BUILD_BRIDGE | ||||
void osc_send_bridge_audio_count(const int32_t ins, const int32_t outs, const int32_t total); | void osc_send_bridge_audio_count(const int32_t ins, const int32_t outs, const int32_t total); | ||||
void osc_send_bridge_midi_count(const int32_t ins, const int32_t outs, const int32_t total); | void osc_send_bridge_midi_count(const int32_t ins, const int32_t outs, const int32_t total); | ||||
void osc_send_bridge_param_count(const int32_t ins, const int32_t outs, const int32_t total); | |||||
void osc_send_bridge_parameter_count(const int32_t ins, const int32_t outs, const int32_t total); | |||||
void osc_send_bridge_program_count(const int32_t count); | void osc_send_bridge_program_count(const int32_t count); | ||||
void osc_send_bridge_midi_program_count(const int32_t count); | void osc_send_bridge_midi_program_count(const int32_t count); | ||||
void osc_send_bridge_plugin_info(const int32_t category, const int32_t hints, const char* const name, const char* const label, const char* const maker, const char* const copyright, const int64_t uniqueId); | void osc_send_bridge_plugin_info(const int32_t category, const int32_t hints, const char* const name, const char* const label, const char* const maker, const char* const copyright, const int64_t uniqueId); | ||||
@@ -276,6 +276,10 @@ public: | |||||
void osc_send_bridge_param_ranges(const int32_t index, const double def, const double min, const double max, const double step, const double stepSmall, const double stepLarge); | void osc_send_bridge_param_ranges(const int32_t index, const double def, const double min, const double max, const double step, const double stepSmall, const double stepLarge); | ||||
void osc_send_bridge_program_info(const int32_t index, const char* const name); | void osc_send_bridge_program_info(const int32_t index, const char* const name); | ||||
void osc_send_bridge_midi_program_info(const int32_t index, const int32_t bank, const int32_t program, const char* const label); | void osc_send_bridge_midi_program_info(const int32_t index, const int32_t bank, const int32_t program, const char* const label); | ||||
void osc_send_bridge_set_parameter_value(const int32_t index, const double value); | |||||
void osc_send_bridge_set_default_value(const int32_t index, const double value); | |||||
void osc_send_bridge_set_program(const int32_t index); | |||||
void osc_send_bridge_set_midi_program(const int32_t index); | |||||
//void osc_send_bridge_program(const int32_t index); | //void osc_send_bridge_program(const int32_t index); | ||||
//void osc_send_bridge_midi_program(const int32_t index); | //void osc_send_bridge_midi_program(const int32_t index); | ||||
//void osc_send_bridge_custom_data(const char* const stype, const char* const key, const char* const value); | //void osc_send_bridge_custom_data(const char* const stype, const char* const key, const char* const value); | ||||
@@ -1452,7 +1452,7 @@ public: | |||||
#ifdef BUILD_BRIDGE | #ifdef BUILD_BRIDGE | ||||
x_engine->osc_send_bridge_audio_count(audioInCount(), audioOutCount(), audioInCount() + audioOutCount()); | x_engine->osc_send_bridge_audio_count(audioInCount(), audioOutCount(), audioInCount() + audioOutCount()); | ||||
x_engine->osc_send_bridge_midi_count(midiInCount(), midiOutCount(), midiInCount() + midiOutCount()); | x_engine->osc_send_bridge_midi_count(midiInCount(), midiOutCount(), midiInCount() + midiOutCount()); | ||||
x_engine->osc_send_bridge_param_count(cIns, cOuts, cTotals); | |||||
x_engine->osc_send_bridge_parameter_count(cIns, cOuts, cTotals); | |||||
#else | #else | ||||
x_engine->osc_send_control_set_plugin_ports(m_id, audioInCount(), audioOutCount(), midiInCount(), midiOutCount(), cIns, cOuts, cTotals); | x_engine->osc_send_control_set_plugin_ports(m_id, audioInCount(), audioOutCount(), midiInCount(), midiOutCount(), cIns, cOuts, cTotals); | ||||
#endif | #endif | ||||
@@ -1488,10 +1488,11 @@ public: | |||||
x_engine->osc_send_bridge_param_info(i, bufName, bufUnit); | x_engine->osc_send_bridge_param_info(i, bufName, bufUnit); | ||||
x_engine->osc_send_bridge_param_data(i, param.data[i].type, param.data[i].rindex, param.data[i].hints, param.data[i].midiChannel, param.data[i].midiCC); | x_engine->osc_send_bridge_param_data(i, param.data[i].type, param.data[i].rindex, param.data[i].hints, param.data[i].midiChannel, param.data[i].midiCC); | ||||
x_engine->osc_send_bridge_param_ranges(i, param.ranges[i].def, param.ranges[i].min, param.ranges[i].max, param.ranges[i].step, param.ranges[i].stepSmall, param.ranges[i].stepLarge); | x_engine->osc_send_bridge_param_ranges(i, param.ranges[i].def, param.ranges[i].min, param.ranges[i].max, param.ranges[i].step, param.ranges[i].stepSmall, param.ranges[i].stepLarge); | ||||
setParameterValue(i, param.ranges[i].def, false, false, true); // FIXME? | |||||
x_engine->osc_send_bridge_set_parameter_value(i, getParameterValue(i)); | |||||
#else | #else | ||||
x_engine->osc_send_control_set_parameter_data(m_id, i, param.data[i].type, param.data[i].hints, bufName, bufUnit, getParameterValue(i)); | x_engine->osc_send_control_set_parameter_data(m_id, i, param.data[i].type, param.data[i].hints, bufName, bufUnit, getParameterValue(i)); | ||||
x_engine->osc_send_control_set_parameter_ranges(m_id, i, param.ranges[i].min, param.ranges[i].max, param.ranges[i].def, param.ranges[i].step, param.ranges[i].stepSmall, param.ranges[i].stepLarge); | x_engine->osc_send_control_set_parameter_ranges(m_id, i, param.ranges[i].min, param.ranges[i].max, param.ranges[i].def, param.ranges[i].step, param.ranges[i].stepSmall, param.ranges[i].stepLarge); | ||||
x_engine->osc_send_control_set_parameter_value(m_id, i, getParameterValue(i)); | |||||
#endif | #endif | ||||
} | } | ||||
} | } | ||||
@@ -1504,7 +1505,7 @@ public: | |||||
for (uint32_t i=0; i < prog.count; i++) | for (uint32_t i=0; i < prog.count; i++) | ||||
x_engine->osc_send_bridge_program_info(i, prog.names[i]); | x_engine->osc_send_bridge_program_info(i, prog.names[i]); | ||||
//x_engine->osc_send_program(prog.current); | |||||
x_engine->osc_send_bridge_set_program(prog.current); | |||||
#else | #else | ||||
x_engine->osc_send_control_set_program_count(m_id, prog.count); | x_engine->osc_send_control_set_program_count(m_id, prog.count); | ||||
@@ -1523,7 +1524,7 @@ public: | |||||
for (uint32_t i=0; i < midiprog.count; i++) | for (uint32_t i=0; i < midiprog.count; i++) | ||||
x_engine->osc_send_bridge_midi_program_info(i, midiprog.data[i].bank, midiprog.data[i].program, midiprog.data[i].name); | x_engine->osc_send_bridge_midi_program_info(i, midiprog.data[i].bank, midiprog.data[i].program, midiprog.data[i].name); | ||||
//x_engine->osc_send_midi_program(midiprog.current); | |||||
x_engine->osc_send_bridge_set_midi_program(prog.current); | |||||
#else | #else | ||||
x_engine->osc_send_control_set_midi_program_count(m_id, midiprog.count); | x_engine->osc_send_control_set_midi_program_count(m_id, midiprog.count); | ||||
@@ -63,8 +63,7 @@ void CarlaCheckThread::run() | |||||
{ | { | ||||
qDebug("CarlaCheckThread::run()"); | qDebug("CarlaCheckThread::run()"); | ||||
bool usesSingleThread, oscControllerRegisted = false; | |||||
unsigned short id; | |||||
bool oscControllerRegisted, usesSingleThread; | |||||
double value; | double value; | ||||
m_stopNow = false; | m_stopNow = false; | ||||
@@ -72,7 +71,10 @@ void CarlaCheckThread::run() | |||||
while (engine->isRunning() && ! m_stopNow) | while (engine->isRunning() && ! m_stopNow) | ||||
{ | { | ||||
const ScopedLocker m(this); | const ScopedLocker m(this); | ||||
#ifndef BUILD_BRIDGE | |||||
#ifdef BUILD_BRIDGE | |||||
oscControllerRegisted = true; | |||||
#else | |||||
oscControllerRegisted = engine->isOscControllerRegisted(); | oscControllerRegisted = engine->isOscControllerRegisted(); | ||||
#endif | #endif | ||||
@@ -82,7 +84,9 @@ void CarlaCheckThread::run() | |||||
if (plugin && plugin->enabled()) | if (plugin && plugin->enabled()) | ||||
{ | { | ||||
id = plugin->id(); | |||||
#ifndef BUILD_BRIDGE | |||||
unsigned short id = plugin->id(); | |||||
#endif | |||||
usesSingleThread = (plugin->hints() & CarlaBackend::PLUGIN_USES_SINGLE_THREAD); | usesSingleThread = (plugin->hints() & CarlaBackend::PLUGIN_USES_SINGLE_THREAD); | ||||
// ------------------------------------------------------- | // ------------------------------------------------------- | ||||
@@ -106,9 +110,11 @@ void CarlaCheckThread::run() | |||||
if (! usesSingleThread) | if (! usesSingleThread) | ||||
plugin->uiParameterChange(i, value); | plugin->uiParameterChange(i, value); | ||||
#ifndef BUILD_BRIDGE | |||||
// Update OSC control client | // Update OSC control client | ||||
if (oscControllerRegisted) | if (oscControllerRegisted) | ||||
#ifdef BUILD_BRIDGE | |||||
engine->osc_send_bridge_set_parameter_value(i, value); | |||||
#else | |||||
engine->osc_send_control_set_parameter_value(id, i, value); | engine->osc_send_control_set_parameter_value(id, i, value); | ||||
#endif | #endif | ||||
} | } | ||||
@@ -424,13 +424,12 @@ public: | |||||
void idleGui() | void idleGui() | ||||
{ | { | ||||
effect->dispatcher(effect, effIdle, 0, 0, nullptr, 0.0f); | |||||
//effect->dispatcher(effect, effIdle, 0, 0, nullptr, 0.0f); | |||||
// FIXME | |||||
//if (gui.type != GUI_EXTERNAL_OSC && gui.visible) | |||||
if (gui.type != GUI_EXTERNAL_OSC && gui.visible) | |||||
effect->dispatcher(effect, effEditIdle, 0, 0, nullptr, 0.0f); | effect->dispatcher(effect, effEditIdle, 0, 0, nullptr, 0.0f); | ||||
//CarlaPlugin::idleGui(); | |||||
CarlaPlugin::idleGui(); | |||||
} | } | ||||
// ------------------------------------------------------------------- | // ------------------------------------------------------------------- | ||||
@@ -8,10 +8,11 @@ CXX ?= g++ | |||||
STRIP ?= strip | STRIP ?= strip | ||||
BASE_FLAGS = -O2 -ffast-math -fomit-frame-pointer -mtune=generic -msse -mfpmath=sse -Wall | BASE_FLAGS = -O2 -ffast-math -fomit-frame-pointer -mtune=generic -msse -mfpmath=sse -Wall | ||||
BASE_FLAGS = -O0 -g | |||||
BUILD_FLAGS = $(BASE_FLAGS) -std=c++0x $(CXXFLAGS) | BUILD_FLAGS = $(BASE_FLAGS) -std=c++0x $(CXXFLAGS) | ||||
BUILD_FLAGS += -I. -I../carla-includes $(shell pkg-config --cflags liblo QtCore) | BUILD_FLAGS += -I. -I../carla-includes $(shell pkg-config --cflags liblo QtCore) | ||||
BUILD_FLAGS += -DBUILD_BRIDGE -DQT_NO_DEBUG -DQT_NO_DEBUG_STREAM -DQT_NO_DEBUG_OUTPUT # -DNDEBUG | |||||
BUILD_FLAGS += -DBUILD_BRIDGE -DDEBUG # -DQT_NO_DEBUG -DQT_NO_DEBUG_STREAM -DQT_NO_DEBUG_OUTPUT # -DNDEBUG | |||||
BUILD_FLAGS += -DVESTIGE_HEADER -I../carla-includes/vestige # Comment this line to not use vestige header | BUILD_FLAGS += -DVESTIGE_HEADER -I../carla-includes/vestige # Comment this line to not use vestige header | ||||
32BIT_FLAGS = -m32 | 32BIT_FLAGS = -m32 | ||||
@@ -210,6 +210,18 @@ public: | |||||
m_osc.sendOscControl(index, value); | m_osc.sendOscControl(index, value); | ||||
} | } | ||||
void sendOscProgram(const int32_t index) | |||||
{ | |||||
qDebug("CarlaClient::sendOscProgram(%i)", index); | |||||
m_osc.sendOscProgram(index); | |||||
} | |||||
void sendOscMidiProgram(const int32_t index) | |||||
{ | |||||
qDebug("CarlaClient::sendOscMidiProgram(%i)", index); | |||||
m_osc.sendOscMidiProgram(index); | |||||
} | |||||
void sendOscMidi(const uint8_t midiBuf[4]) | void sendOscMidi(const uint8_t midiBuf[4]) | ||||
{ | { | ||||
qDebug("CarlaClient::sendOscMidi(%p)", midiBuf); | qDebug("CarlaClient::sendOscMidi(%p)", midiBuf); | ||||
@@ -89,6 +89,22 @@ public: | |||||
osc_send_control(&m_controlData, index, value); | osc_send_control(&m_controlData, index, value); | ||||
} | } | ||||
void sendOscProgram(const int32_t index) | |||||
{ | |||||
Q_ASSERT(m_controlData.target); | |||||
if (m_controlData.target) | |||||
osc_send_program(&m_controlData, index); | |||||
} | |||||
void sendOscMidiProgram(const int32_t index) | |||||
{ | |||||
Q_ASSERT(m_controlData.target); | |||||
if (m_controlData.target) | |||||
osc_send_midi_program(&m_controlData, index); | |||||
} | |||||
void sendOscMidi(const uint8_t midiBuf[4]) | void sendOscMidi(const uint8_t midiBuf[4]) | ||||
{ | { | ||||
Q_ASSERT(m_controlData.target); | Q_ASSERT(m_controlData.target); | ||||
@@ -21,20 +21,57 @@ | |||||
#include "carla_plugin.h" | #include "carla_plugin.h" | ||||
#include <QtCore/QFile> | #include <QtCore/QFile> | ||||
#ifndef __WINE__ | |||||
#include <QtCore/QTimerEvent> | #include <QtCore/QTimerEvent> | ||||
#include <QtGui/QApplication> | #include <QtGui/QApplication> | ||||
#include <QtGui/QDialog> | #include <QtGui/QDialog> | ||||
#include <QtGui/QVBoxLayout> | |||||
#ifdef Q_OS_UNIX | |||||
#include <signal.h> | |||||
#endif | #endif | ||||
#ifdef __WINE__ | |||||
static HINSTANCE hInstGlobal = nullptr; | |||||
#else | |||||
static int qargc = 0; | |||||
static char* qargv[] = { nullptr }; | |||||
static int qargc = 0; | |||||
static char** qargv = nullptr; | |||||
bool qcloseNow = false; | |||||
#if defined(Q_OS_UNIX) | |||||
void closeSignalHandler(int) | |||||
{ | |||||
qcloseNow = true; | |||||
} | |||||
#elif defined(Q_OS_WIN) | |||||
BOOL WINAPI closeSignalHandler(DWORD dwCtrlType) | |||||
{ | |||||
if (dwCtrlType == CTRL_C_EVENT) | |||||
{ | |||||
qcloseNow = true; | |||||
return TRUE; | |||||
} | |||||
return FALSE; | |||||
} | |||||
#endif | #endif | ||||
void initSignalHandler() | |||||
{ | |||||
#if defined(Q_OS_UNIX) | |||||
struct sigaction sint, sterm; | |||||
sint.sa_handler = closeSignalHandler; | |||||
sigemptyset(&sint.sa_mask); | |||||
sint.sa_flags |= SA_RESTART; | |||||
sigaction(SIGINT, &sint, 0); | |||||
sterm.sa_handler = closeSignalHandler; | |||||
sigemptyset(&sterm.sa_mask); | |||||
sterm.sa_flags |= SA_RESTART; | |||||
sigaction(SIGTERM, &sterm, 0); | |||||
#elif defined(Q_OS_WIN) | |||||
SetConsoleCtrlHandler(closeSignalHandler, TRUE); | |||||
#endif | |||||
} | |||||
CARLA_BRIDGE_START_NAMESPACE | CARLA_BRIDGE_START_NAMESPACE | ||||
// ------------------------------------------------------------------------- | // ------------------------------------------------------------------------- | ||||
@@ -65,6 +102,7 @@ public: | |||||
void setParameter(const int32_t rindex, const double value) | void setParameter(const int32_t rindex, const double value) | ||||
{ | { | ||||
qDebug("CarlaPluginClient::setParameter(%i, %g)", rindex, value); | |||||
Q_ASSERT(plugin); | Q_ASSERT(plugin); | ||||
if (! plugin) | if (! plugin) | ||||
@@ -75,6 +113,7 @@ public: | |||||
void setProgram(const uint32_t index) | void setProgram(const uint32_t index) | ||||
{ | { | ||||
qDebug("CarlaPluginClient::setProgram(%i)", index); | |||||
Q_ASSERT(plugin && index < plugin->programCount()); | Q_ASSERT(plugin && index < plugin->programCount()); | ||||
if (! plugin) | if (! plugin) | ||||
@@ -87,6 +126,7 @@ public: | |||||
void setMidiProgram(const uint32_t bank, const uint32_t program) | void setMidiProgram(const uint32_t bank, const uint32_t program) | ||||
{ | { | ||||
qDebug("CarlaPluginClient::setMidiProgram(%i, %i)", bank, program); | |||||
Q_ASSERT(plugin); | Q_ASSERT(plugin); | ||||
if (! plugin) | if (! plugin) | ||||
@@ -97,6 +137,7 @@ public: | |||||
void noteOn(const uint8_t channel, const uint8_t note, const uint8_t velo) | void noteOn(const uint8_t channel, const uint8_t note, const uint8_t velo) | ||||
{ | { | ||||
qDebug("CarlaPluginClient::noteOn(%i, %i, %i)", channel, note, velo); | |||||
Q_ASSERT(plugin); | Q_ASSERT(plugin); | ||||
Q_ASSERT(velo > 0); | Q_ASSERT(velo > 0); | ||||
@@ -108,6 +149,7 @@ public: | |||||
void noteOff(const uint8_t channel, const uint8_t note) | void noteOff(const uint8_t channel, const uint8_t note) | ||||
{ | { | ||||
qDebug("CarlaPluginClient::noteOn(%i, %i)", channel, note); | |||||
Q_ASSERT(plugin); | Q_ASSERT(plugin); | ||||
if (! plugin) | if (! plugin) | ||||
@@ -203,21 +245,35 @@ public: | |||||
//plugin->showGui(true); | //plugin->showGui(true); | ||||
} | } | ||||
void showGui(const bool yesNo) | |||||
{ | |||||
qDebug("CarlaPluginClient::showGui(%s)", bool2str(yesNo)); | |||||
Q_ASSERT(plugin); | |||||
if (! plugin) | |||||
return; | |||||
plugin->showGui(yesNo); | |||||
} | |||||
// --------------------------------------------------------------------- | // --------------------------------------------------------------------- | ||||
// callback | // callback | ||||
void handleCallback(const CarlaBackend::CallbackType action, const int value1, const int value2, const double value3) | void handleCallback(const CarlaBackend::CallbackType action, const int value1, const int value2, const double value3) | ||||
{ | { | ||||
qDebug("CarlaPluginClient::handleCallback(%s, %i, %i, %g)", CarlaBackend::CallbackType2str(action), value1, value2, value3); | |||||
// FIXME - those OSC calls should be on the engine | |||||
switch (action) | switch (action) | ||||
{ | { | ||||
case CarlaBackend::CALLBACK_PARAMETER_VALUE_CHANGED: | case CarlaBackend::CALLBACK_PARAMETER_VALUE_CHANGED: | ||||
//osc_send_control(value1, value3); | |||||
engine->osc_send_bridge_set_parameter_value(value1, value3); | |||||
break; | break; | ||||
case CarlaBackend::CALLBACK_PROGRAM_CHANGED: | case CarlaBackend::CALLBACK_PROGRAM_CHANGED: | ||||
//osc_send_program(value1); | |||||
engine->osc_send_bridge_set_program(value1); | |||||
break; | break; | ||||
case CarlaBackend::CALLBACK_MIDI_PROGRAM_CHANGED: | case CarlaBackend::CALLBACK_MIDI_PROGRAM_CHANGED: | ||||
//osc_send_midi_program(value1, value2, false); | |||||
engine->osc_send_bridge_set_midi_program(value1); | |||||
break; | break; | ||||
case CarlaBackend::CALLBACK_NOTE_ON: | case CarlaBackend::CALLBACK_NOTE_ON: | ||||
{ | { | ||||
@@ -283,7 +339,6 @@ private: | |||||
// ------------------------------------------------------------------------- | // ------------------------------------------------------------------------- | ||||
// toolkit | // toolkit | ||||
#ifndef __WINE__ | |||||
class BridgeApplication : public QApplication | class BridgeApplication : public QApplication | ||||
{ | { | ||||
public: | public: | ||||
@@ -305,6 +360,9 @@ public: | |||||
protected: | protected: | ||||
void timerEvent(QTimerEvent* const event) | void timerEvent(QTimerEvent* const event) | ||||
{ | { | ||||
if (qcloseNow) | |||||
return quit(); | |||||
if (event->timerId() == msgTimer) | if (event->timerId() == msgTimer) | ||||
{ | { | ||||
if (m_client) | if (m_client) | ||||
@@ -323,7 +381,6 @@ private: | |||||
int msgTimer; | int msgTimer; | ||||
CarlaPluginClient* m_client; | CarlaPluginClient* m_client; | ||||
}; | }; | ||||
#endif | |||||
class CarlaToolkitPlugin : public CarlaToolkit | class CarlaToolkitPlugin : public CarlaToolkit | ||||
{ | { | ||||
@@ -332,55 +389,28 @@ public: | |||||
: CarlaToolkit("carla-bridge-plugin") | : CarlaToolkit("carla-bridge-plugin") | ||||
{ | { | ||||
qDebug("CarlaToolkitPlugin::CarlaToolkitPlugin()"); | qDebug("CarlaToolkitPlugin::CarlaToolkitPlugin()"); | ||||
#ifdef __WINE__ | |||||
closeNow = false; | |||||
hwnd = nullptr; | |||||
#else | |||||
app = nullptr; | app = nullptr; | ||||
dialog = nullptr; | dialog = nullptr; | ||||
#endif | |||||
} | } | ||||
~CarlaToolkitPlugin() | ~CarlaToolkitPlugin() | ||||
{ | { | ||||
qDebug("CarlaToolkitPlugin::~CarlaToolkitPlugin()"); | qDebug("CarlaToolkitPlugin::~CarlaToolkitPlugin()"); | ||||
#ifdef __WINE__ | |||||
Q_ASSERT(! closeNow); | |||||
#else | |||||
Q_ASSERT(! app); | Q_ASSERT(! app); | ||||
#endif | |||||
} | } | ||||
void init() | void init() | ||||
{ | { | ||||
qDebug("CarlaToolkitPlugin::init()"); | qDebug("CarlaToolkitPlugin::init()"); | ||||
#ifdef __WINE__ | |||||
Q_ASSERT(! closeNow); | |||||
WNDCLASSEXA wc; | |||||
wc.cbSize = sizeof(WNDCLASSEXA); | |||||
wc.style = 0; | |||||
wc.lpfnWndProc = windowProcA; | |||||
wc.cbClsExtra = 0; | |||||
wc.cbWndExtra = 0; | |||||
wc.hInstance = hInstGlobal; | |||||
wc.hIcon = LoadIconA(nullptr, IDI_APPLICATION); | |||||
wc.hCursor = LoadCursorA(nullptr, IDC_ARROW); | |||||
wc.hbrBackground = (HBRUSH)COLOR_BACKGROUND; | |||||
wc.lpszMenuName = "MENU_CARLA_BRIDGE"; | |||||
wc.lpszClassName = "CLASS_CARLA_BRIDGE"; | |||||
wc.hIconSm = nullptr; | |||||
RegisterClassExA(&wc); | |||||
#else | |||||
Q_ASSERT(! app); | Q_ASSERT(! app); | ||||
app = new BridgeApplication; | app = new BridgeApplication; | ||||
#endif | |||||
} | } | ||||
void exec(CarlaClient* const client, const bool showGui) | void exec(CarlaClient* const client, const bool showGui) | ||||
{ | { | ||||
qDebug("CarlaToolkitPlugin::exec(%p)", client); | qDebug("CarlaToolkitPlugin::exec(%p)", client); | ||||
Q_ASSERT(app); | |||||
Q_ASSERT(client); | Q_ASSERT(client); | ||||
m_client = client; | m_client = client; | ||||
@@ -395,55 +425,12 @@ public: | |||||
m_client->sendOscBridgeUpdate(); | m_client->sendOscBridgeUpdate(); | ||||
} | } | ||||
#ifdef __WINE__ | |||||
Q_ASSERT(! closeNow); | |||||
MSG msg; | |||||
CarlaPluginClient* const pluginClient = (CarlaPluginClient*)client; | |||||
while (! closeNow) | |||||
{ | |||||
//pluginClient->runMessages(); | |||||
//pluginClient->idle(); | |||||
//if (closeNow) | |||||
// break; | |||||
while (GetMessageA(&msg, hwnd, 0, 0) > 0) | |||||
{ | |||||
//if (PeekMessageA(&msg, hwnd, 0, 0, PM_REMOVE)) | |||||
//{ | |||||
//TranslateMessage(&msg); | |||||
DispatchMessageA(&msg); | |||||
pluginClient->runMessages(); | |||||
pluginClient->idle(); | |||||
} | |||||
//if (closeNow) | |||||
// break; | |||||
//carla_msleep(50); | |||||
} | |||||
#else | |||||
Q_ASSERT(app); | |||||
app->exec((CarlaPluginClient*)client); | app->exec((CarlaPluginClient*)client); | ||||
#endif | |||||
} | } | ||||
void quit() | void quit() | ||||
{ | { | ||||
qDebug("CarlaToolkitPlugin::quit()"); | qDebug("CarlaToolkitPlugin::quit()"); | ||||
#ifdef __WINE__ | |||||
if (closeNow && hwnd) | |||||
{ | |||||
DestroyWindow(hwnd); | |||||
hwnd = nullptr; | |||||
} | |||||
closeNow = true; | |||||
#else | |||||
Q_ASSERT(app); | Q_ASSERT(app); | ||||
if (dialog) | if (dialog) | ||||
@@ -462,126 +449,66 @@ public: | |||||
delete app; | delete app; | ||||
app = nullptr; | app = nullptr; | ||||
} | } | ||||
#endif | |||||
} | } | ||||
void show() | void show() | ||||
{ | { | ||||
qDebug("CarlaToolkitPlugin::show()"); | qDebug("CarlaToolkitPlugin::show()"); | ||||
#ifdef __WINE__ | |||||
Q_ASSERT(hwnd); | |||||
if (hwnd) | |||||
{ | |||||
ShowWindow(hwnd, SW_SHOWNORMAL); | |||||
UpdateWindow(hwnd); | |||||
} | |||||
#else | |||||
Q_ASSERT(dialog); | |||||
if (m_client) | |||||
((CarlaPluginClient*)m_client)->showGui(true); | |||||
if (dialog) | if (dialog) | ||||
dialog->show(); | dialog->show(); | ||||
#endif | |||||
} | } | ||||
void hide() | void hide() | ||||
{ | { | ||||
qDebug("CarlaToolkitPlugin::hide()"); | qDebug("CarlaToolkitPlugin::hide()"); | ||||
#ifdef __WINE__ | |||||
Q_ASSERT(hwnd); | |||||
if (hwnd) | |||||
ShowWindow(hwnd, SW_HIDE); | |||||
#else | |||||
Q_ASSERT(dialog); | |||||
if (m_client) | |||||
((CarlaPluginClient*)m_client)->showGui(false); | |||||
if (dialog) | if (dialog) | ||||
dialog->show(); | dialog->show(); | ||||
#endif | |||||
} | } | ||||
void resize(int width, int height) | void resize(int width, int height) | ||||
{ | { | ||||
qDebug("CarlaToolkitPlugin::resize(%i, %i)", width, height); | qDebug("CarlaToolkitPlugin::resize(%i, %i)", width, height); | ||||
#ifdef __WINE__ | |||||
Q_ASSERT(hwnd); | |||||
if (hwnd) | |||||
SetWindowPos(hwnd, 0, 0, 0, width + 6, height + 25, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOZORDER); | |||||
#else | |||||
Q_ASSERT(dialog); | Q_ASSERT(dialog); | ||||
if (dialog) | if (dialog) | ||||
dialog->setFixedSize(width, height); | dialog->setFixedSize(width, height); | ||||
#endif | |||||
} | } | ||||
// --------------------------------------------------------------------- | // --------------------------------------------------------------------- | ||||
void createWindow(const char* const pluginName) | |||||
void createWindow(const char* const pluginName, const bool createLayout) | |||||
{ | { | ||||
#ifdef __WINE__ | |||||
hwnd = CreateWindowA("CLASS_CARLA_BRIDGE", pluginName, WS_OVERLAPPEDWINDOW &~ WS_THICKFRAME &~ WS_MAXIMIZEBOX, | |||||
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, | |||||
HWND_DESKTOP, nullptr, hInstGlobal, nullptr); | |||||
SetWindowLongPtrA(hwnd, GWLP_USERDATA, (LONG_PTR)this); | |||||
SetWindowPos(hwnd, 0, 0, 0, 1100 + 6, 600 + 25, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOZORDER); | |||||
#else | |||||
dialog = new QDialog(nullptr); | dialog = new QDialog(nullptr); | ||||
dialog->resize(10, 10); | dialog->resize(10, 10); | ||||
//window->setLayout(new QVBoxLayout(dialog); | |||||
if (createLayout) | |||||
{ | |||||
QVBoxLayout* const layout = new QVBoxLayout(dialog); | |||||
dialog->setContentsMargins(0, 0, 0, 0); | |||||
dialog->setLayout(layout); | |||||
} | |||||
dialog->setWindowTitle(QString("%1 (GUI)").arg(pluginName)); | dialog->setWindowTitle(QString("%1 (GUI)").arg(pluginName)); | ||||
#endif | |||||
} | } | ||||
CarlaBackend::GuiDataHandle getWindowHandle() const | CarlaBackend::GuiDataHandle getWindowHandle() const | ||||
{ | { | ||||
#ifdef __WINE__ | |||||
return hwnd; | |||||
#else | |||||
return dialog; | return dialog; | ||||
#endif | |||||
} | } | ||||
// --------------------------------------------------------------------- | // --------------------------------------------------------------------- | ||||
private: | private: | ||||
#ifdef __WINE__ | |||||
bool closeNow; | |||||
HWND hwnd; | |||||
void handleWindowCloseMessageA() | |||||
{ | |||||
//m_client->quequeMessage(MESSAGE_QUIT, 0, 0, 0.0); | |||||
//m_client->quequeMessage(MESSAGE_SHOW_GUI, 0, 0, 0.0); | |||||
closeNow = true; | |||||
m_client->sendOscConfigure(CarlaBackend::CARLA_BRIDGE_MSG_HIDE_GUI, ""); | |||||
} | |||||
static LRESULT CALLBACK windowProcA(HWND _hwnd, UINT message, WPARAM wParam, LPARAM lParam) | |||||
{ | |||||
qDebug("windowProcA(%p, %i, %li, %li)", _hwnd, message, wParam, lParam); | |||||
if (message == WM_CLOSE || message == WM_DESTROY) | |||||
{ | |||||
CarlaToolkitPlugin* const toolkit = (CarlaToolkitPlugin*)GetWindowLongPtrA(_hwnd, GWLP_USERDATA); | |||||
Q_ASSERT(toolkit); | |||||
if (toolkit) | |||||
{ | |||||
toolkit->handleWindowCloseMessageA(); | |||||
return TRUE; | |||||
} | |||||
} | |||||
return DefWindowProcA(_hwnd, message, wParam, lParam); | |||||
} | |||||
#else | |||||
BridgeApplication* app; | BridgeApplication* app; | ||||
QDialog* dialog; | QDialog* dialog; | ||||
#endif | |||||
}; | }; | ||||
CarlaToolkit* CarlaToolkit::createNew(const char* const) | CarlaToolkit* CarlaToolkit::createNew(const char* const) | ||||
@@ -593,72 +520,17 @@ CarlaToolkit* CarlaToolkit::createNew(const char* const) | |||||
CARLA_BRIDGE_END_NAMESPACE | CARLA_BRIDGE_END_NAMESPACE | ||||
#ifdef __WINE__ | |||||
int WINAPI WinMain(HINSTANCE hInstX, HINSTANCE, LPSTR, int) | |||||
{ | |||||
hInstGlobal = hInstX; | |||||
#define MAXCMDTOKENS 128 | |||||
int argc; | |||||
LPSTR argv[MAXCMDTOKENS]; | |||||
LPSTR p = GetCommandLine(); | |||||
char command[256]; | |||||
char *args; | |||||
char *d, *e; | |||||
argc = 0; | |||||
args = (char *)malloc(lstrlen(p)+1); | |||||
if (args == (char *)NULL) { | |||||
qCritical("Insufficient memory in WinMain()"); | |||||
return 1; | |||||
} | |||||
// Parse command line handling quotes. | |||||
d = args; | |||||
while (*p) | |||||
{ | |||||
// for each argument | |||||
if (argc >= MAXCMDTOKENS - 1) | |||||
break; | |||||
e = d; | |||||
while ((*p) && (*p != ' ')) { | |||||
if (*p == '\042') { | |||||
// Remove quotes, skipping over embedded spaces. | |||||
// Doesn't handle embedded quotes. | |||||
p++; | |||||
while ((*p) && (*p != '\042')) | |||||
*d++ =*p++; | |||||
} | |||||
else | |||||
*d++ = *p; | |||||
if (*p) | |||||
p++; | |||||
} | |||||
*d++ = '\0'; | |||||
argv[argc++] = e; | |||||
while ((*p) && (*p == ' ')) | |||||
p++; // Skip over trailing spaces | |||||
} | |||||
argv[argc] = 0; | |||||
if (strlen(argv[0]) == 0) | |||||
{ | |||||
GetModuleFileName(hInstGlobal, command, sizeof(command)-1); | |||||
argv[0] = command; | |||||
} | |||||
#else | |||||
int main(int argc, char* argv[]) | int main(int argc, char* argv[]) | ||||
{ | { | ||||
#endif | |||||
if (argc != 6) | if (argc != 6) | ||||
{ | { | ||||
qWarning("usage: %s <osc-url|\"null\"> <type> <filename> <name|\"(none)\"> <label>", argv[0]); | qWarning("usage: %s <osc-url|\"null\"> <type> <filename> <name|\"(none)\"> <label>", argv[0]); | ||||
return 1; | return 1; | ||||
} | } | ||||
qargc = argc; | |||||
qargv = argv; | |||||
const char* const oscUrl = argv[1]; | const char* const oscUrl = argv[1]; | ||||
const char* const stype = argv[2]; | const char* const stype = argv[2]; | ||||
const char* const filename = argv[3]; | const char* const filename = argv[3]; | ||||
@@ -709,9 +581,16 @@ int main(int argc, char* argv[]) | |||||
client.registerOscEngine(&engine); | client.registerOscEngine(&engine); | ||||
// Init engine | // Init engine | ||||
QString engName = QString("%1 (master)").arg(label); | |||||
QString engName = QString("%1 (master)").arg(name ? name : label); | |||||
engName.truncate(engine.maxClientNameSize()); | engName.truncate(engine.maxClientNameSize()); | ||||
engine.init(engName.toUtf8().constData()); | |||||
if (! engine.init(engName.toUtf8().constData())) | |||||
{ | |||||
qWarning("Bridge engine failed to start, error was:\n%s", CarlaBackend::getLastError()); | |||||
engine.close(); | |||||
toolkit.quit(); | |||||
return 2; | |||||
} | |||||
/// Init plugin | /// Init plugin | ||||
short id = engine.addPlugin(itype, filename, name, label); | short id = engine.addPlugin(itype, filename, name, label); | ||||
@@ -722,17 +601,19 @@ int main(int argc, char* argv[]) | |||||
CarlaBackend::CarlaPlugin* const plugin = engine.getPlugin(id); | CarlaBackend::CarlaPlugin* const plugin = engine.getPlugin(id); | ||||
client.setStuff(&engine, plugin); | client.setStuff(&engine, plugin); | ||||
// create window if needed | |||||
bool guiResizable; | |||||
CarlaBackend::GuiType guiType; | |||||
plugin->getGuiInfo(&guiType, &guiResizable); | |||||
if (guiType == CarlaBackend::GUI_INTERNAL_QT4 || guiType == CarlaBackend::GUI_INTERNAL_COCOA || guiType == CarlaBackend::GUI_INTERNAL_HWND || guiType == CarlaBackend::GUI_INTERNAL_X11) | |||||
{ | { | ||||
// create window if needed | |||||
toolkit.createWindow(plugin->name()); | |||||
toolkit.createWindow(plugin->name(), (guiType == CarlaBackend::GUI_INTERNAL_QT4)); | |||||
plugin->setGuiData(toolkit.getWindowHandle()); | plugin->setGuiData(toolkit.getWindowHandle()); | ||||
} | } | ||||
if (! useOsc) | if (! useOsc) | ||||
{ | |||||
plugin->setActive(true, false, false); | plugin->setActive(true, false, false); | ||||
plugin->showGui(true); | |||||
} | |||||
ret = 0; | ret = 0; | ||||
} | } | ||||
@@ -743,7 +624,10 @@ int main(int argc, char* argv[]) | |||||
} | } | ||||
if (ret == 0) | if (ret == 0) | ||||
{ | |||||
initSignalHandler(); | |||||
toolkit.exec(&client, !useOsc); | toolkit.exec(&client, !useOsc); | ||||
} | |||||
engine.removeAllPlugins(); | engine.removeAllPlugins(); | ||||
engine.close(); | engine.close(); | ||||