| @@ -12,6 +12,20 @@ include $(CWD)/Makefile.mk | |||
| BINDIR := $(CWD)/../bin | |||
| RESDIR := $(CWD)/../resources | |||
| ifeq ($(DEBUG),true) | |||
| OBJDIR := $(CWD)/../build/frontend/Debug | |||
| else | |||
| OBJDIR := $(CWD)/../build/frontend/Release | |||
| endif | |||
| # --------------------------------------------------------------------------------------------------------------------- | |||
| BUILD_CXX_FLAGS += -Iutils | |||
| BUILD_CXX_FLAGS += -I../backend | |||
| BUILD_CXX_FLAGS += -I../includes | |||
| BUILD_CXX_FLAGS += -I../utils | |||
| # --------------------------------------------------------------------------------------------------------------------- | |||
| ifeq ($(WINDOWS),true) | |||
| @@ -38,6 +52,15 @@ endif | |||
| TSs = $(patsubst %,translations/carla_%.ts,$(I18N_LANGUAGES)) | |||
| QMs = $(patsubst %,translations/carla_%.qm,$(I18N_LANGUAGES)) | |||
| # --------------------------------------------------------------------------------------------------------------------- | |||
| # C++ files | |||
| CPP_FILES = \ | |||
| carla_frontend.cpp \ | |||
| pluginlist/jackappdialog.cpp | |||
| OBJS = $(CPP_FILES:%=$(OBJDIR)/%.o) | |||
| # --------------------------------------------------------------------------------------------------------------------- | |||
| # Resources | |||
| @@ -119,7 +142,7 @@ UIs += \ | |||
| # --------------------------------------------------------------------------------------------------------------------- | |||
| all: $(QMs) $(RES) $(UIs) | |||
| all: $(BINDIR)/libcarla_frontend$(LIB_EXT) $(QMs) $(RES) $(UIs) | |||
| # --------------------------------------------------------------------------------------------------------------------- | |||
| @@ -149,8 +172,22 @@ $(BINDIR)/resources/zynaddsubfx-ui: ../native-plugins/resources/zynaddsubfx-ui | |||
| # --------------------------------------------------------------------------------------------------------------------- | |||
| $(BINDIR)/libcarla_frontend$(LIB_EXT): $(OBJS) $(LIBS) | |||
| -@mkdir -p $(BINDIR) | |||
| @echo "Linking libcarla_frontend$(LIB_EXT)" | |||
| $(SILENT)$(CXX) $(OBJS) $(BUILD_CXX_FLAGS) $(QT5_LINK_FLAGS) $(SHARED) -o $@ | |||
| $(OBJDIR)/%.cpp.o: %.cpp $(UIs) | |||
| -@mkdir -p $(shell dirname $@) | |||
| @echo "Compiling $<" | |||
| $(SILENT)$(CXX) $< $(BUILD_CXX_FLAGS) -c -o $@ | |||
| -include $(OBJS:%.o=%.d) | |||
| # --------------------------------------------------------------------------------------------------------------------- | |||
| clean: | |||
| rm -rf $(UIs) $(RES) $(QMs) __pycache__ *.pyc | |||
| rm -rf $(BINDIR)/libcarla_frontend$(LIB_EXT) $(UIs) $(RES) $(QMs) __pycache__ *.pyc | |||
| # old files | |||
| rm -f ui_carla_add_jack.py | |||
| rm -f ui_carla_database.py | |||
| @@ -15,25 +15,9 @@ | |||
| * For a full copy of the GNU General Public License see the doc/GPL.txt file. | |||
| */ | |||
| #include "CarlaBackend.h" | |||
| #include "CarlaUtils.hpp" | |||
| namespace CB = CARLA_BACKEND_NAMESPACE; | |||
| // ------------------------------------------------------------------------------------------------------------------- | |||
| // common files | |||
| struct WidgetResult { | |||
| union { | |||
| struct { | |||
| const char* command; | |||
| const char* name; | |||
| const char* labelSetup; | |||
| } jackappdialog; | |||
| }; | |||
| }; | |||
| CARLA_PLUGIN_EXPORT void* carla_frontend_create_widget(void* parent, const char* widgetType); | |||
| CARLA_PLUGIN_EXPORT void* carla_frontend_get_result(void* widget, const char* widgetType); | |||
| #include "utils/qsafesettings.cpp" | |||
| // ------------------------------------------------------------------------------------------------------------------- | |||
| @@ -0,0 +1,72 @@ | |||
| #!/usr/bin/env python3 | |||
| # -*- coding: utf-8 -*- | |||
| # Carla Backend utils | |||
| # Copyright (C) 2011-2022 Filipe Coelho <falktx@falktx.com> | |||
| # | |||
| # This program is free software; you can redistribute it and/or | |||
| # modify it under the terms of the GNU General Public License as | |||
| # published by the Free Software Foundation; either version 2 of | |||
| # the License, or any later version. | |||
| # | |||
| # This program is distributed in the hope that it will be useful, | |||
| # but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
| # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
| # GNU General Public License for more details. | |||
| # | |||
| # For a full copy of the GNU General Public License see the doc/GPL.txt file. | |||
| # ------------------------------------------------------------------------------------------------------------ | |||
| # Imports (Global) | |||
| # ------------------------------------------------------------------------------------------------------------ | |||
| # Imports (ctypes) | |||
| from ctypes import ( | |||
| c_bool, c_char_p, c_double, c_int, c_uint, c_uint32, c_void_p, cast, | |||
| cdll, Structure, | |||
| CFUNCTYPE, POINTER | |||
| ) | |||
| from sip import voidptr | |||
| # ------------------------------------------------------------------------------------------------------------ | |||
| # Imports (Custom) | |||
| from carla_backend import ( | |||
| structToDict | |||
| ) | |||
| # --------------------------------------------------------------------------------------------------------------------- | |||
| # Convert a ctypes struct into a python dict, or None if null | |||
| def structToDictOrNull(struct): | |||
| return structToDict(struct.contents) if struct else None | |||
| # ------------------------------------------------------------------------------------------------------------ | |||
| # Carla Frontend API (C stuff) | |||
| class JackApplicationDialogResults(Structure): | |||
| _fields_ = [ | |||
| ("command", c_char_p), | |||
| ("name", c_char_p), | |||
| ("labelSetup", c_char_p) | |||
| ] | |||
| # ------------------------------------------------------------------------------------------------------------ | |||
| # Carla Frontend object using a DLL | |||
| class CarlaFrontendLib(): | |||
| def __init__(self, filename): | |||
| self.lib = cdll.LoadLibrary(filename) | |||
| self.lib.carla_frontend_createAndExecJackApplicationW.argtypes = (c_void_p, c_char_p) | |||
| self.lib.carla_frontend_createAndExecJackApplicationW.restype = POINTER(JackApplicationDialogResults) | |||
| # -------------------------------------------------------------------------------------------------------- | |||
| def createAndExecJackApplicationW(self, parent, projectFilename): | |||
| # FIXME cast(c_void_p, voidptr(parent)) | |||
| return structToDictOrNull(self.lib.carla_frontend_createAndExecJackApplicationW(None, projectFilename.encode("utf-8"))) | |||
| # ------------------------------------------------------------------------------------------------------------ | |||
| @@ -55,13 +55,14 @@ import ui_carla_host | |||
| from carla_app import * | |||
| from carla_backend import * | |||
| from carla_backend_qt import CarlaHostQtDLL, CarlaHostQtNull | |||
| from carla_frontend import CarlaFrontendLib | |||
| from carla_shared import * | |||
| from carla_settings import * | |||
| from carla_utils import * | |||
| from carla_widgets import * | |||
| from patchcanvas import patchcanvas | |||
| from pluginlist import PluginDatabaseW | |||
| from pluginlist import PluginDatabaseW, JackApplicationW | |||
| from widgets.digitalpeakmeter import DigitalPeakMeter | |||
| from widgets.pixmapkeyboard import PixmapKeyboardHArea | |||
| @@ -1235,16 +1236,16 @@ class HostWindow(QMainWindow): | |||
| return (btype, ptype, filename, label, uniqueId, extraPtr) | |||
| def showAddJackAppDialog(self): | |||
| dialog = JackApplicationW(self.fParentOrSelf, self.fProjectFilename) | |||
| ret = gCarla.felib.createAndExecJackApplicationW(self.fParentOrSelf, self.fProjectFilename) | |||
| if not dialog.exec_(): | |||
| if not ret: | |||
| return | |||
| if not self.host.is_engine_running(): | |||
| QMessageBox.warning(self, self.tr("Warning"), self.tr("Cannot add new plugins while engine is stopped")) | |||
| return | |||
| return dialog.getCommandAndFlags() | |||
| return ret | |||
| @pyqtSlot() | |||
| def slot_favoritePluginAdd(self): | |||
| @@ -1351,16 +1352,16 @@ class HostWindow(QMainWindow): | |||
| if data is None: | |||
| return | |||
| filename, name, label = data | |||
| if not filename: | |||
| if not data['command']: | |||
| CustomMessageBox(self, QMessageBox.Critical, self.tr("Error"), self.tr("Cannot add jack application"), | |||
| self.tr("command is empty"), QMessageBox.Ok, QMessageBox.Ok) | |||
| self.tr("command is empty"), QMessageBox.Ok, QMessageBox.Ok) | |||
| return | |||
| if not self.host.add_plugin(BINARY_NATIVE, PLUGIN_JACK, filename, name, label, 0, None, PLUGIN_OPTIONS_NULL): | |||
| if not self.host.add_plugin(BINARY_NATIVE, PLUGIN_JACK, | |||
| data['command'], data['name'], data['labelSetup'], | |||
| 0, None, PLUGIN_OPTIONS_NULL): | |||
| CustomMessageBox(self, QMessageBox.Critical, self.tr("Error"), self.tr("Failed to load plugin"), | |||
| self.host.get_last_error(), QMessageBox.Ok, QMessageBox.Ok) | |||
| self.host.get_last_error(), QMessageBox.Ok, QMessageBox.Ok) | |||
| # -------------------------------------------------------------------------------------------------------- | |||
| # Plugins (macros) | |||
| @@ -3234,6 +3235,7 @@ def initHost(initName, libPrefix, isControl, isPlugin, failError, HostClass = No | |||
| libname = "libcarla_%s2.%s" % ("control" if isControl else "standalone", DLL_EXTENSION) | |||
| libname = os.path.join(pathBinaries, libname) | |||
| felibname = os.path.join(pathBinaries, "libcarla_frontend.%s" % (DLL_EXTENSION)) | |||
| utilsname = os.path.join(pathBinaries, "libcarla_utils.%s" % (DLL_EXTENSION)) | |||
| # -------------------------------------------------------------------------------------------------------- | |||
| @@ -3275,6 +3277,12 @@ def initHost(initName, libPrefix, isControl, isPlugin, failError, HostClass = No | |||
| if not isControl: | |||
| host.nsmOK = host.nsm_init(os.getpid(), initName) | |||
| # -------------------------------------------------------------------------------------------------------- | |||
| # Init frontend lib | |||
| if not gCarla.nogui: | |||
| gCarla.felib = CarlaFrontendLib(felibname) | |||
| # -------------------------------------------------------------------------------------------------------- | |||
| # Init utils | |||
| @@ -594,6 +594,7 @@ class CarlaObject(): | |||
| self.gui = None # Host Window | |||
| self.nogui = False # Skip UI | |||
| self.term = False # Terminated by OS signal | |||
| self.felib = None # Frontend lib object | |||
| self.utils = None # Utils object | |||
| gCarla = CarlaObject() | |||
| @@ -38,8 +38,10 @@ | |||
| # pragma GCC diagnostic pop | |||
| #endif | |||
| #include "../utils/qsafesettings.hpp" | |||
| #include "../../includes/CarlaLibJackHints.h" | |||
| #include "qsafesettings.hpp" | |||
| #include "CarlaLibJackHints.h" | |||
| #include "CarlaString.hpp" | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| // Jack Application Dialog | |||
| @@ -113,7 +115,7 @@ JackApplicationW::CommandAndFlags JackApplicationW::getCommandAndFlags() const | |||
| } | |||
| SessionManager smgr; | |||
| switch(self.ui.cb_session_mgr->currentIndex()) | |||
| switch (self.ui.cb_session_mgr->currentIndex()) | |||
| { | |||
| case UI_SESSION_LADISH: | |||
| smgr = LIBJACK_SESSION_MANAGER_LADISH; | |||
| @@ -238,6 +240,35 @@ void JackApplicationW::slot_saveSettings() | |||
| settings.setValue("MidiOutMixdown", self.ui.cb_out_midi_mixdown->isChecked()); | |||
| } | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| JackApplicationDialogResults* carla_frontend_createAndExecJackApplicationW(void* const parent, const char* const projectFilename) | |||
| { | |||
| JackApplicationW gui(reinterpret_cast<QWidget*>(parent), projectFilename); | |||
| if (gui.exec()) | |||
| { | |||
| static JackApplicationDialogResults ret = {}; | |||
| static CarlaString retCommand; | |||
| static CarlaString retName; | |||
| static CarlaString retLabelSetup; | |||
| const JackApplicationW::CommandAndFlags cafs = gui.getCommandAndFlags(); | |||
| retCommand = cafs.command.toUtf8().constData(); | |||
| retName = cafs.name.toUtf8().constData(); | |||
| retLabelSetup = cafs.labelSetup.toUtf8().constData(); | |||
| ret.command = retCommand; | |||
| ret.name = retName; | |||
| ret.labelSetup = retLabelSetup; | |||
| return &ret; | |||
| } | |||
| return nullptr; | |||
| } | |||
| #if 0 | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| // Testing | |||
| @@ -246,19 +277,17 @@ void JackApplicationW::slot_saveSettings() | |||
| int main(int argc, char* argv[]) | |||
| { | |||
| QApplication app(argc, argv); | |||
| JackApplicationW gui(nullptr, ""); | |||
| gui.show(); | |||
| if (gui.exec()) | |||
| if (JackApplicationDialogResults* const res = carla_frontend_createAndExecJackApplicationW(nullptr, "")) | |||
| { | |||
| auto cf = gui.getCommandAndFlags(); | |||
| printf("Results:\n"); | |||
| printf("\tCommand: %s\n", cf.command.toUtf8().constData()); | |||
| printf("\tName: %s\n", cf.name.toUtf8().constData()); | |||
| printf("\tLabelSetup: %s\n", cf.labelSetup.toUtf8().constData()); | |||
| printf("\tCommand: %s\n", res->command); | |||
| printf("\tName: %s\n", res->name); | |||
| printf("\tLabelSetup: %s\n", res->labelSetup); | |||
| } | |||
| return 0; | |||
| } | |||
| #endif | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| @@ -35,6 +35,8 @@ | |||
| #include "../utils/qcarlastring.hpp" | |||
| #include "CarlaDefines.h" | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| // Jack Application Dialog | |||
| @@ -43,6 +45,8 @@ class JackApplicationW : public QDialog | |||
| struct Self; | |||
| Self& self; | |||
| // ---------------------------------------------------------------------------------------------------------------- | |||
| public: | |||
| explicit JackApplicationW(QWidget* parent, const char* projectFilename); | |||
| ~JackApplicationW() override; | |||
| @@ -74,3 +78,17 @@ private slots: | |||
| }; | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| extern "C" { | |||
| struct JackApplicationDialogResults { | |||
| const char* command; | |||
| const char* name; | |||
| const char* labelSetup; | |||
| }; | |||
| CARLA_API JackApplicationDialogResults* carla_frontend_createAndExecJackApplicationW(void* parent, const char* projectFilename); | |||
| } | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| @@ -0,0 +1,74 @@ | |||
| /* | |||
| * Carla plugin host | |||
| * Copyright (C) 2011-2022 Filipe Coelho <falktx@falktx.com> | |||
| * | |||
| * This program is free software; you can redistribute it and/or | |||
| * modify it under the terms of the GNU General Public License as | |||
| * published by the Free Software Foundation; either version 2 of | |||
| * the License, or any later version. | |||
| * | |||
| * This program is distributed in the hope that it will be useful, | |||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
| * GNU General Public License for more details. | |||
| * | |||
| * For a full copy of the GNU General Public License see the doc/GPL.txt file. | |||
| */ | |||
| #include "QtWidgets/qboxlayout.h" | |||
| #ifdef __clang__ | |||
| # pragma clang diagnostic push | |||
| # pragma clang diagnostic ignored "-Wdeprecated-copy-with-user-provided-copy" | |||
| # pragma clang diagnostic ignored "-Wdeprecated-register" | |||
| #elif defined(__GNUC__) && __GNUC__ >= 8 | |||
| # pragma GCC diagnostic push | |||
| # pragma GCC diagnostic ignored "-Wclass-memaccess" | |||
| # pragma GCC diagnostic ignored "-Wdeprecated-copy" | |||
| #endif | |||
| #include <QtWidgets/QFrame> | |||
| #include <QtWidgets/QVBoxLayout> | |||
| #ifdef __clang__ | |||
| # pragma clang diagnostic pop | |||
| #elif defined(__GNUC__) && __GNUC__ >= 8 | |||
| # pragma GCC diagnostic pop | |||
| #endif | |||
| #include "CarlaDefines.h" | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| // Jack Application Dialog | |||
| class CollapsibleBox : public QFrame | |||
| { | |||
| struct Self; | |||
| Self& self; | |||
| // ---------------------------------------------------------------------------------------------------------------- | |||
| public: | |||
| explicit CollapsibleBox(QWidget* parent); | |||
| ~CollapsibleBox() override; | |||
| // ---------------------------------------------------------------------------------------------------------------- | |||
| // public methods | |||
| QVBoxLayout* getContentLayout() const noexcept; | |||
| // ---------------------------------------------------------------------------------------------------------------- | |||
| // private slots | |||
| private slots: | |||
| void toolButtonPressed(bool toggled); | |||
| }; | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| extern "C" { | |||
| CARLA_API void* carla_frontend_createCollapsibleBox(void* parent); | |||
| } | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||