Пример #1
0
void run5Tests()
{
    ushort k = 0;
    MyData allMyData[MAX_RT_EVENTS];

    // Make a safe copy of events while clearing them
    postRtEvents.mutex.lock();

    while (! postRtEvents.data.isEmpty())
    {
        static MyData fallback = { { '\0' }, 0 };
        const MyData& my(postRtEvents.data.getFirst(fallback, true));
        allMyData[k++] = my;
    }

    postRtEvents.mutex.unlock();

    carla_stdout("Post-Rt Event Count: %i", k);
    assert(k == 5);

    // data should be empty now
    assert(postRtEvents.data.count() == 0);
    assert(postRtEvents.data.isEmpty());
    assert(postRtEvents.dataPendingRT.count() == 0);
    assert(postRtEvents.dataPendingRT.isEmpty());

    // Handle events now
    for (ushort i=0; i < k; ++i)
    {
        const MyData& my(allMyData[i]);

        carla_stdout("Got data: %i %s", my.id, my.str);
    }
}
Пример #2
0
static void test_CarlaEngineUtils() noexcept
{
    CARLA_BACKEND_USE_NAMESPACE
    carla_stdout(EngineType2Str(kEngineTypeNull));
    carla_stdout(EnginePortType2Str(kEnginePortTypeNull));
    carla_stdout(EngineEventType2Str(kEngineEventTypeNull));
    carla_stdout(EngineControlEventType2Str(kEngineControlEventTypeNull));
}
Пример #3
0
static void test_CarlaVstUtils() noexcept
{
    AEffect effect;
    carla_zeroStruct(effect);
    effect.dispatcher = test_vst_dispatcher;

    vstPluginCanDo(&effect, "test");
    carla_stdout(vstEffectOpcode2str(effOpen));
    carla_stdout(vstMasterOpcode2str(audioMasterAutomate));
}
Пример #4
0
CARLA_EXPORT
int XNextEvent(Display* display, XEvent* event)
{
    const int ret = real_XNextEvent(display, event);

    if (ret != 0)
        return ret;
    if (gCurrentlyMappedWindow == 0)
        return ret;
    if (event->type != ClientMessage)
        return ret;
    if (event->xclient.window != gCurrentlyMappedWindow)
        return ret;

    char* const type = XGetAtomName(display, event->xclient.message_type);
    CARLA_SAFE_ASSERT_RETURN(type != nullptr, 0);

    if (std::strcmp(type, "WM_PROTOCOLS") != 0)
        return ret;
    if ((Atom)event->xclient.data.l[0] != XInternAtom(display, "WM_DELETE_WINDOW", False))
        return ret;

    gCurrentWindowVisible = false;
    gCurrentWindowMapped = false;

    if (gInterposedCallback != nullptr)
        gInterposedCallback(1, nullptr);

    event->type = 0;
    carla_stdout("XNextEvent close event caught, hiding UI instead");
    return real_XUnmapWindow(display, gCurrentlyMappedWindow);
}
Пример #5
0
CARLA_EXPORT
int clone(int (*)(void*), void*, int, void*, ...)
{
    carla_stdout("------------------------------- clone called");
    errno = ENOSYS;
    return -1;
}
Пример #6
0
CARLA_EXPORT
pid_t fork()
{
    carla_stdout("------------------------------- fork called");
    errno = ENOSYS;
    return -1;
}
Пример #7
0
    void uiShow(const bool show) override
    {
        if (show)
        {
            if (isPipeRunning())
            {
                writeFocusMessage();
                return;
            }

            carla_stdout("Trying to start UI using \"%s\"", fExtUiPath.buffer());

            CarlaExternalUI::setData(fExtUiPath, getSampleRate(), getUiName());

            if (! CarlaExternalUI::startPipeServer(true))
            {
                uiClosed();
                hostUiUnavailable();
            }
        }
        else
        {
            CarlaExternalUI::stopPipeServer(2000);
        }
    }
Пример #8
0
static void test_CarlaDssiUtils() noexcept
{
    const char* const ui = find_dssi_ui("/usr/lib/dssi/trivial_sampler.so", "aa");

    CARLA_SAFE_ASSERT(ui != nullptr);

    if (ui != nullptr)
    {
        carla_stdout("%s", ui);
        assert(std::strcmp(ui, "/usr/lib/dssi/trivial_sampler/trivial_sampler_qt") == 0);
        delete[] ui;
    }
}
Пример #9
0
        ScopedPluginAction(CarlaEngineProtectedData* const data, const EnginePostAction action, const unsigned int pluginId, const unsigned int value, const bool lockWait)
            : kData(data)
        {
            kData->nextAction.mutex.lock();

            CARLA_ASSERT(kData->nextAction.opcode == kEnginePostActionNull);

            kData->nextAction.opcode   = action;
            kData->nextAction.pluginId = pluginId;
            kData->nextAction.value    = value;

            if (lockWait)
            {
                // block wait for unlock on proccessing side
                carla_stdout("ScopedPluginAction(%i) - blocking START", pluginId);
                kData->nextAction.mutex.lock();
                carla_stdout("ScopedPluginAction(%i) - blocking DONE", pluginId);
            }
            else
            {
                kData->doNextPluginAction(false);
            }
        }
Пример #10
0
int main()
{
    const char* const filename = carla_get_library_filename();
    CARLA_SAFE_ASSERT_RETURN(filename != nullptr && filename[0] != '\0', 1);

    const char* const folder = carla_get_library_folder();
    CARLA_SAFE_ASSERT_RETURN(folder != nullptr && folder[0] != '\0', 1);

    const NativePluginDescriptor* const rack = carla_get_native_rack_plugin();
    CARLA_SAFE_ASSERT_RETURN(rack != nullptr, 1);

    const NativePluginDescriptor* const patchbay = carla_get_native_patchbay_plugin();
    CARLA_SAFE_ASSERT_RETURN(patchbay != nullptr, 1);

    const NativeHostDescriptor host = {
        nullptr,
        "", // resourceDir
        "Carla Plugin UI",
        0,

        get_buffer_size,
        get_sample_rate,
        is_offline,

        nullptr, // get_time_info
        nullptr, // write_midi_event

        nullptr, // ui_parameter_changed
        nullptr, // ui_midi_program_changed
        nullptr, // ui_custom_data_changed
        nullptr, // ui_closed

        nullptr, // ui_open_file
        nullptr, // ui_save_file

        nullptr, // dispatcher
    };

    const NativePluginHandle handle = rack->instantiate(&host);
    CARLA_SAFE_ASSERT_RETURN(handle != nullptr, 1);

    CarlaEngine* const engine = carla_get_native_plugin_engine(rack, handle);
    CARLA_SAFE_ASSERT_RETURN(engine != nullptr, 1);

    carla_stdout("Got Engine %p, %s, %i, %f",
                 engine, engine->getName(), engine->getBufferSize(), engine->getSampleRate());

    rack->cleanup(handle);
    return 0;
}
Пример #11
0
    void uiShow(const bool show) override
    {
        if (show)
        {
            if (isOk())
                return;

            CarlaString path(getResourceDir() + fExtUiPath);
            carla_stdout("Trying to start UI using \"%s\"", path.buffer());

            CarlaExternalUI::setData(path, getSampleRate(), getUiName());
            CarlaExternalUI::start();
        }
        else
        {
            CarlaExternalUI::stop();
        }
    }
Пример #12
0
static void test_CarlaBridgeUtils() noexcept
{
    carla_stdout(PluginBridgeOscInfoType2str(kPluginBridgeOscPong));
    carla_stdout(PluginBridgeRtOpcode2str(kPluginBridgeRtNull));
    carla_stdout(PluginBridgeNonRtOpcode2str(kPluginBridgeNonRtNull));
}
Пример #13
0
static void test_CarlaBackendUtils() noexcept
{
    CARLA_BACKEND_USE_NAMESPACE
    carla_stdout(PluginOption2Str(PLUGIN_OPTION_FIXED_BUFFERS));
    carla_stdout(BinaryType2Str(BINARY_NONE));
    carla_stdout(PluginType2Str(PLUGIN_NONE));
    carla_stdout(PluginCategory2Str(PLUGIN_CATEGORY_NONE));
    carla_stdout(ParameterType2Str(PARAMETER_UNKNOWN));
    carla_stdout(InternalParameterIndex2Str(PARAMETER_NULL));
    carla_stdout(EngineCallbackOpcode2Str(ENGINE_CALLBACK_DEBUG));
    carla_stdout(EngineOption2Str(ENGINE_OPTION_DEBUG));
    carla_stdout(EngineProcessMode2Str(ENGINE_PROCESS_MODE_SINGLE_CLIENT));
    carla_stdout(EngineTransportMode2Str(ENGINE_TRANSPORT_MODE_INTERNAL));
    carla_stdout(FileCallbackOpcode2Str(FILE_CALLBACK_DEBUG));
    carla_stdout(getPluginTypeAsString(PLUGIN_INTERNAL));
    carla_stdout(PatchbayIcon2Str(PATCHBAY_ICON_APPLICATION));
    getPluginTypeFromString("none");
    getPluginCategoryFromName("cat");
}
Пример #14
0
static void test_CarlaUtils()
{
    // ----------------------------------------------------------------------------------------------------------------
    // misc functions

    {
        bool2str(false);
        bool2str(true);
        pass();

        char strBuf[2];
        nullStrBuf(strBuf);

        char* const strBuf2(strBuf+1);
        nullStrBuf(strBuf2);
    }

    // ----------------------------------------------------------------------------------------------------------------
    // string print functions

    {
        carla_debug("DEBUG");
        carla_stdout("STDOUT %s", bool2str(true));
        carla_stderr("STDERR %s", bool2str(false));
        carla_stderr2("STDERR2 " P_UINT64, 0xffffffff); // 4294967295
    }

    // ----------------------------------------------------------------------------------------------------------------
    // carla_*sleep

    {
        carla_sleep(1);
        carla_msleep(1);
    }

    // ----------------------------------------------------------------------------------------------------------------
    // carla_setenv

    {
        carla_setenv("THIS", "THAT");
        assert(std::strcmp(std::getenv("THIS"), "THAT") == 0);

        carla_unsetenv("THIS");
        assert(std::getenv("THIS") == nullptr);
    }

    // ----------------------------------------------------------------------------------------------------------------
    // carla_strdup

    {
        // with variables
        const char* const str1(carla_strdup("stringN"));
        const char* const strF(carla_strdup_free(strdup("stringF")));
        const char* const str2(carla_strdup_safe("stringS"));
        delete[] str1;
        delete[] str2;
        delete[] strF;

        // without variables
        delete[] carla_strdup("string_normal");
        delete[] carla_strdup_free(strdup("string_free"));
        delete[] carla_strdup_safe("string_safe");
    }

    {
        // common use case in Carla code
        struct TestStruct {
            const char* strNull;
            const char* strNormal;
            const char* strFree;
            const char* strSafe;

            TestStruct()
                : strNull(nullptr),
                  strNormal(carla_strdup("strNormal")),
                  strFree(carla_strdup_free(strdup("strFree"))),
                  strSafe(carla_strdup_safe("strSafe")) {}

            ~TestStruct() noexcept
            {
                if (strNull != nullptr)
                {
                    delete[] strNull;
                    strNull = nullptr;
                }

                if (strNormal != nullptr)
                {
                    delete[] strNormal;
                    strNormal = nullptr;
                }

                if (strFree != nullptr)
                {
                    delete[] strFree;
                    strFree = nullptr;
                }

                if (strSafe != nullptr)
                {
                    delete[] strSafe;
                    strSafe = nullptr;
                }
            }

            CARLA_DECLARE_NON_COPY_STRUCT(TestStruct)
        };

        TestStruct a, b, c;
    }

    // ----------------------------------------------------------------------------------------------------------------
    // memory functions

    {
        int a1[] = { 4, 3, 2, 1 };
        int a2[] = { 4, 3, 2, 1 };
        int b1[] = { 1, 2, 3, 4 };
        int b2[] = { 1, 2, 3, 4 };

        carla_add(a1, b1, 4);
        assert(a1[0] == 5);
        assert(a1[1] == 5);
        assert(a1[2] == 5);
        assert(a1[3] == 5);

        carla_add(b1, a2, 4);
        assert(b1[0] == 5);
        assert(b1[1] == 5);
        assert(b1[2] == 5);
        assert(b1[3] == 5);
        assert(a1[0] == b1[0]);
        assert(a1[1] == b1[1]);
        assert(a1[2] == b1[2]);
        assert(a1[3] == b1[3]);

        carla_copy(a1, b2, 4);
        assert(a1[0] != b1[0]);
        assert(a1[1] != b1[1]);
        assert(a1[2] != b1[2]);
        assert(a1[3] != b1[3]);
        assert(a1[0] == b2[0]);
        assert(a1[1] == b2[1]);
        assert(a1[2] == b2[2]);
        assert(a1[3] == b2[3]);

        carla_copy(a1, b1, 4);
        assert(a1[0] == b1[0]);
        assert(a1[1] == b1[1]);
        assert(a1[2] == b1[2]);
        assert(a1[3] == b1[3]);

        carla_copy(a1, b2, 2);
        assert(a1[0] != b1[0]);
        assert(a1[1] != b1[1]);
        assert(a1[2] == b1[2]);
        assert(a1[3] == b1[3]);

        carla_copy(a1+2, b2+2, 2);
        assert(a1[0] != b1[0]);
        assert(a1[1] != b1[1]);
        assert(a1[2] != b1[2]);
        assert(a1[3] != b1[3]);

        carla_copy(a1, b1, 2);
        assert(a1[0] == b1[0]);
        assert(a1[1] == b1[1]);
        assert(a1[2] != b1[2]);
        assert(a1[3] != b1[3]);

        carla_copy(a1+2, b1+2, 2);
        assert(a1[0] == b1[0]);
        assert(a1[1] == b1[1]);
        assert(a1[2] == b1[2]);
        assert(a1[3] == b1[3]);

        carla_fill(a1, 0, 4);
        assert(a1[0] == 0);
        assert(a1[1] == 0);
        assert(a1[2] == 0);
        assert(a1[3] == 0);

        carla_fill(a1, -11, 4);
        assert(a1[0] == -11);
        assert(a1[1] == -11);
        assert(a1[2] == -11);
        assert(a1[3] == -11);

        carla_fill(a1, 1791, 2);
        assert(a1[0] == 1791);
        assert(a1[1] == 1791);
        assert(a1[2] == -11);
        assert(a1[3] == -11);

        carla_fill(a1+2, 1791, 2);
        assert(a1[0] == 1791);
        assert(a1[1] == 1791);
        assert(a1[2] == 1791);
        assert(a1[3] == 1791);

        int16_t d = 1527, e = 0;

        carla_add(&d, &d, 1);
        assert(d == 1527*2);

        carla_add(&d, &d, 1);
        assert(d == 1527*4);

        carla_add(&d, &e, 1);
        assert(d == 1527*4);
        assert(e == 0);

        carla_add(&e, &d, 1);
        assert(d == e);

        carla_add(&e, &d, 1);
        assert(e == d*2);

        d = -e;
        carla_add(&d, &e, 1);
        assert(d == 0);
    }

    {
        bool x;
        const bool f = false, t = true;

        carla_copy(&x, &t, 1);
        assert(x);

        carla_copy(&x, &f, 1);
        assert(! x);

        carla_fill(&x, true, 1);
        assert(x);

        carla_fill(&x, false, 1);
        assert(! x);
    }

    {
        uint8_t a[] = { 3, 2, 1, 0 };
        carla_zeroBytes(a, 1);
        assert(a[0] == 0);
        assert(a[1] == 2);
        assert(a[2] == 1);
        assert(a[3] == 0);

        carla_zeroBytes(a+1, 2);
        assert(a[0] == 0);
        assert(a[1] == 0);
        assert(a[2] == 0);
        assert(a[3] == 0);
    }

    {
        char a[501];

        for (int i=500; --i>=0;)
            a[i] = 'a';

        carla_zeroChars(a, 501);

        for (int i=501; --i>=0;)
            assert(a[i] == '\0');

        for (int i=500; --i>=0;)
            a[i] = 'a';

        assert(std::strlen(a) == 500);

        carla_fill(a+200, '\0', 1);
        assert(std::strlen(a) == 200);
    }

    {
        void* a[33];
        carla_zeroPointers(a, 33);

        for (int i=33; --i>=0;)
            assert(a[i] == nullptr);
    }

    {
        struct Thing {
            char c;
            int i;
            int64_t h;

            bool operator==(const Thing& t) const noexcept
            {
                return (t.c == c && t.i == i && t.h == h);
            }

            bool operator!=(const Thing& t) const noexcept
            {
                return !operator==(t);
            }
        };

        Thing a, b, c;

        a.c = 0;
        a.i = 0;
        a.h = 0;

        b.c = 64;
        b.i = 64;
        b.h = 64;

        c = a;

        carla_copyStruct(a, b);
        assert(a == b);

        carla_zeroStruct(a);
        assert(a == c);

        carla_copyStruct(c, b);
        assert(a != c);

        // make it non-zero
        a.c = 1;

        Thing d[3];

        carla_zeroStructs(d, 3);
        assert(d[0] != a);
        assert(d[1] != b);
        assert(d[2] != c);

        carla_copyStructs(d, &a, 1);
        assert(d[0] == a);
        assert(d[1] != b);
        assert(d[2] != c);

        carla_copyStructs(&c, d+2, 1);
        assert(d[0] == a);
        assert(d[1] != b);
        assert(d[2] == c);
    }
}
Пример #15
0
void run5Tests()
{
    ushort k = 0;
    MyData allMyData[MAX_RT_EVENTS];

    // Make a safe copy of events while clearing them
    postRtEvents.mutex.lock();

    while (! postRtEvents.data.isEmpty())
    {
        static MyData kFallback = { { '\0' }, 0 };
        const MyData& my(postRtEvents.data.getFirst(kFallback, true));
        allMyData[k++] = my;
    }

    postRtEvents.mutex.unlock();

    carla_stdout("Post-Rt Event Count: %i", k);
    assert(k == 5);

    // data should be empty now
    assert(postRtEvents.data.count() == 0);
    assert(postRtEvents.data.isEmpty());
    assert(postRtEvents.dataPendingRT.count() == 0);
    assert(postRtEvents.dataPendingRT.isEmpty());

    // Handle events now
    for (ushort i=0; i < k; ++i)
    {
        const MyData& my(allMyData[i]);

        carla_stdout("Got data: %i %s", my.id, my.str);
    }

    // append events past minimum size
    MyData dummyData = { { '\0' }, 0 };
    // 5 initial go ok
    assert(postRtEvents.dataPendingRT.append(dummyData));
    assert(postRtEvents.dataPendingRT.append(dummyData));
    assert(postRtEvents.dataPendingRT.append(dummyData));
    assert(postRtEvents.dataPendingRT.append(dummyData));
    assert(postRtEvents.dataPendingRT.append(dummyData));
    // afterwards it fails
    assert(! postRtEvents.dataPendingRT.append(dummyData));
    assert(! postRtEvents.dataPendingRT.append(dummyData));
    carla_stdout("here %i", __LINE__);

    // adding sleepy works
    assert(postRtEvents.dataPendingRT.append_sleepy(dummyData));
    carla_stdout("here %i", __LINE__);

    // now atomic works too, size was increased
    assert(postRtEvents.dataPendingRT.append(dummyData));
    assert(postRtEvents.dataPendingRT.append(dummyData));
    assert(postRtEvents.dataPendingRT.append(dummyData));
    assert(postRtEvents.dataPendingRT.append(dummyData));
    carla_stdout("here %i", __LINE__);

    // fails here now
    assert(! postRtEvents.dataPendingRT.append(dummyData));
    carla_stdout("here %i", __LINE__);

    // adding sleepy still works
    assert(postRtEvents.dataPendingRT.append_sleepy(dummyData));
    carla_stdout("here %i", __LINE__);

    // now atomic works for 1 more
    assert(postRtEvents.dataPendingRT.append(dummyData));
    assert(! postRtEvents.dataPendingRT.append(dummyData));
    carla_stdout("here %i", __LINE__);

    // and adding sleepy no longer works
    assert(! postRtEvents.dataPendingRT.append_sleepy(dummyData));
    carla_stdout("here %i", __LINE__);

    // cleanup
    postRtEvents.trySplice();
    postRtEvents.clear();
}
Пример #16
0
CARLA_EXPORT
int posix_spawnp(pid_t*, const char*, const posix_spawn_file_actions_t*, const posix_spawnattr_t*, char* const[], char* const[])
{
    carla_stdout("------------------------------- posix_spawnp called");
    return ENOSYS;
}
Пример #17
0
int main()
{
    MyData m1;
    m1.id = 1;
    std::strcpy(m1.str, "1");
    MyData m2;
    m2.id = 2;
    std::strcpy(m2.str, "2");
    MyData m3;
    m3.id = 3;
    std::strcpy(m3.str, "3");
    MyData m4;
    m4.id = 4;
    std::strcpy(m4.str, "4");
    MyData m5;
    m5.id = 5;
    std::strcpy(m5.str, "5");

    // start
    assert(postRtEvents.data.count() == 0);
    assert(postRtEvents.data.isEmpty());
    assert(postRtEvents.dataPendingRT.count() == 0);
    assert(postRtEvents.dataPendingRT.isEmpty());

    // single append
    postRtEvents.appendRT(m1);
    assert(postRtEvents.data.count() == 0);
    assert(postRtEvents.dataPendingRT.count() == 1);
    postRtEvents.trySplice();
    assert(postRtEvents.data.count() == 1);
    assert(postRtEvents.dataPendingRT.count() == 0);

    // +3 appends
    postRtEvents.appendRT(m2);
    postRtEvents.appendRT(m4);
    postRtEvents.appendRT(m3);
    assert(postRtEvents.data.count() == 1);
    assert(postRtEvents.dataPendingRT.count() == 3);
    postRtEvents.trySplice();
    assert(postRtEvents.data.count() == 4);
    assert(postRtEvents.dataPendingRT.count() == 0);

    for (RtLinkedList<MyData>::Itenerator it = postRtEvents.data.begin2(); it.valid(); it.next())
    {
        const MyData& my(it.getValue());

        carla_stdout("FOR DATA!!!: %i %s", my.id, my.str);

        if (my.id == 2)
        {
            // +1 append
            postRtEvents.dataPendingRT.insertAt(m5, it);
            assert(postRtEvents.data.count() == 4);
            assert(postRtEvents.dataPendingRT.count() == 1);
        }
    }

    for (const MyData& my : postRtEvents.data)
        carla_stdout("FOR DATA!!! NEW AUTO Itenerator!!!: %i %s", my.id, my.str);

    postRtEvents.trySplice();
    assert(postRtEvents.data.count() == 5);
    assert(postRtEvents.dataPendingRT.count() == 0);

    run5Tests();

    // reset
    postRtEvents.clear();
    assert(postRtEvents.data.count() == 0);
    assert(postRtEvents.data.isEmpty());
    assert(postRtEvents.dataPendingRT.count() == 0);
    assert(postRtEvents.dataPendingRT.isEmpty());

    // test non-rt
    const unsigned int CARLA_EVENT_DATA_ATOM    = 0x01;
    const unsigned int CARLA_EVENT_DATA_MIDI_LL = 0x04;

    LinkedList<uint32_t> evIns, evOuts;
    evIns.append(CARLA_EVENT_DATA_ATOM);
    evOuts.append(CARLA_EVENT_DATA_ATOM);
    evOuts.append(CARLA_EVENT_DATA_MIDI_LL);

    if (evIns.count() > 0)
    {
        for (size_t j=0, count=evIns.count(); j < count; ++j)
        {
            const uint32_t& type(evIns.getAt(j, 0));

            if (type == CARLA_EVENT_DATA_ATOM)
                pass();
            else if (type == CARLA_EVENT_DATA_MIDI_LL)
                pass();
        }
    }

    evIns.clear();
    evOuts.clear();

    return 0;
}
Пример #18
0
static int carlaWindowMap(Display* const display, const Window window, const WindowMappingType fallbackFnType)
{
    const ScopedLibOpen& slo(ScopedLibOpen::getInstance());

    for (;;)
    {
        if (slo.winId < 0)
            break;

        Atom atom;
        int atomFormat;
        unsigned char* atomPtrs;
        unsigned long numItems, ignored;

        const Atom wmWindowType = XInternAtom(display, "_NET_WM_WINDOW_TYPE", False);

        if (XGetWindowProperty(display, window, wmWindowType, 0, ~0L, False, AnyPropertyType,
                               &atom, &atomFormat, &numItems, &ignored, &atomPtrs) != Success)
        {
            carla_debug("carlaWindowMap(%p, %lu, %i) - XGetWindowProperty failed", display, window, fallbackFnType);
            break;
        }

        const Atom* const atomValues = (const Atom*)atomPtrs;
        bool isMainWindow = (numItems == 0);

        for (ulong i=0; i<numItems; ++i)
        {
            const char* const atomValue(XGetAtomName(display, atomValues[i]));
            CARLA_SAFE_ASSERT_CONTINUE(atomValue != nullptr && atomValue[0] != '\0');

            if (std::strcmp(atomValue, "_NET_WM_WINDOW_TYPE_COMBO"        ) == 0 ||
                std::strcmp(atomValue, "_NET_WM_WINDOW_TYPE_DIALOG"       ) == 0 ||
                std::strcmp(atomValue, "_NET_WM_WINDOW_TYPE_DND"          ) == 0 ||
                std::strcmp(atomValue, "_NET_WM_WINDOW_TYPE_DOCK"         ) == 0 ||
                std::strcmp(atomValue, "_NET_WM_WINDOW_TYPE_DROPDOWN_MENU") == 0 ||
                std::strcmp(atomValue, "_NET_WM_WINDOW_TYPE_MENU"         ) == 0 ||
                std::strcmp(atomValue, "_NET_WM_WINDOW_TYPE_NOTIFICATION" ) == 0 ||
                std::strcmp(atomValue, "_NET_WM_WINDOW_TYPE_POPUP_MENU"   ) == 0 ||
                std::strcmp(atomValue, "_NET_WM_WINDOW_TYPE_SPLASH"       ) == 0 ||
                std::strcmp(atomValue, "_NET_WM_WINDOW_TYPE_TOOLBAR"      ) == 0 ||
                std::strcmp(atomValue, "_NET_WM_WINDOW_TYPE_TOOLTIP"      ) == 0 ||
                std::strcmp(atomValue, "_NET_WM_WINDOW_TYPE_UTILITY"      ) == 0)
            {
                isMainWindow = false;
                continue;
            }

            if (std::strcmp(atomValue, "_NET_WM_WINDOW_TYPE_NORMAL") == 0)
            {
                // window is good, use it if no other types are set
                isMainWindow = true;
            }
            else
            {
                carla_stdout("=======================================> %s", atomValue);
            }
        }

        if (! isMainWindow)
        {
            // this has always bothered me...
            if (gCurrentlyMappedWindow != 0 && gCurrentWindowMapped && gCurrentWindowVisible)
                XSetTransientForHint(display, window, gCurrentlyMappedWindow);
            break;
        }

        Window transientWindow = 0;
        if (XGetTransientForHint(display, window, &transientWindow) == Success && transientWindow != 0)
        {
            carla_stdout("Window has transient set already, ignoring it");
            break;
        }

        // got a new window, we may need to forget last one
        if (gCurrentlyMappedDisplay != nullptr && gCurrentlyMappedWindow != 0)
        {
            // ignore requests against the current mapped window
            if (gCurrentlyMappedWindow == window)
                return 0;

            // we already have a mapped window, with carla visible button on, should be a dialog of sorts..
            if (gCurrentWindowMapped && gCurrentWindowVisible)
            {
                XSetTransientForHint(display, window, gCurrentlyMappedWindow);
                break;
            }

            // ignore empty windows created after the main one
            if (numItems == 0)
                break;

            carla_stdout("NOTICE: XMapWindow now showing previous window");
            switch (gCurrentWindowType)
            {
            case WindowMapNone:
                break;
            case WindowMapNormal:
                real_XMapWindow(gCurrentlyMappedDisplay, gCurrentlyMappedWindow);
                break;
            case WindowMapRaised:
                real_XMapRaised(gCurrentlyMappedDisplay, gCurrentlyMappedWindow);
                break;
            case WindowMapSubwindows:
                real_XMapSubwindows(gCurrentlyMappedDisplay, gCurrentlyMappedWindow);
                break;
            }
        }

        gCurrentlyMappedDisplay = display;
        gCurrentlyMappedWindow  = window;
        gCurrentWindowMapped    = true;
        gCurrentWindowType      = fallbackFnType;

        if (slo.winId > 0)
            XSetTransientForHint(display, window, static_cast<Window>(slo.winId));

        if (gCurrentWindowVisible)
        {
            carla_stdout("JACK application window found, showing it now");
            break;
        }

        gCurrentWindowMapped = false;
        carla_stdout("JACK application window found and captured");
        return 0;
    }

    carla_debug("carlaWindowMap(%p, %lu, %i) - not captured", display, window, fallbackFnType);

    switch (fallbackFnType)
    {
    case 1:
        return real_XMapWindow(display, window);
    case 2:
        return real_XMapRaised(display, window);
    case 3:
        return real_XMapSubwindows(display, window);
    default:
        return 0;
    }
}