diff options
Diffstat (limited to 'Source/3rdParty/SDL2/src/video/winrt/SDL_winrtvideo.cpp')
-rw-r--r-- | Source/3rdParty/SDL2/src/video/winrt/SDL_winrtvideo.cpp | 842 |
1 files changed, 0 insertions, 842 deletions
diff --git a/Source/3rdParty/SDL2/src/video/winrt/SDL_winrtvideo.cpp b/Source/3rdParty/SDL2/src/video/winrt/SDL_winrtvideo.cpp deleted file mode 100644 index 99bfd07..0000000 --- a/Source/3rdParty/SDL2/src/video/winrt/SDL_winrtvideo.cpp +++ /dev/null @@ -1,842 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2018 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. -*/ -#include "../../SDL_internal.h" - -#if SDL_VIDEO_DRIVER_WINRT - -/* WinRT SDL video driver implementation - - Initial work on this was done by David Ludwig (dludwig@pobox.com), and - was based off of SDL's "dummy" video driver. - */ - -/* Windows includes */ -#include <agile.h> -#include <windows.graphics.display.h> -#include <windows.system.display.h> -#include <dxgi.h> -#include <dxgi1_2.h> -using namespace Windows::ApplicationModel::Core; -using namespace Windows::Foundation; -using namespace Windows::Graphics::Display; -using namespace Windows::UI::Core; -using namespace Windows::UI::ViewManagement; - - -/* [re]declare Windows GUIDs locally, to limit the amount of external lib(s) SDL has to link to */ -static const GUID IID_IDisplayRequest = { 0xe5732044, 0xf49f, 0x4b60, { 0x8d, 0xd4, 0x5e, 0x7e, 0x3a, 0x63, 0x2a, 0xc0 } }; -static const GUID IID_IDXGIFactory2 = { 0x50c83a1c, 0xe072, 0x4c48, { 0x87, 0xb0, 0x36, 0x30, 0xfa, 0x36, 0xa6, 0xd0 } }; - - -/* SDL includes */ -extern "C" { -#include "SDL_video.h" -#include "SDL_mouse.h" -#include "../SDL_sysvideo.h" -#include "../SDL_pixels_c.h" -#include "../../events/SDL_events_c.h" -#include "../../render/SDL_sysrender.h" -#include "SDL_syswm.h" -#include "SDL_winrtopengles.h" -#include "../../core/windows/SDL_windows.h" -} - -#include "../../core/winrt/SDL_winrtapp_direct3d.h" -#include "../../core/winrt/SDL_winrtapp_xaml.h" -#include "SDL_winrtvideo_cpp.h" -#include "SDL_winrtevents_c.h" -#include "SDL_winrtgamebar_cpp.h" -#include "SDL_winrtmouse_c.h" -#include "SDL_main.h" -#include "SDL_system.h" -//#include "SDL_log.h" - - -/* Initialization/Query functions */ -static int WINRT_VideoInit(_THIS); -static int WINRT_InitModes(_THIS); -static int WINRT_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode); -static void WINRT_VideoQuit(_THIS); - - -/* Window functions */ -static int WINRT_CreateWindow(_THIS, SDL_Window * window); -static void WINRT_SetWindowSize(_THIS, SDL_Window * window); -static void WINRT_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen); -static void WINRT_DestroyWindow(_THIS, SDL_Window * window); -static SDL_bool WINRT_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info); - - -/* Misc functions */ -static ABI::Windows::System::Display::IDisplayRequest * WINRT_CreateDisplayRequest(_THIS); -extern void WINRT_SuspendScreenSaver(_THIS); - - -/* SDL-internal globals: */ -SDL_Window * WINRT_GlobalSDLWindow = NULL; - - -/* WinRT driver bootstrap functions */ - -static int -WINRT_Available(void) -{ - return (1); -} - -static void -WINRT_DeleteDevice(SDL_VideoDevice * device) -{ - if (device->driverdata) { - SDL_VideoData * video_data = (SDL_VideoData *)device->driverdata; - if (video_data->winrtEglWindow) { - video_data->winrtEglWindow->Release(); - } - SDL_free(video_data); - } - - SDL_free(device); -} - -static SDL_VideoDevice * -WINRT_CreateDevice(int devindex) -{ - SDL_VideoDevice *device; - SDL_VideoData *data; - - /* Initialize all variables that we clean on shutdown */ - device = (SDL_VideoDevice *) SDL_calloc(1, sizeof(SDL_VideoDevice)); - if (!device) { - SDL_OutOfMemory(); - return (0); - } - - data = (SDL_VideoData *) SDL_calloc(1, sizeof(SDL_VideoData)); - if (!data) { - SDL_OutOfMemory(); - SDL_free(device); - return (0); - } - device->driverdata = data; - - /* Set the function pointers */ - device->VideoInit = WINRT_VideoInit; - device->VideoQuit = WINRT_VideoQuit; - device->CreateSDLWindow = WINRT_CreateWindow; - device->SetWindowSize = WINRT_SetWindowSize; - device->SetWindowFullscreen = WINRT_SetWindowFullscreen; - device->DestroyWindow = WINRT_DestroyWindow; - device->SetDisplayMode = WINRT_SetDisplayMode; - device->PumpEvents = WINRT_PumpEvents; - device->GetWindowWMInfo = WINRT_GetWindowWMInfo; - device->SuspendScreenSaver = WINRT_SuspendScreenSaver; - -#if NTDDI_VERSION >= NTDDI_WIN10 - device->HasScreenKeyboardSupport = WINRT_HasScreenKeyboardSupport; - device->ShowScreenKeyboard = WINRT_ShowScreenKeyboard; - device->HideScreenKeyboard = WINRT_HideScreenKeyboard; - device->IsScreenKeyboardShown = WINRT_IsScreenKeyboardShown; -#endif - -#ifdef SDL_VIDEO_OPENGL_EGL - device->GL_LoadLibrary = WINRT_GLES_LoadLibrary; - device->GL_GetProcAddress = WINRT_GLES_GetProcAddress; - device->GL_UnloadLibrary = WINRT_GLES_UnloadLibrary; - device->GL_CreateContext = WINRT_GLES_CreateContext; - device->GL_MakeCurrent = WINRT_GLES_MakeCurrent; - device->GL_SetSwapInterval = WINRT_GLES_SetSwapInterval; - device->GL_GetSwapInterval = WINRT_GLES_GetSwapInterval; - device->GL_SwapWindow = WINRT_GLES_SwapWindow; - device->GL_DeleteContext = WINRT_GLES_DeleteContext; -#endif - device->free = WINRT_DeleteDevice; - - return device; -} - -#define WINRTVID_DRIVER_NAME "winrt" -VideoBootStrap WINRT_bootstrap = { - WINRTVID_DRIVER_NAME, "SDL WinRT video driver", - WINRT_Available, WINRT_CreateDevice -}; - -int -WINRT_VideoInit(_THIS) -{ - SDL_VideoData * driverdata = (SDL_VideoData *) _this->driverdata; - if (WINRT_InitModes(_this) < 0) { - return -1; - } - WINRT_InitMouse(_this); - WINRT_InitTouch(_this); - WINRT_InitGameBar(_this); - if (driverdata) { - /* Initialize screensaver-disabling support */ - driverdata->displayRequest = WINRT_CreateDisplayRequest(_this); - } - return 0; -} - -extern "C" -Uint32 D3D11_DXGIFormatToSDLPixelFormat(DXGI_FORMAT dxgiFormat); - -static void -WINRT_DXGIModeToSDLDisplayMode(const DXGI_MODE_DESC * dxgiMode, SDL_DisplayMode * sdlMode) -{ - SDL_zerop(sdlMode); - sdlMode->w = dxgiMode->Width; - sdlMode->h = dxgiMode->Height; - sdlMode->refresh_rate = dxgiMode->RefreshRate.Numerator / dxgiMode->RefreshRate.Denominator; - sdlMode->format = D3D11_DXGIFormatToSDLPixelFormat(dxgiMode->Format); -} - -static int -WINRT_AddDisplaysForOutput (_THIS, IDXGIAdapter1 * dxgiAdapter1, int outputIndex) -{ - HRESULT hr; - IDXGIOutput * dxgiOutput = NULL; - DXGI_OUTPUT_DESC dxgiOutputDesc; - SDL_VideoDisplay display; - char * displayName = NULL; - UINT numModes; - DXGI_MODE_DESC * dxgiModes = NULL; - int functionResult = -1; /* -1 for failure, 0 for success */ - DXGI_MODE_DESC modeToMatch, closestMatch; - - SDL_zero(display); - - hr = dxgiAdapter1->EnumOutputs(outputIndex, &dxgiOutput); - if (FAILED(hr)) { - if (hr != DXGI_ERROR_NOT_FOUND) { - WIN_SetErrorFromHRESULT(__FUNCTION__ ", IDXGIAdapter1::EnumOutputs failed", hr); - } - goto done; - } - - hr = dxgiOutput->GetDesc(&dxgiOutputDesc); - if (FAILED(hr)) { - WIN_SetErrorFromHRESULT(__FUNCTION__ ", IDXGIOutput::GetDesc failed", hr); - goto done; - } - - SDL_zero(modeToMatch); - modeToMatch.Format = DXGI_FORMAT_B8G8R8A8_UNORM; - modeToMatch.Width = (dxgiOutputDesc.DesktopCoordinates.right - dxgiOutputDesc.DesktopCoordinates.left); - modeToMatch.Height = (dxgiOutputDesc.DesktopCoordinates.bottom - dxgiOutputDesc.DesktopCoordinates.top); - hr = dxgiOutput->FindClosestMatchingMode(&modeToMatch, &closestMatch, NULL); - if (hr == DXGI_ERROR_NOT_CURRENTLY_AVAILABLE) { - /* DXGI_ERROR_NOT_CURRENTLY_AVAILABLE gets returned by IDXGIOutput::FindClosestMatchingMode - when running under the Windows Simulator, which uses Remote Desktop (formerly known as Terminal - Services) under the hood. According to the MSDN docs for the similar function, - IDXGIOutput::GetDisplayModeList, DXGI_ERROR_NOT_CURRENTLY_AVAILABLE is returned if and - when an app is run under a Terminal Services session, hence the assumption. - - In this case, just add an SDL display mode, with approximated values. - */ - SDL_DisplayMode mode; - SDL_zero(mode); - display.name = "Windows Simulator / Terminal Services Display"; - mode.w = (dxgiOutputDesc.DesktopCoordinates.right - dxgiOutputDesc.DesktopCoordinates.left); - mode.h = (dxgiOutputDesc.DesktopCoordinates.bottom - dxgiOutputDesc.DesktopCoordinates.top); - mode.format = DXGI_FORMAT_B8G8R8A8_UNORM; - mode.refresh_rate = 0; /* Display mode is unknown, so just fill in zero, as specified by SDL's header files */ - display.desktop_mode = mode; - display.current_mode = mode; - if ( ! SDL_AddDisplayMode(&display, &mode)) { - goto done; - } - } else if (FAILED(hr)) { - WIN_SetErrorFromHRESULT(__FUNCTION__ ", IDXGIOutput::FindClosestMatchingMode failed", hr); - goto done; - } else { - displayName = WIN_StringToUTF8(dxgiOutputDesc.DeviceName); - display.name = displayName; - WINRT_DXGIModeToSDLDisplayMode(&closestMatch, &display.desktop_mode); - display.current_mode = display.desktop_mode; - - hr = dxgiOutput->GetDisplayModeList(DXGI_FORMAT_B8G8R8A8_UNORM, 0, &numModes, NULL); - if (FAILED(hr)) { - if (hr == DXGI_ERROR_NOT_CURRENTLY_AVAILABLE) { - // TODO, WinRT: make sure display mode(s) are added when using Terminal Services / Windows Simulator - } - WIN_SetErrorFromHRESULT(__FUNCTION__ ", IDXGIOutput::GetDisplayModeList [get mode list size] failed", hr); - goto done; - } - - dxgiModes = (DXGI_MODE_DESC *)SDL_calloc(numModes, sizeof(DXGI_MODE_DESC)); - if ( ! dxgiModes) { - SDL_OutOfMemory(); - goto done; - } - - hr = dxgiOutput->GetDisplayModeList(DXGI_FORMAT_B8G8R8A8_UNORM, 0, &numModes, dxgiModes); - if (FAILED(hr)) { - WIN_SetErrorFromHRESULT(__FUNCTION__ ", IDXGIOutput::GetDisplayModeList [get mode contents] failed", hr); - goto done; - } - - for (UINT i = 0; i < numModes; ++i) { - SDL_DisplayMode sdlMode; - WINRT_DXGIModeToSDLDisplayMode(&dxgiModes[i], &sdlMode); - SDL_AddDisplayMode(&display, &sdlMode); - } - } - - if (SDL_AddVideoDisplay(&display) < 0) { - goto done; - } - - functionResult = 0; /* 0 for Success! */ -done: - if (dxgiModes) { - SDL_free(dxgiModes); - } - if (dxgiOutput) { - dxgiOutput->Release(); - } - if (displayName) { - SDL_free(displayName); - } - return functionResult; -} - -static int -WINRT_AddDisplaysForAdapter (_THIS, IDXGIFactory2 * dxgiFactory2, int adapterIndex) -{ - HRESULT hr; - IDXGIAdapter1 * dxgiAdapter1; - - hr = dxgiFactory2->EnumAdapters1(adapterIndex, &dxgiAdapter1); - if (FAILED(hr)) { - if (hr != DXGI_ERROR_NOT_FOUND) { - WIN_SetErrorFromHRESULT(__FUNCTION__ ", IDXGIFactory1::EnumAdapters1() failed", hr); - } - return -1; - } - - for (int outputIndex = 0; ; ++outputIndex) { - if (WINRT_AddDisplaysForOutput(_this, dxgiAdapter1, outputIndex) < 0) { - /* HACK: The Windows App Certification Kit 10.0 can fail, when - running the Store Apps' test, "Direct3D Feature Test". The - certification kit's error is: - - "Application App was not running at the end of the test. It likely crashed or was terminated for having become unresponsive." - - This was caused by SDL/WinRT's DXGI failing to report any - outputs. Attempts to get the 1st display-output from the - 1st display-adapter can fail, with IDXGIAdapter::EnumOutputs - returning DXGI_ERROR_NOT_FOUND. This could be a bug in Windows, - the Windows App Certification Kit, or possibly in SDL/WinRT's - display detection code. Either way, try to detect when this - happens, and use a hackish means to create a reasonable-as-possible - 'display mode'. -- DavidL - */ - if (adapterIndex == 0 && outputIndex == 0) { - SDL_VideoDisplay display; - SDL_DisplayMode mode; -#if SDL_WINRT_USE_APPLICATIONVIEW - ApplicationView ^ appView = ApplicationView::GetForCurrentView(); -#endif - CoreWindow ^ coreWin = CoreWindow::GetForCurrentThread(); - SDL_zero(display); - SDL_zero(mode); - display.name = "DXGI Display-detection Workaround"; - - /* HACK: ApplicationView's VisibleBounds property, appeared, via testing, to - give a better approximation of display-size, than did CoreWindow's - Bounds property, insofar that ApplicationView::VisibleBounds seems like - it will, at least some of the time, give the full display size (during the - failing test), whereas CoreWindow might not. -- DavidL - */ - -#if (NTDDI_VERSION >= NTDDI_WIN10) || (SDL_WINRT_USE_APPLICATIONVIEW && WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) - mode.w = WINRT_DIPS_TO_PHYSICAL_PIXELS(appView->VisibleBounds.Width); - mode.h = WINRT_DIPS_TO_PHYSICAL_PIXELS(appView->VisibleBounds.Height); -#else - /* On platform(s) that do not support VisibleBounds, such as Windows 8.1, - fall back to CoreWindow's Bounds property. - */ - mode.w = WINRT_DIPS_TO_PHYSICAL_PIXELS(coreWin->Bounds.Width); - mode.h = WINRT_DIPS_TO_PHYSICAL_PIXELS(coreWin->Bounds.Height); -#endif - - mode.format = DXGI_FORMAT_B8G8R8A8_UNORM; - mode.refresh_rate = 0; /* Display mode is unknown, so just fill in zero, as specified by SDL's header files */ - display.desktop_mode = mode; - display.current_mode = mode; - if ((SDL_AddDisplayMode(&display, &mode) < 0) || - (SDL_AddVideoDisplay(&display) < 0)) - { - return SDL_SetError("Failed to apply DXGI Display-detection workaround"); - } - } - - break; - } - } - - dxgiAdapter1->Release(); - return 0; -} - -int -WINRT_InitModes(_THIS) -{ - /* HACK: Initialize a single display, for whatever screen the app's - CoreApplicationView is on. - TODO, WinRT: Try initializing multiple displays, one for each monitor. - Appropriate WinRT APIs for this seem elusive, though. -- DavidL - */ - - HRESULT hr; - IDXGIFactory2 * dxgiFactory2 = NULL; - - hr = CreateDXGIFactory1(IID_IDXGIFactory2, (void **)&dxgiFactory2); - if (FAILED(hr)) { - WIN_SetErrorFromHRESULT(__FUNCTION__ ", CreateDXGIFactory1() failed", hr); - return -1; - } - - for (int adapterIndex = 0; ; ++adapterIndex) { - if (WINRT_AddDisplaysForAdapter(_this, dxgiFactory2, adapterIndex) < 0) { - break; - } - } - - return 0; -} - -static int -WINRT_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode) -{ - return 0; -} - -void -WINRT_VideoQuit(_THIS) -{ - SDL_VideoData * driverdata = (SDL_VideoData *) _this->driverdata; - if (driverdata && driverdata->displayRequest) { - driverdata->displayRequest->Release(); - driverdata->displayRequest = NULL; - } - WINRT_QuitGameBar(_this); - WINRT_QuitMouse(_this); -} - -static const Uint32 WINRT_DetectableFlags = - SDL_WINDOW_MAXIMIZED | - SDL_WINDOW_FULLSCREEN_DESKTOP | - SDL_WINDOW_SHOWN | - SDL_WINDOW_HIDDEN | - SDL_WINDOW_MOUSE_FOCUS; - -extern "C" Uint32 -WINRT_DetectWindowFlags(SDL_Window * window) -{ - Uint32 latestFlags = 0; - SDL_WindowData * data = (SDL_WindowData *) window->driverdata; - bool is_fullscreen = false; - -#if SDL_WINRT_USE_APPLICATIONVIEW - if (data->appView) { - is_fullscreen = data->appView->IsFullScreen; - } -#elif (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) || (NTDDI_VERSION == NTDDI_WIN8) - is_fullscreen = true; -#endif - - if (data->coreWindow.Get()) { - if (is_fullscreen) { - SDL_VideoDisplay * display = SDL_GetDisplayForWindow(window); - int w = WINRT_DIPS_TO_PHYSICAL_PIXELS(data->coreWindow->Bounds.Width); - int h = WINRT_DIPS_TO_PHYSICAL_PIXELS(data->coreWindow->Bounds.Height); - -#if (WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP) || (NTDDI_VERSION > NTDDI_WIN8) - // On all WinRT platforms, except for WinPhone 8.0, rotate the - // window size. This is needed to properly calculate - // fullscreen vs. maximized. - const DisplayOrientations currentOrientation = WINRT_DISPLAY_PROPERTY(CurrentOrientation); - switch (currentOrientation) { -#if (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) - case DisplayOrientations::Landscape: - case DisplayOrientations::LandscapeFlipped: -#else - case DisplayOrientations::Portrait: - case DisplayOrientations::PortraitFlipped: -#endif - { - int tmp = w; - w = h; - h = tmp; - } break; - } -#endif - - if (display->desktop_mode.w != w || display->desktop_mode.h != h) { - latestFlags |= SDL_WINDOW_MAXIMIZED; - } else { - latestFlags |= SDL_WINDOW_FULLSCREEN_DESKTOP; - } - } - - if (data->coreWindow->Visible) { - latestFlags |= SDL_WINDOW_SHOWN; - } else { - latestFlags |= SDL_WINDOW_HIDDEN; - } - -#if (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) && (NTDDI_VERSION < NTDDI_WINBLUE) - // data->coreWindow->PointerPosition is not supported on WinPhone 8.0 - latestFlags |= SDL_WINDOW_MOUSE_FOCUS; -#else - if (data->coreWindow->Visible && data->coreWindow->Bounds.Contains(data->coreWindow->PointerPosition)) { - latestFlags |= SDL_WINDOW_MOUSE_FOCUS; - } -#endif - } - - return latestFlags; -} - -// TODO, WinRT: consider removing WINRT_UpdateWindowFlags, and just calling WINRT_DetectWindowFlags as-appropriate (with appropriate calls to SDL_SendWindowEvent) -void -WINRT_UpdateWindowFlags(SDL_Window * window, Uint32 mask) -{ - mask &= WINRT_DetectableFlags; - if (window) { - Uint32 apply = WINRT_DetectWindowFlags(window); - if ((apply & mask) & SDL_WINDOW_FULLSCREEN) { - window->last_fullscreen_flags = window->flags; // seems necessary to programmatically un-fullscreen, via SDL APIs - } - window->flags = (window->flags & ~mask) | (apply & mask); - } -} - -static bool -WINRT_IsCoreWindowActive(CoreWindow ^ coreWindow) -{ - /* WinRT does not appear to offer API(s) to determine window-activation state, - at least not that I am aware of in Win8 - Win10. As such, SDL tracks this - itself, via window-activation events. - - If there *is* an API to track this, it should probably get used instead - of the following hack (that uses "SDLHelperWindowActivationState"). - -- DavidL. - */ - if (coreWindow->CustomProperties->HasKey("SDLHelperWindowActivationState")) { - CoreWindowActivationState activationState = \ - safe_cast<CoreWindowActivationState>(coreWindow->CustomProperties->Lookup("SDLHelperWindowActivationState")); - return (activationState != CoreWindowActivationState::Deactivated); - } - - /* Assume that non-SDL tracked windows are active, although this should - probably be avoided, if possible. - - This might not even be possible, in normal SDL use, at least as of - this writing (Dec 22, 2015; via latest hg.libsdl.org/SDL clone) -- DavidL - */ - return true; -} - -int -WINRT_CreateWindow(_THIS, SDL_Window * window) -{ - // Make sure that only one window gets created, at least until multimonitor - // support is added. - if (WINRT_GlobalSDLWindow != NULL) { - SDL_SetError("WinRT only supports one window"); - return -1; - } - - SDL_WindowData *data = new SDL_WindowData; /* use 'new' here as SDL_WindowData may use WinRT/C++ types */ - if (!data) { - SDL_OutOfMemory(); - return -1; - } - window->driverdata = data; - data->sdlWindow = window; - - /* 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(); -#if SDL_WINRT_USE_APPLICATIONVIEW - data->appView = ApplicationView::GetForCurrentView(); -#endif - } - - /* Make note of the requested window flags, before they start getting changed. */ - const Uint32 requestedFlags = window->flags; - -#if SDL_VIDEO_OPENGL_EGL - /* Setup the EGL surface, but only if OpenGL ES 2 was requested. */ - if (!(window->flags & SDL_WINDOW_OPENGL)) { - /* OpenGL ES 2 wasn't requested. Don't set up an EGL surface. */ - data->egl_surface = EGL_NO_SURFACE; - } else { - /* OpenGL ES 2 was reuqested. Set up an EGL surface. */ - SDL_VideoData * video_data = (SDL_VideoData *)_this->driverdata; - - /* Call SDL_EGL_ChooseConfig and eglCreateWindowSurface directly, - * rather than via SDL_EGL_CreateSurface, as older versions of - * ANGLE/WinRT may require that a C++ object, ComPtr<IUnknown>, - * be passed into eglCreateWindowSurface. - */ - if (SDL_EGL_ChooseConfig(_this) != 0) { - char buf[512]; - SDL_snprintf(buf, sizeof(buf), "SDL_EGL_ChooseConfig failed: %s", SDL_GetError()); - return SDL_SetError("%s", buf); - } - - if (video_data->winrtEglWindow) { /* ... is the 'old' version of ANGLE/WinRT being used? */ - /* Attempt to create a window surface using older versions of - * ANGLE/WinRT: - */ - Microsoft::WRL::ComPtr<IUnknown> cpp_winrtEglWindow = video_data->winrtEglWindow; - data->egl_surface = ((eglCreateWindowSurface_Old_Function)_this->egl_data->eglCreateWindowSurface)( - _this->egl_data->egl_display, - _this->egl_data->egl_config, - cpp_winrtEglWindow, NULL); - if (data->egl_surface == NULL) { - return SDL_EGL_SetError("unable to create EGL native-window surface", "eglCreateWindowSurface"); - } - } else if (data->coreWindow.Get() != nullptr) { - /* Attempt to create a window surface using newer versions of - * ANGLE/WinRT: - */ - IInspectable * coreWindowAsIInspectable = reinterpret_cast<IInspectable *>(data->coreWindow.Get()); - data->egl_surface = _this->egl_data->eglCreateWindowSurface( - _this->egl_data->egl_display, - _this->egl_data->egl_config, - coreWindowAsIInspectable, - NULL); - if (data->egl_surface == NULL) { - return SDL_EGL_SetError("unable to create EGL native-window surface", "eglCreateWindowSurface"); - } - } else { - return SDL_SetError("No supported means to create an EGL window surface are available"); - } - } -#endif - - /* Determine as many flags dynamically, as possible. */ - window->flags = - SDL_WINDOW_BORDERLESS | - SDL_WINDOW_RESIZABLE; - -#if SDL_VIDEO_OPENGL_EGL - if (data->egl_surface) { - window->flags |= SDL_WINDOW_OPENGL; - } -#endif - - if (WINRT_XAMLWasEnabled) { - /* TODO, WinRT: set SDL_Window size, maybe position too, from XAML control */ - window->x = 0; - window->y = 0; - window->flags |= SDL_WINDOW_SHOWN; - SDL_SetMouseFocus(NULL); // TODO: detect this - SDL_SetKeyboardFocus(NULL); // TODO: detect this - } else { - /* WinRT 8.x apps seem to live in an environment where the OS controls the - app's window size, with some apps being fullscreen, depending on - user choice of various things. For now, just adapt the SDL_Window to - whatever Windows set-up as the native-window's geometry. - */ - window->x = WINRT_DIPS_TO_PHYSICAL_PIXELS(data->coreWindow->Bounds.Left); - window->y = WINRT_DIPS_TO_PHYSICAL_PIXELS(data->coreWindow->Bounds.Top); -#if NTDDI_VERSION < NTDDI_WIN10 - /* On WinRT 8.x / pre-Win10, just use the size we were given. */ - window->w = WINRT_DIPS_TO_PHYSICAL_PIXELS(data->coreWindow->Bounds.Width); - window->h = WINRT_DIPS_TO_PHYSICAL_PIXELS(data->coreWindow->Bounds.Height); -#else - /* On Windows 10, we occasionally get control over window size. For windowed - mode apps, try this. - */ - bool didSetSize = false; - if (!(requestedFlags & SDL_WINDOW_FULLSCREEN)) { - const Windows::Foundation::Size size(WINRT_PHYSICAL_PIXELS_TO_DIPS(window->w), - WINRT_PHYSICAL_PIXELS_TO_DIPS(window->h)); - didSetSize = data->appView->TryResizeView(size); - } - if (!didSetSize) { - /* We either weren't able to set the window size, or a request for - fullscreen was made. Get window-size info from the OS. - */ - window->w = WINRT_DIPS_TO_PHYSICAL_PIXELS(data->coreWindow->Bounds.Width); - window->h = WINRT_DIPS_TO_PHYSICAL_PIXELS(data->coreWindow->Bounds.Height); - } -#endif - - WINRT_UpdateWindowFlags( - window, - 0xffffffff /* Update any window flag(s) that WINRT_UpdateWindow can handle */ - ); - - /* Try detecting if the window is active */ - bool isWindowActive = WINRT_IsCoreWindowActive(data->coreWindow.Get()); - if (isWindowActive) { - SDL_SetKeyboardFocus(window); - } - } - - /* Make sure the WinRT app's IFramworkView can post events on - behalf of SDL: - */ - WINRT_GlobalSDLWindow = window; - - /* All done! */ - return 0; -} - -void -WINRT_SetWindowSize(_THIS, SDL_Window * window) -{ -#if NTDDI_VERSION >= NTDDI_WIN10 - SDL_WindowData * data = (SDL_WindowData *)window->driverdata; - const Windows::Foundation::Size size(WINRT_PHYSICAL_PIXELS_TO_DIPS(window->w), - WINRT_PHYSICAL_PIXELS_TO_DIPS(window->h)); - data->appView->TryResizeView(size); // TODO, WinRT: return failure (to caller?) from TryResizeView() -#endif -} - -void -WINRT_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen) -{ -#if NTDDI_VERSION >= NTDDI_WIN10 - SDL_WindowData * data = (SDL_WindowData *)window->driverdata; - bool isWindowActive = WINRT_IsCoreWindowActive(data->coreWindow.Get()); - if (isWindowActive) { - if (fullscreen) { - if (!data->appView->IsFullScreenMode) { - data->appView->TryEnterFullScreenMode(); // TODO, WinRT: return failure (to caller?) from TryEnterFullScreenMode() - } - } else { - if (data->appView->IsFullScreenMode) { - data->appView->ExitFullScreenMode(); - } - } - } -#endif -} - - -void -WINRT_DestroyWindow(_THIS, SDL_Window * window) -{ - SDL_WindowData * data = (SDL_WindowData *) window->driverdata; - - if (WINRT_GlobalSDLWindow == window) { - WINRT_GlobalSDLWindow = NULL; - } - - if (data) { - // Delete the internal window data: - delete data; - data = NULL; - window->driverdata = NULL; - } -} - -SDL_bool -WINRT_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info) -{ - SDL_WindowData * data = (SDL_WindowData *) window->driverdata; - - if (info->version.major <= SDL_MAJOR_VERSION) { - info->subsystem = SDL_SYSWM_WINRT; - info->info.winrt.window = reinterpret_cast<IInspectable *>(data->coreWindow.Get()); - return SDL_TRUE; - } else { - SDL_SetError("Application not compiled with SDL %d.%d", - SDL_MAJOR_VERSION, SDL_MINOR_VERSION); - return SDL_FALSE; - } - return SDL_FALSE; -} - -static ABI::Windows::System::Display::IDisplayRequest * -WINRT_CreateDisplayRequest(_THIS) -{ - /* Setup a WinRT DisplayRequest object, usable for enabling/disabling screensaver requests */ - wchar_t *wClassName = L"Windows.System.Display.DisplayRequest"; - HSTRING hClassName; - IActivationFactory *pActivationFactory = NULL; - IInspectable * pDisplayRequestRaw = nullptr; - ABI::Windows::System::Display::IDisplayRequest * pDisplayRequest = nullptr; - HRESULT hr; - - hr = ::WindowsCreateString(wClassName, (UINT32)wcslen(wClassName), &hClassName); - if (FAILED(hr)) { - goto done; - } - - hr = Windows::Foundation::GetActivationFactory(hClassName, &pActivationFactory); - if (FAILED(hr)) { - goto done; - } - - hr = pActivationFactory->ActivateInstance(&pDisplayRequestRaw); - if (FAILED(hr)) { - goto done; - } - - hr = pDisplayRequestRaw->QueryInterface(IID_IDisplayRequest, (void **) &pDisplayRequest); - if (FAILED(hr)) { - goto done; - } - -done: - if (pDisplayRequestRaw) { - pDisplayRequestRaw->Release(); - } - if (pActivationFactory) { - pActivationFactory->Release(); - } - if (hClassName) { - ::WindowsDeleteString(hClassName); - } - - return pDisplayRequest; -} - -void -WINRT_SuspendScreenSaver(_THIS) -{ - SDL_VideoData *driverdata = (SDL_VideoData *)_this->driverdata; - if (driverdata && driverdata->displayRequest) { - ABI::Windows::System::Display::IDisplayRequest * displayRequest = (ABI::Windows::System::Display::IDisplayRequest *) driverdata->displayRequest; - if (_this->suspend_screensaver) { - displayRequest->RequestActive(); - } else { - displayRequest->RequestRelease(); - } - } -} - -#endif /* SDL_VIDEO_DRIVER_WINRT */ - -/* vi: set ts=4 sw=4 expandtab: */ |