upgrade to JUCE 5.4.3. Remove (probably) unused JUCE modules. Remove VST2 target (it's been end-of-life'd by Steinberg and by JUCE)
This commit is contained in:
		@ -50,7 +50,7 @@ namespace Android
 | 
			
		||||
 | 
			
		||||
    struct Handler
 | 
			
		||||
    {
 | 
			
		||||
        Handler() : nativeHandler (getEnv()->NewObject (AndroidHandler, AndroidHandler.constructor)) {}
 | 
			
		||||
        Handler() : nativeHandler (LocalRef<jobject> (getEnv()->NewObject (AndroidHandler, AndroidHandler.constructor))) {}
 | 
			
		||||
        ~Handler() { clearSingletonInstance(); }
 | 
			
		||||
 | 
			
		||||
        JUCE_DECLARE_SINGLETON (Handler, false)
 | 
			
		||||
@ -72,19 +72,19 @@ struct AndroidMessageQueue     : private Android::Runnable
 | 
			
		||||
    JUCE_DECLARE_SINGLETON_SINGLETHREADED (AndroidMessageQueue, true)
 | 
			
		||||
 | 
			
		||||
    AndroidMessageQueue()
 | 
			
		||||
        : self (CreateJavaInterface (this, "java/lang/Runnable").get())
 | 
			
		||||
        : self (CreateJavaInterface (this, "java/lang/Runnable"))
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ~AndroidMessageQueue()
 | 
			
		||||
    {
 | 
			
		||||
        jassert (MessageManager::getInstance()->isThisTheMessageThread());
 | 
			
		||||
        JUCE_ASSERT_MESSAGE_THREAD
 | 
			
		||||
        clearSingletonInstance();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool post (MessageManager::MessageBase::Ptr&& message)
 | 
			
		||||
    {
 | 
			
		||||
        queue.add (static_cast<MessageManager::MessageBase::Ptr&& > (message));
 | 
			
		||||
        queue.add (std::move (message));
 | 
			
		||||
 | 
			
		||||
        // this will call us on the message thread
 | 
			
		||||
        return handler.post (self.get());
 | 
			
		||||
@ -94,7 +94,7 @@ private:
 | 
			
		||||
 | 
			
		||||
    void run() override
 | 
			
		||||
    {
 | 
			
		||||
        while (true)
 | 
			
		||||
        for (;;)
 | 
			
		||||
        {
 | 
			
		||||
            MessageManager::MessageBase::Ptr message (queue.removeAndReturn (0));
 | 
			
		||||
 | 
			
		||||
@ -131,6 +131,7 @@ bool MessageManager::postMessageToSystemQueue (MessageManager::MessageBase* cons
 | 
			
		||||
{
 | 
			
		||||
    return AndroidMessageQueue::getInstance()->post (message);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//==============================================================================
 | 
			
		||||
void MessageManager::broadcastMessage (const String&)
 | 
			
		||||
{
 | 
			
		||||
@ -149,18 +150,26 @@ void MessageManager::stopDispatchLoop()
 | 
			
		||||
        void messageCallback() override
 | 
			
		||||
        {
 | 
			
		||||
            auto* env = getEnv();
 | 
			
		||||
            LocalRef<jobject> activity (getCurrentActivity());
 | 
			
		||||
 | 
			
		||||
            jmethodID quitMethod = env->GetMethodID (JuceAppActivity, "finishAndRemoveTask", "()V");
 | 
			
		||||
 | 
			
		||||
            if (quitMethod != 0)
 | 
			
		||||
            if (activity != nullptr)
 | 
			
		||||
            {
 | 
			
		||||
                env->CallVoidMethod (android.activity, quitMethod);
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
                jmethodID quitMethod = env->GetMethodID (AndroidActivity, "finishAndRemoveTask", "()V");
 | 
			
		||||
 | 
			
		||||
            quitMethod = env->GetMethodID (JuceAppActivity, "finish", "()V");
 | 
			
		||||
            jassert (quitMethod != 0);
 | 
			
		||||
            env->CallVoidMethod (android.activity, quitMethod);
 | 
			
		||||
                if (quitMethod != 0)
 | 
			
		||||
                {
 | 
			
		||||
                    env->CallVoidMethod (activity.get(), quitMethod);
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                quitMethod = env->GetMethodID (AndroidActivity, "finish", "()V");
 | 
			
		||||
                jassert (quitMethod != 0);
 | 
			
		||||
                env->CallVoidMethod (activity.get(), quitMethod);
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                jassertfalse;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
@ -168,4 +177,134 @@ void MessageManager::stopDispatchLoop()
 | 
			
		||||
    quitMessagePosted = true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//==============================================================================
 | 
			
		||||
class JuceAppLifecycle   : public ActivityLifecycleCallbacks
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    JuceAppLifecycle (juce::JUCEApplicationBase* (*initSymbolAddr)())
 | 
			
		||||
        : createApplicationSymbol (initSymbolAddr)
 | 
			
		||||
    {
 | 
			
		||||
        LocalRef<jobject> appContext (getAppContext());
 | 
			
		||||
 | 
			
		||||
        if (appContext != nullptr)
 | 
			
		||||
        {
 | 
			
		||||
            auto* env = getEnv();
 | 
			
		||||
 | 
			
		||||
            myself = GlobalRef (CreateJavaInterface (this, "android/app/Application$ActivityLifecycleCallbacks"));
 | 
			
		||||
            env->CallVoidMethod (appContext.get(), AndroidApplication.registerActivityLifecycleCallbacks, myself.get());
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ~JuceAppLifecycle()
 | 
			
		||||
    {
 | 
			
		||||
        LocalRef<jobject> appContext (getAppContext());
 | 
			
		||||
 | 
			
		||||
        if (appContext != nullptr && myself != nullptr)
 | 
			
		||||
        {
 | 
			
		||||
            auto* env = getEnv();
 | 
			
		||||
 | 
			
		||||
            clear();
 | 
			
		||||
            env->CallVoidMethod (appContext.get(), AndroidApplication.unregisterActivityLifecycleCallbacks, myself.get());
 | 
			
		||||
            myself.clear();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void onActivityCreated (jobject, jobject) override
 | 
			
		||||
    {
 | 
			
		||||
        checkCreated();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void onActivityDestroyed (jobject activity) override
 | 
			
		||||
    {
 | 
			
		||||
        auto* env = getEnv();
 | 
			
		||||
 | 
			
		||||
        // if the main activity is being destroyed, only then tear-down JUCE
 | 
			
		||||
        if (env->IsSameObject (getMainActivity().get(), activity) != 0)
 | 
			
		||||
        {
 | 
			
		||||
            JUCEApplicationBase::appWillTerminateByForce();
 | 
			
		||||
            JNIClassBase::releaseAllClasses (env);
 | 
			
		||||
 | 
			
		||||
            jclass systemClass = (jclass) env->FindClass ("java/lang/System");
 | 
			
		||||
            jmethodID exitMethod = env->GetStaticMethodID (systemClass, "exit", "(I)V");
 | 
			
		||||
            env->CallStaticVoidMethod (systemClass, exitMethod, 0);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void onActivityStarted (jobject) override
 | 
			
		||||
    {
 | 
			
		||||
        checkCreated();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void onActivityPaused (jobject) override
 | 
			
		||||
    {
 | 
			
		||||
        if (auto* app = JUCEApplicationBase::getInstance())
 | 
			
		||||
            app->suspended();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void onActivityResumed (jobject) override
 | 
			
		||||
    {
 | 
			
		||||
        checkInitialised();
 | 
			
		||||
 | 
			
		||||
        if (auto* app = JUCEApplicationBase::getInstance())
 | 
			
		||||
            app->resumed();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static JuceAppLifecycle& getInstance (juce::JUCEApplicationBase* (*initSymbolAddr)())
 | 
			
		||||
    {
 | 
			
		||||
        static JuceAppLifecycle juceAppLifecycle (initSymbolAddr);
 | 
			
		||||
        return juceAppLifecycle;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    void checkCreated()
 | 
			
		||||
    {
 | 
			
		||||
        if (JUCEApplicationBase::getInstance() == nullptr)
 | 
			
		||||
        {
 | 
			
		||||
            DBG (SystemStats::getJUCEVersion());
 | 
			
		||||
 | 
			
		||||
            JUCEApplicationBase::createInstance = createApplicationSymbol;
 | 
			
		||||
 | 
			
		||||
            initialiseJuce_GUI();
 | 
			
		||||
 | 
			
		||||
            if (! JUCEApplicationBase::createInstance())
 | 
			
		||||
                jassertfalse; // you must supply an application object for an android app!
 | 
			
		||||
 | 
			
		||||
            jassert (MessageManager::getInstance()->isThisTheMessageThread());
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void checkInitialised()
 | 
			
		||||
    {
 | 
			
		||||
        checkCreated();
 | 
			
		||||
 | 
			
		||||
        if (! hasBeenInitialised)
 | 
			
		||||
        {
 | 
			
		||||
            if (auto* app = JUCEApplicationBase::getInstance())
 | 
			
		||||
            {
 | 
			
		||||
                hasBeenInitialised = app->initialiseApp();
 | 
			
		||||
 | 
			
		||||
                if (! hasBeenInitialised)
 | 
			
		||||
                    exit (app->shutdownApp());
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    GlobalRef myself;
 | 
			
		||||
    juce::JUCEApplicationBase* (*createApplicationSymbol)();
 | 
			
		||||
    bool hasBeenInitialised = false;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//==============================================================================
 | 
			
		||||
File juce_getExecutableFile();
 | 
			
		||||
 | 
			
		||||
void juce_juceEventsAndroidStartApp()
 | 
			
		||||
{
 | 
			
		||||
    auto dllPath = juce_getExecutableFile().getFullPathName();
 | 
			
		||||
    auto addr = reinterpret_cast<juce::JUCEApplicationBase*(*)()> (DynamicLibrary (dllPath)
 | 
			
		||||
                                                                    .getFunction ("juce_CreateApplication"));
 | 
			
		||||
 | 
			
		||||
    if (addr != nullptr)
 | 
			
		||||
        JuceAppLifecycle::getInstance (addr);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
} // namespace juce
 | 
			
		||||
 | 
			
		||||
@ -23,13 +23,13 @@
 | 
			
		||||
namespace juce
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
typedef void (*AppFocusChangeCallback)();
 | 
			
		||||
using AppFocusChangeCallback = void (*)();
 | 
			
		||||
AppFocusChangeCallback appFocusChangeCallback = nullptr;
 | 
			
		||||
 | 
			
		||||
typedef bool (*CheckEventBlockedByModalComps) (NSEvent*);
 | 
			
		||||
using CheckEventBlockedByModalComps = bool (*)(NSEvent*);
 | 
			
		||||
CheckEventBlockedByModalComps isEventBlockedByModalComps = nullptr;
 | 
			
		||||
 | 
			
		||||
typedef void (*MenuTrackingChangedCallback)(bool);
 | 
			
		||||
using MenuTrackingChangedCallback = void (*)(bool);
 | 
			
		||||
MenuTrackingChangedCallback menuTrackingChangedCallback = nullptr;
 | 
			
		||||
 | 
			
		||||
//==============================================================================
 | 
			
		||||
@ -235,8 +235,10 @@ private:
 | 
			
		||||
        static String quotedIfContainsSpaces (NSString* file)
 | 
			
		||||
        {
 | 
			
		||||
            String s (nsStringToJuce (file));
 | 
			
		||||
            s = s.unquoted().replace ("\"", "\\\"");
 | 
			
		||||
 | 
			
		||||
            if (s.containsChar (' '))
 | 
			
		||||
                s = s.quoted ('"');
 | 
			
		||||
                s = s.quoted();
 | 
			
		||||
 | 
			
		||||
            return s;
 | 
			
		||||
        }
 | 
			
		||||
@ -381,7 +383,7 @@ bool MessageManager::runDispatchLoopUntil (int millisecondsToRunFor)
 | 
			
		||||
    jassert (millisecondsToRunFor >= 0);
 | 
			
		||||
    jassert (isThisTheMessageThread()); // must only be called by the message thread
 | 
			
		||||
 | 
			
		||||
    uint32 endTime = Time::getMillisecondCounter() + (uint32) millisecondsToRunFor;
 | 
			
		||||
    auto endTime = Time::currentTimeMillis() + millisecondsToRunFor;
 | 
			
		||||
 | 
			
		||||
    while (quitMessagePosted.get() == 0)
 | 
			
		||||
    {
 | 
			
		||||
@ -397,7 +399,7 @@ bool MessageManager::runDispatchLoopUntil (int millisecondsToRunFor)
 | 
			
		||||
            if (e != nil && (isEventBlockedByModalComps == nullptr || ! (*isEventBlockedByModalComps) (e)))
 | 
			
		||||
                [NSApp sendEvent: e];
 | 
			
		||||
 | 
			
		||||
            if (Time::getMillisecondCounter() >= endTime)
 | 
			
		||||
            if (Time::currentTimeMillis() >= endTime)
 | 
			
		||||
                break;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
@ -454,7 +456,7 @@ void __attribute__ ((visibility("default"))) repostCurrentNSEvent()
 | 
			
		||||
    struct EventReposter  : public CallbackMessage
 | 
			
		||||
    {
 | 
			
		||||
        EventReposter() : e ([[NSApp currentEvent] retain])  {}
 | 
			
		||||
        ~EventReposter()  { [e release]; }
 | 
			
		||||
        ~EventReposter() override  { [e release]; }
 | 
			
		||||
 | 
			
		||||
        void messageCallback() override
 | 
			
		||||
        {
 | 
			
		||||
 | 
			
		||||
@ -25,12 +25,16 @@ namespace juce
 | 
			
		||||
 | 
			
		||||
extern HWND juce_messageWindowHandle;
 | 
			
		||||
 | 
			
		||||
typedef bool (*CheckEventBlockedByModalComps) (const MSG&);
 | 
			
		||||
using CheckEventBlockedByModalComps = bool (*)(const MSG&);
 | 
			
		||||
CheckEventBlockedByModalComps isEventBlockedByModalComps = nullptr;
 | 
			
		||||
 | 
			
		||||
typedef void (*SettingChangeCallbackFunc) (void);
 | 
			
		||||
using SettingChangeCallbackFunc = void (*)(void);
 | 
			
		||||
SettingChangeCallbackFunc settingChangeCallback = nullptr;
 | 
			
		||||
 | 
			
		||||
#if JUCE_MODULE_AVAILABLE_juce_audio_plugin_client && JucePlugin_Build_Unity
 | 
			
		||||
 bool juce_isRunningInUnity();
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
//==============================================================================
 | 
			
		||||
namespace WindowsMessageHelpers
 | 
			
		||||
{
 | 
			
		||||
@ -42,7 +46,7 @@ namespace WindowsMessageHelpers
 | 
			
		||||
 | 
			
		||||
    void dispatchMessageFromLParam (LPARAM lParam)
 | 
			
		||||
    {
 | 
			
		||||
        if (MessageManager::MessageBase* message = reinterpret_cast<MessageManager::MessageBase*> (lParam))
 | 
			
		||||
        if (auto message = reinterpret_cast<MessageManager::MessageBase*> (lParam))
 | 
			
		||||
        {
 | 
			
		||||
            JUCE_TRY
 | 
			
		||||
            {
 | 
			
		||||
@ -68,7 +72,7 @@ namespace WindowsMessageHelpers
 | 
			
		||||
        return TRUE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void handleBroadcastMessage (const COPYDATASTRUCT* const data)
 | 
			
		||||
    void handleBroadcastMessage (const COPYDATASTRUCT* data)
 | 
			
		||||
    {
 | 
			
		||||
        if (data != nullptr && data->dwData == broadcastMessageMagicNumber)
 | 
			
		||||
        {
 | 
			
		||||
@ -87,7 +91,7 @@ namespace WindowsMessageHelpers
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    LRESULT CALLBACK messageWndProc (HWND h, const UINT message, const WPARAM wParam, const LPARAM lParam) noexcept
 | 
			
		||||
    LRESULT CALLBACK messageWndProc (HWND h, UINT message, WPARAM wParam, LPARAM lParam) noexcept
 | 
			
		||||
    {
 | 
			
		||||
        if (h == juce_messageWindowHandle)
 | 
			
		||||
        {
 | 
			
		||||
@ -104,11 +108,10 @@ namespace WindowsMessageHelpers
 | 
			
		||||
                handleBroadcastMessage (reinterpret_cast<const COPYDATASTRUCT*> (lParam));
 | 
			
		||||
                return 0;
 | 
			
		||||
            }
 | 
			
		||||
            else if (message == WM_SETTINGCHANGE)
 | 
			
		||||
            {
 | 
			
		||||
 | 
			
		||||
            if (message == WM_SETTINGCHANGE)
 | 
			
		||||
                if (settingChangeCallback != nullptr)
 | 
			
		||||
                    settingChangeCallback();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return DefWindowProc (h, message, wParam, lParam);
 | 
			
		||||
@ -120,7 +123,7 @@ LRESULT juce_offerEventToActiveXControl (::MSG&);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
//==============================================================================
 | 
			
		||||
bool MessageManager::dispatchNextMessageOnSystemQueue (const bool returnIfNoPendingMessages)
 | 
			
		||||
bool MessageManager::dispatchNextMessageOnSystemQueue (bool returnIfNoPendingMessages)
 | 
			
		||||
{
 | 
			
		||||
    using namespace WindowsMessageHelpers;
 | 
			
		||||
    MSG m;
 | 
			
		||||
@ -130,10 +133,10 @@ bool MessageManager::dispatchNextMessageOnSystemQueue (const bool returnIfNoPend
 | 
			
		||||
 | 
			
		||||
    if (GetMessage (&m, (HWND) 0, 0, 0) >= 0)
 | 
			
		||||
    {
 | 
			
		||||
      #if JUCE_MODULE_AVAILABLE_juce_gui_extra
 | 
			
		||||
       #if JUCE_MODULE_AVAILABLE_juce_gui_extra
 | 
			
		||||
        if (juce_offerEventToActiveXControl (m) != S_FALSE)
 | 
			
		||||
            return true;
 | 
			
		||||
      #endif
 | 
			
		||||
       #endif
 | 
			
		||||
 | 
			
		||||
        if (m.message == customMessageID && m.hwnd == juce_messageWindowHandle)
 | 
			
		||||
        {
 | 
			
		||||
@ -151,7 +154,7 @@ bool MessageManager::dispatchNextMessageOnSystemQueue (const bool returnIfNoPend
 | 
			
		||||
            {
 | 
			
		||||
                // if it's someone else's window being clicked on, and the focus is
 | 
			
		||||
                // currently on a juce window, pass the kb focus over..
 | 
			
		||||
                HWND currentFocus = GetFocus();
 | 
			
		||||
                auto currentFocus = GetFocus();
 | 
			
		||||
 | 
			
		||||
                if (currentFocus == 0 || JuceWindowIdentifier::isJUCEWindow (currentFocus))
 | 
			
		||||
                    SetFocus (m.hwnd);
 | 
			
		||||
@ -168,12 +171,18 @@ bool MessageManager::dispatchNextMessageOnSystemQueue (const bool returnIfNoPend
 | 
			
		||||
bool MessageManager::postMessageToSystemQueue (MessageManager::MessageBase* const message)
 | 
			
		||||
{
 | 
			
		||||
    message->incReferenceCount();
 | 
			
		||||
 | 
			
		||||
   #if JUCE_MODULE_AVAILABLE_juce_audio_plugin_client && JucePlugin_Build_Unity
 | 
			
		||||
    if (juce_isRunningInUnity())
 | 
			
		||||
        return SendNotifyMessage (juce_messageWindowHandle, WindowsMessageHelpers::customMessageID, 0, (LPARAM) message) != 0;
 | 
			
		||||
   #endif
 | 
			
		||||
 | 
			
		||||
    return PostMessage (juce_messageWindowHandle, WindowsMessageHelpers::customMessageID, 0, (LPARAM) message) != 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void MessageManager::broadcastMessage (const String& value)
 | 
			
		||||
{
 | 
			
		||||
    const String localCopy (value);
 | 
			
		||||
    auto localCopy = value;
 | 
			
		||||
 | 
			
		||||
    Array<HWND> windows;
 | 
			
		||||
    EnumWindows (&WindowsMessageHelpers::broadcastEnumWindowProc, (LPARAM) &windows);
 | 
			
		||||
 | 
			
		||||
@ -22,5 +22,60 @@
 | 
			
		||||
 | 
			
		||||
namespace juce
 | 
			
		||||
{
 | 
			
		||||
    JUCE_IMPLEMENT_SINGLETON (WinRTWrapper)
 | 
			
		||||
 | 
			
		||||
WinRTWrapper::ScopedHString::ScopedHString (String str)
 | 
			
		||||
{
 | 
			
		||||
    if (WinRTWrapper::getInstance()->isInitialised())
 | 
			
		||||
        WinRTWrapper::getInstance()->createHString (str.toWideCharPointer(),
 | 
			
		||||
                                                    static_cast<uint32_t> (str.length()),
 | 
			
		||||
                                                    &hstr);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
WinRTWrapper::ScopedHString::~ScopedHString()
 | 
			
		||||
{
 | 
			
		||||
    if (WinRTWrapper::getInstance()->isInitialised() && hstr != nullptr)
 | 
			
		||||
        WinRTWrapper::getInstance()->deleteHString (hstr);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
WinRTWrapper::~WinRTWrapper()
 | 
			
		||||
{
 | 
			
		||||
    if (winRTHandle != nullptr)
 | 
			
		||||
        ::FreeLibrary (winRTHandle);
 | 
			
		||||
 | 
			
		||||
    clearSingletonInstance();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
String WinRTWrapper::hStringToString (HSTRING hstr)
 | 
			
		||||
{
 | 
			
		||||
    if (isInitialised())
 | 
			
		||||
        if (const wchar_t* str = getHStringRawBuffer (hstr, nullptr))
 | 
			
		||||
            return String (str);
 | 
			
		||||
 | 
			
		||||
    return {};
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
WinRTWrapper::WinRTWrapper()
 | 
			
		||||
{
 | 
			
		||||
    winRTHandle = ::LoadLibraryA ("api-ms-win-core-winrt-l1-1-0");
 | 
			
		||||
 | 
			
		||||
    if (winRTHandle == nullptr)
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
    roInitialize           = (RoInitializeFuncPtr)              ::GetProcAddress (winRTHandle, "RoInitialize");
 | 
			
		||||
    createHString          = (WindowsCreateStringFuncPtr)       ::GetProcAddress (winRTHandle, "WindowsCreateString");
 | 
			
		||||
    deleteHString          = (WindowsDeleteStringFuncPtr)       ::GetProcAddress (winRTHandle, "WindowsDeleteString");
 | 
			
		||||
    getHStringRawBuffer    = (WindowsGetStringRawBufferFuncPtr) ::GetProcAddress (winRTHandle, "WindowsGetStringRawBuffer");
 | 
			
		||||
    roActivateInstance     = (RoActivateInstanceFuncPtr)        ::GetProcAddress (winRTHandle, "RoActivateInstance");
 | 
			
		||||
    roGetActivationFactory = (RoGetActivationFactoryFuncPtr)    ::GetProcAddress (winRTHandle, "RoGetActivationFactory");
 | 
			
		||||
 | 
			
		||||
    if (roInitialize == nullptr || createHString == nullptr || deleteHString == nullptr
 | 
			
		||||
        || getHStringRawBuffer == nullptr || roActivateInstance == nullptr || roGetActivationFactory == nullptr)
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
    HRESULT status = roInitialize (1);
 | 
			
		||||
    initialised = ! (status != S_OK && status != S_FALSE && status != 0x80010106L);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
JUCE_IMPLEMENT_SINGLETON (WinRTWrapper)
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -26,29 +26,14 @@ namespace juce
 | 
			
		||||
class WinRTWrapper :   public DeletedAtShutdown
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    JUCE_DECLARE_SINGLETON (WinRTWrapper, true)
 | 
			
		||||
 | 
			
		||||
    class ScopedHString
 | 
			
		||||
    {
 | 
			
		||||
    public:
 | 
			
		||||
        ScopedHString (String str)
 | 
			
		||||
        {
 | 
			
		||||
            if (WinRTWrapper::getInstance()->isInitialised())
 | 
			
		||||
                WinRTWrapper::getInstance()->createHString (str.toWideCharPointer(),
 | 
			
		||||
                                                            static_cast<uint32_t> (str.length()),
 | 
			
		||||
                                                            &hstr);
 | 
			
		||||
        }
 | 
			
		||||
        ScopedHString (String);
 | 
			
		||||
 | 
			
		||||
        ~ScopedHString()
 | 
			
		||||
        {
 | 
			
		||||
            if (WinRTWrapper::getInstance()->isInitialised() && hstr != nullptr)
 | 
			
		||||
                WinRTWrapper::getInstance()->deleteHString (hstr);
 | 
			
		||||
        }
 | 
			
		||||
        ~ScopedHString();
 | 
			
		||||
 | 
			
		||||
        HSTRING get() const noexcept
 | 
			
		||||
        {
 | 
			
		||||
            return hstr;
 | 
			
		||||
        }
 | 
			
		||||
        HSTRING get() const noexcept          { return hstr; }
 | 
			
		||||
 | 
			
		||||
    private:
 | 
			
		||||
        HSTRING hstr = nullptr;
 | 
			
		||||
@ -56,36 +41,81 @@ public:
 | 
			
		||||
        JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ScopedHString)
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    ~WinRTWrapper()
 | 
			
		||||
    template <class ComClass>
 | 
			
		||||
    class ComPtr
 | 
			
		||||
    {
 | 
			
		||||
        if (winRTHandle != nullptr)
 | 
			
		||||
            ::FreeLibrary (winRTHandle);
 | 
			
		||||
    public:
 | 
			
		||||
        ComPtr() noexcept {}
 | 
			
		||||
        ComPtr (ComClass* obj) : p (obj) { if (p) p->AddRef(); }
 | 
			
		||||
        ComPtr (const ComPtr& other) : p (other.p) { if (p) p->AddRef(); }
 | 
			
		||||
        ~ComPtr() { release(); }
 | 
			
		||||
 | 
			
		||||
        clearSingletonInstance();
 | 
			
		||||
    }
 | 
			
		||||
        operator ComClass*()   const noexcept { return p; }
 | 
			
		||||
        ComClass& operator*()  const noexcept { return *p; }
 | 
			
		||||
        ComClass* operator->() const noexcept { return p; }
 | 
			
		||||
 | 
			
		||||
    String hStringToString (HSTRING hstr)
 | 
			
		||||
        ComPtr& operator= (ComClass* const newP)
 | 
			
		||||
        {
 | 
			
		||||
            if (newP != nullptr)
 | 
			
		||||
                newP->AddRef();
 | 
			
		||||
 | 
			
		||||
            release();
 | 
			
		||||
            p = newP;
 | 
			
		||||
            return *this;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        ComPtr& operator= (const ComPtr& newP) { return operator= (newP.p); }
 | 
			
		||||
 | 
			
		||||
        ComClass** resetAndGetPointerAddress()
 | 
			
		||||
        {
 | 
			
		||||
            release();
 | 
			
		||||
            p = nullptr;
 | 
			
		||||
            return &p;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    private:
 | 
			
		||||
        ComClass* p = nullptr;
 | 
			
		||||
 | 
			
		||||
        void release() { if (p != nullptr) p->Release(); }
 | 
			
		||||
 | 
			
		||||
        ComClass** operator&() noexcept; // private to avoid it being used accidentally
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    JUCE_DECLARE_SINGLETON (WinRTWrapper, true)
 | 
			
		||||
 | 
			
		||||
    ~WinRTWrapper();
 | 
			
		||||
 | 
			
		||||
    String hStringToString (HSTRING);
 | 
			
		||||
 | 
			
		||||
    bool isInitialised() const noexcept       { return initialised; }
 | 
			
		||||
 | 
			
		||||
    template <class ComClass>
 | 
			
		||||
    ComPtr<ComClass> activateInstance (const wchar_t* runtimeClassID, REFCLSID classUUID)
 | 
			
		||||
    {
 | 
			
		||||
        ComPtr<ComClass> result;
 | 
			
		||||
 | 
			
		||||
        if (isInitialised())
 | 
			
		||||
            if (const wchar_t* str = getHStringRawBuffer (hstr, nullptr))
 | 
			
		||||
                return String (str);
 | 
			
		||||
        {
 | 
			
		||||
            ComPtr<IInspectable> inspectable;
 | 
			
		||||
            ScopedHString runtimeClass (runtimeClassID);
 | 
			
		||||
            auto hr = roActivateInstance (runtimeClass.get(), inspectable.resetAndGetPointerAddress());
 | 
			
		||||
 | 
			
		||||
        return {};
 | 
			
		||||
    }
 | 
			
		||||
            if (SUCCEEDED (hr))
 | 
			
		||||
                inspectable->QueryInterface (classUUID, (void**) result.resetAndGetPointerAddress());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    bool isInitialised() const noexcept
 | 
			
		||||
    {
 | 
			
		||||
        return initialised;
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template <class ComClass>
 | 
			
		||||
    ComSmartPtr<ComClass> getWRLFactory (const wchar_t* runtimeClassID)
 | 
			
		||||
    ComPtr<ComClass> getWRLFactory (const wchar_t* runtimeClassID)
 | 
			
		||||
    {
 | 
			
		||||
        ComSmartPtr<ComClass> comPtr;
 | 
			
		||||
        ComPtr<ComClass> comPtr;
 | 
			
		||||
 | 
			
		||||
        if (isInitialised())
 | 
			
		||||
        {
 | 
			
		||||
            ScopedHString classID (runtimeClassID);
 | 
			
		||||
 | 
			
		||||
            if (classID.get() != nullptr)
 | 
			
		||||
                roGetActivationFactory (classID.get(), __uuidof (ComClass), (void**) comPtr.resetAndGetPointerAddress());
 | 
			
		||||
        }
 | 
			
		||||
@ -94,25 +124,7 @@ public:
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    WinRTWrapper()
 | 
			
		||||
    {
 | 
			
		||||
        winRTHandle = ::LoadLibraryA ("api-ms-win-core-winrt-l1-1-0");
 | 
			
		||||
        if (winRTHandle == nullptr)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        roInitialize           = (RoInitializeFuncPtr)              ::GetProcAddress (winRTHandle, "RoInitialize");
 | 
			
		||||
        createHString          = (WindowsCreateStringFuncPtr)       ::GetProcAddress (winRTHandle, "WindowsCreateString");
 | 
			
		||||
        deleteHString          = (WindowsDeleteStringFuncPtr)       ::GetProcAddress (winRTHandle, "WindowsDeleteString");
 | 
			
		||||
        getHStringRawBuffer    = (WindowsGetStringRawBufferFuncPtr) ::GetProcAddress (winRTHandle, "WindowsGetStringRawBuffer");
 | 
			
		||||
        roGetActivationFactory = (RoGetActivationFactoryFuncPtr)    ::GetProcAddress (winRTHandle, "RoGetActivationFactory");
 | 
			
		||||
 | 
			
		||||
        if (roInitialize == nullptr || createHString == nullptr || deleteHString == nullptr
 | 
			
		||||
         || getHStringRawBuffer == nullptr || roGetActivationFactory == nullptr)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        HRESULT status = roInitialize (1);
 | 
			
		||||
        initialised = ! (status != S_OK && status != S_FALSE && status != 0x80010106L);
 | 
			
		||||
    }
 | 
			
		||||
    WinRTWrapper();
 | 
			
		||||
 | 
			
		||||
    HMODULE winRTHandle = nullptr;
 | 
			
		||||
    bool initialised = false;
 | 
			
		||||
@ -121,12 +133,14 @@ private:
 | 
			
		||||
    typedef HRESULT (WINAPI* WindowsCreateStringFuncPtr) (LPCWSTR, UINT32, HSTRING*);
 | 
			
		||||
    typedef HRESULT (WINAPI* WindowsDeleteStringFuncPtr) (HSTRING);
 | 
			
		||||
    typedef PCWSTR  (WINAPI* WindowsGetStringRawBufferFuncPtr) (HSTRING, UINT32*);
 | 
			
		||||
    typedef HRESULT (WINAPI* RoActivateInstanceFuncPtr) (HSTRING, IInspectable**);
 | 
			
		||||
    typedef HRESULT (WINAPI* RoGetActivationFactoryFuncPtr) (HSTRING, REFIID, void**);
 | 
			
		||||
 | 
			
		||||
    RoInitializeFuncPtr roInitialize = nullptr;
 | 
			
		||||
    WindowsCreateStringFuncPtr createHString = nullptr;
 | 
			
		||||
    WindowsDeleteStringFuncPtr deleteHString = nullptr;
 | 
			
		||||
    WindowsGetStringRawBufferFuncPtr getHStringRawBuffer = nullptr;
 | 
			
		||||
    RoActivateInstanceFuncPtr roActivateInstance = nullptr;
 | 
			
		||||
    RoGetActivationFactoryFuncPtr roGetActivationFactory = nullptr;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user