Skip to content
This repository has been archived by the owner on Feb 11, 2021. It is now read-only.

Commit

Permalink
WinRT: made SDL's inner WinRT CoreWindow be accessible to non-C++/CX …
Browse files Browse the repository at this point in the history
…code, in theory
  • Loading branch information
DavidLudwig committed Apr 17, 2013
1 parent 0989304 commit 1f9095c
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 23 deletions.
6 changes: 5 additions & 1 deletion include/SDL_syswm.h
Expand Up @@ -58,6 +58,10 @@ struct SDL_SysWMinfo;
#include <windows.h>
#endif

#if defined(SDL_VIDEO_DRIVER_WINRT)
#include <Unknwn.h>
#endif

/* This is the structure for custom window manager events */
#if defined(SDL_VIDEO_DRIVER_X11)
#if defined(__APPLE__) && defined(__MACH__)
Expand Down Expand Up @@ -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)
Expand Down
52 changes: 41 additions & 11 deletions src/render/direct3d11/SDL_render_d3d11.cpp
Expand Up @@ -23,6 +23,11 @@

#if SDL_VIDEO_RENDER_D3D11 && !SDL_RENDER_DISABLED

#ifdef __WINRT__
#include <windows.ui.core.h>
#include <windows.foundation.h>
#endif

extern "C" {
#include "../../core/windows/SDL_windows.h"
//#include "SDL_hints.h"
Expand Down Expand Up @@ -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;
Expand All @@ -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.
Expand All @@ -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);
Expand Down Expand Up @@ -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<IUnknown*>(coreWindow),
coreWindowAsIUnknown,
&swapChainDesc,
nullptr, // Allow on all displays.
&data->swapChain
Expand Down Expand Up @@ -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};
Expand Down
12 changes: 2 additions & 10 deletions src/video/windowsrt/SDL_winrtvideo.cpp
Expand Up @@ -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.
Expand Down Expand Up @@ -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;
Expand All @@ -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<IUnknown *>(data->coreWindow.Get());
return SDL_TRUE;
} else {
SDL_SetError("Application not compiled with SDL %d.%d\n",
Expand Down
4 changes: 3 additions & 1 deletion src/video/windowsrt/SDL_winrtvideo.h
Expand Up @@ -27,10 +27,12 @@ extern "C" {
#include "../SDL_sysvideo.h"
}

#include <agile.h>

struct SDL_WindowData
{
SDL_Window *sdlWindow;
Windows::UI::Core::CoreWindow ^* coreWindow;
Platform::Agile<Windows::UI::Core::CoreWindow> coreWindow;
};

#endif /* _SDL_winrtvideo_h */
Expand Down

0 comments on commit 1f9095c

Please sign in to comment.