|  | /*
 * Carla Plugin Host
 * Copyright (C) 2011-2022 Filipe Coelho <falktx@falktx.com>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of
 * the License, or any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * For a full copy of the GNU General Public License see the doc/GPL.txt file.
 */
#ifndef USING_JUCE
# error this file is not meant to be built if not using juce!
#endif
#include "carla_juce.h"
#include "CarlaUtils.hpp"
#include "juce_events/juce_events.h"
#if defined(CARLA_OS_MAC) || defined(CARLA_OS_WIN)
# include "juce_gui_basics/juce_gui_basics.h"
#endif
namespace juce {
bool dispatchNextMessageOnSystemQueue(bool returnIfNoPendingMessages);
}
namespace CarlaJUCE {
void initialiseJuce_GUI()
{
    juce::initialiseJuce_GUI();
#if !(defined(CARLA_OS_MAC) || defined(CARLA_OS_WIN))
    juce::MessageManager::getInstance()->setCurrentThreadAsMessageThread();
#endif
}
void idleJuce_GUI()
{
#if !(defined(CARLA_OS_MAC) || defined(CARLA_OS_WIN))
    juce::dispatchNextMessageOnSystemQueue(true);
#endif
}
void shutdownJuce_GUI()
{
    juce::shutdownJuce_GUI();
}
const char* getVersion()
{
    static const juce::String version(juce::SystemStats::getJUCEVersion());
    return version.toRawUTF8();
}
static int numScopedInitInstances = 0;
ScopedJuceInitialiser_GUI::ScopedJuceInitialiser_GUI()
{
    if (numScopedInitInstances++ == 0)
        initialiseJuce_GUI();
}
ScopedJuceInitialiser_GUI::~ScopedJuceInitialiser_GUI()
{
    if (--numScopedInitInstances == 0)
        shutdownJuce_GUI();
}
#ifdef USE_REFCOUNTER_JUCE_MESSAGE_MANAGER
ReferenceCountedJuceMessageMessager::ReferenceCountedJuceMessageMessager()
{
    CARLA_SAFE_ASSERT(numScopedInitInstances == 0);
}
ReferenceCountedJuceMessageMessager::~ReferenceCountedJuceMessageMessager()
{
    CARLA_SAFE_ASSERT(numScopedInitInstances == 0);
}
void ReferenceCountedJuceMessageMessager::incRef() const
{
    if (numScopedInitInstances++ == 0)
    {
        juce::initialiseJuce_GUI();
        juce::MessageManager::getInstance()->setCurrentThreadAsMessageThread();
    }
}
void ReferenceCountedJuceMessageMessager::decRef() const
{
    if (--numScopedInitInstances == 0)
    {
        juce::shutdownJuce_GUI();
    }
}
void setMessageManagerForThisThread()
{
    juce::MessageManager* const msgMgr = juce::MessageManager::getInstanceWithoutCreating();
    CARLA_SAFE_ASSERT_RETURN(msgMgr != nullptr,);
    if (! msgMgr->isThisTheMessageThread())
    {
        try {
            msgMgr->setCurrentThreadAsMessageThread();
        } CARLA_SAFE_EXCEPTION_RETURN("setCurrentThreadAsMessageThread",);
    }
}
void dispatchMessageManagerMessages()
{
    const juce::MessageManagerLock mml;
    juce::dispatchNextMessageOnSystemQueue(true);
}
#endif
#ifdef USE_STANDALONE_JUCE_APPLICATION
static std::function<void()> sIdleFn;
static volatile bool* sClosedSignalPtr;
class CarlaJuceApp : public juce::JUCEApplication,
                     private juce::Timer
{
public:
    CarlaJuceApp()  {}
    ~CarlaJuceApp() {}
    void initialise(const juce::String&) override
    {
        startTimer(8);
    }
    void shutdown() override
    {
        *sClosedSignalPtr = true;
        stopTimer();
    }
    const juce::String getApplicationName() override
    {
        return "CarlaPlugin";
    }
    const juce::String getApplicationVersion() override
    {
        return CARLA_VERSION_STRING;
    }
    void timerCallback() override
    {
        sIdleFn();
        if (*sClosedSignalPtr)
        {
            quit();
            *sClosedSignalPtr = false;
        }
    }
};
static juce::JUCEApplicationBase* juce_CreateApplication() { return new CarlaJuceApp(); }
void setupAndUseMainApplication(std::function<void()> idleFn, volatile bool* closedSignalPtr)
{
#ifndef CARLA_OS_WIN
    static const int argc = 0;
    static const char* argv[] = {};
#endif
    sIdleFn = idleFn;
    sClosedSignalPtr = closedSignalPtr;
    juce::JUCEApplicationBase::createInstance = &juce_CreateApplication;
    juce::JUCEApplicationBase::main(JUCE_MAIN_FUNCTION_ARGS);
}
#endif
} // namespace CarlaJUCE
 |