21 #include "../../SDL_internal.h" 23 #if SDL_VIDEO_DRIVER_WINRT 33 #include <windows.graphics.display.h> 34 #include <windows.system.display.h> 41 using namespace Windows::UI::ViewManagement;
45 static const GUID IID_IDisplayRequest = { 0xe5732044, 0xf49f, 0x4b60, { 0x8d, 0xd4, 0x5e, 0x7e, 0x3a, 0x63, 0x2a, 0xc0 } };
46 static const GUID IID_IDXGIFactory2 = { 0x50c83a1c, 0xe072, 0x4c48, { 0x87, 0xb0, 0x36, 0x30, 0xfa, 0x36, 0xa6, 0xd0 } };
53 #include "../SDL_sysvideo.h" 54 #include "../SDL_pixels_c.h" 55 #include "../../events/SDL_events_c.h" 56 #include "../../render/SDL_sysrender.h" 59 #include "../../core/windows/SDL_windows.h" 62 #include "../../core/winrt/SDL_winrtapp_direct3d.h" 63 #include "../../core/winrt/SDL_winrtapp_xaml.h" 74 static int WINRT_VideoInit(
_THIS);
75 static int WINRT_InitModes(
_THIS);
77 static void WINRT_VideoQuit(
_THIS);
89 static ABI::Windows::System::Display::IDisplayRequest * WINRT_CreateDisplayRequest(
_THIS);
90 extern void WINRT_SuspendScreenSaver(
_THIS);
100 WINRT_Available(
void)
152 #if NTDDI_VERSION >= NTDDI_WIN10 159 #ifdef SDL_VIDEO_OPENGL_EGL 170 device->
free = WINRT_DeleteDevice;
175 #define WINRTVID_DRIVER_NAME "winrt" 177 WINRTVID_DRIVER_NAME,
"SDL WinRT video driver",
178 WINRT_Available, WINRT_CreateDevice
182 WINRT_VideoInit(
_THIS)
185 if (WINRT_InitModes(
_this) < 0) {
190 WINRT_InitGameBar(
_this);
199 Uint32 D3D11_DXGIFormatToSDLPixelFormat(DXGI_FORMAT dxgiFormat);
202 WINRT_DXGIModeToSDLDisplayMode(
const DXGI_MODE_DESC * dxgiMode,
SDL_DisplayMode * sdlMode)
205 sdlMode->
w = dxgiMode->Width;
206 sdlMode->
h = dxgiMode->Height;
207 sdlMode->
refresh_rate = dxgiMode->RefreshRate.Numerator / dxgiMode->RefreshRate.Denominator;
208 sdlMode->
format = D3D11_DXGIFormatToSDLPixelFormat(dxgiMode->Format);
212 WINRT_AddDisplaysForOutput (
_THIS, IDXGIAdapter1 * dxgiAdapter1,
int outputIndex)
215 IDXGIOutput * dxgiOutput =
NULL;
216 DXGI_OUTPUT_DESC dxgiOutputDesc;
218 char * displayName =
NULL;
220 DXGI_MODE_DESC * dxgiModes =
NULL;
221 int functionResult = -1;
222 DXGI_MODE_DESC modeToMatch, closestMatch;
226 hr = dxgiAdapter1->EnumOutputs(outputIndex, &dxgiOutput);
228 if (hr != DXGI_ERROR_NOT_FOUND) {
234 hr = dxgiOutput->GetDesc(&dxgiOutputDesc);
241 modeToMatch.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
242 modeToMatch.Width = (dxgiOutputDesc.DesktopCoordinates.right - dxgiOutputDesc.DesktopCoordinates.left);
243 modeToMatch.Height = (dxgiOutputDesc.DesktopCoordinates.bottom - dxgiOutputDesc.DesktopCoordinates.top);
244 hr = dxgiOutput->FindClosestMatchingMode(&modeToMatch, &closestMatch,
NULL);
245 if (hr == DXGI_ERROR_NOT_CURRENTLY_AVAILABLE) {
256 display.
name =
"Windows Simulator / Terminal Services Display";
257 mode.
w = (dxgiOutputDesc.DesktopCoordinates.right - dxgiOutputDesc.DesktopCoordinates.left);
258 mode.
h = (dxgiOutputDesc.DesktopCoordinates.bottom - dxgiOutputDesc.DesktopCoordinates.top);
259 mode.
format = DXGI_FORMAT_B8G8R8A8_UNORM;
271 display.
name = displayName;
272 WINRT_DXGIModeToSDLDisplayMode(&closestMatch, &display.
desktop_mode);
275 hr = dxgiOutput->GetDisplayModeList(DXGI_FORMAT_B8G8R8A8_UNORM, 0, &numModes,
NULL);
277 if (hr == DXGI_ERROR_NOT_CURRENTLY_AVAILABLE) {
284 dxgiModes = (DXGI_MODE_DESC *)
SDL_calloc(numModes,
sizeof(DXGI_MODE_DESC));
290 hr = dxgiOutput->GetDisplayModeList(DXGI_FORMAT_B8G8R8A8_UNORM, 0, &numModes, dxgiModes);
296 for (
UINT i = 0;
i < numModes; ++
i) {
298 WINRT_DXGIModeToSDLDisplayMode(&dxgiModes[
i], &sdlMode);
313 dxgiOutput->Release();
318 return functionResult;
322 WINRT_AddDisplaysForAdapter (
_THIS, IDXGIFactory2 * dxgiFactory2,
int adapterIndex)
325 IDXGIAdapter1 * dxgiAdapter1;
327 hr = dxgiFactory2->EnumAdapters1(adapterIndex, &dxgiAdapter1);
329 if (hr != DXGI_ERROR_NOT_FOUND) {
335 for (
int outputIndex = 0; ; ++outputIndex) {
336 if (WINRT_AddDisplaysForOutput(
_this, dxgiAdapter1, outputIndex) < 0) {
352 if (adapterIndex == 0 && outputIndex == 0) {
355 #if SDL_WINRT_USE_APPLICATIONVIEW 356 ApplicationView ^ appView = ApplicationView::GetForCurrentView();
358 CoreWindow ^ coreWin = CoreWindow::GetForCurrentThread();
361 display.
name =
"DXGI Display-detection Workaround";
370 #if (NTDDI_VERSION >= NTDDI_WIN10) || (SDL_WINRT_USE_APPLICATIONVIEW && WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) 371 mode.
w = WINRT_DIPS_TO_PHYSICAL_PIXELS(appView->VisibleBounds.Width);
372 mode.
h = WINRT_DIPS_TO_PHYSICAL_PIXELS(appView->VisibleBounds.Height);
377 mode.
w = WINRT_DIPS_TO_PHYSICAL_PIXELS(coreWin->Bounds.Width);
378 mode.
h = WINRT_DIPS_TO_PHYSICAL_PIXELS(coreWin->Bounds.Height);
381 mode.
format = DXGI_FORMAT_B8G8R8A8_UNORM;
388 return SDL_SetError(
"Failed to apply DXGI Display-detection workaround");
396 dxgiAdapter1->Release();
401 WINRT_InitModes(
_THIS)
410 IDXGIFactory2 * dxgiFactory2 =
NULL;
412 hr = CreateDXGIFactory1(IID_IDXGIFactory2, (
void **)&dxgiFactory2);
418 for (
int adapterIndex = 0; ; ++adapterIndex) {
419 if (WINRT_AddDisplaysForAdapter(
_this, dxgiFactory2, adapterIndex) < 0) {
434 WINRT_VideoQuit(
_THIS)
441 WINRT_QuitGameBar(
_this);
445 static const Uint32 WINRT_DetectableFlags =
457 bool is_fullscreen =
false;
461 is_fullscreen = data->appView->IsFullScreen;
463 #elif (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) || (NTDDI_VERSION == NTDDI_WIN8) 464 is_fullscreen =
true;
467 if (data->coreWindow.Get()) {
470 int w = WINRT_DIPS_TO_PHYSICAL_PIXELS(data->coreWindow->Bounds.Width);
471 int h = WINRT_DIPS_TO_PHYSICAL_PIXELS(data->coreWindow->Bounds.Height);
473 #if (WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP) || (NTDDI_VERSION > NTDDI_WIN8) 477 const DisplayOrientations currentOrientation = WINRT_DISPLAY_PROPERTY(CurrentOrientation);
478 switch (currentOrientation) {
479 #if (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) 480 case DisplayOrientations::Landscape:
481 case DisplayOrientations::LandscapeFlipped:
483 case DisplayOrientations::Portrait:
484 case DisplayOrientations::PortraitFlipped:
501 if (data->coreWindow->Visible) {
507 #if (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) && (NTDDI_VERSION < NTDDI_WINBLUE) 511 if (data->coreWindow->Visible && data->coreWindow->Bounds.Contains(data->coreWindow->PointerPosition)) {
524 mask &= WINRT_DetectableFlags;
530 window->
flags = (window->
flags & ~mask) | (apply & mask);
535 WINRT_IsCoreWindowActive(CoreWindow ^ coreWindow)
545 if (coreWindow->CustomProperties->HasKey(
"SDLHelperWindowActivationState")) {
546 CoreWindowActivationState activationState = \
547 safe_cast<CoreWindowActivationState>(coreWindow->CustomProperties->Lookup(
"SDLHelperWindowActivationState"));
548 return (activationState != CoreWindowActivationState::Deactivated);
565 if (WINRT_GlobalSDLWindow !=
NULL) {
585 data->coreWindow = CoreWindow::GetForCurrentThread();
586 #if SDL_WINRT_USE_APPLICATIONVIEW 587 data->appView = ApplicationView::GetForCurrentView();
594 #if SDL_VIDEO_OPENGL_EGL 608 if (SDL_EGL_ChooseConfig(
_this) != 0) {
618 Microsoft::WRL::ComPtr<IUnknown> cpp_winrtEglWindow = video_data->
winrtEglWindow;
619 data->
egl_surface = ((eglCreateWindowSurface_Old_Function)
_this->egl_data->eglCreateWindowSurface)(
620 _this->egl_data->egl_display,
621 _this->egl_data->egl_config,
622 cpp_winrtEglWindow,
NULL);
624 return SDL_EGL_SetError(
"unable to create EGL native-window surface",
"eglCreateWindowSurface");
626 }
else if (data->coreWindow.Get() !=
nullptr) {
630 IInspectable * coreWindowAsIInspectable =
reinterpret_cast<IInspectable *
>(data->coreWindow.Get());
632 _this->egl_data->egl_display,
633 _this->egl_data->egl_config,
634 coreWindowAsIInspectable,
637 return SDL_EGL_SetError(
"unable to create EGL native-window surface",
"eglCreateWindowSurface");
640 return SDL_SetError(
"No supported means to create an EGL window surface are available");
650 #if SDL_VIDEO_OPENGL_EGL 669 window->
x = WINRT_DIPS_TO_PHYSICAL_PIXELS(data->coreWindow->Bounds.Left);
670 window->
y = WINRT_DIPS_TO_PHYSICAL_PIXELS(data->coreWindow->Bounds.Top);
671 #if NTDDI_VERSION < NTDDI_WIN10 673 window->
w = WINRT_DIPS_TO_PHYSICAL_PIXELS(data->coreWindow->Bounds.Width);
674 window->
h = WINRT_DIPS_TO_PHYSICAL_PIXELS(data->coreWindow->Bounds.Height);
679 bool didSetSize =
false;
681 const Windows::Foundation::Size
size(WINRT_PHYSICAL_PIXELS_TO_DIPS(window->
w),
682 WINRT_PHYSICAL_PIXELS_TO_DIPS(window->
h));
683 didSetSize = data->appView->TryResizeView(
size);
689 window->
w = WINRT_DIPS_TO_PHYSICAL_PIXELS(data->coreWindow->Bounds.Width);
690 window->
h = WINRT_DIPS_TO_PHYSICAL_PIXELS(data->coreWindow->Bounds.Height);
700 bool isWindowActive = WINRT_IsCoreWindowActive(data->coreWindow.Get());
701 if (isWindowActive) {
709 WINRT_GlobalSDLWindow =
window;
718 #if NTDDI_VERSION >= NTDDI_WIN10 720 const Windows::Foundation::Size
size(WINRT_PHYSICAL_PIXELS_TO_DIPS(window->
w),
721 WINRT_PHYSICAL_PIXELS_TO_DIPS(window->
h));
722 data->appView->TryResizeView(
size);
729 #if NTDDI_VERSION >= NTDDI_WIN10 731 bool isWindowActive = WINRT_IsCoreWindowActive(data->coreWindow.Get());
732 if (isWindowActive) {
734 if (!data->appView->IsFullScreenMode) {
735 data->appView->TryEnterFullScreenMode();
738 if (data->appView->IsFullScreenMode) {
739 data->appView->ExitFullScreenMode();
752 if (WINRT_GlobalSDLWindow == window) {
753 WINRT_GlobalSDLWindow =
NULL;
771 info->
info.winrt.
window =
reinterpret_cast<IInspectable *
>(data->coreWindow.Get());
781 static ABI::Windows::System::Display::IDisplayRequest *
782 WINRT_CreateDisplayRequest(
_THIS)
785 wchar_t *wClassName = L
"Windows.System.Display.DisplayRequest";
787 IActivationFactory *pActivationFactory =
NULL;
788 IInspectable * pDisplayRequestRaw =
nullptr;
789 ABI::Windows::System::Display::IDisplayRequest * pDisplayRequest =
nullptr;
792 hr = ::WindowsCreateString(wClassName, (UINT32)wcslen(wClassName), &hClassName);
797 hr = Windows::Foundation::GetActivationFactory(hClassName, &pActivationFactory);
802 hr = pActivationFactory->ActivateInstance(&pDisplayRequestRaw);
807 hr = pDisplayRequestRaw->QueryInterface(IID_IDisplayRequest, (
void **) &pDisplayRequest);
813 if (pDisplayRequestRaw) {
814 pDisplayRequestRaw->Release();
816 if (pActivationFactory) {
817 pActivationFactory->Release();
820 ::WindowsDeleteString(hClassName);
823 return pDisplayRequest;
827 WINRT_SuspendScreenSaver(
_THIS)
831 ABI::Windows::System::Display::IDisplayRequest *
displayRequest = (ABI::Windows::System::Display::IDisplayRequest *) driverdata->
displayRequest;
833 displayRequest->RequestActive();
835 displayRequest->RequestRelease();
#define SDL_MINOR_VERSION
void WINRT_UpdateWindowFlags(SDL_Window *window, Uint32 mask)
void SDL_SetKeyboardFocus(SDL_Window *window)
#define SDL_MAJOR_VERSION
SDL_bool(* IsScreenKeyboardShown)(_THIS, SDL_Window *window)
#define SDL_WINRT_USE_APPLICATIONVIEW
struct wl_display * display
GLfloat GLfloat GLfloat GLfloat h
int WIN_SetErrorFromHRESULT(const char *prefix, HRESULT hr)
int(* GL_SetSwapInterval)(_THIS, int interval)
The structure that defines a display mode.
void WINRT_InitMouse(_THIS)
void(* SetWindowSize)(_THIS, SDL_Window *window)
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
void SDL_SetMouseFocus(SDL_Window *window)
int SDL_AddVideoDisplay(const SDL_VideoDisplay *display)
int(* GL_LoadLibrary)(_THIS, const char *path)
int(* SetDisplayMode)(_THIS, SDL_VideoDisplay *display, SDL_DisplayMode *mode)
static SDL_VideoDevice * _this
static SDL_AudioDeviceID device
VideoBootStrap WINRT_bootstrap
SDL_bool(* GetWindowWMInfo)(_THIS, SDL_Window *window, struct SDL_SysWMinfo *info)
SDL_GLContext(* GL_CreateContext)(_THIS, SDL_Window *window)
int(* GL_MakeCurrent)(_THIS, SDL_Window *window, SDL_GLContext context)
void WINRT_InitTouch(_THIS)
HRESULT(WINAPI *GetDpiForMonitor)(HMONITOR hmonitor
void WINRT_PumpEvents(_THIS)
IUnknown * displayRequest
SDL_DisplayMode current_mode
GLubyte GLubyte GLubyte GLubyte w
void(* DestroyWindow)(_THIS, SDL_Window *window)
#define WIN_StringToUTF8(S)
Uint32 WINRT_DetectWindowFlags(SDL_Window *window)
GLenum GLuint GLenum GLsizei const GLchar * buf
SDL_bool(* HasScreenKeyboardSupport)(_THIS)
SDL_Window * WINRT_GlobalSDLWindow
void(* GL_UnloadLibrary)(_THIS)
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int in i)
int(* CreateSDLWindow)(_THIS, SDL_Window *window)
#define SDL_OutOfMemory()
SDL_DisplayMode desktop_mode
Uint32 last_fullscreen_flags
SDL_VideoDisplay * SDL_GetDisplayForWindow(SDL_Window *window)
EGLSurface EGLNativeWindowType * window
int(* GL_SwapWindow)(_THIS, SDL_Window *window)
void(* ShowScreenKeyboard)(_THIS, SDL_Window *window)
The type used to identify a window.
SDL_bool WINRT_XAMLWasEnabled
void WINRT_QuitMouse(_THIS)
SDL_bool SDL_AddDisplayMode(SDL_VideoDisplay *display, const SDL_DisplayMode *mode)
IUnknown * winrtEglWindow
SDL_bool suspend_screensaver
union SDL_SysWMinfo::@18 info
void(* SetWindowFullscreen)(_THIS, SDL_Window *window, SDL_VideoDisplay *display, SDL_bool fullscreen)
void(* GL_DeleteContext)(_THIS, SDL_GLContext context)
int(* GL_GetSwapInterval)(_THIS)
void(* SuspendScreenSaver)(_THIS)
void *(* GL_GetProcAddress)(_THIS, const char *proc)
void(* PumpEvents)(_THIS)
void(* HideScreenKeyboard)(_THIS, SDL_Window *window)