21 #include "../../SDL_internal.h" 23 #if SDL_VIDEO_DRIVER_WINRT 33 #include <windows.graphics.display.h> 40 using namespace Windows::UI::ViewManagement;
44 static const GUID IID_IDXGIFactory2 = { 0x50c83a1c, 0xe072, 0x4c48,{ 0x87, 0xb0, 0x36, 0x30, 0xfa, 0x36, 0xa6, 0xd0 } };
51 #include "../SDL_sysvideo.h" 52 #include "../SDL_pixels_c.h" 53 #include "../../events/SDL_events_c.h" 54 #include "../../render/SDL_sysrender.h" 57 #include "../../core/windows/SDL_windows.h" 60 #include "../../core/winrt/SDL_winrtapp_direct3d.h" 61 #include "../../core/winrt/SDL_winrtapp_xaml.h" 71 static int WINRT_VideoInit(
_THIS);
72 static int WINRT_InitModes(
_THIS);
74 static void WINRT_VideoQuit(
_THIS);
112 WINRT_CreateDevice(
int devindex)
145 #ifdef SDL_VIDEO_OPENGL_EGL 156 device->
free = WINRT_DeleteDevice;
161 #define WINRTVID_DRIVER_NAME "winrt" 163 WINRTVID_DRIVER_NAME,
"SDL WinRT video driver",
164 WINRT_Available, WINRT_CreateDevice
168 WINRT_VideoInit(
_THIS)
170 if (WINRT_InitModes(
_this) < 0) {
180 Uint32 D3D11_DXGIFormatToSDLPixelFormat(DXGI_FORMAT dxgiFormat);
183 WINRT_DXGIModeToSDLDisplayMode(
const DXGI_MODE_DESC * dxgiMode,
SDL_DisplayMode * sdlMode)
186 sdlMode->
w = dxgiMode->Width;
187 sdlMode->
h = dxgiMode->Height;
188 sdlMode->
refresh_rate = dxgiMode->RefreshRate.Numerator / dxgiMode->RefreshRate.Denominator;
189 sdlMode->
format = D3D11_DXGIFormatToSDLPixelFormat(dxgiMode->Format);
193 WINRT_AddDisplaysForOutput (
_THIS, IDXGIAdapter1 * dxgiAdapter1,
int outputIndex)
196 IDXGIOutput * dxgiOutput =
NULL;
197 DXGI_OUTPUT_DESC dxgiOutputDesc;
199 char * displayName =
NULL;
201 DXGI_MODE_DESC * dxgiModes =
NULL;
202 int functionResult = -1;
203 DXGI_MODE_DESC modeToMatch, closestMatch;
207 hr = dxgiAdapter1->EnumOutputs(outputIndex, &dxgiOutput);
209 if (hr != DXGI_ERROR_NOT_FOUND) {
215 hr = dxgiOutput->GetDesc(&dxgiOutputDesc);
222 modeToMatch.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
223 modeToMatch.Width = (dxgiOutputDesc.DesktopCoordinates.right - dxgiOutputDesc.DesktopCoordinates.left);
224 modeToMatch.Height = (dxgiOutputDesc.DesktopCoordinates.bottom - dxgiOutputDesc.DesktopCoordinates.top);
225 hr = dxgiOutput->FindClosestMatchingMode(&modeToMatch, &closestMatch,
NULL);
226 if (hr == DXGI_ERROR_NOT_CURRENTLY_AVAILABLE) {
237 display.
name =
"Windows Simulator / Terminal Services Display";
238 mode.
w = (dxgiOutputDesc.DesktopCoordinates.right - dxgiOutputDesc.DesktopCoordinates.left);
239 mode.
h = (dxgiOutputDesc.DesktopCoordinates.bottom - dxgiOutputDesc.DesktopCoordinates.top);
240 mode.
format = DXGI_FORMAT_B8G8R8A8_UNORM;
252 display.
name = displayName;
253 WINRT_DXGIModeToSDLDisplayMode(&closestMatch, &display.
desktop_mode);
256 hr = dxgiOutput->GetDisplayModeList(DXGI_FORMAT_B8G8R8A8_UNORM, 0, &numModes,
NULL);
258 if (hr == DXGI_ERROR_NOT_CURRENTLY_AVAILABLE) {
265 dxgiModes = (DXGI_MODE_DESC *)
SDL_calloc(numModes,
sizeof(DXGI_MODE_DESC));
271 hr = dxgiOutput->GetDisplayModeList(DXGI_FORMAT_B8G8R8A8_UNORM, 0, &numModes, dxgiModes);
277 for (
UINT i = 0;
i < numModes; ++
i) {
279 WINRT_DXGIModeToSDLDisplayMode(&dxgiModes[
i], &sdlMode);
294 dxgiOutput->Release();
299 return functionResult;
303 WINRT_AddDisplaysForAdapter (
_THIS, IDXGIFactory2 * dxgiFactory2,
int adapterIndex)
306 IDXGIAdapter1 * dxgiAdapter1;
308 hr = dxgiFactory2->EnumAdapters1(adapterIndex, &dxgiAdapter1);
310 if (hr != DXGI_ERROR_NOT_FOUND) {
316 for (
int outputIndex = 0; ; ++outputIndex) {
317 if (WINRT_AddDisplaysForOutput(
_this, dxgiAdapter1, outputIndex) < 0) {
333 if (adapterIndex == 0 && outputIndex == 0) {
336 #if SDL_WINRT_USE_APPLICATIONVIEW 337 ApplicationView ^ appView = ApplicationView::GetForCurrentView();
339 CoreWindow ^ coreWin = CoreWindow::GetForCurrentThread();
342 display.
name =
"DXGI Display-detection Workaround";
351 #if (NTDDI_VERSION >= NTDDI_WIN10) || (SDL_WINRT_USE_APPLICATIONVIEW && WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) 352 mode.
w = WINRT_DIPS_TO_PHYSICAL_PIXELS(appView->VisibleBounds.Width);
353 mode.
h = WINRT_DIPS_TO_PHYSICAL_PIXELS(appView->VisibleBounds.Height);
358 mode.
w = WINRT_DIPS_TO_PHYSICAL_PIXELS(coreWin->Bounds.Width);
359 mode.
h = WINRT_DIPS_TO_PHYSICAL_PIXELS(coreWin->Bounds.Height);
362 mode.
format = DXGI_FORMAT_B8G8R8A8_UNORM;
369 return SDL_SetError(
"Failed to apply DXGI Display-detection workaround");
377 dxgiAdapter1->Release();
382 WINRT_InitModes(
_THIS)
391 IDXGIFactory2 * dxgiFactory2 =
NULL;
393 hr = CreateDXGIFactory1(IID_IDXGIFactory2, (
void **)&dxgiFactory2);
399 for (
int adapterIndex = 0; ; ++adapterIndex) {
400 if (WINRT_AddDisplaysForAdapter(
_this, dxgiFactory2, adapterIndex) < 0) {
415 WINRT_VideoQuit(
_THIS)
420 static const Uint32 WINRT_DetectableFlags =
432 bool is_fullscreen =
false;
436 is_fullscreen = data->appView->IsFullScreen;
438 #elif (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) || (NTDDI_VERSION == NTDDI_WIN8) 439 is_fullscreen =
true;
442 if (data->coreWindow.Get()) {
445 int w = WINRT_DIPS_TO_PHYSICAL_PIXELS(data->coreWindow->Bounds.Width);
446 int h = WINRT_DIPS_TO_PHYSICAL_PIXELS(data->coreWindow->Bounds.Height);
448 #if (WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP) || (NTDDI_VERSION > NTDDI_WIN8) 452 const DisplayOrientations currentOrientation = WINRT_DISPLAY_PROPERTY(CurrentOrientation);
453 switch (currentOrientation) {
454 #if (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) 455 case DisplayOrientations::Landscape:
456 case DisplayOrientations::LandscapeFlipped:
458 case DisplayOrientations::Portrait:
459 case DisplayOrientations::PortraitFlipped:
476 if (data->coreWindow->Visible) {
482 #if (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) && (NTDDI_VERSION < NTDDI_WINBLUE) 486 if (data->coreWindow->Bounds.Contains(data->coreWindow->PointerPosition)) {
499 mask &= WINRT_DetectableFlags;
505 window->
flags = (window->
flags & ~mask) | (apply & mask);
510 WINRT_IsCoreWindowActive(CoreWindow ^ coreWindow)
520 if (coreWindow->CustomProperties->HasKey(
"SDLHelperWindowActivationState")) {
521 CoreWindowActivationState activationState = \
522 safe_cast<CoreWindowActivationState>(coreWindow->CustomProperties->Lookup(
"SDLHelperWindowActivationState"));
523 return (activationState != CoreWindowActivationState::Deactivated);
540 if (WINRT_GlobalSDLWindow !=
NULL) {
560 data->coreWindow = CoreWindow::GetForCurrentThread();
561 #if SDL_WINRT_USE_APPLICATIONVIEW 562 data->appView = ApplicationView::GetForCurrentView();
569 #if SDL_VIDEO_OPENGL_EGL 583 if (SDL_EGL_ChooseConfig(
_this) != 0) {
593 Microsoft::WRL::ComPtr<IUnknown> cpp_winrtEglWindow = video_data->
winrtEglWindow;
594 data->
egl_surface = ((eglCreateWindowSurface_Old_Function)
_this->egl_data->eglCreateWindowSurface)(
595 _this->egl_data->egl_display,
596 _this->egl_data->egl_config,
597 cpp_winrtEglWindow,
NULL);
601 }
else if (data->coreWindow.Get() !=
nullptr) {
605 IInspectable * coreWindowAsIInspectable =
reinterpret_cast<IInspectable *
>(data->coreWindow.Get());
607 _this->egl_data->egl_display,
608 _this->egl_data->egl_config,
609 coreWindowAsIInspectable,
615 return SDL_SetError(
"No supported means to create an EGL window surface are available");
625 #if SDL_VIDEO_OPENGL_EGL 644 window->
x = WINRT_DIPS_TO_PHYSICAL_PIXELS(data->coreWindow->Bounds.Left);
645 window->
y = WINRT_DIPS_TO_PHYSICAL_PIXELS(data->coreWindow->Bounds.Top);
646 #if NTDDI_VERSION < NTDDI_WIN10 648 window->
w = WINRT_DIPS_TO_PHYSICAL_PIXELS(data->coreWindow->Bounds.Width);
649 window->
h = WINRT_DIPS_TO_PHYSICAL_PIXELS(data->coreWindow->Bounds.Height);
654 bool didSetSize =
false;
656 const Windows::Foundation::Size
size(WINRT_PHYSICAL_PIXELS_TO_DIPS(window->
w),
657 WINRT_PHYSICAL_PIXELS_TO_DIPS(window->
h));
658 didSetSize = data->appView->TryResizeView(
size);
664 window->
w = WINRT_DIPS_TO_PHYSICAL_PIXELS(data->coreWindow->Bounds.Width);
665 window->
h = WINRT_DIPS_TO_PHYSICAL_PIXELS(data->coreWindow->Bounds.Height);
675 bool isWindowActive = WINRT_IsCoreWindowActive(data->coreWindow.Get());
676 if (isWindowActive) {
684 WINRT_GlobalSDLWindow =
window;
693 #if NTDDI_VERSION >= NTDDI_WIN10 695 const Windows::Foundation::Size
size(WINRT_PHYSICAL_PIXELS_TO_DIPS(window->
w),
696 WINRT_PHYSICAL_PIXELS_TO_DIPS(window->
h));
697 data->appView->TryResizeView(
size);
704 #if NTDDI_VERSION >= NTDDI_WIN10 706 bool isWindowActive = WINRT_IsCoreWindowActive(data->coreWindow.Get());
707 if (isWindowActive) {
709 if (!data->appView->IsFullScreenMode) {
710 data->appView->TryEnterFullScreenMode();
713 if (data->appView->IsFullScreenMode) {
714 data->appView->ExitFullScreenMode();
727 if (WINRT_GlobalSDLWindow == window) {
728 WINRT_GlobalSDLWindow =
NULL;
746 info->
info.winrt.
window =
reinterpret_cast<IInspectable *
>(data->coreWindow.Get());
749 SDL_SetError(
"Application not compiled with SDL %d.%d\n",
#define SDL_MINOR_VERSION
void WINRT_UpdateWindowFlags(SDL_Window *window, Uint32 mask)
void SDL_SetKeyboardFocus(SDL_Window *window)
uint32_t Uint32
An unsigned 32-bit integer type.
#define SDL_MAJOR_VERSION
#define SDL_WINRT_USE_APPLICATIONVIEW
struct wl_display * display
int WIN_SetErrorFromHRESULT(const char *prefix, HRESULT hr)
int(* GL_SetSwapInterval)(_THIS, int interval)
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
The structure that defines a display mode.
void WINRT_InitMouse(_THIS)
void(* SetWindowSize)(_THIS, SDL_Window *window)
void SDL_SetMouseFocus(SDL_Window *window)
void(* GL_SwapWindow)(_THIS, 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
void * SDL_calloc(size_t nmemb, size_t size)
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)
SDL_DisplayMode current_mode
void(* DestroyWindow)(_THIS, SDL_Window *window)
#define WIN_StringToUTF8(S)
Uint32 WINRT_DetectWindowFlags(SDL_Window *window)
GLenum GLuint GLenum GLsizei const GLchar * buf
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)
#define SDL_OutOfMemory()
SDL_DisplayMode desktop_mode
Uint32 last_fullscreen_flags
SDL_VideoDisplay * SDL_GetDisplayForWindow(SDL_Window *window)
int(* CreateWindow)(_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
union SDL_SysWMinfo::@18 info
void(* SetWindowFullscreen)(_THIS, SDL_Window *window, SDL_VideoDisplay *display, SDL_bool fullscreen)
GLubyte GLubyte GLubyte GLubyte w
void(* GL_DeleteContext)(_THIS, SDL_GLContext context)
int(* GL_GetSwapInterval)(_THIS)
GLfloat GLfloat GLfloat GLfloat h
void *(* GL_GetProcAddress)(_THIS, const char *proc)
void(* PumpEvents)(_THIS)