mirror of
https://github.com/Relintai/sdl2_frt.git
synced 2025-01-26 12:59:18 +01:00
WinRT: experimental and preliminary support for XAML-based overlays on Windows 8/RT
The XAML support here is still rudimentary. Bugs do exist. You've been warned. XAML support in Windows Phone 8 is not yet available (in SDL/WinRT).
This commit is contained in:
parent
86ea4c4edf
commit
2cafee9de1
@ -70,6 +70,14 @@
|
|||||||
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</CompileAsWinRT>
|
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</CompileAsWinRT>
|
||||||
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</CompileAsWinRT>
|
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</CompileAsWinRT>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\src\core\winrt\SDL_winrtxaml.cpp">
|
||||||
|
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">true</CompileAsWinRT>
|
||||||
|
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">true</CompileAsWinRT>
|
||||||
|
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</CompileAsWinRT>
|
||||||
|
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</CompileAsWinRT>
|
||||||
|
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</CompileAsWinRT>
|
||||||
|
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</CompileAsWinRT>
|
||||||
|
</ClCompile>
|
||||||
<ClCompile Include="..\..\src\cpuinfo\SDL_cpuinfo.c" />
|
<ClCompile Include="..\..\src\cpuinfo\SDL_cpuinfo.c" />
|
||||||
<ClCompile Include="..\..\src\events\SDL_clipboardevents.c" />
|
<ClCompile Include="..\..\src\events\SDL_clipboardevents.c" />
|
||||||
<ClCompile Include="..\..\src\events\SDL_dropevents.c" />
|
<ClCompile Include="..\..\src\events\SDL_dropevents.c" />
|
||||||
|
@ -270,6 +270,9 @@
|
|||||||
<ClCompile Include="..\..\src\joystick\winrt\SDL_xinputjoystick.c">
|
<ClCompile Include="..\..\src\joystick\winrt\SDL_xinputjoystick.c">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\src\core\winrt\SDL_winrtxaml.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="..\..\include\begin_code.h">
|
<ClInclude Include="..\..\include\begin_code.h">
|
||||||
|
@ -155,6 +155,20 @@ extern DECLSPEC const wchar_t * SDLCALL SDL_WinRTGetFSPathUNICODE(SDL_WinRT_Path
|
|||||||
*/
|
*/
|
||||||
extern DECLSPEC const char * SDLCALL SDL_WinRTGetFSPathUTF8(SDL_WinRT_Path pathType);
|
extern DECLSPEC const char * SDLCALL SDL_WinRTGetFSPathUTF8(SDL_WinRT_Path pathType);
|
||||||
|
|
||||||
|
#ifdef __cplusplus_winrt
|
||||||
|
/**
|
||||||
|
* \brief Initializes a WinRT and XAML based application.
|
||||||
|
*
|
||||||
|
* \param backgroundPanel The XAML background panel to draw onto and receive
|
||||||
|
* events from.
|
||||||
|
* \param mainFunction The SDL app's C-style main().
|
||||||
|
* \ret 0 on success, -1 on failure. On failure, use SDL_GetError to retrieve more
|
||||||
|
* information on the failure.
|
||||||
|
*/
|
||||||
|
/* TODO, WinRT: consider making SDL_WinRTInitXAMLApp accept a void pointer to IUnknown, rather than a C++/CX reference */
|
||||||
|
extern DECLSPEC int SDLCALL SDL_WinRTInitXAMLApp(Platform::Object^ backgroundPanel, int (*mainFunction)(int, char **));
|
||||||
|
|
||||||
|
#endif // ifdef __cplusplus_winrt
|
||||||
|
|
||||||
#endif /* __WINRT__ */
|
#endif /* __WINRT__ */
|
||||||
|
|
||||||
|
@ -361,17 +361,17 @@ void SDL_WinRTApp::OnWindowClosed(CoreWindow^ sender, CoreWindowEventArgs^ args)
|
|||||||
|
|
||||||
void SDL_WinRTApp::OnPointerPressed(CoreWindow^ sender, PointerEventArgs^ args)
|
void SDL_WinRTApp::OnPointerPressed(CoreWindow^ sender, PointerEventArgs^ args)
|
||||||
{
|
{
|
||||||
WINRT_ProcessPointerPressedEvent(WINRT_GlobalSDLWindow, args);
|
WINRT_ProcessPointerPressedEvent(WINRT_GlobalSDLWindow, args->CurrentPoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SDL_WinRTApp::OnPointerReleased(CoreWindow^ sender, PointerEventArgs^ args)
|
void SDL_WinRTApp::OnPointerReleased(CoreWindow^ sender, PointerEventArgs^ args)
|
||||||
{
|
{
|
||||||
WINRT_ProcessPointerReleasedEvent(WINRT_GlobalSDLWindow, args);
|
WINRT_ProcessPointerReleasedEvent(WINRT_GlobalSDLWindow, args->CurrentPoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SDL_WinRTApp::OnPointerWheelChanged(CoreWindow^ sender, PointerEventArgs^ args)
|
void SDL_WinRTApp::OnPointerWheelChanged(CoreWindow^ sender, PointerEventArgs^ args)
|
||||||
{
|
{
|
||||||
WINRT_ProcessPointerWheelChangedEvent(WINRT_GlobalSDLWindow, args);
|
WINRT_ProcessPointerWheelChangedEvent(WINRT_GlobalSDLWindow, args->CurrentPoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SDL_WinRTApp::OnMouseMoved(MouseDevice^ mouseDevice, MouseEventArgs^ args)
|
void SDL_WinRTApp::OnMouseMoved(MouseDevice^ mouseDevice, MouseEventArgs^ args)
|
||||||
@ -381,7 +381,7 @@ void SDL_WinRTApp::OnMouseMoved(MouseDevice^ mouseDevice, MouseEventArgs^ args)
|
|||||||
|
|
||||||
void SDL_WinRTApp::OnPointerMoved(CoreWindow^ sender, PointerEventArgs^ args)
|
void SDL_WinRTApp::OnPointerMoved(CoreWindow^ sender, PointerEventArgs^ args)
|
||||||
{
|
{
|
||||||
WINRT_ProcessPointerMovedEvent(WINRT_GlobalSDLWindow, args);
|
WINRT_ProcessPointerMovedEvent(WINRT_GlobalSDLWindow, args->CurrentPoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SDL_WinRTApp::OnKeyDown(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::KeyEventArgs^ args)
|
void SDL_WinRTApp::OnKeyDown(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::KeyEventArgs^ args)
|
||||||
|
162
src/core/winrt/SDL_winrtxaml.cpp
Normal file
162
src/core/winrt/SDL_winrtxaml.cpp
Normal file
@ -0,0 +1,162 @@
|
|||||||
|
/*
|
||||||
|
Simple DirectMedia Layer
|
||||||
|
Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
|
||||||
|
|
||||||
|
This software is provided 'as-is', without any express or implied
|
||||||
|
warranty. In no event will the authors be held liable for any damages
|
||||||
|
arising from the use of this software.
|
||||||
|
|
||||||
|
Permission is granted to anyone to use this software for any purpose,
|
||||||
|
including commercial applications, and to alter it and redistribute it
|
||||||
|
freely, subject to the following restrictions:
|
||||||
|
|
||||||
|
1. The origin of this software must not be misrepresented; you must not
|
||||||
|
claim that you wrote the original software. If you use this software
|
||||||
|
in a product, an acknowledgment in the product documentation would be
|
||||||
|
appreciated but is not required.
|
||||||
|
2. Altered source versions must be plainly marked as such, and must not be
|
||||||
|
misrepresented as being the original software.
|
||||||
|
3. This notice may not be removed or altered from any source distribution.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Windows includes */
|
||||||
|
#include <agile.h>
|
||||||
|
#include <Windows.h>
|
||||||
|
|
||||||
|
#if WINAPI_FAMILY == WINAPI_FAMILY_APP
|
||||||
|
#include <windows.ui.xaml.media.dxinterop.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* SDL includes */
|
||||||
|
#include "SDL.h"
|
||||||
|
//#include "SDL_error.h"
|
||||||
|
//#include "SDL_log.h"
|
||||||
|
//#include "SDL_main.h"
|
||||||
|
//#include "SDL_system.h"
|
||||||
|
#include "../../video/winrt/SDL_winrtevents_c.h"
|
||||||
|
|
||||||
|
|
||||||
|
/* External globals: */
|
||||||
|
extern SDL_Window * WINRT_GlobalSDLWindow;
|
||||||
|
|
||||||
|
|
||||||
|
/* Internal globals: */
|
||||||
|
SDL_bool WINRT_XAMLWasEnabled = SDL_FALSE;
|
||||||
|
int (*WINRT_XAMLAppMainFunction)(int, char **) = NULL;
|
||||||
|
|
||||||
|
#if WINAPI_FAMILY == WINAPI_FAMILY_APP
|
||||||
|
ISwapChainBackgroundPanelNative * WINRT_GlobalSwapChainBackgroundPanelNative = NULL;
|
||||||
|
static Windows::Foundation::EventRegistrationToken WINRT_XAMLAppEventToken;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Input event handlers (XAML)
|
||||||
|
*/
|
||||||
|
#if WINAPI_FAMILY == WINAPI_FAMILY_APP
|
||||||
|
|
||||||
|
static void
|
||||||
|
WINRT_OnPointerPressedViaXAML(Platform::Object^ sender, Windows::UI::Xaml::Input::PointerRoutedEventArgs^ args)
|
||||||
|
{
|
||||||
|
WINRT_ProcessPointerPressedEvent(WINRT_GlobalSDLWindow, args->GetCurrentPoint(nullptr));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
WINRT_OnPointerReleasedViaXAML(Platform::Object^ sender, Windows::UI::Xaml::Input::PointerRoutedEventArgs^ args)
|
||||||
|
{
|
||||||
|
WINRT_ProcessPointerReleasedEvent(WINRT_GlobalSDLWindow, args->GetCurrentPoint(nullptr));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
WINRT_OnPointerWheelChangedViaXAML(Platform::Object^ sender, Windows::UI::Xaml::Input::PointerRoutedEventArgs^ args)
|
||||||
|
{
|
||||||
|
WINRT_ProcessPointerWheelChangedEvent(WINRT_GlobalSDLWindow, args->GetCurrentPoint(nullptr));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
WINRT_OnPointerMovedViaXAML(Platform::Object^ sender, Windows::UI::Xaml::Input::PointerRoutedEventArgs^ args)
|
||||||
|
{
|
||||||
|
WINRT_ProcessPointerMovedEvent(WINRT_GlobalSDLWindow, args->GetCurrentPoint(nullptr));
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // WINAPI_FAMILY == WINAPI_FAMILY_APP
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* XAML-to-SDL Rendering Callback
|
||||||
|
*/
|
||||||
|
#if WINAPI_FAMILY == WINAPI_FAMILY_APP
|
||||||
|
|
||||||
|
static void
|
||||||
|
WINRT_OnRenderViaXAML(_In_ Platform::Object^ sender, _In_ Platform::Object^ args)
|
||||||
|
{
|
||||||
|
WINRT_CycleXAMLThread();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // WINAPI_FAMILY == WINAPI_FAMILY_APP
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SDL + XAML Initialization
|
||||||
|
*/
|
||||||
|
|
||||||
|
extern "C" int
|
||||||
|
SDL_WinRTInitXAMLApp(Platform::Object ^backgroundPanel, int (*mainFunction)(int, char **))
|
||||||
|
{
|
||||||
|
#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
|
||||||
|
return SDL_SetError("XAML support is not yet available in Windows Phone.");
|
||||||
|
#else
|
||||||
|
// Declare C++/CX namespaces:
|
||||||
|
using namespace Platform;
|
||||||
|
using namespace Windows::Foundation;
|
||||||
|
using namespace Windows::UI::Core;
|
||||||
|
using namespace Windows::UI::Xaml;
|
||||||
|
using namespace Windows::UI::Xaml::Controls;
|
||||||
|
using namespace Windows::UI::Xaml::Input;
|
||||||
|
using namespace Windows::UI::Xaml::Media;
|
||||||
|
|
||||||
|
// Make sure we have a valid XAML element (to draw onto):
|
||||||
|
if ( ! backgroundPanel) {
|
||||||
|
return SDL_SetError("'backgroundPanel' can't be NULL");
|
||||||
|
}
|
||||||
|
|
||||||
|
SwapChainBackgroundPanel ^swapChainBackgroundPanel = dynamic_cast<SwapChainBackgroundPanel ^>(backgroundPanel);
|
||||||
|
if ( ! swapChainBackgroundPanel) {
|
||||||
|
return SDL_SetError("An unknown or unsupported type of XAML control was specified.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Setup event handlers:
|
||||||
|
swapChainBackgroundPanel->PointerPressed += ref new PointerEventHandler(WINRT_OnPointerPressedViaXAML);
|
||||||
|
swapChainBackgroundPanel->PointerReleased += ref new PointerEventHandler(WINRT_OnPointerReleasedViaXAML);
|
||||||
|
swapChainBackgroundPanel->PointerWheelChanged += ref new PointerEventHandler(WINRT_OnPointerWheelChangedViaXAML);
|
||||||
|
swapChainBackgroundPanel->PointerMoved += ref new PointerEventHandler(WINRT_OnPointerMovedViaXAML);
|
||||||
|
|
||||||
|
// Setup for rendering:
|
||||||
|
IInspectable *panelInspectable = (IInspectable*) reinterpret_cast<IInspectable*>(swapChainBackgroundPanel);
|
||||||
|
panelInspectable->QueryInterface(__uuidof(ISwapChainBackgroundPanelNative), (void **)&WINRT_GlobalSwapChainBackgroundPanelNative);
|
||||||
|
|
||||||
|
WINRT_XAMLAppEventToken = CompositionTarget::Rendering::add(ref new EventHandler<Object^>(WINRT_OnRenderViaXAML));
|
||||||
|
|
||||||
|
// Make sure the app is ready to call the SDL-centric main() function:
|
||||||
|
WINRT_XAMLAppMainFunction = mainFunction;
|
||||||
|
SDL_SetMainReady();
|
||||||
|
|
||||||
|
// Make sure video-init knows that we're initializing XAML:
|
||||||
|
SDL_bool oldXAMLWasEnabledValue = WINRT_XAMLWasEnabled;
|
||||||
|
WINRT_XAMLWasEnabled = SDL_TRUE;
|
||||||
|
|
||||||
|
// Make sure video modes are detected now, while we still have access to the WinRT
|
||||||
|
// CoreWindow. WinRT will not allow the app's CoreWindow to be accessed via the
|
||||||
|
// SDL/WinRT thread.
|
||||||
|
if (SDL_InitSubSystem(SDL_INIT_VIDEO) < 0) {
|
||||||
|
// SDL_InitSubSystem will, on error, set the SDL error. Let that propogate to
|
||||||
|
// the caller to here:
|
||||||
|
WINRT_XAMLWasEnabled = oldXAMLWasEnabledValue;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// All done, for now.
|
||||||
|
return 0;
|
||||||
|
#endif // WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP / else
|
||||||
|
}
|
@ -26,6 +26,11 @@
|
|||||||
#ifdef __WINRT__
|
#ifdef __WINRT__
|
||||||
#include <windows.ui.core.h>
|
#include <windows.ui.core.h>
|
||||||
#include <windows.foundation.h>
|
#include <windows.foundation.h>
|
||||||
|
|
||||||
|
#if WINAPI_FAMILY == WINAPI_FAMILY_APP
|
||||||
|
#include <windows.ui.xaml.media.dxinterop.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@ -608,6 +613,13 @@ D3D11_ConvertDipsToPixels(float dips)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#if WINAPI_FAMILY == WINAPI_FAMILY_APP
|
||||||
|
// TODO, WinRT, XAML: get the ISwapChainBackgroundPanelNative from something other than a global var
|
||||||
|
extern ISwapChainBackgroundPanelNative * WINRT_GlobalSwapChainBackgroundPanelNative;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
// Initialize all resources that change when the window's size changes.
|
// Initialize all resources that change when the window's size changes.
|
||||||
// TODO, WinRT: get D3D11_CreateWindowSizeDependentResources working on Win32
|
// TODO, WinRT: get D3D11_CreateWindowSizeDependentResources working on Win32
|
||||||
HRESULT
|
HRESULT
|
||||||
@ -619,15 +631,28 @@ D3D11_CreateWindowSizeDependentResources(SDL_Renderer * renderer)
|
|||||||
|
|
||||||
// Store the window bounds so the next time we get a SizeChanged event we can
|
// Store the window bounds so the next time we get a SizeChanged event we can
|
||||||
// avoid rebuilding everything if the size is identical.
|
// avoid rebuilding everything if the size is identical.
|
||||||
ABI::Windows::Foundation::Rect coreWindowBounds;
|
ABI::Windows::Foundation::Rect nativeWindowBounds;
|
||||||
result = coreWindow->get_Bounds(&coreWindowBounds);
|
if (coreWindow) {
|
||||||
if (FAILED(result)) {
|
result = coreWindow->get_Bounds(&nativeWindowBounds);
|
||||||
WIN_SetErrorFromHRESULT(__FUNCTION__", Get Window Bounds", result);
|
if (FAILED(result)) {
|
||||||
return result;
|
WIN_SetErrorFromHRESULT(__FUNCTION__", Get Window Bounds", result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// TODO, WinRT, XAML: clean up window-bounds code in D3D11_CreateWindowSizeDependentResources
|
||||||
|
SDL_DisplayMode displayMode;
|
||||||
|
if (SDL_GetDesktopDisplayMode(0, &displayMode) < 0) {
|
||||||
|
SDL_SetError(__FUNCTION__", Get Window Bounds (XAML): Unable to retrieve the native window's size");
|
||||||
|
return E_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
nativeWindowBounds.Width = (FLOAT) displayMode.w;
|
||||||
|
nativeWindowBounds.Height = (FLOAT) displayMode.h;
|
||||||
}
|
}
|
||||||
|
|
||||||
data->windowSizeInDIPs.x = coreWindowBounds.Width;
|
// TODO, WinRT, XAML: see if window/control sizes are in DIPs, or something else. If something else, then adjust renderer size tracking accordingly.
|
||||||
data->windowSizeInDIPs.y = coreWindowBounds.Height;
|
data->windowSizeInDIPs.x = nativeWindowBounds.Width;
|
||||||
|
data->windowSizeInDIPs.y = nativeWindowBounds.Height;
|
||||||
|
|
||||||
// Calculate the necessary swap chain and render target size in pixels.
|
// Calculate the necessary swap chain and render target size in pixels.
|
||||||
float windowWidth = D3D11_ConvertDipsToPixels(data->windowSizeInDIPs.x);
|
float windowWidth = D3D11_ConvertDipsToPixels(data->windowSizeInDIPs.x);
|
||||||
@ -660,6 +685,8 @@ D3D11_CreateWindowSizeDependentResources(SDL_Renderer * renderer)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
const bool usingXAML = (coreWindow == nullptr);
|
||||||
|
|
||||||
// Otherwise, create a new one using the same adapter as the existing Direct3D device.
|
// Otherwise, create a new one using the same adapter as the existing Direct3D device.
|
||||||
DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {0};
|
DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {0};
|
||||||
swapChainDesc.Width = static_cast<UINT>(data->renderTargetSize.x); // Match the size of the window.
|
swapChainDesc.Width = static_cast<UINT>(data->renderTargetSize.x); // Match the size of the window.
|
||||||
@ -674,7 +701,11 @@ D3D11_CreateWindowSizeDependentResources(SDL_Renderer * renderer)
|
|||||||
swapChainDesc.Scaling = DXGI_SCALING_STRETCH; // On phone, only stretch and aspect-ratio stretch scaling are allowed.
|
swapChainDesc.Scaling = DXGI_SCALING_STRETCH; // On phone, only stretch and aspect-ratio stretch scaling are allowed.
|
||||||
swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; // On phone, no swap effects are supported.
|
swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; // On phone, no swap effects are supported.
|
||||||
#else
|
#else
|
||||||
swapChainDesc.Scaling = DXGI_SCALING_NONE;
|
if (usingXAML) {
|
||||||
|
swapChainDesc.Scaling = DXGI_SCALING_STRETCH;
|
||||||
|
} else {
|
||||||
|
swapChainDesc.Scaling = DXGI_SCALING_NONE;
|
||||||
|
}
|
||||||
swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; // All Windows Store apps must use this SwapEffect.
|
swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; // All Windows Store apps must use this SwapEffect.
|
||||||
#endif
|
#endif
|
||||||
swapChainDesc.Flags = 0;
|
swapChainDesc.Flags = 0;
|
||||||
@ -703,25 +734,48 @@ D3D11_CreateWindowSizeDependentResources(SDL_Renderer * renderer)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
IUnknown * coreWindowAsIUnknown = nullptr;
|
if (usingXAML) {
|
||||||
result = coreWindow->QueryInterface(&coreWindowAsIUnknown);
|
result = dxgiFactory->CreateSwapChainForComposition(
|
||||||
if (FAILED(result)) {
|
data->d3dDevice.Get(),
|
||||||
WIN_SetErrorFromHRESULT(__FUNCTION__ ", CoreWindow to IUnknown", result);
|
&swapChainDesc,
|
||||||
return result;
|
nullptr,
|
||||||
}
|
&data->swapChain);
|
||||||
|
if (FAILED(result)) {
|
||||||
|
WIN_SetErrorFromHRESULT(__FUNCTION__ ", CreateSwapChainForComposition", result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
result = dxgiFactory->CreateSwapChainForCoreWindow(
|
#if WINAPI_FAMILY == WINAPI_FAMILY_APP
|
||||||
data->d3dDevice.Get(),
|
result = WINRT_GlobalSwapChainBackgroundPanelNative->SetSwapChain(data->swapChain.Get());
|
||||||
coreWindowAsIUnknown,
|
if (FAILED(result)) {
|
||||||
&swapChainDesc,
|
WIN_SetErrorFromHRESULT(__FUNCTION__ ", ISwapChainBackgroundPanelNative::SetSwapChain", result);
|
||||||
nullptr, // Allow on all displays.
|
return result;
|
||||||
&data->swapChain
|
}
|
||||||
);
|
#else
|
||||||
if (FAILED(result)) {
|
SDL_SetError(__FUNCTION__ ", XAML support is not yet available for Windows Phone");
|
||||||
WIN_SetErrorFromHRESULT(__FUNCTION__, result);
|
return E_FAIL;
|
||||||
return result;
|
#endif
|
||||||
|
} else {
|
||||||
|
IUnknown * coreWindowAsIUnknown = nullptr;
|
||||||
|
result = coreWindow->QueryInterface(&coreWindowAsIUnknown);
|
||||||
|
if (FAILED(result)) {
|
||||||
|
WIN_SetErrorFromHRESULT(__FUNCTION__ ", CoreWindow to IUnknown", result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = dxgiFactory->CreateSwapChainForCoreWindow(
|
||||||
|
data->d3dDevice.Get(),
|
||||||
|
coreWindowAsIUnknown,
|
||||||
|
&swapChainDesc,
|
||||||
|
nullptr, // Allow on all displays.
|
||||||
|
&data->swapChain
|
||||||
|
);
|
||||||
|
if (FAILED(result)) {
|
||||||
|
WIN_SetErrorFromHRESULT(__FUNCTION__, result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure that DXGI does not queue more than one frame at a time. This both reduces latency and
|
// Ensure that DXGI does not queue more than one frame at a time. This both reduces latency and
|
||||||
// ensures that the application will only render after each VSync, minimizing power consumption.
|
// ensures that the application will only render after each VSync, minimizing power consumption.
|
||||||
result = dxgiDevice->SetMaximumFrameLatency(1);
|
result = dxgiDevice->SetMaximumFrameLatency(1);
|
||||||
|
@ -25,23 +25,117 @@
|
|||||||
/* SDL includes */
|
/* SDL includes */
|
||||||
#include "SDL_winrtevents_c.h"
|
#include "SDL_winrtevents_c.h"
|
||||||
#include "../../core/winrt/SDL_winrtapp.h"
|
#include "../../core/winrt/SDL_winrtapp.h"
|
||||||
|
#include "SDL_assert.h"
|
||||||
|
#include "SDL_system.h"
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#include "../SDL_sysvideo.h"
|
#include "../SDL_sysvideo.h"
|
||||||
#include "../../events/SDL_events_c.h"
|
#include "../../events/SDL_events_c.h"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Forward declarations and globals */
|
||||||
extern SDL_WinRTApp ^ SDL_WinRTGlobalApp;
|
extern SDL_WinRTApp ^ SDL_WinRTGlobalApp;
|
||||||
|
extern int (*WINRT_XAMLAppMainFunction)(int, char **);
|
||||||
|
extern void WINRT_YieldXAMLThread();
|
||||||
|
|
||||||
|
|
||||||
/* General event-management function(s) */
|
/* Global event management */
|
||||||
|
|
||||||
void
|
void
|
||||||
WINRT_PumpEvents(_THIS)
|
WINRT_PumpEvents(_THIS)
|
||||||
{
|
{
|
||||||
SDL_WinRTGlobalApp->PumpEvents();
|
if (SDL_WinRTGlobalApp) {
|
||||||
|
SDL_WinRTGlobalApp->PumpEvents();
|
||||||
|
} else if (WINRT_XAMLAppMainFunction) {
|
||||||
|
WINRT_YieldXAMLThread();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* XAML Thread management */
|
||||||
|
|
||||||
|
enum SDL_XAMLAppThreadState
|
||||||
|
{
|
||||||
|
ThreadState_NotLaunched = 0,
|
||||||
|
ThreadState_Running,
|
||||||
|
ThreadState_Yielding
|
||||||
|
};
|
||||||
|
|
||||||
|
static SDL_XAMLAppThreadState _threadState = ThreadState_NotLaunched;
|
||||||
|
static SDL_Thread * _XAMLThread = nullptr;
|
||||||
|
static SDL_mutex * _mutex = nullptr;
|
||||||
|
static SDL_cond * _cond = nullptr;
|
||||||
|
|
||||||
|
static void
|
||||||
|
WINRT_YieldXAMLThread()
|
||||||
|
{
|
||||||
|
SDL_LockMutex(_mutex);
|
||||||
|
SDL_assert(_threadState == ThreadState_Running);
|
||||||
|
_threadState = ThreadState_Yielding;
|
||||||
|
SDL_UnlockMutex(_mutex);
|
||||||
|
|
||||||
|
SDL_CondSignal(_cond);
|
||||||
|
|
||||||
|
SDL_LockMutex(_mutex);
|
||||||
|
while (_threadState != ThreadState_Running) {
|
||||||
|
SDL_CondWait(_cond, _mutex);
|
||||||
|
}
|
||||||
|
SDL_UnlockMutex(_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
WINRT_XAMLThreadMain(void * userdata)
|
||||||
|
{
|
||||||
|
return WINRT_XAMLAppMainFunction(0, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
WINRT_CycleXAMLThread()
|
||||||
|
{
|
||||||
|
switch (_threadState) {
|
||||||
|
case ThreadState_NotLaunched:
|
||||||
|
{
|
||||||
|
_cond = SDL_CreateCond();
|
||||||
|
|
||||||
|
_mutex = SDL_CreateMutex();
|
||||||
|
_threadState = ThreadState_Running;
|
||||||
|
_XAMLThread = SDL_CreateThread(WINRT_XAMLThreadMain, "SDL/XAML App Thread", nullptr);
|
||||||
|
|
||||||
|
SDL_LockMutex(_mutex);
|
||||||
|
while (_threadState != ThreadState_Yielding) {
|
||||||
|
SDL_CondWait(_cond, _mutex);
|
||||||
|
}
|
||||||
|
SDL_UnlockMutex(_mutex);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case ThreadState_Running:
|
||||||
|
{
|
||||||
|
SDL_assert(false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case ThreadState_Yielding:
|
||||||
|
{
|
||||||
|
SDL_LockMutex(_mutex);
|
||||||
|
SDL_assert(_threadState == ThreadState_Yielding);
|
||||||
|
_threadState = ThreadState_Running;
|
||||||
|
SDL_UnlockMutex(_mutex);
|
||||||
|
|
||||||
|
SDL_CondSignal(_cond);
|
||||||
|
|
||||||
|
SDL_LockMutex(_mutex);
|
||||||
|
while (_threadState != ThreadState_Yielding) {
|
||||||
|
SDL_CondWait(_cond, _mutex);
|
||||||
|
}
|
||||||
|
SDL_UnlockMutex(_mutex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif /* SDL_VIDEO_DRIVER_WINRT */
|
#endif /* SDL_VIDEO_DRIVER_WINRT */
|
||||||
|
|
||||||
/* vi: set ts=4 sw=4 expandtab: */
|
/* vi: set ts=4 sw=4 expandtab: */
|
||||||
|
@ -50,10 +50,13 @@ extern void WINRT_ProcessKeyUpEvent(Windows::UI::Core::KeyEventArgs ^args);
|
|||||||
|
|
||||||
/* Pointers (Mice, Touch, etc.) */
|
/* Pointers (Mice, Touch, etc.) */
|
||||||
extern void WINRT_ProcessMouseMovedEvent(SDL_Window * window, Windows::Devices::Input::MouseEventArgs ^args);
|
extern void WINRT_ProcessMouseMovedEvent(SDL_Window * window, Windows::Devices::Input::MouseEventArgs ^args);
|
||||||
extern void WINRT_ProcessPointerMovedEvent(SDL_Window *window, Windows::UI::Core::PointerEventArgs ^args);
|
extern void WINRT_ProcessPointerMovedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint);
|
||||||
extern void WINRT_ProcessPointerWheelChangedEvent(SDL_Window *window, Windows::UI::Core::PointerEventArgs ^args);
|
extern void WINRT_ProcessPointerWheelChangedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint);
|
||||||
extern void WINRT_ProcessPointerReleasedEvent(SDL_Window *window, Windows::UI::Core::PointerEventArgs ^args);
|
extern void WINRT_ProcessPointerReleasedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint);
|
||||||
extern void WINRT_ProcessPointerPressedEvent(SDL_Window *window, Windows::UI::Core::PointerEventArgs ^args);
|
extern void WINRT_ProcessPointerPressedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint);
|
||||||
|
|
||||||
|
/* XAML Thread Management */
|
||||||
|
extern void WINRT_CycleXAMLThread();
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -110,6 +110,11 @@ WINRT_FreeCursor(SDL_Cursor * cursor)
|
|||||||
static int
|
static int
|
||||||
WINRT_ShowCursor(SDL_Cursor * cursor)
|
WINRT_ShowCursor(SDL_Cursor * cursor)
|
||||||
{
|
{
|
||||||
|
// TODO, WinRT, XAML: make WINRT_ShowCursor work when XAML support is enabled.
|
||||||
|
if ( ! CoreWindow::GetForCurrentThread()) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (cursor) {
|
if (cursor) {
|
||||||
CoreCursor ^* theCursor = (CoreCursor ^*) cursor->driverdata;
|
CoreCursor ^* theCursor = (CoreCursor ^*) cursor->driverdata;
|
||||||
CoreWindow::GetForCurrentThread()->PointerCursor = *theCursor;
|
CoreWindow::GetForCurrentThread()->PointerCursor = *theCursor;
|
||||||
@ -334,25 +339,25 @@ WINRT_LogPointerEvent(const char * header, PointerEventArgs ^ args, Windows::Fou
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
WINRT_ProcessPointerMovedEvent(SDL_Window *window, Windows::UI::Core::PointerEventArgs ^args)
|
WINRT_ProcessPointerMovedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint)
|
||||||
{
|
{
|
||||||
#if LOG_POINTER_EVENTS
|
#if LOG_POINTER_EVENTS
|
||||||
WINRT_LogPointerEvent("pointer moved", args, TransformCursor(args->CurrentPoint->Position));
|
WINRT_LogPointerEvent("pointer moved", args, TransformCursor(pointerPoint->Position));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!window || WINRT_UseRelativeMouseMode) {
|
if (!window || WINRT_UseRelativeMouseMode) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Windows::Foundation::Point transformedPoint = TransformCursor(window, args->CurrentPoint->Position);
|
Windows::Foundation::Point transformedPoint = TransformCursor(window, pointerPoint->Position);
|
||||||
SDL_SendMouseMotion(window, 0, 0, (int)transformedPoint.X, (int)transformedPoint.Y);
|
SDL_SendMouseMotion(window, 0, 0, (int)transformedPoint.X, (int)transformedPoint.Y);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
WINRT_ProcessPointerWheelChangedEvent(SDL_Window *window, Windows::UI::Core::PointerEventArgs ^args)
|
WINRT_ProcessPointerWheelChangedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint)
|
||||||
{
|
{
|
||||||
#if LOG_POINTER_EVENTS
|
#if LOG_POINTER_EVENTS
|
||||||
WINRT_LogPointerEvent("wheel changed", args, TransformCursor(args->CurrentPoint->Position));
|
WINRT_LogPointerEvent("wheel changed", args, TransformCursor(pointerPoint->Position));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!window) {
|
if (!window) {
|
||||||
@ -360,11 +365,11 @@ WINRT_ProcessPointerWheelChangedEvent(SDL_Window *window, Windows::UI::Core::Poi
|
|||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: This may need to accumulate deltas up to WHEEL_DELTA
|
// FIXME: This may need to accumulate deltas up to WHEEL_DELTA
|
||||||
short motion = args->CurrentPoint->Properties->MouseWheelDelta / WHEEL_DELTA;
|
short motion = pointerPoint->Properties->MouseWheelDelta / WHEEL_DELTA;
|
||||||
SDL_SendMouseWheel(window, 0, 0, motion);
|
SDL_SendMouseWheel(window, 0, 0, motion);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WINRT_ProcessPointerReleasedEvent(SDL_Window *window, Windows::UI::Core::PointerEventArgs ^args)
|
void WINRT_ProcessPointerReleasedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint)
|
||||||
{
|
{
|
||||||
#if LOG_POINTER_EVENTS
|
#if LOG_POINTER_EVENTS
|
||||||
WINRT_LogPointerEvent("mouse up", args, TransformCursor(args->CurrentPoint->Position));
|
WINRT_LogPointerEvent("mouse up", args, TransformCursor(args->CurrentPoint->Position));
|
||||||
@ -374,13 +379,13 @@ void WINRT_ProcessPointerReleasedEvent(SDL_Window *window, Windows::UI::Core::Po
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Uint8 button = WINRT_GetSDLButtonForPointerPoint(args->CurrentPoint);
|
Uint8 button = WINRT_GetSDLButtonForPointerPoint(pointerPoint);
|
||||||
if (button) {
|
if (button) {
|
||||||
SDL_SendMouseButton(window, 0, SDL_RELEASED, button);
|
SDL_SendMouseButton(window, 0, SDL_RELEASED, button);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void WINRT_ProcessPointerPressedEvent(SDL_Window *window, Windows::UI::Core::PointerEventArgs ^args)
|
void WINRT_ProcessPointerPressedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint)
|
||||||
{
|
{
|
||||||
#if LOG_POINTER_EVENTS
|
#if LOG_POINTER_EVENTS
|
||||||
WINRT_LogPointerEvent("mouse down", args, TransformCursor(args->CurrentPoint->Position));
|
WINRT_LogPointerEvent("mouse down", args, TransformCursor(args->CurrentPoint->Position));
|
||||||
@ -390,7 +395,7 @@ void WINRT_ProcessPointerPressedEvent(SDL_Window *window, Windows::UI::Core::Poi
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Uint8 button = WINRT_GetSDLButtonForPointerPoint(args->CurrentPoint);
|
Uint8 button = WINRT_GetSDLButtonForPointerPoint(pointerPoint);
|
||||||
if (button) {
|
if (button) {
|
||||||
SDL_SendMouseButton(window, 0, SDL_PRESSED, button);
|
SDL_SendMouseButton(window, 0, SDL_PRESSED, button);
|
||||||
}
|
}
|
||||||
|
@ -47,8 +47,11 @@ extern "C" {
|
|||||||
#include "../../core/winrt/SDL_winrtapp.h"
|
#include "../../core/winrt/SDL_winrtapp.h"
|
||||||
#include "SDL_winrtevents_c.h"
|
#include "SDL_winrtevents_c.h"
|
||||||
#include "SDL_winrtmouse.h"
|
#include "SDL_winrtmouse.h"
|
||||||
|
#include "SDL_main.h"
|
||||||
|
#include "SDL_system.h"
|
||||||
|
|
||||||
extern SDL_WinRTApp ^ SDL_WinRTGlobalApp;
|
extern SDL_WinRTApp ^ SDL_WinRTGlobalApp;
|
||||||
|
extern SDL_bool WINRT_XAMLWasEnabled;
|
||||||
|
|
||||||
|
|
||||||
/* Initialization/Query functions */
|
/* Initialization/Query functions */
|
||||||
@ -84,6 +87,7 @@ SDL_Window * WINRT_GlobalSDLWindow = NULL;
|
|||||||
SDL_VideoDevice * WINRT_GlobalSDLVideoDevice = NULL;
|
SDL_VideoDevice * WINRT_GlobalSDLVideoDevice = NULL;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* WinRT driver bootstrap functions */
|
/* WinRT driver bootstrap functions */
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -154,6 +158,13 @@ WINRT_CalcDisplayModeUsingNativeWindow()
|
|||||||
SDL_DisplayMode mode;
|
SDL_DisplayMode mode;
|
||||||
SDL_zero(mode);
|
SDL_zero(mode);
|
||||||
|
|
||||||
|
// Go no further if a native window cannot be accessed. This can happen,
|
||||||
|
// for example, if this function is called from certain threads, such as
|
||||||
|
// the SDL/XAML thread.
|
||||||
|
if (!CoreWindow::GetForCurrentThread()) {
|
||||||
|
return mode;
|
||||||
|
}
|
||||||
|
|
||||||
// Fill in most fields:
|
// Fill in most fields:
|
||||||
mode.format = SDL_PIXELFORMAT_RGB888;
|
mode.format = SDL_PIXELFORMAT_RGB888;
|
||||||
mode.refresh_rate = 0; // TODO, WinRT: see if refresh rate data is available, or relevant (for WinRT apps)
|
mode.refresh_rate = 0; // TODO, WinRT: see if refresh rate data is available, or relevant (for WinRT apps)
|
||||||
@ -169,11 +180,15 @@ WINRT_CalcDisplayModeUsingNativeWindow()
|
|||||||
return mode;
|
return mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
static int
|
|
||||||
WINRT_InitModes(_THIS)
|
WINRT_InitModes(_THIS)
|
||||||
{
|
{
|
||||||
|
// Retrieve the display mode:
|
||||||
SDL_DisplayMode mode = WINRT_CalcDisplayModeUsingNativeWindow();
|
SDL_DisplayMode mode = WINRT_CalcDisplayModeUsingNativeWindow();
|
||||||
|
if (mode.w == 0 || mode.h == 0) {
|
||||||
|
return SDL_SetError("Unable to calculate the WinRT window/display's size");
|
||||||
|
}
|
||||||
|
|
||||||
if (SDL_AddBasicVideoDisplay(&mode) < 0) {
|
if (SDL_AddBasicVideoDisplay(&mode) < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -211,7 +226,16 @@ WINRT_CreateWindow(_THIS, SDL_Window * window)
|
|||||||
}
|
}
|
||||||
window->driverdata = data;
|
window->driverdata = data;
|
||||||
data->sdlWindow = window;
|
data->sdlWindow = window;
|
||||||
data->coreWindow = CoreWindow::GetForCurrentThread();
|
|
||||||
|
/* To note, when XAML support is enabled, access to the CoreWindow will not
|
||||||
|
be possible, at least not via the SDL/XAML thread. Attempts to access it
|
||||||
|
from there will throw exceptions. As such, the SDL_WindowData's
|
||||||
|
'coreWindow' field will only be set (to a non-null value) if XAML isn't
|
||||||
|
enabled.
|
||||||
|
*/
|
||||||
|
if (!WINRT_XAMLWasEnabled) {
|
||||||
|
data->coreWindow = CoreWindow::GetForCurrentThread();
|
||||||
|
}
|
||||||
|
|
||||||
/* Make sure the window is considered to be positioned at {0,0},
|
/* Make sure the window is considered to be positioned at {0,0},
|
||||||
and is considered fullscreen, shown, and the like.
|
and is considered fullscreen, shown, and the like.
|
||||||
|
Loading…
Reference in New Issue
Block a user