From 1f9095cdd81d23b79a066ccb00a7c1e3746ed479 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Tue, 16 Apr 2013 23:40:03 -0400 Subject: [PATCH] WinRT: made SDL's inner WinRT CoreWindow be accessible to non-C++/CX code, in theory --- include/SDL_syswm.h | 6 ++- src/render/direct3d11/SDL_render_d3d11.cpp | 52 +++++++++++++++++----- src/video/windowsrt/SDL_winrtvideo.cpp | 12 +---- src/video/windowsrt/SDL_winrtvideo.h | 4 +- 4 files changed, 51 insertions(+), 23 deletions(-) diff --git a/include/SDL_syswm.h b/include/SDL_syswm.h index f6e824672..c01c27141 100644 --- a/include/SDL_syswm.h +++ b/include/SDL_syswm.h @@ -58,6 +58,10 @@ struct SDL_SysWMinfo; #include #endif +#if defined(SDL_VIDEO_DRIVER_WINRT) +#include +#endif + /* This is the structure for custom window manager events */ #if defined(SDL_VIDEO_DRIVER_X11) #if defined(__APPLE__) && defined(__MACH__) @@ -175,7 +179,7 @@ struct SDL_SysWMinfo #if defined(SDL_VIDEO_DRIVER_WINRT) struct { - void * window; /**< The Windows RT CoreWindow, casted from 'CoreWindow ^*' to 'void *' */ + IUnknown * window; /**< The Windows RT CoreWindow */ } winrt; #endif #if defined(SDL_VIDEO_DRIVER_X11) diff --git a/src/render/direct3d11/SDL_render_d3d11.cpp b/src/render/direct3d11/SDL_render_d3d11.cpp index 374c39b6e..ed741c278 100644 --- a/src/render/direct3d11/SDL_render_d3d11.cpp +++ b/src/render/direct3d11/SDL_render_d3d11.cpp @@ -23,6 +23,11 @@ #if SDL_VIDEO_RENDER_D3D11 && !SDL_RENDER_DISABLED +#ifdef __WINRT__ +#include +#include +#endif + extern "C" { #include "../../core/windows/SDL_windows.h" //#include "SDL_hints.h" @@ -562,7 +567,7 @@ D3D11_CreateDeviceResources(SDL_Renderer * renderer) #ifdef __WINRT__ -static CoreWindow ^ +static ABI::Windows::UI::Core::ICoreWindow * D3D11_GetCoreWindowFromSDLRenderer(SDL_Renderer * renderer) { SDL_Window * sdlWindow = renderer->window; @@ -580,12 +585,16 @@ D3D11_GetCoreWindowFromSDLRenderer(SDL_Renderer * renderer) return nullptr; } - CoreWindow ^* coreWindowPointer = (CoreWindow ^*) sdlWindowInfo.info.winrt.window; - if ( ! coreWindowPointer ) { + if ( ! sdlWindowInfo.info.winrt.window ) { return nullptr; } - return *coreWindowPointer; + ABI::Windows::UI::Core::ICoreWindow * coreWindow = nullptr; + if (FAILED(sdlWindowInfo.info.winrt.window->QueryInterface(&coreWindow))) { + return nullptr; + } + + return coreWindow; } // Method to convert a length in device-independent pixels (DIPs) to a length in physical pixels. @@ -604,12 +613,19 @@ D3D11_CreateWindowSizeDependentResources(SDL_Renderer * renderer) { D3D11_RenderData *data = (D3D11_RenderData *) renderer->driverdata; HRESULT result = S_OK; - Windows::UI::Core::CoreWindow ^ coreWindow = D3D11_GetCoreWindowFromSDLRenderer(renderer); + ABI::Windows::UI::Core::ICoreWindow * coreWindow = D3D11_GetCoreWindowFromSDLRenderer(renderer); // Store the window bounds so the next time we get a SizeChanged event we can // avoid rebuilding everything if the size is identical. - data->windowSizeInDIPs.x = coreWindow->Bounds.Width; - data->windowSizeInDIPs.y = coreWindow->Bounds.Height; + ABI::Windows::Foundation::Rect coreWindowBounds; + result = coreWindow->get_Bounds(&coreWindowBounds); + if (FAILED(result)) { + WIN_SetErrorFromHRESULT(__FUNCTION__", Get Window Bounds", result); + return result; + } + + data->windowSizeInDIPs.x = coreWindowBounds.Width; + data->windowSizeInDIPs.y = coreWindowBounds.Height; // Calculate the necessary swap chain and render target size in pixels. float windowWidth = D3D11_ConvertDipsToPixels(data->windowSizeInDIPs.x); @@ -685,9 +701,16 @@ D3D11_CreateWindowSizeDependentResources(SDL_Renderer * renderer) return result; } + 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(), - reinterpret_cast(coreWindow), + coreWindowAsIUnknown, &swapChainDesc, nullptr, // Allow on all displays. &data->swapChain @@ -776,10 +799,17 @@ D3D11_UpdateForWindowSizeChange(SDL_Renderer * renderer) { D3D11_RenderData *data = (D3D11_RenderData *) renderer->driverdata; HRESULT result = S_OK; - Windows::UI::Core::CoreWindow ^ coreWindow = D3D11_GetCoreWindowFromSDLRenderer(renderer); + ABI::Windows::UI::Core::ICoreWindow * coreWindow = D3D11_GetCoreWindowFromSDLRenderer(renderer); + ABI::Windows::Foundation::Rect coreWindowBounds; + + result = coreWindow->get_Bounds(&coreWindowBounds); + if (FAILED(result)) { + WIN_SetErrorFromHRESULT(__FUNCTION__ ", Get Window Bounds", result); + return result; + } - if (coreWindow->Bounds.Width != data->windowSizeInDIPs.x || - coreWindow->Bounds.Height != data->windowSizeInDIPs.y || + if (coreWindowBounds.Width != data->windowSizeInDIPs.x || + coreWindowBounds.Height != data->windowSizeInDIPs.y || data->orientation != DisplayProperties::CurrentOrientation) { ID3D11RenderTargetView* nullViews[] = {nullptr}; diff --git a/src/video/windowsrt/SDL_winrtvideo.cpp b/src/video/windowsrt/SDL_winrtvideo.cpp index 846debb50..cdd8b3e03 100644 --- a/src/video/windowsrt/SDL_winrtvideo.cpp +++ b/src/video/windowsrt/SDL_winrtvideo.cpp @@ -172,7 +172,7 @@ WINRT_CreateWindow(_THIS, SDL_Window * window) } window->driverdata = data; data->sdlWindow = window; - data->coreWindow = new CoreWindow^(CoreWindow::GetForCurrentThread()); + data->coreWindow = CoreWindow::GetForCurrentThread(); /* Make sure the window is considered to be positioned at {0,0}, and is considered fullscreen, shown, and the like. @@ -233,13 +233,6 @@ WINRT_DestroyWindow(_THIS, SDL_Window * window) } if (data) { - // Delete the reference to the WinRT CoreWindow: - CoreWindow ^* windowPointer = ((SDL_WindowData *) window->driverdata)->coreWindow; - if (windowPointer) { - *windowPointer = nullptr; // Clear the C++/CX reference to the CoreWindow - delete windowPointer; // Delete the C++/CX reference itself - } - // Delete the internal window data: delete data; data = NULL; @@ -250,11 +243,10 @@ SDL_bool WINRT_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info) { SDL_WindowData * data = (SDL_WindowData *) window->driverdata; - CoreWindow ^* windowPointer = data->coreWindow; if (info->version.major <= SDL_MAJOR_VERSION) { info->subsystem = SDL_SYSWM_WINDOWSRT; - info->info.winrt.window = windowPointer; + info->info.winrt.window = reinterpret_cast(data->coreWindow.Get()); return SDL_TRUE; } else { SDL_SetError("Application not compiled with SDL %d.%d\n", diff --git a/src/video/windowsrt/SDL_winrtvideo.h b/src/video/windowsrt/SDL_winrtvideo.h index 83eb78733..4418754c2 100644 --- a/src/video/windowsrt/SDL_winrtvideo.h +++ b/src/video/windowsrt/SDL_winrtvideo.h @@ -27,10 +27,12 @@ extern "C" { #include "../SDL_sysvideo.h" } +#include + struct SDL_WindowData { SDL_Window *sdlWindow; - Windows::UI::Core::CoreWindow ^* coreWindow; + Platform::Agile coreWindow; }; #endif /* _SDL_winrtvideo_h */