| @@ -82,3 +82,79 @@ jobs: | |||
| with: | |||
| name: macOS artifacts | |||
| path: ${{runner.workspace}}/build/bin/ | |||
| cmake_win32: | |||
| runs-on: windows-2019 | |||
| steps: | |||
| - name: Set environment | |||
| 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 | |||
| 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@v2 | |||
| 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 16 2019" -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" | |||
| - name: Build all | |||
| working-directory: ${{runner.workspace}}/build | |||
| run: cmake --build . --config "${Env:BUILD_TYPE}" -j 2 | |||
| - name: Show built files | |||
| working-directory: ${{runner.workspace}}/build/bin | |||
| run: tree | |||
| - uses: actions/upload-artifact@v2 | |||
| with: | |||
| name: Win32 artifacts | |||
| path: ${{runner.workspace}}/build/bin/ | |||
| cmake_win64: | |||
| runs-on: windows-2019 | |||
| 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@v2 | |||
| 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 16 2019" -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" | |||
| - name: Build all | |||
| working-directory: ${{runner.workspace}}/build | |||
| run: cmake --build . --config "${Env:BUILD_TYPE}" -j 2 | |||
| - name: Show built files | |||
| working-directory: ${{runner.workspace}}/build/bin | |||
| run: tree | |||
| - uses: actions/upload-artifact@v2 | |||
| with: | |||
| name: Win64 artifacts | |||
| path: ${{runner.workspace}}/build/bin/ | |||
| @@ -10,6 +10,8 @@ | |||
| .kdev_include_paths | |||
| .kdev4/ | |||
| .DS_Store | |||
| .vs/ | |||
| CMakeSettings.json | |||
| bin/ | |||
| build/ | |||
| @@ -293,7 +293,8 @@ function(dpf__build_lv2 NAME DGL_LIBRARY MONOLITHIC) | |||
| COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR} | |||
| "$<TARGET_FILE:lv2_ttl_generator>" | |||
| "$<TARGET_FILE:${NAME}-lv2>" | |||
| WORKING_DIRECTORY "${PROJECT_BINARY_DIR}/bin/${NAME}.lv2") | |||
| WORKING_DIRECTORY "${PROJECT_BINARY_DIR}/bin/${NAME}.lv2" | |||
| DEPENDS lv2_ttl_generator) | |||
| endfunction() | |||
| # dpf__build_vst2 | |||
| @@ -488,6 +489,22 @@ function(dpf__add_dgl_system_libs) | |||
| # target_compile_definitions(dgl-system-libs-definitions INTERFACE "HAVE_XCURSOR") | |||
| #endif() | |||
| endif() | |||
| if(MSVC) | |||
| file(MAKE_DIRECTORY "${DPF_ROOT_DIR}/khronos/GL") | |||
| foreach(_gl_header "glext.h") | |||
| if(NOT EXISTS "${DPF_ROOT_DIR}/khronos/GL/${_gl_header}") | |||
| file(DOWNLOAD "https://www.khronos.org/registry/OpenGL/api/GL/${_gl_header}" "${DPF_ROOT_DIR}/khronos/GL/${_gl_header}" SHOW_PROGRESS) | |||
| endif() | |||
| endforeach() | |||
| foreach(_khr_header "khrplatform.h") | |||
| if(NOT EXISTS "${DPF_ROOT_DIR}/khronos/KHR/${_khr_header}") | |||
| file(DOWNLOAD "https://www.khronos.org/registry/EGL/api/KHR/${_khr_header}" "${DPF_ROOT_DIR}/khronos/KHR/${_khr_header}" SHOW_PROGRESS) | |||
| endif() | |||
| endforeach() | |||
| target_include_directories(dgl-system-libs-definitions INTERFACE "${DPF_ROOT_DIR}/khronos") | |||
| endif() | |||
| target_link_libraries(dgl-system-libs INTERFACE dgl-system-libs-definitions) | |||
| endfunction() | |||
| @@ -498,14 +515,7 @@ endfunction() | |||
| # | |||
| function(dpf__add_executable NAME) | |||
| add_executable("${NAME}" ${ARGN}) | |||
| set_target_properties("${NAME}" PROPERTIES | |||
| POSITION_INDEPENDENT_CODE TRUE | |||
| C_VISIBILITY_PRESET "hidden" | |||
| CXX_VISIBILITY_PRESET "hidden" | |||
| VISIBILITY_INLINES_HIDDEN TRUE) | |||
| if (MINGW) | |||
| target_compile_options("${NAME}" PUBLIC "-mstackrealign") | |||
| endif() | |||
| dpf__set_target_defaults("${NAME}") | |||
| endfunction() | |||
| # dpf__add_module | |||
| @@ -515,17 +525,7 @@ endfunction() | |||
| # | |||
| function(dpf__add_module NAME) | |||
| add_library("${NAME}" MODULE ${ARGN}) | |||
| set_target_properties("${NAME}" PROPERTIES | |||
| POSITION_INDEPENDENT_CODE TRUE | |||
| C_VISIBILITY_PRESET "hidden" | |||
| CXX_VISIBILITY_PRESET "hidden" | |||
| VISIBILITY_INLINES_HIDDEN TRUE) | |||
| if ((NOT WIN32 AND NOT APPLE) OR MINGW) | |||
| target_link_libraries("${NAME}" PRIVATE "-Wl,--no-undefined") | |||
| endif() | |||
| if (MINGW) | |||
| target_compile_options("${NAME}" PUBLIC "-mstackrealign") | |||
| endif() | |||
| dpf__set_target_defaults("${NAME}") | |||
| endfunction() | |||
| # dpf__add_static_library | |||
| @@ -535,14 +535,30 @@ endfunction() | |||
| # | |||
| function(dpf__add_static_library NAME) | |||
| add_library("${NAME}" STATIC ${ARGN}) | |||
| dpf__set_target_defaults("${NAME}") | |||
| endfunction() | |||
| # dpf__set_target_defaults | |||
| # ------------------------------------------------------------------------------ | |||
| # | |||
| # Set default properties which must apply to all DPF-defined targets. | |||
| # | |||
| function(dpf__set_target_defaults NAME) | |||
| set_target_properties("${NAME}" PROPERTIES | |||
| POSITION_INDEPENDENT_CODE TRUE | |||
| C_VISIBILITY_PRESET "hidden" | |||
| CXX_VISIBILITY_PRESET "hidden" | |||
| VISIBILITY_INLINES_HIDDEN TRUE) | |||
| if(WIN32) | |||
| target_compile_definitions("${NAME}" PUBLIC "NOMINMAX") | |||
| endif() | |||
| if (MINGW) | |||
| target_compile_options("${NAME}" PUBLIC "-mstackrealign") | |||
| endif() | |||
| if (MSVC) | |||
| target_compile_options("${NAME}" PUBLIC "/UTF-8") | |||
| target_compile_definitions("${NAME}" PUBLIC "_CRT_SECURE_NO_WARNINGS") | |||
| endif() | |||
| endfunction() | |||
| # dpf__add_plugin_main | |||
| @@ -597,7 +613,7 @@ function(dpf__add_lv2_ttl_generator) | |||
| return() | |||
| endif() | |||
| add_executable(lv2_ttl_generator "${DPF_ROOT_DIR}/utils/lv2-ttl-generator/lv2_ttl_generator.c") | |||
| if(NOT WINDOWS AND NOT APPLE AND NOT HAIKU) | |||
| if((NOT WIN32) AND (NOT APPLE) AND (NOT HAIKU)) | |||
| target_link_libraries(lv2_ttl_generator "dl") | |||
| endif() | |||
| endfunction() | |||
| @@ -33,6 +33,11 @@ | |||
| # include <stdint.h> | |||
| #endif | |||
| #if defined(DISTRHO_OS_WINDOWS) && defined(_MSC_VER) | |||
| #include <basetsd.h> | |||
| typedef SSIZE_T ssize_t; | |||
| #endif | |||
| #if defined(DISTRHO_OS_MAC) && ! defined(CARLA_OS_MAC) && ! defined(DISTRHO_PROPER_CPP11_SUPPORT) | |||
| namespace std { | |||
| inline float fmin(float __x, float __y) | |||
| @@ -94,12 +99,12 @@ static inline | |||
| void d_debug(const char* const fmt, ...) noexcept | |||
| { | |||
| try { | |||
| ::va_list args; | |||
| ::va_start(args, fmt); | |||
| va_list args; | |||
| va_start(args, fmt); | |||
| std::fprintf(stdout, "\x1b[30;1m"); | |||
| std::vfprintf(stdout, fmt, args); | |||
| std::fprintf(stdout, "\x1b[0m\n"); | |||
| ::va_end(args); | |||
| va_end(args); | |||
| } catch (...) {} | |||
| } | |||
| #endif | |||
| @@ -111,11 +116,11 @@ static inline | |||
| void d_stdout(const char* const fmt, ...) noexcept | |||
| { | |||
| try { | |||
| ::va_list args; | |||
| ::va_start(args, fmt); | |||
| va_list args; | |||
| va_start(args, fmt); | |||
| std::vfprintf(stdout, fmt, args); | |||
| std::fprintf(stdout, "\n"); | |||
| ::va_end(args); | |||
| va_end(args); | |||
| } catch (...) {} | |||
| } | |||
| @@ -126,11 +131,11 @@ static inline | |||
| void d_stderr(const char* const fmt, ...) noexcept | |||
| { | |||
| try { | |||
| ::va_list args; | |||
| ::va_start(args, fmt); | |||
| va_list args; | |||
| va_start(args, fmt); | |||
| std::vfprintf(stderr, fmt, args); | |||
| std::fprintf(stderr, "\n"); | |||
| ::va_end(args); | |||
| va_end(args); | |||
| } catch (...) {} | |||
| } | |||
| @@ -141,12 +146,12 @@ static inline | |||
| void d_stderr2(const char* const fmt, ...) noexcept | |||
| { | |||
| try { | |||
| ::va_list args; | |||
| ::va_start(args, fmt); | |||
| va_list args; | |||
| va_start(args, fmt); | |||
| std::fprintf(stderr, "\x1b[31m"); | |||
| std::vfprintf(stderr, fmt, args); | |||
| std::fprintf(stderr, "\x1b[0m\n"); | |||
| ::va_end(args); | |||
| va_end(args); | |||
| } catch (...) {} | |||
| } | |||
| @@ -651,14 +651,18 @@ public: | |||
| "abcdefghijklmnopqrstuvwxyz" | |||
| "0123456789+/"; | |||
| #ifndef _MSC_VER | |||
| const std::size_t kTmpBufSize = std::min(d_nextPowerOf2(static_cast<uint32_t>(dataSize/3)), 65536U); | |||
| #else | |||
| constexpr std::size_t kTmpBufSize = 65536U; | |||
| #endif | |||
| const uchar* bytesToEncode((const uchar*)data); | |||
| uint i=0, j=0; | |||
| uint charArray3[3], charArray4[4]; | |||
| char strBuf[kTmpBufSize+1]; | |||
| char strBuf[kTmpBufSize + 1]; | |||
| strBuf[kTmpBufSize] = '\0'; | |||
| std::size_t strBufIndex = 0; | |||
| @@ -55,7 +55,7 @@ | |||
| # if HAVE_CPP11_SUPPORT | |||
| # define DISTRHO_PROPER_CPP11_SUPPORT | |||
| # endif | |||
| #elif __cplusplus >= 201103L || (defined(__GNUC__) && defined(__GXX_EXPERIMENTAL_CXX0X__) && (__GNUC__ * 100 + __GNUC_MINOR__) >= 405) || __has_extension(cxx_noexcept) | |||
| #elif __cplusplus >= 201103L || (defined(__GNUC__) && defined(__GXX_EXPERIMENTAL_CXX0X__) && (__GNUC__ * 100 + __GNUC_MINOR__) >= 405) || __has_extension(cxx_noexcept) || (defined(_MSC_VER) && _MSVC_LANG >= 201103L) | |||
| # define DISTRHO_PROPER_CPP11_SUPPORT | |||
| # if (defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) < 407 && ! defined(__clang__)) || (defined(__clang__) && ! __has_extension(cxx_override_control)) | |||
| # define override // gcc4.7+ only | |||
| @@ -74,7 +74,7 @@ | |||
| #if defined(__GNUC__) | |||
| # define DISTRHO_DEPRECATED __attribute__((deprecated)) | |||
| #elif defined(_MSC_VER) | |||
| # define DISTRHO_DEPRECATED __declspec(deprecated) | |||
| # define DISTRHO_DEPRECATED [[deprecated]] /* Note: __declspec(deprecated) it not applicable to enum members */ | |||
| #else | |||
| # define DISTRHO_DEPRECATED | |||
| #endif | |||
| @@ -48,9 +48,9 @@ extern Window* d_lastUiWindow; | |||
| // ----------------------------------------------------------------------- | |||
| #if DISTRHO_PLUGIN_HAS_EXTERNAL_UI | |||
| UI* createUiWrapper(void* dspPtr, uintptr_t winId, double scaleFactor, const char* bundlePath); | |||
| UI* createUiWrapper(void* const dspPtr, const uintptr_t winId, const double scaleFactor, const char* const bundlePath); | |||
| #else // DISTRHO_PLUGIN_HAS_EXTERNAL_UI | |||
| UI* createUiWrapper(void* dspPtr, Window* window); | |||
| UI* createUiWrapper(void* const dspPtr, Window* const window); | |||
| #endif | |||
| #if !DISTRHO_PLUGIN_HAS_EXTERNAL_UI | |||
| @@ -289,7 +289,7 @@ protected: | |||
| // reserve atom space | |||
| const size_t atomSize = sizeof(LV2_Atom) + msgSize; | |||
| char atomBuf[atomSize]; | |||
| char* const atomBuf = (char*)malloc(atomSize); | |||
| std::memset(atomBuf, 0, atomSize); | |||
| // set atom info | |||
| @@ -302,6 +302,9 @@ protected: | |||
| // send to DSP side | |||
| fWriteFunction(fController, eventInPortIndex, atomSize, fURIDs.atomEventTransfer, atom); | |||
| // free atom space | |||
| free(atomBuf); | |||
| } | |||
| #if DISTRHO_PLUGIN_WANT_MIDI_INPUT | |||
| @@ -35,6 +35,10 @@ | |||
| extern "C" { | |||
| #endif | |||
| #ifndef DSSI_PLUGIN_EXPORT | |||
| # define DSSI_PLUGIN_EXPORT LADSPA_PLUGIN_EXPORT | |||
| #endif | |||
| /* | |||
| There is a need for an API that supports hosted MIDI soft synths | |||
| with GUIs in Linux audio applications. In time the GMPI initiative | |||
| @@ -411,7 +415,7 @@ typedef struct _DSSI_Descriptor { | |||
| * of a distinct plugin type. | |||
| */ | |||
| const DSSI_Descriptor *dssi_descriptor(unsigned long Index); | |||
| DSSI_PLUGIN_EXPORT const DSSI_Descriptor *dssi_descriptor(unsigned long Index); | |||
| typedef const DSSI_Descriptor *(*DSSI_Descriptor_Function)(unsigned long Index); | |||
| @@ -30,6 +30,14 @@ | |||
| extern "C" { | |||
| #endif | |||
| #ifndef LADSPA_PLUGIN_EXPORT | |||
| # ifdef _WIN32 | |||
| # define LADSPA_PLUGIN_EXPORT __declspec(dllexport) | |||
| # else | |||
| # define LADSPA_PLUGIN_EXPORT __attribute__((visibility("default"))) | |||
| # endif | |||
| #endif | |||
| /*****************************************************************************/ | |||
| /* Overview: | |||
| @@ -586,7 +594,7 @@ typedef struct _LADSPA_Descriptor { | |||
| returning NULL, so the plugin count can be determined by checking | |||
| for the least index that results in NULL being returned. */ | |||
| const LADSPA_Descriptor * ladspa_descriptor(unsigned long Index); | |||
| LADSPA_PLUGIN_EXPORT const LADSPA_Descriptor * ladspa_descriptor(unsigned long Index); | |||
| /* Datatype corresponding to the ladspa_descriptor() function. */ | |||
| typedef const LADSPA_Descriptor * | |||
| @@ -15,6 +15,7 @@ | |||
| */ | |||
| #include <stdio.h> | |||
| #include <stdlib.h> | |||
| #include <string.h> | |||
| #ifdef _WIN32 | |||
| @@ -30,6 +31,11 @@ | |||
| typedef void (*TTL_Generator_Function)(const char* basename); | |||
| static int isPathSeparator(char c); | |||
| static char* makeNormalPath(const char* path); | |||
| // TODO support Unicode paths on the Windows platform | |||
| int main(int argc, char* argv[]) | |||
| { | |||
| if (argc != 2) | |||
| @@ -38,10 +44,12 @@ int main(int argc, char* argv[]) | |||
| return 1; | |||
| } | |||
| const char* path = argv[1]; | |||
| #ifdef TTL_GENERATOR_WINDOWS | |||
| const HMODULE handle = LoadLibraryA(argv[1]); | |||
| const HMODULE handle = LoadLibraryA(path); | |||
| #else | |||
| void* const handle = dlopen(argv[1], RTLD_LAZY); | |||
| void* const handle = dlopen(path, RTLD_LAZY); | |||
| #endif | |||
| if (! handle) | |||
| @@ -62,31 +70,32 @@ int main(int argc, char* argv[]) | |||
| if (ttlFn != NULL) | |||
| { | |||
| char basename[strlen(argv[1])+1]; | |||
| // convert the paths to a normalized form, such that path separators are | |||
| // replaced with '/', and duplicate separators are removed | |||
| char* normalPath = makeNormalPath(path); | |||
| #ifdef TTL_GENERATOR_WINDOWS | |||
| char* base2 = strrchr(argv[1], '\\'); | |||
| #else | |||
| char* base2 = strrchr(argv[1], '/'); | |||
| #endif | |||
| if (base2 != NULL) | |||
| { | |||
| strcpy(basename, base2+1); | |||
| basename[strrchr(base2, '.')-base2-1] = '\0'; | |||
| } | |||
| else if (argv[1][0] == '.' && argv[1][1] == '/') | |||
| { | |||
| strcpy(basename, argv[1]+2); | |||
| basename[strrchr(basename, '.')-basename] = '\0'; | |||
| } | |||
| // get rid of any "./" prefixes | |||
| path = normalPath; | |||
| while (path[0] == '.' && path[1] == '/') | |||
| path += 2; | |||
| // extract the file name part | |||
| char* basename = strrchr(path, '/'); | |||
| if (basename != NULL) | |||
| basename += 1; | |||
| else | |||
| { | |||
| strcpy(basename, argv[1]); | |||
| } | |||
| basename = (char*)path; | |||
| // remove the file extension | |||
| char* dotPos = strrchr(basename, '.'); | |||
| if (dotPos) | |||
| *dotPos = '\0'; | |||
| printf("Generate ttl data for '%s', basename: '%s'\n", argv[1], basename); | |||
| printf("Generate ttl data for '%s', basename: '%s'\n", path, basename); | |||
| ttlFn(basename); | |||
| free(normalPath); | |||
| } | |||
| else | |||
| printf("Failed to find 'lv2_generate_ttl' function\n"); | |||
| @@ -99,3 +108,31 @@ int main(int argc, char* argv[]) | |||
| return 0; | |||
| } | |||
| static int isPathSeparator(char c) | |||
| { | |||
| #ifdef TTL_GENERATOR_WINDOWS | |||
| return c == '/' || c == '\\'; | |||
| #else | |||
| return c == '/'; | |||
| #endif | |||
| } | |||
| static char* makeNormalPath(const char* path) | |||
| { | |||
| size_t i, j; | |||
| size_t len = strlen(path); | |||
| char* result = (char*)malloc(len + 1); | |||
| int isSep, wasSep = 0; | |||
| for (i = 0, j = 0; i < len; ++i) | |||
| { | |||
| isSep = isPathSeparator(path[i]); | |||
| if (!isSep) | |||
| result[j++] = path[i]; | |||
| else if (!wasSep) | |||
| result[j++] = '/'; | |||
| wasSep = isSep; | |||
| } | |||
| result[j] = '\0'; | |||
| return result; | |||
| } | |||