21 #include "../../SDL_internal.h"
23 #if SDL_VIDEO_DRIVER_WINRT
33 #include <windows.graphics.display.h>
34 #include <windows.system.display.h>
37 using namespace Windows::ApplicationModel::Core;
38 using namespace Windows::Foundation;
39 using namespace Windows::Graphics::Display;
40 using namespace Windows::UI::Core;
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"
73 static int WINRT_VideoInit(
_THIS);
74 static int WINRT_InitModes(
_THIS);
76 static void WINRT_VideoQuit(
_THIS);
88 static ABI::Windows::System::Display::IDisplayRequest * WINRT_CreateDisplayRequest(
_THIS);
89 extern void WINRT_SuspendScreenSaver(
_THIS);
113 WINRT_CreateDevice(
int devindex)
134 device->VideoInit = WINRT_VideoInit;
135 device->VideoQuit = WINRT_VideoQuit;
136 device->CreateSDLWindow = WINRT_CreateWindow;
137 device->SetWindowSize = WINRT_SetWindowSize;
138 device->SetWindowFullscreen = WINRT_SetWindowFullscreen;
139 device->DestroyWindow = WINRT_DestroyWindow;
140 device->SetDisplayMode = WINRT_SetDisplayMode;
142 device->GetWindowWMInfo = WINRT_GetWindowWMInfo;
143 device->SuspendScreenSaver = WINRT_SuspendScreenSaver;
145 #if NTDDI_VERSION >= NTDDI_WIN10
146 device->HasScreenKeyboardSupport = WINRT_HasScreenKeyboardSupport;
147 device->ShowScreenKeyboard = WINRT_ShowScreenKeyboard;
148 device->HideScreenKeyboard = WINRT_HideScreenKeyboard;
149 device->IsScreenKeyboardShown = WINRT_IsScreenKeyboardShown;
152 #ifdef SDL_VIDEO_OPENGL_EGL
153 device->GL_LoadLibrary = WINRT_GLES_LoadLibrary;
154 device->GL_GetProcAddress = WINRT_GLES_GetProcAddress;
155 device->GL_UnloadLibrary = WINRT_GLES_UnloadLibrary;
156 device->GL_CreateContext = WINRT_GLES_CreateContext;
157 device->GL_MakeCurrent = WINRT_GLES_MakeCurrent;
158 device->GL_SetSwapInterval = WINRT_GLES_SetSwapInterval;
159 device->GL_GetSwapInterval = WINRT_GLES_GetSwapInterval;
160 device->GL_SwapWindow = WINRT_GLES_SwapWindow;
161 device->GL_DeleteContext = WINRT_GLES_DeleteContext;
163 device->free = WINRT_DeleteDevice;
168 #define WINRTVID_DRIVER_NAME "winrt"
170 WINRTVID_DRIVER_NAME,
"SDL WinRT video driver",
175 WINRT_VideoInit(
_THIS)
178 if (WINRT_InitModes(
_this) < 0) {
183 WINRT_InitGameBar(
_this);
192 Uint32 D3D11_DXGIFormatToSDLPixelFormat(DXGI_FORMAT dxgiFormat);
195 WINRT_DXGIModeToSDLDisplayMode(
const DXGI_MODE_DESC * dxgiMode,
SDL_DisplayMode * sdlMode)
198 sdlMode->
w = dxgiMode->Width;
199 sdlMode->
h = dxgiMode->Height;
200 sdlMode->
refresh_rate = dxgiMode->RefreshRate.Numerator / dxgiMode->RefreshRate.Denominator;
201 sdlMode->
format = D3D11_DXGIFormatToSDLPixelFormat(dxgiMode->Format);
205 WINRT_AddDisplaysForOutput (
_THIS, IDXGIAdapter1 * dxgiAdapter1,
int outputIndex)
208 IDXGIOutput * dxgiOutput =
NULL;
209 DXGI_OUTPUT_DESC dxgiOutputDesc;
211 char * displayName =
NULL;
213 DXGI_MODE_DESC * dxgiModes =
NULL;
214 int functionResult = -1;
215 DXGI_MODE_DESC modeToMatch, closestMatch;
219 hr = dxgiAdapter1->EnumOutputs(outputIndex, &dxgiOutput);
221 if (hr != DXGI_ERROR_NOT_FOUND) {
227 hr = dxgiOutput->GetDesc(&dxgiOutputDesc);
234 modeToMatch.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
235 modeToMatch.Width = (dxgiOutputDesc.DesktopCoordinates.right - dxgiOutputDesc.DesktopCoordinates.left);
236 modeToMatch.Height = (dxgiOutputDesc.DesktopCoordinates.bottom - dxgiOutputDesc.DesktopCoordinates.top);
237 hr = dxgiOutput->FindClosestMatchingMode(&modeToMatch, &closestMatch,
NULL);
238 if (hr == DXGI_ERROR_NOT_CURRENTLY_AVAILABLE) {
249 display.
name =
"Windows Simulator / Terminal Services Display";
250 mode.w = (dxgiOutputDesc.DesktopCoordinates.right - dxgiOutputDesc.DesktopCoordinates.left);
251 mode.h = (dxgiOutputDesc.DesktopCoordinates.bottom - dxgiOutputDesc.DesktopCoordinates.top);
252 mode.format = DXGI_FORMAT_B8G8R8A8_UNORM;
253 mode.refresh_rate = 0;
264 display.
name = displayName;
265 WINRT_DXGIModeToSDLDisplayMode(&closestMatch, &display.
desktop_mode);
268 hr = dxgiOutput->GetDisplayModeList(DXGI_FORMAT_B8G8R8A8_UNORM, 0, &numModes,
NULL);
270 if (hr == DXGI_ERROR_NOT_CURRENTLY_AVAILABLE) {
277 dxgiModes = (DXGI_MODE_DESC *)
SDL_calloc(numModes,
sizeof(DXGI_MODE_DESC));
283 hr = dxgiOutput->GetDisplayModeList(DXGI_FORMAT_B8G8R8A8_UNORM, 0, &numModes, dxgiModes);
289 for (UINT
i = 0;
i < numModes; ++
i) {
291 WINRT_DXGIModeToSDLDisplayMode(&dxgiModes[
i], &sdlMode);
306 dxgiOutput->Release();
311 return functionResult;
315 WINRT_AddDisplaysForAdapter (
_THIS, IDXGIFactory2 * dxgiFactory2,
int adapterIndex)
318 IDXGIAdapter1 * dxgiAdapter1;
320 hr = dxgiFactory2->EnumAdapters1(adapterIndex, &dxgiAdapter1);
322 if (hr != DXGI_ERROR_NOT_FOUND) {
328 for (
int outputIndex = 0; ; ++outputIndex) {
329 if (WINRT_AddDisplaysForOutput(
_this, dxgiAdapter1, outputIndex) < 0) {
345 if (adapterIndex == 0 && outputIndex == 0) {
348 #if SDL_WINRT_USE_APPLICATIONVIEW
349 ApplicationView ^ appView = ApplicationView::GetForCurrentView();
351 CoreWindow ^ coreWin = CoreWindow::GetForCurrentThread();
354 display.
name =
"DXGI Display-detection Workaround";
363 #if (NTDDI_VERSION >= NTDDI_WIN10) || (SDL_WINRT_USE_APPLICATIONVIEW && WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP)
364 mode.w = WINRT_DIPS_TO_PHYSICAL_PIXELS(appView->VisibleBounds.Width);
365 mode.h = WINRT_DIPS_TO_PHYSICAL_PIXELS(appView->VisibleBounds.Height);
370 mode.w = WINRT_DIPS_TO_PHYSICAL_PIXELS(coreWin->Bounds.Width);
371 mode.h = WINRT_DIPS_TO_PHYSICAL_PIXELS(coreWin->Bounds.Height);
374 mode.format = DXGI_FORMAT_B8G8R8A8_UNORM;
375 mode.refresh_rate = 0;
381 return SDL_SetError(
"Failed to apply DXGI Display-detection workaround");
389 dxgiAdapter1->Release();
394 WINRT_InitModes(
_THIS)
403 IDXGIFactory2 * dxgiFactory2 =
NULL;
405 hr = CreateDXGIFactory1(IID_IDXGIFactory2, (
void **)&dxgiFactory2);
411 for (
int adapterIndex = 0; ; ++adapterIndex) {
412 if (WINRT_AddDisplaysForAdapter(
_this, dxgiFactory2, adapterIndex) < 0) {
427 WINRT_VideoQuit(
_THIS)
434 WINRT_QuitGameBar(
_this);
438 static const Uint32 WINRT_DetectableFlags =
450 bool is_fullscreen =
false;
454 is_fullscreen =
data->appView->IsFullScreen;
456 #elif (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) || (NTDDI_VERSION == NTDDI_WIN8)
457 is_fullscreen =
true;
460 if (
data->coreWindow.Get()) {
463 int w = WINRT_DIPS_TO_PHYSICAL_PIXELS(
data->coreWindow->Bounds.Width);
464 int h = WINRT_DIPS_TO_PHYSICAL_PIXELS(
data->coreWindow->Bounds.Height);
466 #if (WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP) || (NTDDI_VERSION > NTDDI_WIN8)
470 const DisplayOrientations currentOrientation = WINRT_DISPLAY_PROPERTY(CurrentOrientation);
471 switch (currentOrientation) {
472 #if (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP)
473 case DisplayOrientations::Landscape:
474 case DisplayOrientations::LandscapeFlipped:
476 case DisplayOrientations::Portrait:
477 case DisplayOrientations::PortraitFlipped:
494 if (
data->coreWindow->Visible) {
500 #if (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) && (NTDDI_VERSION < NTDDI_WINBLUE)
504 if (
data->coreWindow->Visible &&
data->coreWindow->Bounds.Contains(
data->coreWindow->PointerPosition)) {
517 mask &= WINRT_DetectableFlags;
528 WINRT_IsCoreWindowActive(CoreWindow ^ coreWindow)
538 if (coreWindow->CustomProperties->HasKey(
"SDLHelperWindowActivationState")) {
539 CoreWindowActivationState activationState = \
540 safe_cast<CoreWindowActivationState>(coreWindow->CustomProperties->Lookup(
"SDLHelperWindowActivationState"));
541 return (activationState != CoreWindowActivationState::Deactivated);
578 data->coreWindow = CoreWindow::GetForCurrentThread();
579 #if SDL_WINRT_USE_APPLICATIONVIEW
580 data->appView = ApplicationView::GetForCurrentView();
587 #if SDL_VIDEO_OPENGL_EGL
601 if (SDL_EGL_ChooseConfig(
_this) != 0) {
611 Microsoft::WRL::ComPtr<IUnknown> cpp_winrtEglWindow = video_data->
winrtEglWindow;
612 data->egl_surface = ((eglCreateWindowSurface_Old_Function)
_this->egl_data->eglCreateWindowSurface)(
613 _this->egl_data->egl_display,
614 _this->egl_data->egl_config,
615 cpp_winrtEglWindow,
NULL);
617 return SDL_EGL_SetError(
"unable to create EGL native-window surface",
"eglCreateWindowSurface");
619 }
else if (
data->coreWindow.Get() !=
nullptr) {
623 IInspectable * coreWindowAsIInspectable =
reinterpret_cast<IInspectable *
>(
data->coreWindow.Get());
624 data->egl_surface =
_this->egl_data->eglCreateWindowSurface(
625 _this->egl_data->egl_display,
626 _this->egl_data->egl_config,
627 coreWindowAsIInspectable,
630 return SDL_EGL_SetError(
"unable to create EGL native-window surface",
"eglCreateWindowSurface");
633 return SDL_SetError(
"No supported means to create an EGL window surface are available");
643 #if SDL_VIDEO_OPENGL_EGL
644 if (
data->egl_surface) {
662 window->x = WINRT_DIPS_TO_PHYSICAL_PIXELS(
data->coreWindow->Bounds.Left);
663 window->y = WINRT_DIPS_TO_PHYSICAL_PIXELS(
data->coreWindow->Bounds.Top);
664 #if NTDDI_VERSION < NTDDI_WIN10
666 window->w = WINRT_DIPS_TO_PHYSICAL_PIXELS(
data->coreWindow->Bounds.Width);
667 window->h = WINRT_DIPS_TO_PHYSICAL_PIXELS(
data->coreWindow->Bounds.Height);
672 bool didSetSize =
false;
674 const Windows::Foundation::Size
size(WINRT_PHYSICAL_PIXELS_TO_DIPS(
window->w),
675 WINRT_PHYSICAL_PIXELS_TO_DIPS(
window->h));
676 didSetSize =
data->appView->TryResizeView(
size);
682 window->w = WINRT_DIPS_TO_PHYSICAL_PIXELS(
data->coreWindow->Bounds.Width);
683 window->h = WINRT_DIPS_TO_PHYSICAL_PIXELS(
data->coreWindow->Bounds.Height);
693 bool isWindowActive = WINRT_IsCoreWindowActive(
data->coreWindow.Get());
694 if (isWindowActive) {
711 #if NTDDI_VERSION >= NTDDI_WIN10
713 const Windows::Foundation::Size
size(WINRT_PHYSICAL_PIXELS_TO_DIPS(
window->w),
714 WINRT_PHYSICAL_PIXELS_TO_DIPS(
window->h));
722 #if NTDDI_VERSION >= NTDDI_WIN10
724 bool isWindowActive = WINRT_IsCoreWindowActive(
data->coreWindow.Get());
725 if (isWindowActive) {
727 if (!
data->appView->IsFullScreenMode) {
728 data->appView->TryEnterFullScreenMode();
731 if (
data->appView->IsFullScreenMode) {
732 data->appView->ExitFullScreenMode();
764 info->
info.winrt.
window =
reinterpret_cast<IInspectable *
>(
data->coreWindow.Get());
774 static ABI::Windows::System::Display::IDisplayRequest *
775 WINRT_CreateDisplayRequest(
_THIS)
778 wchar_t *wClassName = L
"Windows.System.Display.DisplayRequest";
780 IActivationFactory *pActivationFactory =
NULL;
781 IInspectable * pDisplayRequestRaw =
nullptr;
782 ABI::Windows::System::Display::IDisplayRequest * pDisplayRequest =
nullptr;
785 hr = ::WindowsCreateString(wClassName, (UINT32)wcslen(wClassName), &hClassName);
790 hr = Windows::Foundation::GetActivationFactory(hClassName, &pActivationFactory);
795 hr = pActivationFactory->ActivateInstance(&pDisplayRequestRaw);
800 hr = pDisplayRequestRaw->QueryInterface(IID_IDisplayRequest, (
void **) &pDisplayRequest);
806 if (pDisplayRequestRaw) {
807 pDisplayRequestRaw->Release();
809 if (pActivationFactory) {
810 pActivationFactory->Release();
813 ::WindowsDeleteString(hClassName);
816 return pDisplayRequest;
820 WINRT_SuspendScreenSaver(
_THIS)
824 ABI::Windows::System::Display::IDisplayRequest * displayRequest = (ABI::Windows::System::Display::IDisplayRequest *) driverdata->
displayRequest;
826 displayRequest->RequestActive();
828 displayRequest->RequestRelease();
#define SDL_OutOfMemory()
void SDL_SetKeyboardFocus(SDL_Window *window)
void SDL_SetMouseFocus(SDL_Window *window)
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
GLenum GLuint GLenum GLsizei const GLchar * buf
GLfloat GLfloat GLfloat GLfloat h
GLubyte GLubyte GLubyte GLubyte w
VideoBootStrap WINRT_bootstrap
int SDL_AddVideoDisplay(const SDL_VideoDisplay *display, SDL_bool send_event)
SDL_bool SDL_AddDisplayMode(SDL_VideoDisplay *display, const SDL_DisplayMode *mode)
SDL_VideoDisplay * SDL_GetDisplayForWindow(SDL_Window *window)
#define SDL_MINOR_VERSION
#define SDL_MAJOR_VERSION
static SDL_VideoDevice * _this
@ SDL_WINDOW_FULLSCREEN_DESKTOP
#define WIN_StringToUTF8(S)
int WIN_SetErrorFromHRESULT(const char *prefix, HRESULT hr)
SDL_bool WINRT_XAMLWasEnabled
void WINRT_InitTouch(_THIS)
void WINRT_PumpEvents(_THIS)
void WINRT_QuitMouse(_THIS)
void WINRT_InitMouse(_THIS)
Uint32 WINRT_DetectWindowFlags(SDL_Window *window)
#define SDL_WINRT_USE_APPLICATIONVIEW
SDL_Window * WINRT_GlobalSDLWindow
void WINRT_UpdateWindowFlags(SDL_Window *window, Uint32 mask)
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)
EGLSurface EGLNativeWindowType * window
static SDL_AudioDeviceID device
set set set set set set set macro pixldst1 abits if abits op else op endif endm macro pixldst2 abits if abits op else op endif endm macro pixldst4 abits if abits op else op endif endm macro pixldst0 abits op endm macro pixldst3 mem_operand op endm macro pixldst30 mem_operand op endm macro pixldst abits if abits elseif abits elseif abits elseif abits elseif abits pixldst0 abits else pixldst0 abits pixldst0 abits pixldst0 abits pixldst0 abits endif elseif abits else pixldst0 abits pixldst0 abits endif elseif abits else error unsupported bpp *numpix else pixst endif endm macro pixld1_s mem_operand if asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl elseif asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl else error unsupported endif endm macro pixld2_s mem_operand if mov asr add asl add asl mov asr sub UNIT_X add asl mov asr add asl add asl mov asr add UNIT_X add asl else pixld1_s mem_operand pixld1_s mem_operand endif endm macro pixld0_s mem_operand if asr adds SRC_WIDTH_FIXED bpl add asl elseif asr adds SRC_WIDTH_FIXED bpl add asl endif endm macro pixld_s_internal mem_operand if mem_operand pixld2_s mem_operand pixdeinterleave basereg elseif mem_operand elseif mem_operand elseif mem_operand elseif mem_operand pixld0_s mem_operand else pixld0_s mem_operand pixld0_s mem_operand pixld0_s mem_operand pixld0_s mem_operand endif elseif mem_operand else pixld0_s mem_operand pixld0_s mem_operand endif elseif mem_operand else error unsupported mem_operand if bpp mem_operand endif endm macro vuzp8 reg2 vuzp d d ®2 endm macro vzip8 reg2 vzip d d ®2 endm macro pixdeinterleave basereg basereg basereg basereg basereg endif endm macro pixinterleave basereg basereg basereg basereg basereg endif endm macro PF boost_increment endif if endif PF tst PF addne PF subne PF cmp ORIG_W if endif if endif if endif PF subge ORIG_W PF subges if endif if endif if endif endif endm macro cache_preload_simple endif if dst_r_bpp pld[DST_R, #(PREFETCH_DISTANCE_SIMPLE *dst_r_bpp/8)] endif if mask_bpp pld if[MASK, #(PREFETCH_DISTANCE_SIMPLE *mask_bpp/8)] endif endif endm macro fetch_mask_pixblock pixld mask_basereg pixblock_size MASK endm macro ensure_destination_ptr_alignment process_pixblock_tail_head if beq irp skip1(dst_w_bpp<=(lowbit *8)) &&((lowbit *8)<(pixblock_size *dst_w_bpp)) .if lowbit< 16 tst DST_R
The structure that defines a display mode.
union SDL_SysWMinfo::@10 info
IUnknown * winrtEglWindow
IUnknown * displayRequest
SDL_bool suspend_screensaver
SDL_DisplayMode desktop_mode
SDL_DisplayMode current_mode
The type used to identify a window.