Skip to content

Commit

Permalink
WinRT: lots of display and windowing related fixes
Browse files Browse the repository at this point in the history
This change-set fixes a lot of windowing related bugs, especially with
regards to Windows 8.x apps running on Windows 10 (which was the driver for
this work).  The primary fixes include:
* listed display modes were wrong, especially when launching apps into a
  non-fullscreen space
* reported window flags were often wrong, especially on Windows 10
* fullscreen/windowed mode switches weren't failing (they are not
  programmatically possible in Win 8.x apps).
  • Loading branch information
DavidLudwig committed Nov 26, 2015
1 parent a5a80cd commit 623898f
Show file tree
Hide file tree
Showing 9 changed files with 543 additions and 235 deletions.
18 changes: 15 additions & 3 deletions include/SDL_config_winrt.h
Expand Up @@ -19,11 +19,23 @@
3. This notice may not be removed or altered from any source distribution.
*/

#ifndef _SDL_config_windows_h
#define _SDL_config_windows_h
#ifndef _SDL_config_winrt_h
#define _SDL_config_winrt_h

#include "SDL_platform.h"

/* Make sure the Windows SDK's NTDDI_VERSION macro gets defined. This is used
by SDL to determine which version of the Windows SDK is being used.
*/
#include <sdkddkver.h>

/* Define possibly-undefined NTDDI values (used when compiling SDL against
older versions of the Windows SDK.
*/
#ifndef NTDDI_WINBLUE
#define NTDDI_WINBLUE 0x06030000
#endif

/* This is a set of defines to configure the SDL features */

#if !defined(_STDINT_H_) && (!defined(HAVE_STDINT_H) || !_HAVE_STDINT_H)
Expand Down Expand Up @@ -191,4 +203,4 @@ typedef unsigned int uintptr_t;
#define SDL_ASSEMBLY_ROUTINES 1
#endif

#endif /* _SDL_config_windows_h */
#endif /* _SDL_config_winrt_h */
284 changes: 174 additions & 110 deletions src/core/winrt/SDL_winrtapp_direct3d.cpp

Large diffs are not rendered by default.

5 changes: 4 additions & 1 deletion src/core/winrt/SDL_winrtapp_direct3d.h
Expand Up @@ -56,16 +56,19 @@ ref class SDL_WinRTApp sealed : public Windows::ApplicationModel::Core::IFramewo
#endif
void OnWindowSizeChanged(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::WindowSizeChangedEventArgs^ args);
void OnLogicalDpiChanged(Platform::Object^ sender);
void OnActivated(Windows::ApplicationModel::Core::CoreApplicationView^ applicationView, Windows::ApplicationModel::Activation::IActivatedEventArgs^ args);
void OnAppActivated(Windows::ApplicationModel::Core::CoreApplicationView^ applicationView, Windows::ApplicationModel::Activation::IActivatedEventArgs^ args);
void OnSuspending(Platform::Object^ sender, Windows::ApplicationModel::SuspendingEventArgs^ args);
void OnResuming(Platform::Object^ sender, Platform::Object^ args);
void OnExiting(Platform::Object^ sender, Platform::Object^ args);
void OnWindowActivated(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::WindowActivatedEventArgs^ args);
void OnWindowClosed(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::CoreWindowEventArgs^ args);
void OnVisibilityChanged(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::VisibilityChangedEventArgs^ args);
void OnPointerPressed(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::PointerEventArgs^ args);
void OnPointerReleased(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::PointerEventArgs^ args);
void OnPointerWheelChanged(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::PointerEventArgs^ args);
void OnPointerMoved(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::PointerEventArgs^ args);
void OnPointerEntered(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::PointerEventArgs^ args);
void OnPointerExited(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::PointerEventArgs^ args);
void OnMouseMoved(Windows::Devices::Input::MouseDevice^ mouseDevice, Windows::Devices::Input::MouseEventArgs^ args);
void OnKeyDown(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::KeyEventArgs^ args);
void OnKeyUp(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::KeyEventArgs^ args);
Expand Down
6 changes: 3 additions & 3 deletions src/render/direct3d11/SDL_render_d3d11.c
Expand Up @@ -760,8 +760,8 @@ SDL_RenderDriver D3D11_RenderDriver = {
};


static Uint32
DXGIFormatToSDLPixelFormat(DXGI_FORMAT dxgiFormat) {
Uint32
D3D11_DXGIFormatToSDLPixelFormat(DXGI_FORMAT dxgiFormat) {
switch (dxgiFormat) {
case DXGI_FORMAT_B8G8R8A8_UNORM:
return SDL_PIXELFORMAT_ARGB8888;
Expand Down Expand Up @@ -2911,7 +2911,7 @@ D3D11_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
*/
if (SDL_ConvertPixels(
rect->w, rect->h,
DXGIFormatToSDLPixelFormat(stagingTextureDesc.Format),
D3D11_DXGIFormatToSDLPixelFormat(stagingTextureDesc.Format),
textureMemory.pData,
textureMemory.RowPitch,
format,
Expand Down
40 changes: 40 additions & 0 deletions src/video/SDL_video.c
Expand Up @@ -1125,6 +1125,10 @@ SDL_RestoreMousePosition(SDL_Window *window)
}
}

#if __WINRT__
extern Uint32 WINRT_DetectWindowFlags(SDL_Window * window);
#endif

static int
SDL_UpdateFullscreenMode(SDL_Window * window, SDL_bool fullscreen)
{
Expand Down Expand Up @@ -1164,6 +1168,30 @@ SDL_UpdateFullscreenMode(SDL_Window * window, SDL_bool fullscreen)
window->last_fullscreen_flags = window->flags;
return 0;
}
#elif __WINRT__
/* HACK: WinRT 8.x apps can't choose whether or not they are fullscreen
or not. The user can choose this, via OS-provided UI, but this can't
be set programmatically.
Just look at what SDL's WinRT video backend code detected with regards
to fullscreen (being active, or not), and figure out a return/error code
from that.
*/
if (fullscreen == !(WINRT_DetectWindowFlags(window) & FULLSCREEN_MASK)) {
/* Uh oh, either:
1. fullscreen was requested, and we're already windowed
2. windowed-mode was requested, and we're already fullscreen
WinRT 8.x can't resolve either programmatically, so we're
giving up.
*/
return -1;
} else {
/* Whatever was requested, fullscreen or windowed mode, is already
in-place.
*/
return 0;
}
#endif

display = SDL_GetDisplayForWindow(window);
Expand Down Expand Up @@ -1377,6 +1405,18 @@ SDL_CreateWindow(const char *title, int x, int y, int w, int h, Uint32 flags)
return NULL;
}

#if __WINRT__
/* HACK: WinRT 8.x apps can't choose whether or not they are fullscreen
or not. The user can choose this, via OS-provided UI, but this can't
be set programmatically.
Just look at what SDL's WinRT video backend code detected with regards
to fullscreen (being active, or not), and figure out a return/error code
from that.
*/
flags = window->flags;
#endif

if (title) {
SDL_SetWindowTitle(window, title);
}
Expand Down
2 changes: 2 additions & 0 deletions src/video/winrt/SDL_winrtevents_c.h
Expand Up @@ -57,6 +57,8 @@ extern Uint8 WINRT_GetSDLButtonForPointerPoint(Windows::UI::Input::PointerPoint
extern void WINRT_ProcessPointerPressedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint);
extern void WINRT_ProcessPointerMovedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint);
extern void WINRT_ProcessPointerReleasedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint);
extern void WINRT_ProcessPointerEnteredEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint);
extern void WINRT_ProcessPointerExitedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint);
extern void WINRT_ProcessPointerWheelChangedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint);
extern void WINRT_ProcessMouseMovedEvent(SDL_Window * window, Windows::Devices::Input::MouseEventArgs ^args);

Expand Down
22 changes: 22 additions & 0 deletions src/video/winrt/SDL_winrtpointerinput.cpp
Expand Up @@ -306,6 +306,28 @@ void WINRT_ProcessPointerReleasedEvent(SDL_Window *window, Windows::UI::Input::P
}
}

void WINRT_ProcessPointerEnteredEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint)
{
if (!window) {
return;
}

if (!WINRT_IsTouchEvent(pointerPoint)) {
SDL_SetMouseFocus(window);
}
}

void WINRT_ProcessPointerExitedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint)
{
if (!window) {
return;
}

if (!WINRT_IsTouchEvent(pointerPoint)) {
SDL_SetMouseFocus(NULL);
}
}

void
WINRT_ProcessPointerWheelChangedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint)
{
Expand Down

0 comments on commit 623898f

Please sign in to comment.