| @@ -8,9 +8,6 @@ on: | |||
| branches: | |||
| - '*' | |||
| env: | |||
| BUILD_TYPE: Release | |||
| jobs: | |||
| ubuntu-22-04: | |||
| strategy: | |||
| @@ -87,78 +84,61 @@ jobs: | |||
| suffix: _15 | |||
| target: ${{ matrix.target }} | |||
| cmake_win32: | |||
| msvc-win32: | |||
| runs-on: windows-2022 | |||
| steps: | |||
| - name: Set environment | |||
| - uses: actions/checkout@v4 | |||
| with: | |||
| submodules: recursive | |||
| - name: Configure | |||
| run: | | |||
| echo "release_arch=Win32" >> "${Env:GITHUB_ENV}" | |||
| echo "vcpkg_triplet=x86-windows-static" >> "${Env:GITHUB_ENV}" | |||
| echo "vcpkg_git_commit_id=a3db16a4475b963cacf0260068c497fb72c8f3c0" >> "${Env:GITHUB_ENV}" | |||
| - name: Restore from cache and install vcpkg | |||
| uses: lukka/run-vcpkg@v6 | |||
| cmake -S . -B build -G"Visual Studio 17 2022" -A"Win32" -DCMAKE_BUILD_TYPE="Release" | |||
| - name: Build | |||
| run: cmake --build build --config "Release" -j 2 | |||
| - name: Show built files | |||
| working-directory: build/bin | |||
| run: tree | |||
| - uses: actions/upload-artifact@v4 | |||
| with: | |||
| setupOnly: true | |||
| vcpkgTriplet: ${{env.vcpkg_triplet}} | |||
| vcpkgGitCommitId: ${{env.vcpkg_git_commit_id}} | |||
| #- name: Install packages | |||
| # run: | | |||
| # & "${Env:VCPKG_ROOT}/vcpkg" install "cairo:${Env:vcpkg_triplet}" | |||
| name: msvc-win32 | |||
| path: build/bin/ | |||
| msvc-win64: | |||
| runs-on: windows-2022 | |||
| steps: | |||
| - uses: actions/checkout@v4 | |||
| with: | |||
| submodules: recursive | |||
| - name: Create Build Environment | |||
| working-directory: ${{runner.workspace}} | |||
| run: cmake -E make_directory build | |||
| - name: Configure CMake | |||
| working-directory: ${{runner.workspace}}/build | |||
| run: | | |||
| cmake "${Env:GITHUB_WORKSPACE}" -G"Visual Studio 17 2022" -A"${Env:release_arch}" -DCMAKE_BUILD_TYPE="${Env:BUILD_TYPE}" -DVCPKG_TARGET_TRIPLET="${Env:vcpkg_triplet}" -DCMAKE_TOOLCHAIN_FILE="${Env:VCPKG_INSTALLATION_ROOT}/scripts/buildsystems/vcpkg.cmake" | |||
| cmake -S . -B build -G"Visual Studio 17 2022" -A"x64" -DCMAKE_BUILD_TYPE="Release" | |||
| - name: Build all | |||
| working-directory: ${{runner.workspace}}/build | |||
| run: cmake --build . --config "${Env:BUILD_TYPE}" -j 2 | |||
| working-directory: build | |||
| run: cmake --build . --config "Release" -j 2 | |||
| - name: Show built files | |||
| working-directory: ${{runner.workspace}}/build/bin | |||
| working-directory: build/bin | |||
| run: tree | |||
| - uses: actions/upload-artifact@v4 | |||
| with: | |||
| name: Win32 artifacts | |||
| path: ${{runner.workspace}}/build/bin/ | |||
| name: msvc-win64 | |||
| path: build/bin/ | |||
| cmake_win64: | |||
| runs-on: windows-2022 | |||
| msvc-arm64: | |||
| runs-on: windows-11-arm | |||
| steps: | |||
| - name: Set environment | |||
| run: | | |||
| echo "release_arch=x64" >> "${Env:GITHUB_ENV}" | |||
| echo "vcpkg_triplet=x64-windows-static" >> "${Env:GITHUB_ENV}" | |||
| echo "vcpkg_git_commit_id=a3db16a4475b963cacf0260068c497fb72c8f3c0" >> "${Env:GITHUB_ENV}" | |||
| - name: Restore from cache and install vcpkg | |||
| uses: lukka/run-vcpkg@v6 | |||
| with: | |||
| setupOnly: true | |||
| vcpkgTriplet: ${{env.vcpkg_triplet}} | |||
| vcpkgGitCommitId: ${{env.vcpkg_git_commit_id}} | |||
| #- name: Install packages | |||
| # run: | | |||
| # & "${Env:VCPKG_ROOT}/vcpkg" install "cairo:${Env:vcpkg_triplet}" | |||
| - uses: actions/checkout@v4 | |||
| with: | |||
| submodules: recursive | |||
| - name: Create Build Environment | |||
| working-directory: ${{runner.workspace}} | |||
| run: cmake -E make_directory build | |||
| - name: Configure CMake | |||
| working-directory: ${{runner.workspace}}/build | |||
| run: | | |||
| cmake "${Env:GITHUB_WORKSPACE}" -G"Visual Studio 17 2022" -A"${Env:release_arch}" -DCMAKE_BUILD_TYPE="${Env:BUILD_TYPE}" -DVCPKG_TARGET_TRIPLET="${Env:vcpkg_triplet}" -DCMAKE_TOOLCHAIN_FILE="${Env:VCPKG_INSTALLATION_ROOT}/scripts/buildsystems/vcpkg.cmake" | |||
| cmake -S . -B build -G"Visual Studio 17 2022" -A"ARM64" -DCMAKE_BUILD_TYPE="Release" | |||
| - name: Build all | |||
| working-directory: ${{runner.workspace}}/build | |||
| run: cmake --build . --config "${Env:BUILD_TYPE}" -j 2 | |||
| working-directory: build | |||
| run: cmake --build . --config "Release" -j 2 | |||
| - name: Show built files | |||
| working-directory: ${{runner.workspace}}/build/bin | |||
| working-directory: build/bin | |||
| run: tree | |||
| - uses: actions/upload-artifact@v4 | |||
| with: | |||
| name: Win64 artifacts | |||
| path: ${{runner.workspace}}/build/bin/ | |||
| name: msvc-arm64 | |||
| path: build/bin/ | |||
| @@ -668,13 +668,9 @@ endif | |||
| ifeq ($(USE_GLES2),true) | |||
| BUILD_CXX_FLAGS += -DDGL_USE_OPENGL3 -DDGL_USE_GLES -DDGL_USE_GLES2 | |||
| endif | |||
| ifeq ($(USE_GLES3),true) | |||
| else ifeq ($(USE_GLES3),true) | |||
| BUILD_CXX_FLAGS += -DDGL_USE_OPENGL3 -DDGL_USE_GLES -DDGL_USE_GLES3 | |||
| endif | |||
| ifeq ($(USE_OPENGL3),true) | |||
| else ifeq ($(USE_OPENGL3),true) | |||
| BUILD_CXX_FLAGS += -DDGL_USE_OPENGL3 | |||
| endif | |||
| @@ -205,8 +205,12 @@ UI_TYPE = none | |||
| endif | |||
| ifeq ($(UI_TYPE),) | |||
| ifeq ($(WASM),true) | |||
| UI_TYPE = gles2 | |||
| else | |||
| UI_TYPE = opengl | |||
| endif | |||
| endif | |||
| ifeq ($(UI_TYPE),generic) | |||
| ifeq ($(HAVE_OPENGL),true) | |||
| @@ -315,7 +319,7 @@ HAVE_DGL = false | |||
| endif | |||
| endif | |||
| ifeq ($(HAVE_DGL)$(LINUX)$(UI_TYPE),truetruewebview) | |||
| ifeq ($(HAVE_DGL)$(LINUX)$(USE_WEB_VIEW),truetruetrue) | |||
| DGL_LIB_SHARED = $(shell $(CC) -print-file-name=Scrt1.o) | |||
| endif | |||
| @@ -368,6 +372,18 @@ ifeq ($(WINDOWS)$(HAVE_DGL),truetrue) | |||
| JACK_LIBS += -Wl,-subsystem,windows | |||
| endif | |||
| ifeq ($(WASM),true) | |||
| MAPI_EXT = -mapi.js | |||
| MAPI_SHARED = \ | |||
| -sEXPORT_NAME="$(MAPI_MODULE_NAME)" \ | |||
| -sEXPORTED_RUNTIME_METHODS=['addFunction','lengthBytesUTF8','stringToUTF8','UTF8ToString'] \ | |||
| -sMAIN_MODULE=2 \ | |||
| -sMODULARIZE=1 | |||
| else | |||
| MAPI_EXT = $(LIB_EXT) | |||
| MAPI_SHARED = $(SHARED) | |||
| endif | |||
| ifeq ($(MACOS_APP_BUNDLE),true) | |||
| jack = $(TARGET_DIR)/$(NAME).app/Contents/MacOS/$(NAME) | |||
| jackfiles = $(TARGET_DIR)/$(NAME).app/Contents/Info.plist | |||
| @@ -382,7 +398,7 @@ ladspa_dsp = $(TARGET_DIR)/$(NAME)-ladspa$(LIB_EXT) | |||
| lv2 = $(TARGET_DIR)/$(NAME).lv2/$(NAME)$(LIB_EXT) | |||
| lv2_dsp = $(TARGET_DIR)/$(NAME).lv2/$(NAME)_dsp$(LIB_EXT) | |||
| lv2_ui = $(TARGET_DIR)/$(NAME).lv2/$(NAME)_ui$(LIB_EXT) | |||
| mapi = $(TARGET_DIR)/$(NAME)$(LIB_EXT) | |||
| mapi = $(TARGET_DIR)/$(NAME)$(MAPI_EXT) | |||
| static = $(TARGET_DIR)/$(NAME).a | |||
| vst2 = $(TARGET_DIR)/$(VST2_FILENAME) | |||
| ifneq ($(VST3_FILENAME),) | |||
| @@ -434,7 +450,7 @@ SYMBOLS_LADSPA = -sEXPORTED_FUNCTIONS="['ladspa_descriptor']" | |||
| SYMBOLS_LV2 = -sEXPORTED_FUNCTIONS="['lv2_descriptor','lv2_generate_ttl','lv2ui_descriptor']" | |||
| SYMBOLS_LV2DSP = -sEXPORTED_FUNCTIONS="['lv2_descriptor','lv2_generate_ttl']" | |||
| SYMBOLS_LV2UI = -sEXPORTED_FUNCTIONS="['lv2ui_descriptor']" | |||
| SYMBOLS_MAPI = -sEXPORTED_FUNCTIONS="['mapi_create','mapi_process','mapi_set_parameter','mapi_set_state','mapi_destroy']" | |||
| SYMBOLS_MAPI = -sEXPORTED_FUNCTIONS="['_mapi_create','_mapi_process','_mapi_set_parameter','_mapi_set_state','_mapi_destroy']" | |||
| SYMBOLS_VST2 = -sEXPORTED_FUNCTIONS="['VSTPluginMain']" | |||
| SYMBOLS_VST3 = -sEXPORTED_FUNCTIONS="['GetPluginFactory','ModuleEntry','ModuleExit']" | |||
| else ifeq ($(WINDOWS),true) | |||
| @@ -823,7 +839,7 @@ mapi: $(mapi) | |||
| $(mapi): $(OBJS_DSP) $(BUILD_DIR)/DistrhoPluginMain_MAPI.cpp.o | |||
| -@mkdir -p $(shell dirname $@) | |||
| @echo "Creating MAPI for $(NAME)" | |||
| $(SILENT)$(CXX) $^ $(BUILD_CXX_FLAGS) $(LINK_FLAGS) $(EXTRA_LIBS) $(EXTRA_DSP_LIBS) $(EXTRA_UI_LIBS) $(DGL_LIBS) $(SHARED) $(SYMBOLS_MAPI) -o $@ | |||
| $(SILENT)$(CXX) $^ $(BUILD_CXX_FLAGS) $(LINK_FLAGS) $(EXTRA_LIBS) $(EXTRA_DSP_LIBS) $(EXTRA_UI_LIBS) $(DGL_LIBS) $(MAPI_SHARED) $(SYMBOLS_MAPI) -o $@ | |||
| # --------------------------------------------------------------------------------------------------------------------- | |||
| # Export | |||
| @@ -582,6 +582,10 @@ function(dpf__build_lv2 NAME HAS_UI MONOLITHIC EXTRA_UI_LINK_OPTS) | |||
| OUTPUT_NAME "${NAME}_dsp" | |||
| PREFIX "") | |||
| # helper property for custom outside handling | |||
| set_target_properties("${NAME}" PROPERTIES | |||
| LV2_BUNDLE "${PROJECT_BINARY_DIR}/bin/${NAME}.lv2") | |||
| if(HAS_UI) | |||
| if(MONOLITHIC) | |||
| dpf__add_ui_main("${NAME}-lv2" "lv2" "${HAS_UI}") | |||
| @@ -674,8 +678,15 @@ function(dpf__determine_vst3_package_architecture OUTPUT_VARIABLE) | |||
| endif() | |||
| # transform the processor name to a format that VST3 recognizes | |||
| # see https://steinbergmedia.github.io/vst3_dev_portal/pages/Technical+Documentation/Locations+Format/Plugin+Format.html | |||
| if(vst3_system_arch MATCHES "^(x86_64|amd64|AMD64|x64|X64)$") | |||
| set(vst3_package_arch "x86_64") | |||
| elseif(vst3_system_arch MATCHES "^(ARM)$") | |||
| set(vst3_package_arch "arm") | |||
| elseif(vst3_system_arch MATCHES "^(ARM64)$") | |||
| set(vst3_package_arch "arm64") | |||
| elseif(vst3_system_arch MATCHES "^(ARM64EC)$") | |||
| set(vst3_package_arch "arm64x") | |||
| elseif(vst3_system_arch MATCHES "^(i.86|x86|X86)$") | |||
| if(WIN32) | |||
| set(vst3_package_arch "x86") | |||
| @@ -83,10 +83,21 @@ BUILD_CONFIG_SENTINEL(fail_to_link_is_mismatch_dgl_no_shared_resources_off) | |||
| class DISTRHO_API Application | |||
| { | |||
| public: | |||
| /** | |||
| Type of application to setup, either "classic" or "modern". | |||
| What this means depends on the OS. | |||
| */ | |||
| enum Type { | |||
| kTypeAuto, | |||
| kTypeClassic, | |||
| kTypeModern, | |||
| }; | |||
| /** | |||
| Constructor for standalone or plugin application. | |||
| */ | |||
| Application(bool isStandalone = true); | |||
| Application(bool isStandalone = true, Type type = kTypeAuto); | |||
| /** | |||
| Constructor for a standalone application. | |||
| @@ -141,6 +152,12 @@ public: | |||
| */ | |||
| double getTime() const; | |||
| /** | |||
| Return the application type, either kTypeClassic or kTypeModern. | |||
| This function never return kTypeAuto. | |||
| */ | |||
| Type getType() const noexcept; | |||
| /** | |||
| Add a callback function to be triggered on every idle cycle. | |||
| You can add more than one, and remove them at anytime with removeIdleCallback(). | |||
| @@ -171,8 +171,13 @@ all: $(TARGETS) | |||
| cairo: $(BUILD_DIR)/libdgl-cairo.a | |||
| gles2: $(BUILD_DIR)/libdgl-gles2.a | |||
| gles3: $(BUILD_DIR)/libdgl-gles3.a | |||
| ifeq ($(WASM),true) | |||
| opengl: gles2 | |||
| opengl3: gles3 | |||
| else | |||
| opengl: $(BUILD_DIR)/libdgl-opengl.a | |||
| opengl3: $(BUILD_DIR)/libdgl-opengl3.a | |||
| endif | |||
| stub: $(BUILD_DIR)/libdgl-stub.a | |||
| vulkan: $(BUILD_DIR)/libdgl-vulkan.a | |||
| web: $(BUILD_DIR)/libdgl-web.a | |||
| @@ -249,6 +249,18 @@ public: | |||
| */ | |||
| void drawAt(const GraphicsContext& context, const Point<int>& pos) override; | |||
| #ifdef DGL_USE_GLES | |||
| /** | |||
| Get the image format. | |||
| */ | |||
| ImageFormat getFormat() const noexcept; | |||
| /** | |||
| Get the raw image data. | |||
| */ | |||
| const char* getRawData() const noexcept; | |||
| #endif | |||
| /** | |||
| TODO document this. | |||
| */ | |||
| @@ -312,6 +324,10 @@ private: | |||
| bool setupCalled; | |||
| bool textureInit; | |||
| GLuint textureId; | |||
| #ifdef DGL_USE_GLES | |||
| mutable char* convertedData; | |||
| mutable const char* rawDataLast; | |||
| #endif | |||
| }; | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| @@ -98,8 +98,8 @@ static void app_idle(void* const app) | |||
| } | |||
| #endif | |||
| Application::Application(const bool isStandalone) | |||
| : pData(new PrivateData(isStandalone)) | |||
| Application::Application(const bool isStandalone, const Type type) | |||
| : pData(new PrivateData(isStandalone, type)) | |||
| { | |||
| // build config sentinels | |||
| #ifdef DPF_DEBUG | |||
| @@ -126,7 +126,7 @@ Application::Application(const bool isStandalone) | |||
| } | |||
| Application::Application(int argc, char* argv[]) | |||
| : pData(new PrivateData(true)) | |||
| : pData(new PrivateData(true, kTypeAuto)) | |||
| { | |||
| #if defined(HAVE_X11) && defined(DISTRHO_OS_LINUX) && defined(DGL_USE_WEB_VIEW) | |||
| if (argc >= 2 && std::strcmp(argv[1], "dpf-ld-linux-webview") == 0) | |||
| @@ -213,6 +213,11 @@ double Application::getTime() const | |||
| return pData->getTime(); | |||
| } | |||
| Application::Type Application::getType() const noexcept | |||
| { | |||
| return pData->isModern ? kTypeModern : kTypeClassic; | |||
| } | |||
| void Application::addIdleCallback(IdleCallback* const callback) | |||
| { | |||
| DISTRHO_SAFE_ASSERT_RETURN(callback != nullptr,) | |||
| @@ -1,6 +1,6 @@ | |||
| /* | |||
| * DISTRHO Plugin Framework (DPF) | |||
| * Copyright (C) 2012-2024 Filipe Coelho <falktx@falktx.com> | |||
| * Copyright (C) 2012-2025 Filipe Coelho <falktx@falktx.com> | |||
| * | |||
| * Permission to use, copy, modify, and/or distribute this software for any purpose with | |||
| * or without fee is hereby granted, provided that the above copyright notice and this | |||
| @@ -53,13 +53,14 @@ const char* Application::getClassName() const noexcept | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| Application::PrivateData::PrivateData(const bool standalone) | |||
| Application::PrivateData::PrivateData(const bool standalone, const Type type) | |||
| : world(puglNewWorld(standalone ? PUGL_PROGRAM : PUGL_MODULE, | |||
| standalone ? PUGL_WORLD_THREADS : 0x0)), | |||
| (standalone ? PUGL_WORLD_THREADS : 0))), | |||
| isModern(false), | |||
| isStandalone(standalone), | |||
| isStarting(true), | |||
| isQuitting(false), | |||
| isQuittingInNextCycle(false), | |||
| isStarting(true), | |||
| needsRepaint(false), | |||
| visibleWindows(0), | |||
| mainThreadHandle(getCurrentThreadHandle()), | |||
| @@ -68,16 +69,11 @@ Application::PrivateData::PrivateData(const bool standalone) | |||
| { | |||
| DISTRHO_SAFE_ASSERT_RETURN(world != nullptr,); | |||
| #ifdef DGL_USING_SDL | |||
| SDL_Init(SDL_INIT_EVENTS|SDL_INIT_TIMER|SDL_INIT_VIDEO); | |||
| #else | |||
| puglSetWorldHandle(world, this); | |||
| #ifdef __EMSCRIPTEN__ | |||
| puglSetWorldString(world, PUGL_CLASS_NAME, "canvas"); | |||
| #else | |||
| puglSetWorldString(world, PUGL_CLASS_NAME, DISTRHO_MACRO_AS_STRING(DGL_NAMESPACE)); | |||
| #endif | |||
| #endif | |||
| } | |||
| Application::PrivateData::~PrivateData() | |||
| @@ -88,12 +84,8 @@ Application::PrivateData::~PrivateData() | |||
| windows.clear(); | |||
| idleCallbacks.clear(); | |||
| #ifdef DGL_USING_SDL | |||
| SDL_Quit(); | |||
| #else | |||
| if (world != nullptr) | |||
| puglFreeWorld(world); | |||
| #endif | |||
| } | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| @@ -1,6 +1,6 @@ | |||
| /* | |||
| * DISTRHO Plugin Framework (DPF) | |||
| * Copyright (C) 2012-2021 Filipe Coelho <falktx@falktx.com> | |||
| * Copyright (C) 2012-2025 Filipe Coelho <falktx@falktx.com> | |||
| * | |||
| * Permission to use, copy, modify, and/or distribute this software for any purpose with | |||
| * or without fee is hereby granted, provided that the above copyright notice and this | |||
| @@ -51,18 +51,21 @@ struct Application::PrivateData { | |||
| /** Pugl world instance. */ | |||
| PuglWorld* const world; | |||
| /** Whether the applicating uses modern backend, otherwise classic. */ | |||
| const bool isModern; | |||
| /** Whether the application is running as standalone, otherwise it is part of a plugin. */ | |||
| const bool isStandalone; | |||
| /** Whether the applicating is starting up, that is, no windows have been made visible yet. Defaults to true. */ | |||
| bool isStarting; | |||
| /** Whether the applicating is about to quit, or already stopped. Defaults to false. */ | |||
| bool isQuitting; | |||
| /** Helper for safely close everything from main thread. */ | |||
| bool isQuittingInNextCycle; | |||
| /** Whether the applicating is starting up, that is, no windows have been made visible yet. Defaults to true. */ | |||
| bool isStarting; | |||
| /** When true force all windows to be repainted on next idle. */ | |||
| bool needsRepaint; | |||
| @@ -80,7 +83,7 @@ struct Application::PrivateData { | |||
| std::list<DGL_NAMESPACE::IdleCallback*> idleCallbacks; | |||
| /** Constructor and destructor */ | |||
| explicit PrivateData(bool standalone); | |||
| explicit PrivateData(bool standalone, Type type); | |||
| ~PrivateData(); | |||
| /** Flag one window as shown, which increments @a visibleWindows. | |||
| @@ -37,6 +37,10 @@ OpenGLImage::OpenGLImage() | |||
| setupCalled(false), | |||
| textureInit(false), | |||
| textureId(0) | |||
| #ifdef DGL_USE_GLES | |||
| , convertedData(nullptr) | |||
| , rawDataLast(nullptr) | |||
| #endif | |||
| { | |||
| } | |||
| @@ -45,6 +49,10 @@ OpenGLImage::OpenGLImage(const char* const rdata, const uint w, const uint h, co | |||
| setupCalled(false), | |||
| textureInit(true), | |||
| textureId(0) | |||
| #ifdef DGL_USE_GLES | |||
| , convertedData(nullptr) | |||
| , rawDataLast(nullptr) | |||
| #endif | |||
| { | |||
| glGenTextures(1, &textureId); | |||
| DISTRHO_SAFE_ASSERT(textureId != 0); | |||
| @@ -55,6 +63,10 @@ OpenGLImage::OpenGLImage(const char* const rdata, const Size<uint>& s, const Ima | |||
| setupCalled(false), | |||
| textureInit(true), | |||
| textureId(0) | |||
| #ifdef DGL_USE_GLES | |||
| , convertedData(nullptr) | |||
| , rawDataLast(nullptr) | |||
| #endif | |||
| { | |||
| glGenTextures(1, &textureId); | |||
| DISTRHO_SAFE_ASSERT(textureId != 0); | |||
| @@ -65,6 +77,10 @@ OpenGLImage::OpenGLImage(const OpenGLImage& image) | |||
| setupCalled(false), | |||
| textureInit(true), | |||
| textureId(0) | |||
| #ifdef DGL_USE_GLES | |||
| , convertedData(nullptr) | |||
| , rawDataLast(nullptr) | |||
| #endif | |||
| { | |||
| glGenTextures(1, &textureId); | |||
| DISTRHO_SAFE_ASSERT(textureId != 0); | |||
| @@ -74,6 +90,10 @@ OpenGLImage::~OpenGLImage() | |||
| { | |||
| if (textureId != 0) | |||
| glDeleteTextures(1, &textureId); | |||
| #ifdef DGL_USE_GLES | |||
| std::free(convertedData); | |||
| #endif | |||
| } | |||
| void OpenGLImage::loadFromMemory(const char* const rdata, const Size<uint>& s, const ImageFormat fmt) noexcept | |||
| @@ -111,6 +131,10 @@ OpenGLImage::OpenGLImage(const char* const rdata, const uint w, const uint h, co | |||
| setupCalled(false), | |||
| textureInit(true), | |||
| textureId(0) | |||
| #ifdef DGL_USE_GLES | |||
| , convertedData(nullptr) | |||
| , rawDataLast(nullptr) | |||
| #endif | |||
| { | |||
| glGenTextures(1, &textureId); | |||
| DISTRHO_SAFE_ASSERT(textureId != 0); | |||
| @@ -121,6 +145,10 @@ OpenGLImage::OpenGLImage(const char* const rdata, const Size<uint>& s, const GLe | |||
| setupCalled(false), | |||
| textureInit(true), | |||
| textureId(0) | |||
| #ifdef DGL_USE_GLES | |||
| , convertedData(nullptr) | |||
| , rawDataLast(nullptr) | |||
| #endif | |||
| { | |||
| glGenTextures(1, &textureId); | |||
| DISTRHO_SAFE_ASSERT(textureId != 0); | |||
| @@ -562,6 +562,70 @@ void OpenGLImage::drawAt(const GraphicsContext& context, const Point<int>& pos) | |||
| glBindTexture(GL_TEXTURE_2D, 0); | |||
| } | |||
| #ifdef DGL_USE_GLES | |||
| ImageFormat OpenGLImage::getFormat() const noexcept | |||
| { | |||
| switch (format) | |||
| { | |||
| case kImageFormatBGR: | |||
| return kImageFormatRGB; | |||
| case kImageFormatBGRA: | |||
| return kImageFormatRGBA; | |||
| default: | |||
| return format; | |||
| } | |||
| } | |||
| const char* OpenGLImage::getRawData() const noexcept | |||
| { | |||
| if (rawDataLast != rawData) | |||
| { | |||
| if (format == kImageFormatBGR || format == kImageFormatBGRA) | |||
| { | |||
| const uint w = size.getWidth(); | |||
| const uint h = size.getHeight(); | |||
| std::free(convertedData); | |||
| if (format == kImageFormatBGR) | |||
| { | |||
| convertedData = static_cast<char*>(std::malloc(sizeof(char) * 3 * w * h)); | |||
| for (int i = 0; i < w * h; ++i) | |||
| { | |||
| convertedData[i * 3 + 0] = rawData[i * 3 + 2]; | |||
| convertedData[i * 3 + 1] = rawData[i * 3 + 1]; | |||
| convertedData[i * 3 + 2] = rawData[i * 3 + 0]; | |||
| } | |||
| } | |||
| else | |||
| { | |||
| convertedData = static_cast<char*>(std::malloc(sizeof(char) * 4 * w * h)); | |||
| for (int i = 0; i < w * h; ++i) | |||
| { | |||
| convertedData[i * 4 + 0] = rawData[i * 4 + 2]; | |||
| convertedData[i * 4 + 1] = rawData[i * 4 + 1]; | |||
| convertedData[i * 4 + 2] = rawData[i * 4 + 0]; | |||
| convertedData[i * 4 + 3] = rawData[i * 4 + 3]; | |||
| } | |||
| } | |||
| } | |||
| else | |||
| { | |||
| std::free(convertedData); | |||
| convertedData = nullptr; | |||
| } | |||
| rawDataLast = rawData; | |||
| } | |||
| return | |||
| #ifdef DGL_USE_GLES | |||
| convertedData != nullptr ? convertedData : | |||
| #endif | |||
| rawData; | |||
| } | |||
| #endif | |||
| #ifdef DGL_ALLOW_DEPRECATED_METHODS | |||
| void OpenGLImage::draw() | |||
| { | |||
| @@ -634,6 +698,9 @@ void ImageBaseKnob<OpenGLImage>::onDisplay() | |||
| DISTRHO_SAFE_ASSERT_RETURN(imageFormat != kImageFormatBGR && imageFormat != kImageFormatBGRA,); | |||
| #endif | |||
| glEnable(GL_BLEND); | |||
| glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | |||
| const GLfloat color[4] = { 1.0f, 1.0f, 1.0f, 1.0f }; | |||
| glUniform4fv(gl3context.color, 1, color); | |||
| @@ -748,6 +815,8 @@ void ImageBaseKnob<OpenGLImage>::onDisplay() | |||
| glUniform1i(gl3context.usingTexture, 0); | |||
| glBindBuffer(GL_ARRAY_BUFFER, 0); | |||
| glBindTexture(GL_TEXTURE_2D, 0); | |||
| glDisable(GL_BLEND); | |||
| } | |||
| template class ImageBaseKnob<OpenGLImage>; | |||
| @@ -834,10 +834,10 @@ static int glnvg__renderCreateTexture(void* uptr, int type, int w, int h, int im | |||
| tex->data = (uint8_t*)malloc(sizeof(uint8_t) * 4 * w * h); | |||
| for (int i = 0; i < w * h; ++i) | |||
| { | |||
| tex->data[i*3+0] = data[i*3+3]; | |||
| tex->data[i*3+1] = data[i*3+2]; | |||
| tex->data[i*3+2] = data[i*3+1]; | |||
| tex->data[i*3+3] = data[i*3+0]; | |||
| tex->data[i*4+0] = data[i*4+2]; | |||
| tex->data[i*4+1] = data[i*4+1]; | |||
| tex->data[i*4+2] = data[i*4+0]; | |||
| tex->data[i*4+3] = data[i*4+3]; | |||
| } | |||
| data = tex->data; | |||
| glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); | |||
| @@ -1,10 +1,11 @@ | |||
| // Copyright 2012-2022 David Robillard <d@drobilla.net> | |||
| // Copyright 2021-2022 Filipe Coelho <falktx@falktx.com> | |||
| // Copyright 2021-2025 Filipe Coelho <falktx@falktx.com> | |||
| // SPDX-License-Identifier: ISC | |||
| #include "wasm.h" | |||
| #include "../pugl-upstream/src/internal.h" | |||
| #include "../pugl-upstream/src/platform.h" | |||
| #include <stdio.h> | |||
| @@ -82,8 +83,15 @@ puglInitViewInternals(PuglWorld* const world) | |||
| return impl; | |||
| } | |||
| static PuglStatus | |||
| updateSizeHints(const PuglView* const view) | |||
| PuglStatus | |||
| puglApplySizeHint(PuglView* const view, const PuglSizeHint PUGL_UNUSED(hint)) | |||
| { | |||
| // No fine-grained updates, hints are always recalculated together | |||
| return puglUpdateSizeHints(view); | |||
| } | |||
| PuglStatus | |||
| puglUpdateSizeHints(PuglView* const view) | |||
| { | |||
| const char* const className = view->world->strings[PUGL_CLASS_NAME]; | |||
| @@ -102,22 +110,6 @@ updateSizeHints(const PuglView* const view) | |||
| canvasWrapper.style.setProperty("max-height", height + 'px'); | |||
| }, className, size.width, size.height); | |||
| } else { | |||
| // Avoid setting PBaseSize for top level views to avoid window manager bugs | |||
| const PuglArea defaultSize = view->sizeHints[PUGL_DEFAULT_SIZE]; | |||
| if (puglIsValidArea(defaultSize) && view->parent) { | |||
| EM_ASM({ | |||
| var canvasWrapper = document.getElementById(UTF8ToString($0)).parentElement; | |||
| canvasWrapper.style.setProperty("width", parseInt($1 / window.devicePixelRatio) + 'px'); | |||
| canvasWrapper.style.setProperty("height", parseInt($2 / window.devicePixelRatio) + 'px'); | |||
| }, className, defaultSize.width, defaultSize.height); | |||
| } else { | |||
| EM_ASM({ | |||
| var canvasWrapper = document.getElementById(UTF8ToString($0)).parentElement; | |||
| canvasWrapper.style.removeProperty("width"); | |||
| canvasWrapper.style.removeProperty("height"); | |||
| }, className); | |||
| } | |||
| const PuglArea minSize = view->sizeHints[PUGL_MIN_SIZE]; | |||
| if (puglIsValidArea(minSize)) { | |||
| EM_ASM({ | |||
| @@ -837,7 +829,7 @@ puglRealize(PuglView* const view) | |||
| canvasWrapper.style.setProperty("--device-pixel-ratio", window.devicePixelRatio); | |||
| }, className); | |||
| updateSizeHints(view); | |||
| puglUpdateSizeHints(view); | |||
| emscripten_set_canvas_element_size(className, defaultSize.width, defaultSize.height); | |||
| #ifndef PUGL_WASM_NO_KEYBOARD_INPUT | |||
| @@ -1005,18 +997,9 @@ puglViewStringChanged(PuglView*, const PuglStringHint key, const char* const val | |||
| } | |||
| PuglStatus | |||
| puglSetSizeHint(PuglView* const view, | |||
| const PuglSizeHint hint, | |||
| const unsigned width, | |||
| const unsigned height) | |||
| puglSetWindowSize(PuglView* const view, const unsigned width, const unsigned height) | |||
| { | |||
| const PuglStatus st = puglStoreSizeHint(view, hint, width, height); | |||
| if (st != PUGL_SUCCESS) | |||
| return st; | |||
| updateSizeHints(view); | |||
| if (hint == PUGL_CURRENT_SIZE && view->impl->created) { | |||
| if (view->impl->created) { | |||
| const char* const className = view->world->strings[PUGL_CLASS_NAME]; | |||
| emscripten_set_canvas_element_size(className, width, height); | |||
| } | |||
| @@ -1248,25 +1231,3 @@ puglSetTransientParent(PuglView* const view, const PuglNativeView parent) | |||
| view->transientParent = parent; | |||
| return PUGL_FAILURE; | |||
| } | |||
| PuglStatus | |||
| puglSetPositionHint(PuglView* const view, | |||
| const PuglPositionHint hint, | |||
| const int x, | |||
| const int y) | |||
| { | |||
| if (x <= INT16_MIN || x > INT16_MAX || y <= INT16_MIN || y > INT16_MAX) { | |||
| return PUGL_BAD_PARAMETER; | |||
| } | |||
| view->positionHints[hint].x = (PuglCoord)x; | |||
| view->positionHints[hint].y = (PuglCoord)y; | |||
| if (!view->impl->created || hint != PUGL_CURRENT_POSITION) { | |||
| return PUGL_SUCCESS; | |||
| } | |||
| view->lastConfigure.x = x; | |||
| view->lastConfigure.y = y; | |||
| return puglObscureView(view); | |||
| } | |||
| @@ -1 +1 @@ | |||
| Subproject commit 86185d8d7b2c1ef0d72179af8e7a1930ecb16e4f | |||
| Subproject commit 5e2621d714ddf1cb0f86e852f8ba5dffe04aa3a3 | |||
| @@ -313,10 +313,7 @@ PuglStatus puglSetGeometryConstraints(PuglView* const view, const uint width, co | |||
| #elif defined(DISTRHO_OS_MAC) | |||
| if (view->impl->window) | |||
| { | |||
| if (const PuglStatus status = updateSizeHint(view, PUGL_MIN_SIZE)) | |||
| return status; | |||
| if (const PuglStatus status = updateSizeHint(view, PUGL_FIXED_ASPECT)) | |||
| if (const PuglStatus status = puglUpdateSizeHints(view)) | |||
| return status; | |||
| } | |||
| #elif defined(DISTRHO_OS_WASM) | |||
| @@ -331,7 +328,7 @@ PuglStatus puglSetGeometryConstraints(PuglView* const view, const uint width, co | |||
| #elif defined(HAVE_X11) | |||
| if (view->impl->win) | |||
| { | |||
| if (const PuglStatus status = updateSizeHints(view)) | |||
| if (const PuglStatus status = puglUpdateSizeHints(view)) | |||
| return status; | |||
| XFlush(view->world->impl->display); | |||
| @@ -358,7 +355,7 @@ void puglSetResizable(PuglView* const view, const bool resizable) | |||
| } | |||
| // FIXME use [view setAutoresizingMask:NSViewNotSizable] ? | |||
| #elif defined(DISTRHO_OS_WASM) | |||
| updateSizeHints(view); | |||
| puglUpdateSizeHints(view); | |||
| #elif defined(DISTRHO_OS_WINDOWS) | |||
| if (const HWND hwnd = view->impl->hwnd) | |||
| { | |||
| @@ -367,7 +364,7 @@ void puglSetResizable(PuglView* const view, const bool resizable) | |||
| SetWindowLong(hwnd, GWL_STYLE, winFlags); | |||
| } | |||
| #elif defined(HAVE_X11) | |||
| updateSizeHints(view); | |||
| puglUpdateSizeHints(view); | |||
| #endif | |||
| } | |||
| @@ -391,7 +388,7 @@ PuglStatus puglSetSizeAndDefault(PuglView* const view, const uint width, const u | |||
| return status; | |||
| } | |||
| #elif defined(DISTRHO_OS_WASM) | |||
| if (const PuglStatus status = updateSizeHints(view)) | |||
| if (const PuglStatus status = puglUpdateSizeHints(view)) | |||
| return status; | |||
| emscripten_set_canvas_element_size(view->world->strings[PUGL_CLASS_NAME], width, height); | |||
| @@ -411,7 +408,7 @@ PuglStatus puglSetSizeAndDefault(PuglView* const view, const uint width, const u | |||
| // matches upstream pugl, adds flush at the end | |||
| if (view->impl->win) | |||
| { | |||
| if (const PuglStatus status = updateSizeHints(view)) | |||
| if (const PuglStatus status = puglUpdateSizeHints(view)) | |||
| return status; | |||
| if (const PuglStatus status = puglSetWindowSize(view, width, height)) | |||
| @@ -608,8 +605,8 @@ void puglWin32ShowCentered(PuglView* const view) | |||
| PuglStatus puglX11UpdateWithoutExposures(PuglWorld* const world) | |||
| { | |||
| const bool wasDispatchingEvents = world->impl->dispatchingEvents; | |||
| world->impl->dispatchingEvents = true; | |||
| const PuglWorldState startState = world->state; | |||
| world->state = PUGL_WORLD_UPDATING; | |||
| PuglStatus st = PUGL_SUCCESS; | |||
| const double startTime = puglGetTime(world); | |||
| @@ -617,11 +614,11 @@ PuglStatus puglX11UpdateWithoutExposures(PuglWorld* const world) | |||
| for (double t = startTime; !st && t < endTime; t = puglGetTime(world)) | |||
| { | |||
| pollX11Socket(world, endTime - t); | |||
| st = dispatchX11Events(world); | |||
| if (!(st = pollX11Socket(world, endTime - t))) | |||
| st = dispatchX11Events(world); | |||
| } | |||
| world->impl->dispatchingEvents = wasDispatchingEvents; | |||
| world->state = startState; | |||
| return st; | |||
| } | |||
| @@ -869,6 +869,24 @@ START_NAMESPACE_DISTRHO | |||
| */ | |||
| #define DISTRHO_PLUGIN_CLAP_ID "studio.kx.distrho.effect" | |||
| /** | |||
| Plugin name abbreviation consisting of 2 or 3 characters in uppercase. | |||
| @note This macro is required when building plugins for the Darkglass Anagram unit. | |||
| */ | |||
| #define DISTRHO_PLUGIN_ABBREVIATION "DFX" | |||
| /** | |||
| Path to a in-bundle/local 200x200 PNG image file to be used as the plugin's block image asset when OFF. | |||
| @note This macro is required when building plugins for the Darkglass Anagram unit. | |||
| */ | |||
| #define DISTRHO_PLUGIN_ANAGRAM_BLOCK_IMAGE_OFF "anagram-block-off.png" | |||
| /** | |||
| Path to a in-bundle/local 200x200 PNG image file to be used as the plugin's block image asset when ON. | |||
| @note This macro is required when building plugins for the Darkglass Anagram unit. | |||
| */ | |||
| #define DISTRHO_PLUGIN_ANAGRAM_BLOCK_IMAGE_ON "anagram-block-on.png" | |||
| /** @} */ | |||
| /* ------------------------------------------------------------------------------------------------------------ | |||
| @@ -77,6 +77,11 @@ int main(int argc, char* argv[]) | |||
| { | |||
| return DISTRHO_NAMESPACE::dpf_webview_start(argc, argv); | |||
| } | |||
| #elif defined(DISTRHO_OS_LINUX) && defined(DGL_USE_WEB_VIEW) && !DISTRHO_IS_STANDALONE | |||
| int main() | |||
| { | |||
| return 0; | |||
| } | |||
| #endif | |||
| #endif | |||
| @@ -1,6 +1,6 @@ | |||
| /* | |||
| * DISTRHO Plugin Framework (DPF) | |||
| * Copyright (C) 2012-2024 Filipe Coelho <falktx@falktx.com> | |||
| * Copyright (C) 2012-2025 Filipe Coelho <falktx@falktx.com> | |||
| * | |||
| * Permission to use, copy, modify, and/or distribute this software for any purpose with | |||
| * or without fee is hereby granted, provided that the above copyright notice and this | |||
| @@ -286,7 +286,7 @@ public: | |||
| #else | |||
| UIExporter tmpUI(nullptr, 0, fPlugin.getSampleRate(), | |||
| nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, d_nextBundlePath, | |||
| fPlugin.getInstancePointer(), scaleFactor); | |||
| fPlugin.getInstancePointer(), scaleFactor, DGL_NAMESPACE::Application::kTypeClassic); | |||
| *width = tmpUI.getWidth(); | |||
| *height = tmpUI.getHeight(); | |||
| scaleFactor = tmpUI.getScaleFactor(); | |||
| @@ -314,7 +314,7 @@ public: | |||
| bool getResizeHints(clap_gui_resize_hints_t* const hints) const | |||
| { | |||
| if (canResize()) | |||
| if (fUI != nullptr && fUI->isResizable()) | |||
| { | |||
| uint minimumWidth, minimumHeight; | |||
| bool keepAspectRatio; | |||
| @@ -346,7 +346,7 @@ public: | |||
| bool adjustSize(uint32_t* const width, uint32_t* const height) const | |||
| { | |||
| if (canResize()) | |||
| if (fUI != nullptr && fUI->isResizable()) | |||
| { | |||
| uint minimumWidth, minimumHeight; | |||
| bool keepAspectRatio; | |||
| @@ -584,7 +584,8 @@ private: | |||
| nullptr, // TODO fileRequestCallback, | |||
| d_nextBundlePath, | |||
| fPlugin.getInstancePointer(), | |||
| fScaleFactor); | |||
| fScaleFactor, | |||
| DGL_NAMESPACE::Application::kTypeClassic); | |||
| #if DISTRHO_PLUGIN_WANT_PROGRAMS | |||
| fUI->programLoaded(fCurrentProgram); | |||
| @@ -367,6 +367,7 @@ void lv2_generate_ttl(const char* const basename) | |||
| #if DISTRHO_LV2_USE_EVENTS_IN || DISTRHO_LV2_USE_EVENTS_OUT | |||
| pluginString += "@prefix atom: <" LV2_ATOM_PREFIX "> .\n"; | |||
| #endif | |||
| pluginString += "@prefix dg: <http://www.darkglass.com/lv2/ns#> .\n"; | |||
| pluginString += "@prefix doap: <http://usefulinc.com/ns/doap#> .\n"; | |||
| pluginString += "@prefix foaf: <http://xmlns.com/foaf/0.1/> .\n"; | |||
| pluginString += "@prefix lv2: <" LV2_CORE_PREFIX "> .\n"; | |||
| @@ -997,6 +998,22 @@ void lv2_generate_ttl(const char* const basename) | |||
| } | |||
| } | |||
| // Darkglass Anagram | |||
| #ifdef DISTRHO_PLUGIN_ABBREVIATION | |||
| pluginString += " dg:abbreviation \"" DISTRHO_PLUGIN_ABBREVIATION "\" ;\n"; | |||
| #endif | |||
| #ifdef DISTRHO_PLUGIN_ANAGRAM_BLOCK_IMAGE_OFF | |||
| pluginString += " dg:blockImageOff <" DISTRHO_PLUGIN_ANAGRAM_BLOCK_IMAGE_OFF "> ;\n"; | |||
| #endif | |||
| #ifdef DISTRHO_PLUGIN_ANAGRAM_BLOCK_IMAGE_ON | |||
| pluginString += " dg:blockImageOn <" DISTRHO_PLUGIN_ANAGRAM_BLOCK_IMAGE_ON "> ;\n"; | |||
| #endif | |||
| #if defined(DISTRHO_PLUGIN_ABBREVIATION) || \ | |||
| defined(DISTRHO_PLUGIN_ANAGRAM_BLOCK_IMAGE_OFF) || \ | |||
| defined(DISTRHO_PLUGIN_ANAGRAM_BLOCK_IMAGE_ON) | |||
| pluginString += "\n"; | |||
| #endif | |||
| #ifdef DISTRHO_PLUGIN_BRAND | |||
| // MOD | |||
| pluginString += " mod:brand \"" DISTRHO_PLUGIN_BRAND "\" ;\n"; | |||
| @@ -66,15 +66,19 @@ public: | |||
| void setParameter(unsigned int index, float value) | |||
| { | |||
| fPlugin.setParameterValue(index, fPlugin.getParameterRanges(index).getUnnormalizedValue(value)); | |||
| fPlugin.setParameterValue(index, fPlugin.getParameterRanges(index).getFixedValue(value)); | |||
| } | |||
| #if DISTRHO_PLUGIN_WANT_STATE | |||
| void setState(const char* key, const char* value) | |||
| { | |||
| #if DISTRHO_PLUGIN_WANT_STATE | |||
| fPlugin.setState(key, value); | |||
| #else | |||
| // unused | |||
| (void)key; | |||
| (void)value; | |||
| #endif | |||
| } | |||
| #endif | |||
| // ---------------------------------------------------------------------------------------------------------------- | |||
| @@ -137,13 +141,11 @@ void mapi_set_parameter(mapi_handle_t handle, unsigned int index, float value) | |||
| static_cast<PluginMAPI*>(handle)->setParameter(index, value); | |||
| } | |||
| #if DISTRHO_PLUGIN_WANT_STATE | |||
| MAPI_EXPORT | |||
| void mapi_set_state(mapi_handle_t handle, const char* key, const char* value) | |||
| { | |||
| static_cast<PluginMAPI*>(handle)->setState(key, value); | |||
| } | |||
| #endif | |||
| MAPI_EXPORT | |||
| void mapi_destroy(mapi_handle_t handle) | |||
| @@ -175,7 +175,8 @@ public: | |||
| nullptr, // TODO file request | |||
| d_nextBundlePath, | |||
| plugin->getInstancePointer(), | |||
| scaleFactor), | |||
| scaleFactor, | |||
| DGL_NAMESPACE::Application::kTypeClassic), | |||
| fKeyboardModifiers(0) | |||
| #if DISTRHO_PLUGIN_WANT_MIDI_INPUT | |||
| , fNotesRingBuffer() | |||
| @@ -600,7 +601,7 @@ public: | |||
| #else | |||
| UIExporter tmpUI(nullptr, 0, fPlugin.getSampleRate(), | |||
| nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, d_nextBundlePath, | |||
| fPlugin.getInstancePointer(), scaleFactor); | |||
| fPlugin.getInstancePointer(), scaleFactor, DGL_NAMESPACE::Application::kTypeClassic); | |||
| fVstRect.right = tmpUI.getWidth(); | |||
| fVstRect.bottom = tmpUI.getHeight(); | |||
| scaleFactor = tmpUI.getScaleFactor(); | |||
| @@ -1709,7 +1710,7 @@ const vst_effect* VSTPluginMain(const vst_host_callback audioMaster) | |||
| return effect; | |||
| } | |||
| #if !(defined(DISTRHO_OS_MAC) || defined(DISTRHO_OS_WASM) || defined(DISTRHO_OS_WINDOWS) || DISTRHO_UI_WEB_VIEW) | |||
| #if !(defined(DISTRHO_OS_MAC) || defined(DISTRHO_OS_WASM) || defined(DISTRHO_OS_WINDOWS) || (defined(DISTRHO_OS_LINUX) && defined(DGL_USE_WEB_VIEW))) | |||
| DISTRHO_PLUGIN_EXPORT | |||
| const vst_effect* VSTPluginMainCompat(vst_host_callback) asm ("main"); | |||
| @@ -1,6 +1,6 @@ | |||
| /* | |||
| * DISTRHO Plugin Framework (DPF) | |||
| * Copyright (C) 2012-2024 Filipe Coelho <falktx@falktx.com> | |||
| * Copyright (C) 2012-2025 Filipe Coelho <falktx@falktx.com> | |||
| * | |||
| * Permission to use, copy, modify, and/or distribute this software for any purpose with | |||
| * or without fee is hereby granted, provided that the above copyright notice and this | |||
| @@ -21,18 +21,18 @@ | |||
| START_NAMESPACE_DISTRHO | |||
| // ----------------------------------------------------------------------- | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| // UI exporter class | |||
| class UIExporter | |||
| { | |||
| // ------------------------------------------------------------------- | |||
| // ---------------------------------------------------------------------------------------------------------------- | |||
| // UI Widget and its private data | |||
| UI* ui; | |||
| UI::PrivateData* uiData; | |||
| // ------------------------------------------------------------------- | |||
| // ---------------------------------------------------------------------------------------------------------------- | |||
| public: | |||
| UIExporter(void* const callbacksPtr, | |||
| @@ -47,11 +47,12 @@ public: | |||
| const char* const bundlePath = nullptr, | |||
| void* const dspPtr = nullptr, | |||
| const double scaleFactor = 0.0, | |||
| const DGL_NAMESPACE::Application::Type appType = DGL_NAMESPACE::Application::kTypeAuto, | |||
| const uint32_t bgColor = 0, | |||
| const uint32_t fgColor = 0xffffffff, | |||
| const char* const appClassName = nullptr) | |||
| : ui(nullptr), | |||
| uiData(new UI::PrivateData(appClassName)) | |||
| uiData(new UI::PrivateData(appClassName, appType)) | |||
| { | |||
| uiData->sampleRate = sampleRate; | |||
| uiData->bundlePath = bundlePath != nullptr ? strdup(bundlePath) : nullptr; | |||
| @@ -1,6 +1,6 @@ | |||
| /* | |||
| * DISTRHO Plugin Framework (DPF) | |||
| * Copyright (C) 2012-2021 Filipe Coelho <falktx@falktx.com> | |||
| * Copyright (C) 2012-2025 Filipe Coelho <falktx@falktx.com> | |||
| * | |||
| * Permission to use, copy, modify, and/or distribute this software for any purpose with | |||
| * or without fee is hereby granted, provided that the above copyright notice and this | |||
| @@ -52,7 +52,7 @@ static constexpr const sendNoteFunc sendNoteCallback = nullptr; | |||
| // unwanted in LV2, resize extension is deprecated and hosts can do it without extensions | |||
| static constexpr const setSizeFunc setSizeCallback = nullptr; | |||
| // ----------------------------------------------------------------------- | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| template <class LV2F> | |||
| static const LV2F* getLv2Feature(const LV2_Feature* const* features, const char* const uri) | |||
| @@ -80,6 +80,7 @@ public: | |||
| void* const dspPtr, | |||
| const float sampleRate, | |||
| const float scaleFactor, | |||
| const DGL_NAMESPACE::Application::Type appType, | |||
| const uint32_t bgColor, | |||
| const uint32_t fgColor, | |||
| const char* const appClassName) | |||
| @@ -101,7 +102,7 @@ public: | |||
| sendNoteCallback, | |||
| setSizeCallback, | |||
| fileRequestCallback, | |||
| bundlePath, dspPtr, scaleFactor, bgColor, fgColor, appClassName) | |||
| bundlePath, dspPtr, scaleFactor, appType, bgColor, fgColor, appClassName) | |||
| { | |||
| if (widget != nullptr) | |||
| *widget = (LV2UI_Widget)fUI.getNativeWindowHandle(); | |||
| @@ -483,7 +484,7 @@ private: | |||
| } | |||
| }; | |||
| // ----------------------------------------------------------------------- | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| static LV2UI_Handle lv2ui_instantiate(const LV2UI_Descriptor*, | |||
| const char* const uri, | |||
| @@ -499,6 +500,9 @@ static LV2UI_Handle lv2ui_instantiate(const LV2UI_Descriptor*, | |||
| return nullptr; | |||
| } | |||
| // TODO allow classic vs modern ui type | |||
| static constexpr const DGL_NAMESPACE::Application::Type appType = DGL_NAMESPACE::Application::kTypeClassic; | |||
| const LV2_Options_Option* options = nullptr; | |||
| const LV2_URID_Map* uridMap = nullptr; | |||
| void* parentId = nullptr; | |||
| @@ -633,7 +637,7 @@ static LV2UI_Handle lv2ui_instantiate(const LV2UI_Descriptor*, | |||
| return new UiLv2(bundlePath, winId, options, uridMap, features, | |||
| controller, writeFunction, widget, instance, | |||
| sampleRate, scaleFactor, bgColor, fgColor, appClassName); | |||
| sampleRate, scaleFactor, appType, bgColor, fgColor, appClassName); | |||
| } | |||
| #define uiPtr ((UiLv2*)ui) | |||
| @@ -648,7 +652,7 @@ static void lv2ui_port_event(LV2UI_Handle ui, uint32_t portIndex, uint32_t buffe | |||
| uiPtr->lv2ui_port_event(portIndex, bufferSize, format, buffer); | |||
| } | |||
| // ----------------------------------------------------------------------- | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| static int lv2ui_idle(LV2UI_Handle ui) | |||
| { | |||
| @@ -665,7 +669,7 @@ static int lv2ui_hide(LV2UI_Handle ui) | |||
| return uiPtr->lv2ui_hide(); | |||
| } | |||
| // ----------------------------------------------------------------------- | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| static uint32_t lv2_get_options(LV2UI_Handle ui, LV2_Options_Option* options) | |||
| { | |||
| @@ -677,7 +681,7 @@ static uint32_t lv2_set_options(LV2UI_Handle ui, const LV2_Options_Option* optio | |||
| return uiPtr->lv2_set_options(options); | |||
| } | |||
| // ----------------------------------------------------------------------- | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| #if DISTRHO_PLUGIN_WANT_PROGRAMS | |||
| static void lv2ui_select_program(LV2UI_Handle ui, uint32_t bank, uint32_t program) | |||
| @@ -686,7 +690,7 @@ static void lv2ui_select_program(LV2UI_Handle ui, uint32_t bank, uint32_t progra | |||
| } | |||
| #endif | |||
| // ----------------------------------------------------------------------- | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| static const void* lv2ui_extension_data(const char* uri) | |||
| { | |||
| @@ -713,7 +717,7 @@ static const void* lv2ui_extension_data(const char* uri) | |||
| #undef instancePtr | |||
| // ----------------------------------------------------------------------- | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| static const LV2UI_Descriptor sLv2UiDescriptor = { | |||
| DISTRHO_UI_URI, | |||
| @@ -723,7 +727,7 @@ static const LV2UI_Descriptor sLv2UiDescriptor = { | |||
| lv2ui_extension_data | |||
| }; | |||
| // ----------------------------------------------------------------------- | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| END_NAMESPACE_DISTRHO | |||
| @@ -929,4 +933,4 @@ void modgui_cleanup(const LV2UI_Handle handle) | |||
| } | |||
| #endif | |||
| // ----------------------------------------------------------------------- | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| @@ -67,14 +67,14 @@ START_NAMESPACE_DISTRHO | |||
| int dpf_webview_start(int argc, char* argv[]); | |||
| #endif | |||
| // ----------------------------------------------------------------------- | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| // Plugin Application, will set class name based on plugin details | |||
| class PluginApplication : public DGL_NAMESPACE::Application | |||
| { | |||
| public: | |||
| explicit PluginApplication(const char* className) | |||
| : DGL_NAMESPACE::Application(DISTRHO_UI_IS_STANDALONE) | |||
| explicit PluginApplication(const char* className, const Application::Type type) | |||
| : DGL_NAMESPACE::Application(DISTRHO_UI_IS_STANDALONE, type) | |||
| { | |||
| #if defined(__MOD_DEVICES__) || !defined(__EMSCRIPTEN__) | |||
| if (className == nullptr) | |||
| @@ -108,7 +108,7 @@ public: | |||
| DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(PluginApplication) | |||
| }; | |||
| // ----------------------------------------------------------------------- | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| // Plugin Window, will pass some Window events to UI | |||
| class PluginWindow : public DGL_NAMESPACE::Window | |||
| @@ -243,7 +243,7 @@ protected: | |||
| DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(PluginWindow) | |||
| }; | |||
| // ----------------------------------------------------------------------- | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| // UI callbacks | |||
| typedef void (*editParamFunc) (void* ptr, uint32_t rindex, bool started); | |||
| @@ -253,7 +253,7 @@ typedef void (*sendNoteFunc) (void* ptr, uint8_t channel, uint8_t note, uint8 | |||
| typedef void (*setSizeFunc) (void* ptr, uint width, uint height); | |||
| typedef bool (*fileRequestFunc) (void* ptr, const char* key); | |||
| // ----------------------------------------------------------------------- | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| // UI private data | |||
| struct UI::PrivateData { | |||
| @@ -292,8 +292,8 @@ struct UI::PrivateData { | |||
| setSizeFunc setSizeCallbackFunc; | |||
| fileRequestFunc fileRequestCallbackFunc; | |||
| PrivateData(const char* const appClassName) noexcept | |||
| : app(appClassName), | |||
| PrivateData(const char* const appClassName, const DGL_NAMESPACE::Application::Type appType) noexcept | |||
| : app(appClassName, appType), | |||
| window(nullptr), | |||
| #if DISTRHO_UI_USE_WEB_VIEW | |||
| webview(nullptr), | |||
| @@ -392,7 +392,7 @@ struct UI::PrivateData { | |||
| #endif | |||
| }; | |||
| // ----------------------------------------------------------------------- | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| // UI private data fileRequestCallback, which requires PluginWindow definitions | |||
| inline bool UI::PrivateData::fileRequestCallback(const char* const key) | |||
| @@ -419,7 +419,7 @@ inline bool UI::PrivateData::fileRequestCallback(const char* const key) | |||
| return false; | |||
| } | |||
| // ----------------------------------------------------------------------- | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| // PluginWindow onFileSelected that require UI::PrivateData definitions | |||
| #if DISTRHO_UI_FILE_BROWSER | |||
| @@ -457,7 +457,7 @@ inline void PluginWindow::onFileSelected(const char* const filename) | |||
| } | |||
| #endif | |||
| // ----------------------------------------------------------------------- | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| END_NAMESPACE_DISTRHO | |||
| @@ -205,7 +205,8 @@ public: | |||
| nullptr, // TODO file request | |||
| d_nextBundlePath, | |||
| instancePointer, | |||
| scaleFactor) | |||
| scaleFactor, | |||
| DGL_NAMESPACE::Application::kTypeClassic) | |||
| { | |||
| } | |||
| @@ -1374,7 +1375,7 @@ struct dpf_plugin_view : v3_plugin_view_cpp { | |||
| #else | |||
| UIExporter tmpUI(nullptr, 0, view->sampleRate, | |||
| nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, d_nextBundlePath, | |||
| view->instancePointer, scaleFactor); | |||
| view->instancePointer, scaleFactor, DGL_NAMESPACE::Application::kTypeClassic); | |||
| rect->right = tmpUI.getWidth(); | |||
| rect->bottom = tmpUI.getHeight(); | |||
| scaleFactor = tmpUI.getScaleFactor(); | |||
| @@ -38,7 +38,7 @@ mapi_handle_t mapi_create(unsigned int sample_rate); | |||
| typically referred to as "in-place processing". | |||
| */ | |||
| MAPI_EXPORT | |||
| void mapi_process(mapi_handle_t filter, | |||
| void mapi_process(mapi_handle_t handle, | |||
| const float* const* ins, | |||
| float** outs, | |||
| unsigned int frames); | |||
| @@ -47,10 +47,10 @@ void mapi_process(mapi_handle_t filter, | |||
| Set an effect parameter. | |||
| @param handle A previously created effect. | |||
| @param index A known index for this effect. | |||
| @param value A normalized value between 0 and 1, scaled internally by the effect as necessary. | |||
| @param value A full-ranged value. | |||
| */ | |||
| MAPI_EXPORT | |||
| void mapi_set_parameter(mapi_handle_t filter, unsigned int index, float value); | |||
| void mapi_set_parameter(mapi_handle_t handle, unsigned int index, float value); | |||
| /** | |||
| Set an effect state, using strings for both key and value. | |||
| @@ -59,14 +59,14 @@ void mapi_set_parameter(mapi_handle_t filter, unsigned int index, float value); | |||
| @param value A non-NULL value, allowed to be empty. | |||
| */ | |||
| MAPI_EXPORT | |||
| void mapi_set_state(mapi_handle_t filter, const char* key, const char* value); | |||
| void mapi_set_state(mapi_handle_t handle, const char* key, const char* value); | |||
| /** | |||
| Destroy a previously created effect. | |||
| @param handle A previously created effect. | |||
| */ | |||
| MAPI_EXPORT | |||
| void mapi_destroy(mapi_handle_t filter); | |||
| void mapi_destroy(mapi_handle_t handle); | |||
| #ifdef __cplusplus | |||
| } | |||