blob: 11f0551d8f2049184d45e518047280a069636734 [file] [log] [blame]
//
// Copyright (c) 2015 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// WinRTWindow.cpp: Implementation of OSWindow for WinRT (Windows)
#include "windows/winrt/WinRTWindow.h"
#include <windows.applicationmodel.core.h>
#include <windows.ui.xaml.h>
#include <wrl.h>
#include "angle_windowsstore.h"
#include "common/debug.h"
using namespace ABI::Windows::ApplicationModel::Core;
using namespace ABI::Windows::Foundation;
using namespace ABI::Windows::Foundation::Collections;
using namespace ABI::Windows::UI::Core;
using namespace Microsoft::WRL;
using namespace Microsoft::WRL::Wrappers;
WinRTWindow::WinRTWindow() : mNativeWindow(nullptr) {}
WinRTWindow::~WinRTWindow()
{
destroy();
}
bool WinRTWindow::initialize(const std::string &name, size_t width, size_t height)
{
ComPtr<ICoreWindowStatic> coreWindowStatic;
ComPtr<IActivationFactory> propertySetFactory;
ComPtr<IPropertyValueStatics> propertyValueStatics;
ComPtr<ICoreApplication> coreApplication;
ComPtr<IPropertySet> coreApplicationProperties;
ComPtr<IMap<HSTRING, IInspectable *>> coreApplicationPropertiesAsMap;
ComPtr<IMap<HSTRING, IInspectable *>> nativeWindowAsMap;
ComPtr<IInspectable> sizeValue;
HRESULT result = S_OK;
boolean propertyReplaced = false;
destroy();
// Get all the relevant activation factories
result = GetActivationFactory(HStringReference(RuntimeClass_Windows_UI_Core_CoreWindow).Get(),
&coreWindowStatic);
if (FAILED(result))
{
return false;
}
result = GetActivationFactory(
HStringReference(RuntimeClass_Windows_Foundation_Collections_PropertySet).Get(),
&propertySetFactory);
if (FAILED(result))
{
return false;
}
result =
GetActivationFactory(HStringReference(RuntimeClass_Windows_Foundation_PropertyValue).Get(),
&propertyValueStatics);
if (FAILED(result))
{
return false;
}
result = GetActivationFactory(
HStringReference(RuntimeClass_Windows_ApplicationModel_Core_CoreApplication).Get(),
&coreApplication);
if (FAILED(result))
{
return false;
}
// Create a PropertySet to be used as the native window
result = propertySetFactory->ActivateInstance(&mNativeWindow);
if (FAILED(result))
{
return false;
}
// Get the PropertySet as a map, so we can Insert things into it later
ComPtr<IInspectable> tempNativeWindow = mNativeWindow;
result = tempNativeWindow.As(&nativeWindowAsMap);
if (FAILED(result))
{
return false;
}
// Get the CoreApplication properties
result = coreApplication->get_Properties(coreApplicationProperties.GetAddressOf());
if (FAILED(result))
{
return false;
}
// Get the CoreApplication properties as a map
result = coreApplicationProperties.As(&coreApplicationPropertiesAsMap);
if (FAILED(result))
{
return false;
}
// See if the application properties contain an EGLNativeWindowTypeProperty
boolean hasEGLNativeWindowTypeProperty;
result = coreApplicationPropertiesAsMap->HasKey(
HStringReference(EGLNativeWindowTypeProperty).Get(), &hasEGLNativeWindowTypeProperty);
if (FAILED(result))
{
return false;
}
// If an EGLNativeWindowTypeProperty is inputted then use it
if (hasEGLNativeWindowTypeProperty)
{
ComPtr<IInspectable> coreApplicationPropertyNativeWindow;
result = coreApplicationPropertiesAsMap->Lookup(
HStringReference(EGLNativeWindowTypeProperty).Get(),
&coreApplicationPropertyNativeWindow);
if (FAILED(result))
{
return false;
}
// See if the inputted window was a CoreWindow
ComPtr<ICoreWindow> applicationPropertyCoreWindow;
if (SUCCEEDED(coreApplicationPropertyNativeWindow.As(&applicationPropertyCoreWindow)))
{
// Store away the CoreWindow's dispatcher, to be used later to process messages
result = applicationPropertyCoreWindow->get_Dispatcher(&mCoreDispatcher);
if (FAILED(result))
{
return false;
}
}
else
{
ComPtr<IPropertySet> propSet;
// Disallow Property Sets here, since we want to wrap this window in
// a property set with the size property below
if (SUCCEEDED(coreApplicationPropertyNativeWindow.As(&propSet)))
{
return false;
}
}
// Add the window to the map
result =
nativeWindowAsMap->Insert(HStringReference(EGLNativeWindowTypeProperty).Get(),
coreApplicationPropertyNativeWindow.Get(), &propertyReplaced);
if (FAILED(result))
{
return false;
}
}
else
{
ComPtr<ICoreWindow> currentThreadCoreWindow;
// Get the CoreWindow for the current thread
result = coreWindowStatic->GetForCurrentThread(&currentThreadCoreWindow);
if (FAILED(result))
{
return false;
}
// By default, just add this thread's CoreWindow to the PropertySet
result = nativeWindowAsMap->Insert(HStringReference(EGLNativeWindowTypeProperty).Get(),
currentThreadCoreWindow.Get(), &propertyReplaced);
if (FAILED(result))
{
return false;
}
// Store away the CoreWindow's dispatcher, to be used later to process messages
result = currentThreadCoreWindow->get_Dispatcher(&mCoreDispatcher);
if (FAILED(result))
{
return false;
}
}
// Create a Size to represent the Native Window's size
Size renderSize;
renderSize.Width = static_cast<float>(width);
renderSize.Height = static_cast<float>(height);
result = propertyValueStatics->CreateSize(renderSize, sizeValue.GetAddressOf());
if (FAILED(result))
{
return false;
}
// Add the Size to the PropertySet
result = nativeWindowAsMap->Insert(HStringReference(EGLRenderSurfaceSizeProperty).Get(),
sizeValue.Get(), &propertyReplaced);
if (FAILED(result))
{
return false;
}
return true;
};
void WinRTWindow::destroy()
{
SafeRelease(mNativeWindow);
mCoreDispatcher.Reset();
}
void WinRTWindow::resetNativeWindow() {}
EGLNativeWindowType WinRTWindow::getNativeWindow() const
{
return mNativeWindow;
}
EGLNativeDisplayType WinRTWindow::getNativeDisplay() const
{
UNIMPLEMENTED();
return static_cast<EGLNativeDisplayType>(0);
}
void WinRTWindow::messageLoop()
{
// If we have a CoreDispatcher then use it to process events
if (mCoreDispatcher)
{
HRESULT result =
mCoreDispatcher->ProcessEvents(CoreProcessEventsOption_ProcessAllIfPresent);
UNUSED_ASSERTION_VARIABLE(result);
ASSERT(SUCCEEDED(result));
}
}
void WinRTWindow::setMousePosition(int /* x */, int /* y */)
{
UNIMPLEMENTED();
}
bool WinRTWindow::setPosition(int /* x */, int /* y */)
{
UNIMPLEMENTED();
return false;
}
bool WinRTWindow::resize(int /* width */, int /* height */)
{
UNIMPLEMENTED();
return false;
}
void WinRTWindow::setVisible(bool isVisible)
{
if (isVisible)
{
// Already visible by default
return;
}
else
{
// Not implemented in WinRT
UNIMPLEMENTED();
}
}
void WinRTWindow::signalTestEvent()
{
UNIMPLEMENTED();
}
OSWindow *OSWindow::New()
{
return new WinRTWindow();
}