removed WinRT support.

This commit is contained in:
Ozkan Sezer
2022-11-22 23:36:24 +03:00
parent bd5d26071a
commit dc2a3e06e9
86 changed files with 81 additions and 8098 deletions

View File

@@ -22,7 +22,7 @@
#if defined(__WIN32__) || defined(__GDK__)
#include "core/windows/SDL_windows.h"
#elif !defined(__WINRT__)
#else
#include <unistd.h> /* _exit(), etc. */
#endif
@@ -575,8 +575,6 @@ SDL_GetPlatform(void)
return "Solaris";
#elif __WIN32__
return "Windows";
#elif __WINRT__
return "WinRT";
#elif __WINGDK__
return "WinGDK";
#elif __XBOXONE__

View File

@@ -20,7 +20,7 @@
*/
#include "./SDL_internal.h"
#if defined(__WIN32__) || defined(__WINRT__) || defined(__GDK__)
#if defined(__WIN32__) || defined(__GDK__)
#include "core/windows/SDL_windows.h"
#endif
@@ -366,7 +366,7 @@ SDL_LogMessageV(int category, SDL_LogPriority priority, const char *fmt, va_list
}
}
#if defined(__WIN32__) && !defined(HAVE_STDIO_H) && !defined(__WINRT__) && !defined(__GDK__)
#if defined(__WIN32__) && !defined(HAVE_STDIO_H) && !defined(__GDK__)
/* Flag tracking the attachment of the console: 0=unattached, 1=attached to a console, 2=attached to a file, -1=error */
static int consoleAttached = 0;
@@ -378,7 +378,7 @@ static void SDLCALL
SDL_LogOutput(void *userdata, int category, SDL_LogPriority priority,
const char *message)
{
#if defined(__WIN32__) || defined(__WINRT__) || defined(__GDK__)
#if defined(__WIN32__) || defined(__GDK__)
/* Way too many allocations here, urgh */
/* Note: One can't call SDL_SetError here, since that function itself logs. */
{
@@ -387,7 +387,7 @@ SDL_LogOutput(void *userdata, int category, SDL_LogPriority priority,
LPTSTR tstr;
SDL_bool isstack;
#if !defined(HAVE_STDIO_H) && !defined(__WINRT__) && !defined(__GDK__)
#if !defined(HAVE_STDIO_H) && !defined(__GDK__)
BOOL attachResult;
DWORD attachError;
DWORD charsWritten;
@@ -426,7 +426,7 @@ SDL_LogOutput(void *userdata, int category, SDL_LogPriority priority,
}
}
}
#endif /* !defined(HAVE_STDIO_H) && !defined(__WINRT__) && !defined(__GDK__) */
#endif /* !defined(HAVE_STDIO_H) && !defined(__GDK__) */
length = SDL_strlen(SDL_priority_prefixes[priority]) + 2 + SDL_strlen(message) + 1 + 1 + 1;
output = SDL_small_alloc(char, length, &isstack);
@@ -436,7 +436,7 @@ SDL_LogOutput(void *userdata, int category, SDL_LogPriority priority,
/* Output to debugger */
OutputDebugString(tstr);
#if !defined(HAVE_STDIO_H) && !defined(__WINRT__) && !defined(__GDK__)
#if !defined(HAVE_STDIO_H) && !defined(__GDK__)
/* Screen output to stderr, if console was attached. */
if (consoleAttached == 1) {
if (!WriteConsole(stderrHandle, tstr, (DWORD) SDL_tcslen(tstr), &charsWritten, NULL)) {
@@ -451,7 +451,7 @@ SDL_LogOutput(void *userdata, int category, SDL_LogPriority priority,
OutputDebugString(TEXT("Error calling WriteFile\r\n"));
}
}
#endif /* !defined(HAVE_STDIO_H) && !defined(__WINRT__) && !defined(__GDK__) */
#endif /* !defined(HAVE_STDIO_H) && !defined(__GDK__) */
SDL_free(tstr);
SDL_small_free(output, isstack);

View File

@@ -20,7 +20,7 @@
*/
#include "../SDL_internal.h"
#if defined(__WIN32__) || defined(__WINRT__) || defined(__GDK__)
#if defined(__WIN32__) || defined(__GDK__)
#include "../core/windows/SDL_windows.h"
#endif

View File

@@ -419,7 +419,7 @@ WASAPI_PrepDevice(_THIS, const SDL_bool updatestream)
SDL_assert(client != NULL);
#if defined(__WINRT__) || defined(__GDK__) /* CreateEventEx() arrived in Vista, so we need an #ifdef for XP. */
#if defined(__GDK__) /* CreateEventEx() arrived in Vista, so we need an #ifdef for XP. */
this->hidden->event = CreateEventEx(NULL, NULL, 0, EVENT_ALL_ACCESS);
#else
this->hidden->event = CreateEventW(NULL, 0, 0, NULL);

View File

@@ -26,7 +26,7 @@
The code in SDL_wasapi.c is used by both standard Windows and WinRT builds
to deal with audio and calls into these functions. */
#if SDL_AUDIO_DRIVER_WASAPI && !defined(__WINRT__)
#if SDL_AUDIO_DRIVER_WASAPI
#include "../../core/windows/SDL_windows.h"
#include "../../core/windows/SDL_immdevice.h"
@@ -156,7 +156,7 @@ WASAPI_PlatformDeleteActivationHandler(void *handler)
SDL_assert(!"This function should have only been called on WinRT.");
}
#endif /* SDL_AUDIO_DRIVER_WASAPI && !defined(__WINRT__) */
#endif /* SDL_AUDIO_DRIVER_WASAPI */
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -1,447 +0,0 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2022 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"
// This is C++/CX code that the WinRT port uses to talk to WASAPI-related
// system APIs. The C implementation of these functions, for non-WinRT apps,
// is in SDL_wasapi_win32.c. The code in SDL_wasapi.c is used by both standard
// Windows and WinRT builds to deal with audio and calls into these functions.
#if SDL_AUDIO_DRIVER_WASAPI && defined(__WINRT__)
#include <Windows.h>
#include <windows.ui.core.h>
#include <windows.devices.enumeration.h>
#include <windows.media.devices.h>
#include <wrl/implements.h>
#include <collection.h>
extern "C" {
#include "../../core/windows/SDL_windows.h"
#include "SDL_audio.h"
#include "SDL_timer.h"
#include "../SDL_audio_c.h"
#include "../SDL_sysaudio.h"
}
#define COBJMACROS
#include <mmdeviceapi.h>
#include <audioclient.h>
#include "SDL_wasapi.h"
using namespace Windows::Devices::Enumeration;
using namespace Windows::Media::Devices;
using namespace Windows::Foundation;
using namespace Microsoft::WRL;
static Platform::String^ SDL_PKEY_AudioEngine_DeviceFormat = L"{f19f064d-082c-4e27-bc73-6882a1bb8e4c} 0";
static void WASAPI_AddDevice(const SDL_bool iscapture, const char *devname, WAVEFORMATEXTENSIBLE *fmt, LPCWSTR devid);
static void WASAPI_RemoveDevice(const SDL_bool iscapture, LPCWSTR devid);
extern "C" {
SDL_atomic_t SDL_IMMDevice_DefaultPlaybackGeneration;
SDL_atomic_t SDL_IMMDevice_DefaultCaptureGeneration;
}
/* This is a list of device id strings we have inflight, so we have consistent pointers to the same device. */
typedef struct DevIdList
{
WCHAR *str;
struct DevIdList *next;
} DevIdList;
static DevIdList *deviceid_list = NULL;
class SDL_WasapiDeviceEventHandler
{
public:
SDL_WasapiDeviceEventHandler(const SDL_bool _iscapture);
~SDL_WasapiDeviceEventHandler();
void OnDeviceAdded(DeviceWatcher^ sender, DeviceInformation^ args);
void OnDeviceRemoved(DeviceWatcher^ sender, DeviceInformationUpdate^ args);
void OnDeviceUpdated(DeviceWatcher^ sender, DeviceInformationUpdate^ args);
void OnEnumerationCompleted(DeviceWatcher^ sender, Platform::Object^ args);
void OnDefaultRenderDeviceChanged(Platform::Object^ sender, DefaultAudioRenderDeviceChangedEventArgs^ args);
void OnDefaultCaptureDeviceChanged(Platform::Object^ sender, DefaultAudioCaptureDeviceChangedEventArgs^ args);
SDL_semaphore* completed;
private:
const SDL_bool iscapture;
DeviceWatcher^ watcher;
Windows::Foundation::EventRegistrationToken added_handler;
Windows::Foundation::EventRegistrationToken removed_handler;
Windows::Foundation::EventRegistrationToken updated_handler;
Windows::Foundation::EventRegistrationToken completed_handler;
Windows::Foundation::EventRegistrationToken default_changed_handler;
};
SDL_WasapiDeviceEventHandler::SDL_WasapiDeviceEventHandler(const SDL_bool _iscapture)
: iscapture(_iscapture)
, completed(SDL_CreateSemaphore(0))
{
if (!completed)
return; // uhoh.
Platform::String^ selector = _iscapture ? MediaDevice::GetAudioCaptureSelector() :
MediaDevice::GetAudioRenderSelector();
Platform::Collections::Vector<Platform::String^> properties;
properties.Append(SDL_PKEY_AudioEngine_DeviceFormat);
watcher = DeviceInformation::CreateWatcher(selector, properties.GetView());
if (!watcher)
return; // uhoh.
// !!! FIXME: this doesn't need a lambda here, I think, if I make SDL_WasapiDeviceEventHandler a proper C++/CX class. --ryan.
added_handler = watcher->Added += ref new TypedEventHandler<DeviceWatcher^, DeviceInformation^>([this](DeviceWatcher^ sender, DeviceInformation^ args) { OnDeviceAdded(sender, args); } );
removed_handler = watcher->Removed += ref new TypedEventHandler<DeviceWatcher^, DeviceInformationUpdate^>([this](DeviceWatcher^ sender, DeviceInformationUpdate^ args) { OnDeviceRemoved(sender, args); } );
updated_handler = watcher->Updated += ref new TypedEventHandler<DeviceWatcher^, DeviceInformationUpdate^>([this](DeviceWatcher^ sender, DeviceInformationUpdate^ args) { OnDeviceUpdated(sender, args); } );
completed_handler = watcher->EnumerationCompleted += ref new TypedEventHandler<DeviceWatcher^, Platform::Object^>([this](DeviceWatcher^ sender, Platform::Object^ args) { OnEnumerationCompleted(sender, args); } );
if (iscapture) {
default_changed_handler = MediaDevice::DefaultAudioCaptureDeviceChanged += ref new TypedEventHandler<Platform::Object^, DefaultAudioCaptureDeviceChangedEventArgs^>([this](Platform::Object^ sender, DefaultAudioCaptureDeviceChangedEventArgs^ args) { OnDefaultCaptureDeviceChanged(sender, args); } );
} else {
default_changed_handler = MediaDevice::DefaultAudioRenderDeviceChanged += ref new TypedEventHandler<Platform::Object^, DefaultAudioRenderDeviceChangedEventArgs^>([this](Platform::Object^ sender, DefaultAudioRenderDeviceChangedEventArgs^ args) { OnDefaultRenderDeviceChanged(sender, args); } );
}
watcher->Start();
}
SDL_WasapiDeviceEventHandler::~SDL_WasapiDeviceEventHandler()
{
if (watcher) {
watcher->Added -= added_handler;
watcher->Removed -= removed_handler;
watcher->Updated -= updated_handler;
watcher->EnumerationCompleted -= completed_handler;
watcher->Stop();
watcher = nullptr;
}
if (completed) {
SDL_DestroySemaphore(completed);
completed = nullptr;
}
if (iscapture) {
MediaDevice::DefaultAudioCaptureDeviceChanged -= default_changed_handler;
} else {
MediaDevice::DefaultAudioRenderDeviceChanged -= default_changed_handler;
}
}
void
SDL_WasapiDeviceEventHandler::OnDeviceAdded(DeviceWatcher^ sender, DeviceInformation^ info)
{
SDL_assert(sender == this->watcher);
char *utf8dev = WIN_StringToUTF8(info->Name->Data());
if (utf8dev) {
WAVEFORMATEXTENSIBLE fmt;
Platform::Object^ obj = info->Properties->Lookup(SDL_PKEY_AudioEngine_DeviceFormat);
if (obj) {
IPropertyValue^ property = (IPropertyValue^) obj;
Platform::Array<unsigned char>^ data;
property->GetUInt8Array(&data);
SDL_memcpy(&fmt, data->Data, SDL_min(data->Length, sizeof(WAVEFORMATEXTENSIBLE)));
} else {
SDL_zero(fmt);
}
WASAPI_AddDevice(this->iscapture, utf8dev, &fmt, info->Id->Data());
SDL_free(utf8dev);
}
}
void
SDL_WasapiDeviceEventHandler::OnDeviceRemoved(DeviceWatcher^ sender, DeviceInformationUpdate^ info)
{
SDL_assert(sender == this->watcher);
WASAPI_RemoveDevice(this->iscapture, info->Id->Data());
}
void
SDL_WasapiDeviceEventHandler::OnDeviceUpdated(DeviceWatcher^ sender, DeviceInformationUpdate^ args)
{
SDL_assert(sender == this->watcher);
}
void
SDL_WasapiDeviceEventHandler::OnEnumerationCompleted(DeviceWatcher^ sender, Platform::Object^ args)
{
SDL_assert(sender == this->watcher);
SDL_SemPost(this->completed);
}
void
SDL_WasapiDeviceEventHandler::OnDefaultRenderDeviceChanged(Platform::Object^ sender, DefaultAudioRenderDeviceChangedEventArgs^ args)
{
SDL_assert(this->iscapture);
SDL_AtomicAdd(&SDL_IMMDevice_DefaultPlaybackGeneration, 1);
}
void
SDL_WasapiDeviceEventHandler::OnDefaultCaptureDeviceChanged(Platform::Object^ sender, DefaultAudioCaptureDeviceChangedEventArgs^ args)
{
SDL_assert(!this->iscapture);
SDL_AtomicAdd(&SDL_IMMDevice_DefaultCaptureGeneration, 1);
}
static SDL_WasapiDeviceEventHandler *playback_device_event_handler;
static SDL_WasapiDeviceEventHandler *capture_device_event_handler;
int WASAPI_PlatformInit(void)
{
SDL_AtomicSet(&SDL_IMMDevice_DefaultPlaybackGeneration, 1);
SDL_AtomicSet(&SDL_IMMDevice_DefaultCaptureGeneration, 1);
return 0;
}
void WASAPI_PlatformDeinit(void)
{
DevIdList *devidlist;
DevIdList *next;
delete playback_device_event_handler;
playback_device_event_handler = nullptr;
delete capture_device_event_handler;
capture_device_event_handler = nullptr;
for (devidlist = deviceid_list; devidlist; devidlist = next) {
next = devidlist->next;
SDL_free(devidlist->str);
SDL_free(devidlist);
}
deviceid_list = NULL;
}
void WASAPI_EnumerateEndpoints(void)
{
// DeviceWatchers will fire an Added event for each existing device at
// startup, so we don't need to enumerate them separately before
// listening for updates.
playback_device_event_handler = new SDL_WasapiDeviceEventHandler(SDL_FALSE);
capture_device_event_handler = new SDL_WasapiDeviceEventHandler(SDL_TRUE);
SDL_SemWait(playback_device_event_handler->completed);
SDL_SemWait(capture_device_event_handler->completed);
}
struct SDL_WasapiActivationHandler : public RuntimeClass< RuntimeClassFlags< ClassicCom >, FtmBase, IActivateAudioInterfaceCompletionHandler >
{
SDL_WasapiActivationHandler() : device(nullptr) {}
STDMETHOD(ActivateCompleted)(IActivateAudioInterfaceAsyncOperation *operation);
SDL_AudioDevice *device;
};
HRESULT
SDL_WasapiActivationHandler::ActivateCompleted(IActivateAudioInterfaceAsyncOperation *async)
{
// Just set a flag, since we're probably in a different thread. We'll pick it up and init everything on our own thread to prevent races.
SDL_AtomicSet(&device->hidden->just_activated, 1);
WASAPI_UnrefDevice(device);
return S_OK;
}
void
WASAPI_PlatformDeleteActivationHandler(void *handler)
{
((SDL_WasapiActivationHandler *) handler)->Release();
}
int
WASAPI_GetDefaultAudioInfo(char **name, SDL_AudioSpec *spec, int iscapture)
{
return SDL_Unsupported();
}
int
WASAPI_ActivateDevice(_THIS, const SDL_bool isrecovery)
{
LPCWSTR devid = _this->hidden->devid;
Platform::String^ defdevid;
if (devid == nullptr) {
defdevid = _this->iscapture ? MediaDevice::GetDefaultAudioCaptureId(AudioDeviceRole::Default) : MediaDevice::GetDefaultAudioRenderId(AudioDeviceRole::Default);
if (defdevid) {
devid = defdevid->Data();
}
}
SDL_AtomicSet(&_this->hidden->just_activated, 0);
ComPtr<SDL_WasapiActivationHandler> handler = Make<SDL_WasapiActivationHandler>();
if (handler == nullptr) {
return SDL_SetError("Failed to allocate WASAPI activation handler");
}
handler.Get()->AddRef(); // we hold a reference after ComPtr destructs on return, causing a Release, and Release ourselves in WASAPI_PlatformDeleteActivationHandler(), etc.
handler.Get()->device = _this;
_this->hidden->activation_handler = handler.Get();
WASAPI_RefDevice(_this); /* completion handler will unref it. */
IActivateAudioInterfaceAsyncOperation *async = nullptr;
const HRESULT ret = ActivateAudioInterfaceAsync(devid, __uuidof(IAudioClient), nullptr, handler.Get(), &async);
if (FAILED(ret) || async == nullptr) {
if (async != nullptr) {
async->Release();
}
handler.Get()->Release();
WASAPI_UnrefDevice(_this);
return WIN_SetErrorFromHRESULT("WASAPI can't activate requested audio endpoint", ret);
}
/* Spin until the async operation is complete.
* If we don't PrepDevice before leaving this function, the bug list gets LONG:
* - device.spec is not filled with the correct information
* - The 'obtained' spec will be wrong for ALLOW_CHANGE properties
* - SDL_AudioStreams will/will not be allocated at the right time
* - SDL_assert(device->callbackspec.size == device->spec.size) will fail
* - When the assert is ignored, skipping or a buffer overflow will occur
*/
while (!SDL_AtomicCAS(&_this->hidden->just_activated, 1, 0)) {
SDL_Delay(1);
}
HRESULT activateRes = S_OK;
IUnknown *iunknown = nullptr;
const HRESULT getActivateRes = async->GetActivateResult(&activateRes, &iunknown);
async->Release();
if (FAILED(getActivateRes)) {
return WIN_SetErrorFromHRESULT("Failed to get WASAPI activate result", getActivateRes);
} else if (FAILED(activateRes)) {
return WIN_SetErrorFromHRESULT("Failed to activate WASAPI device", activateRes);
}
iunknown->QueryInterface(IID_PPV_ARGS(&_this->hidden->client));
if (!_this->hidden->client) {
return SDL_SetError("Failed to query WASAPI client interface");
}
if (WASAPI_PrepDevice(_this, isrecovery) == -1) {
return -1;
}
return 0;
}
void
WASAPI_PlatformThreadInit(_THIS)
{
// !!! FIXME: set this thread to "Pro Audio" priority.
}
void
WASAPI_PlatformThreadDeinit(_THIS)
{
// !!! FIXME: set this thread to "Pro Audio" priority.
}
/* Everything below was copied from SDL_wasapi.c, before it got moved to SDL_immdevice.c! */
static const GUID SDL_KSDATAFORMAT_SUBTYPE_PCM = { 0x00000001, 0x0000, 0x0010,{ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 } };
static const GUID SDL_KSDATAFORMAT_SUBTYPE_IEEE_FLOAT = { 0x00000003, 0x0000, 0x0010,{ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 } };
extern "C" SDL_AudioFormat
WaveFormatToSDLFormat(WAVEFORMATEX *waveformat)
{
if ((waveformat->wFormatTag == WAVE_FORMAT_IEEE_FLOAT) && (waveformat->wBitsPerSample == 32)) {
return AUDIO_F32SYS;
} else if ((waveformat->wFormatTag == WAVE_FORMAT_PCM) && (waveformat->wBitsPerSample == 16)) {
return AUDIO_S16SYS;
} else if ((waveformat->wFormatTag == WAVE_FORMAT_PCM) && (waveformat->wBitsPerSample == 32)) {
return AUDIO_S32SYS;
} else if (waveformat->wFormatTag == WAVE_FORMAT_EXTENSIBLE) {
const WAVEFORMATEXTENSIBLE *ext = (const WAVEFORMATEXTENSIBLE *)waveformat;
if ((SDL_memcmp(&ext->SubFormat, &SDL_KSDATAFORMAT_SUBTYPE_IEEE_FLOAT, sizeof(GUID)) == 0) && (waveformat->wBitsPerSample == 32)) {
return AUDIO_F32SYS;
} else if ((SDL_memcmp(&ext->SubFormat, &SDL_KSDATAFORMAT_SUBTYPE_PCM, sizeof(GUID)) == 0) && (waveformat->wBitsPerSample == 16)) {
return AUDIO_S16SYS;
} else if ((SDL_memcmp(&ext->SubFormat, &SDL_KSDATAFORMAT_SUBTYPE_PCM, sizeof(GUID)) == 0) && (waveformat->wBitsPerSample == 32)) {
return AUDIO_S32SYS;
}
}
return 0;
}
static void
WASAPI_RemoveDevice(const SDL_bool iscapture, LPCWSTR devid)
{
DevIdList *i;
DevIdList *next;
DevIdList *prev = NULL;
for (i = deviceid_list; i; i = next) {
next = i->next;
if (SDL_wcscmp(i->str, devid) == 0) {
if (prev) {
prev->next = next;
}
else {
deviceid_list = next;
}
SDL_RemoveAudioDevice(iscapture, i->str);
SDL_free(i->str);
SDL_free(i);
} else {
prev = i;
}
}
}
static void
WASAPI_AddDevice(const SDL_bool iscapture, const char *devname, WAVEFORMATEXTENSIBLE *fmt, LPCWSTR devid)
{
DevIdList *devidlist;
SDL_AudioSpec spec;
/* You can have multiple endpoints on a device that are mutually exclusive ("Speakers" vs "Line Out" or whatever).
In a perfect world, things that are unplugged won't be in this collection. The only gotcha is probably for
phones and tablets, where you might have an internal speaker and a headphone jack and expect both to be
available and switch automatically. (!!! FIXME...?) */
/* see if we already have this one. */
for (devidlist = deviceid_list; devidlist; devidlist = devidlist->next) {
if (SDL_wcscmp(devidlist->str, devid) == 0) {
return; /* we already have this. */
}
}
devidlist = (DevIdList *)SDL_malloc(sizeof(*devidlist));
if (!devidlist) {
return; /* oh well. */
}
devid = SDL_wcsdup(devid);
if (!devid) {
SDL_free(devidlist);
return; /* oh well. */
}
devidlist->str = (WCHAR *)devid;
devidlist->next = deviceid_list;
deviceid_list = devidlist;
SDL_zero(spec);
spec.channels = (Uint8)fmt->Format.nChannels;
spec.freq = fmt->Format.nSamplesPerSec;
spec.format = WaveFormatToSDLFormat((WAVEFORMATEX *)fmt);
SDL_AddAudioDevice(iscapture, devname, &spec, (void *)devid);
}
#endif // SDL_AUDIO_DRIVER_WASAPI && defined(__WINRT__)
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -20,8 +20,6 @@
*/
#include "../../SDL_internal.h"
#ifndef __WINRT__
#include "SDL_hid.h"
@@ -85,6 +83,4 @@ WIN_UnloadHIDDLL(void)
}
}
#endif /* !__WINRT__ */
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -25,8 +25,6 @@
#include "SDL_windows.h"
#ifndef __WINRT__
typedef LONG NTSTATUS;
typedef USHORT USAGE;
typedef struct _HIDP_PREPARSED_DATA *PHIDP_PREPARSED_DATA;
@@ -197,8 +195,6 @@ extern HidP_GetValueCaps_t SDL_HidP_GetValueCaps;
extern HidP_MaxDataListLength_t SDL_HidP_MaxDataListLength;
extern HidP_GetData_t SDL_HidP_GetData;
#endif /* !__WINRT__ */
#endif /* SDL_hid_h_ */
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -20,7 +20,7 @@
*/
#include "../../SDL_internal.h"
#if defined(__WIN32__) || defined(__WINRT__) || defined(__GDK__)
#if defined(__WIN32__) || defined(__GDK__)
#include "SDL_windows.h"
#include "SDL_error.h"
@@ -89,14 +89,7 @@ WIN_CoInitialize(void)
If you need multi-threaded mode, call CoInitializeEx() before SDL_Init()
*/
#ifdef __WINRT__
/* DLudwig: On WinRT, it is assumed that COM was initialized in main().
CoInitializeEx is available (not CoInitialize though), however
on WinRT, main() is typically declared with the [MTAThread]
attribute, which, AFAIK, should initialize COM.
*/
return S_OK;
#elif defined(__XBOXONE__) || defined(__XBOXSERIES__)
#if defined(__XBOXONE__) || defined(__XBOXSERIES__)
/* On Xbox, there's no need to call CoInitializeEx (and it's not implemented) */
return S_OK;
#else
@@ -118,12 +111,9 @@ WIN_CoInitialize(void)
void
WIN_CoUninitialize(void)
{
#ifndef __WINRT__
CoUninitialize();
#endif
}
#ifndef __WINRT__
void *
WIN_LoadComBaseFunction(const char *name)
{
@@ -140,14 +130,10 @@ WIN_LoadComBaseFunction(const char *name)
return NULL;
}
}
#endif
HRESULT
WIN_RoInitialize(void)
{
#ifdef __WINRT__
return S_OK;
#else
typedef HRESULT (WINAPI *RoInitialize_t)(RO_INIT_TYPE initType);
RoInitialize_t RoInitializeFunc = (RoInitialize_t)WIN_LoadComBaseFunction("RoInitialize");
if (RoInitializeFunc) {
@@ -167,22 +153,19 @@ WIN_RoInitialize(void)
} else {
return E_NOINTERFACE;
}
#endif
}
void
WIN_RoUninitialize(void)
{
#ifndef __WINRT__
typedef void (WINAPI *RoUninitialize_t)(void);
RoUninitialize_t RoUninitializeFunc = (RoUninitialize_t)WIN_LoadComBaseFunction("RoUninitialize");
if (RoUninitializeFunc) {
RoUninitializeFunc();
}
#endif
}
#if !defined(__WINRT__) && !defined(__XBOXONE__) && !defined(__XBOXSERIES__)
#if !defined(__XBOXONE__) && !defined(__XBOXSERIES__)
static BOOL
IsWindowsVersionOrGreater(WORD wMajorVersion, WORD wMinorVersion, WORD wServicePackMajor)
{
@@ -206,7 +189,7 @@ IsWindowsVersionOrGreater(WORD wMajorVersion, WORD wMinorVersion, WORD wServiceP
BOOL WIN_IsWindowsVistaOrGreater(void)
{
#if defined(__WINRT__) || defined(__XBOXONE__) || defined(__XBOXSERIES__)
#if defined(__XBOXONE__) || defined(__XBOXSERIES__)
return TRUE;
#else
return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_VISTA), LOBYTE(_WIN32_WINNT_VISTA), 0);
@@ -215,7 +198,7 @@ BOOL WIN_IsWindowsVistaOrGreater(void)
BOOL WIN_IsWindows7OrGreater(void)
{
#if defined(__WINRT__) || defined(__XBOXONE__) || defined(__XBOXSERIES__)
#if defined(__XBOXONE__) || defined(__XBOXSERIES__)
return TRUE;
#else
return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WIN7), LOBYTE(_WIN32_WINNT_WIN7), 0);
@@ -224,7 +207,7 @@ BOOL WIN_IsWindows7OrGreater(void)
BOOL WIN_IsWindows8OrGreater(void)
{
#if defined(__WINRT__) || defined(__XBOXONE__) || defined(__XBOXSERIES__)
#if defined(__XBOXONE__) || defined(__XBOXSERIES__)
return TRUE;
#else
return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WIN8), LOBYTE(_WIN32_WINNT_WIN8), 0);
@@ -255,8 +238,8 @@ WASAPI doesn't need this. This is just for DirectSound/WinMM.
char *
WIN_LookupAudioDeviceName(const WCHAR *name, const GUID *guid)
{
#if defined(__WINRT__) || defined(__XBOXONE__) || defined(__XBOXSERIES__)
return WIN_StringToUTF8(name); /* No registry access on WinRT/UWP and Xbox, go with what we've got. */
#if defined(__XBOXONE__) || defined(__XBOXSERIES__)
return WIN_StringToUTF8(name); /* No registry access on Xbox, go with what we've got. */
#else
static const GUID nullguid = { 0 };
const unsigned char *ptr;
@@ -308,7 +291,7 @@ WIN_LookupAudioDeviceName(const WCHAR *name, const GUID *guid)
retval = WIN_StringToUTF8(strw);
SDL_free(strw);
return retval ? retval : WIN_StringToUTF8(name);
#endif /* if __WINRT__ / else */
#endif /**/
}
BOOL
@@ -341,6 +324,6 @@ WIN_RectToRECT(const SDL_Rect *sdlrect, RECT *winrect)
winrect->bottom = sdlrect->y + sdlrect->h - 1;
}
#endif /* defined(__WIN32__) || defined(__WINRT__) || defined(__GDK__) */
#endif /* defined(__WIN32__) || defined(__GDK__) */
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -120,10 +120,8 @@ extern int WIN_SetErrorFromHRESULT(const char *prefix, HRESULT hr);
/* Sets an error message based on GetLastError(). Always return -1. */
extern int WIN_SetError(const char *prefix);
#if !defined(__WINRT__)
/* Load a function from combase.dll */
void *WIN_LoadComBaseFunction(const char *name);
#endif
/* Wrap up the oddities of CoInitialize() into a common function. */
extern HRESULT WIN_CoInitialize(void);

View File

@@ -37,7 +37,7 @@ static HANDLE s_pXInputDLL = 0;
static int s_XInputDLLRefCount = 0;
#if defined(__WINRT__) || defined(__XBOXONE__) || defined(__XBOXSERIES__)
#if defined(__XBOXONE__) || defined(__XBOXSERIES__)
int
WIN_LoadXInputDLL(void)
@@ -70,7 +70,7 @@ WIN_UnloadXInputDLL(void)
{
}
#else /* !(defined(__WINRT__) || defined(__XBOXONE__) || defined(__XBOXSERIES__)) */
#else /* !(defined(__XBOXONE__) || defined(__XBOXSERIES__)) */
int
WIN_LoadXInputDLL(void)
@@ -138,7 +138,7 @@ WIN_UnloadXInputDLL(void)
}
}
#endif /* __WINRT__ */
#endif /**/
/* Ends C function definitions when using C++ */
#ifdef __cplusplus

View File

@@ -1,67 +0,0 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2022 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"
#include "SDL_main.h"
#include "SDL_system.h"
#include "SDL_winrtapp_direct3d.h"
#include "SDL_winrtapp_xaml.h"
#include <wrl.h>
int (*WINRT_SDLAppEntryPoint)(int, char **) = NULL;
extern "C" DECLSPEC int
SDL_WinRTRunApp(SDL_main_func mainFunction, void * xamlBackgroundPanel)
{
if (xamlBackgroundPanel) {
return SDL_WinRTInitXAMLApp(mainFunction, xamlBackgroundPanel);
} else {
if (FAILED(Windows::Foundation::Initialize(RO_INIT_MULTITHREADED))) {
return 1;
}
return SDL_WinRTInitNonXAMLApp(mainFunction);
}
}
extern "C" DECLSPEC SDL_WinRT_DeviceFamily
SDL_WinRTGetDeviceFamily()
{
#if NTDDI_VERSION >= NTDDI_WIN10 /* !!! FIXME: I have no idea if this is the right test. This is a UWP API, I think. Older windows should...just return "mobile"? I don't know. --ryan. */
Platform::String^ deviceFamily = Windows::System::Profile::AnalyticsInfo::VersionInfo->DeviceFamily;
if (deviceFamily->Equals("Windows.Desktop"))
{
return SDL_WINRT_DEVICEFAMILY_DESKTOP;
}
else if (deviceFamily->Equals("Windows.Mobile"))
{
return SDL_WINRT_DEVICEFAMILY_MOBILE;
}
else if (deviceFamily->Equals("Windows.Xbox"))
{
return SDL_WINRT_DEVICEFAMILY_XBOX;
}
#endif
return SDL_WINRT_DEVICEFAMILY_UNKNOWN;
}

View File

@@ -1,31 +0,0 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2022 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_config.h"
#ifndef SDL_winrtapp_common_h_
#define SDL_winrtapp_common_h_
/* A pointer to the app's C-style main() function (which is a different
function than the WinRT app's actual entry point).
*/
extern int (*WINRT_SDLAppEntryPoint)(int, char **);
#endif // SDL_winrtapp_common_h_

View File

@@ -1,797 +0,0 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2022 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"
/* Standard C++11 includes */
#include <functional>
#include <string>
#include <sstream>
using namespace std;
/* Windows includes */
#include "ppltasks.h"
using namespace concurrency;
using namespace Windows::ApplicationModel;
using namespace Windows::ApplicationModel::Core;
using namespace Windows::ApplicationModel::Activation;
using namespace Windows::Devices::Input;
using namespace Windows::Graphics::Display;
using namespace Windows::Foundation;
using namespace Windows::System;
using namespace Windows::UI::Core;
using namespace Windows::UI::Input;
#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
using namespace Windows::Phone::UI::Input;
#endif
/* SDL includes */
extern "C" {
#include "SDL_events.h"
#include "SDL_hints.h"
#include "SDL_main.h"
#include "SDL_stdinc.h"
#include "SDL_render.h"
#include "../../video/SDL_sysvideo.h"
//#include "../../SDL_hints_c.h"
#include "../../events/SDL_events_c.h"
#include "../../events/SDL_keyboard_c.h"
#include "../../events/SDL_mouse_c.h"
#include "../../events/SDL_windowevents_c.h"
#include "../../render/SDL_sysrender.h"
#include "../windows/SDL_windows.h"
}
#include "../../video/winrt/SDL_winrtevents_c.h"
#include "../../video/winrt/SDL_winrtvideo_cpp.h"
#include "SDL_winrtapp_common.h"
#include "SDL_winrtapp_direct3d.h"
#if SDL_VIDEO_RENDER_D3D11 && !SDL_RENDER_DISABLED
/* Calling IDXGIDevice3::Trim on the active Direct3D 11.x device is necessary
* when Windows 8.1 apps are about to get suspended.
*/
extern "C" void D3D11_Trim(SDL_Renderer *);
#endif
// Compile-time debugging options:
// To enable, uncomment; to disable, comment them out.
//#define LOG_POINTER_EVENTS 1
//#define LOG_WINDOW_EVENTS 1
//#define LOG_ORIENTATION_EVENTS 1
// HACK, DLudwig: record a reference to the global, WinRT 'app'/view.
// SDL/WinRT will use this throughout its code.
//
// TODO, WinRT: consider replacing SDL_WinRTGlobalApp with something
// non-global, such as something created inside
// SDL_InitSubSystem(SDL_INIT_VIDEO), or something inside
// SDL_CreateWindow().
SDL_WinRTApp ^ SDL_WinRTGlobalApp = nullptr;
ref class SDLApplicationSource sealed : Windows::ApplicationModel::Core::IFrameworkViewSource
{
public:
virtual Windows::ApplicationModel::Core::IFrameworkView^ CreateView();
};
IFrameworkView^ SDLApplicationSource::CreateView()
{
// TODO, WinRT: see if this function (CreateView) can ever get called
// more than once. For now, just prevent it from ever assigning
// SDL_WinRTGlobalApp more than once.
SDL_assert(!SDL_WinRTGlobalApp);
SDL_WinRTApp ^ app = ref new SDL_WinRTApp();
if (!SDL_WinRTGlobalApp)
{
SDL_WinRTGlobalApp = app;
}
return app;
}
int SDL_WinRTInitNonXAMLApp(int (*mainFunction)(int, char **))
{
WINRT_SDLAppEntryPoint = mainFunction;
auto direct3DApplicationSource = ref new SDLApplicationSource();
CoreApplication::Run(direct3DApplicationSource);
return 0;
}
static void
WINRT_ProcessWindowSizeChange() // TODO: Pass an SDL_Window-identifying thing into WINRT_ProcessWindowSizeChange()
{
CoreWindow ^ coreWindow = CoreWindow::GetForCurrentThread();
if (coreWindow) {
if (WINRT_GlobalSDLWindow) {
SDL_Window * window = WINRT_GlobalSDLWindow;
SDL_WindowData * data = (SDL_WindowData *) window->driverdata;
int x = WINRT_DIPS_TO_PHYSICAL_PIXELS(data->coreWindow->Bounds.Left);
int y = WINRT_DIPS_TO_PHYSICAL_PIXELS(data->coreWindow->Bounds.Top);
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)
/* WinPhone 8.0 always keeps its native window size in portrait,
regardless of orientation. This changes in WinPhone 8.1,
in which the native window's size changes along with
orientation.
Attempt to emulate WinPhone 8.1's behavior on WinPhone 8.0, with
regards to window size. This fixes a rendering bug that occurs
when a WinPhone 8.0 app is rotated to either 90 or 270 degrees.
*/
const DisplayOrientations currentOrientation = WINRT_DISPLAY_PROPERTY(CurrentOrientation);
switch (currentOrientation) {
case DisplayOrientations::Landscape:
case DisplayOrientations::LandscapeFlipped: {
int tmp = w;
w = h;
h = tmp;
} break;
}
#endif
const Uint32 latestFlags = WINRT_DetectWindowFlags(window);
if (latestFlags & SDL_WINDOW_MAXIMIZED) {
SDL_SendWindowEvent(window, SDL_WINDOWEVENT_MAXIMIZED, 0, 0);
} else {
SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESTORED, 0, 0);
}
WINRT_UpdateWindowFlags(window, SDL_WINDOW_FULLSCREEN_DESKTOP);
/* The window can move during a resize event, such as when maximizing
or resizing from a corner */
SDL_SendWindowEvent(window, SDL_WINDOWEVENT_MOVED, x, y);
SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESIZED, w, h);
}
}
}
SDL_WinRTApp::SDL_WinRTApp() :
m_windowClosed(false),
m_windowVisible(true)
{
}
void SDL_WinRTApp::Initialize(CoreApplicationView^ applicationView)
{
applicationView->Activated +=
ref new TypedEventHandler<CoreApplicationView^, IActivatedEventArgs^>(this, &SDL_WinRTApp::OnAppActivated);
CoreApplication::Suspending +=
ref new EventHandler<SuspendingEventArgs^>(this, &SDL_WinRTApp::OnSuspending);
CoreApplication::Resuming +=
ref new EventHandler<Platform::Object^>(this, &SDL_WinRTApp::OnResuming);
CoreApplication::Exiting +=
ref new EventHandler<Platform::Object^>(this, &SDL_WinRTApp::OnExiting);
#if NTDDI_VERSION >= NTDDI_WIN10
/* HACK ALERT! Xbox One doesn't seem to detect gamepads unless something
gets registered to receive Win10's Windows.Gaming.Input.Gamepad.GamepadAdded
events. We'll register an event handler for these events here, to make
sure that gamepad detection works later on, if requested.
*/
Windows::Gaming::Input::Gamepad::GamepadAdded +=
ref new Windows::Foundation::EventHandler<Windows::Gaming::Input::Gamepad^>(
this, &SDL_WinRTApp::OnGamepadAdded
);
#endif
}
#if NTDDI_VERSION > NTDDI_WIN8
void SDL_WinRTApp::OnOrientationChanged(DisplayInformation^ sender, Object^ args)
#else
void SDL_WinRTApp::OnOrientationChanged(Object^ sender)
#endif
{
#if LOG_ORIENTATION_EVENTS==1
{
CoreWindow^ window = CoreWindow::GetForCurrentThread();
if (window) {
SDL_Log("%s, current orientation=%d, native orientation=%d, auto rot. pref=%d, CoreWindow Bounds={%f,%f,%f,%f}\n",
__FUNCTION__,
WINRT_DISPLAY_PROPERTY(CurrentOrientation),
WINRT_DISPLAY_PROPERTY(NativeOrientation),
WINRT_DISPLAY_PROPERTY(AutoRotationPreferences),
window->Bounds.X,
window->Bounds.Y,
window->Bounds.Width,
window->Bounds.Height);
} else {
SDL_Log("%s, current orientation=%d, native orientation=%d, auto rot. pref=%d\n",
__FUNCTION__,
WINRT_DISPLAY_PROPERTY(CurrentOrientation),
WINRT_DISPLAY_PROPERTY(NativeOrientation),
WINRT_DISPLAY_PROPERTY(AutoRotationPreferences));
}
}
#endif
WINRT_ProcessWindowSizeChange();
#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
// HACK: Make sure that orientation changes
// lead to the Direct3D renderer's viewport getting updated:
//
// For some reason, this doesn't seem to need to be done on Windows 8.x,
// even when going from Landscape to LandscapeFlipped. It only seems to
// be needed on Windows Phone, at least when I tested on my devices.
// I'm not currently sure why this is, but it seems to work fine. -- David L.
//
// TODO, WinRT: do more extensive research into why orientation changes on Win 8.x don't need D3D changes, or if they might, in some cases
SDL_Window * window = WINRT_GlobalSDLWindow;
if (window) {
SDL_WindowData * data = (SDL_WindowData *)window->driverdata;
int w = WINRT_DIPS_TO_PHYSICAL_PIXELS(data->coreWindow->Bounds.Width);
int h = WINRT_DIPS_TO_PHYSICAL_PIXELS(data->coreWindow->Bounds.Height);
SDL_SendWindowEvent(WINRT_GlobalSDLWindow, SDL_WINDOWEVENT_SIZE_CHANGED, w, h);
}
#endif
}
void SDL_WinRTApp::SetWindow(CoreWindow^ window)
{
#if LOG_WINDOW_EVENTS==1
SDL_Log("%s, current orientation=%d, native orientation=%d, auto rot. pref=%d, window bounds={%f, %f, %f,%f}\n",
__FUNCTION__,
WINRT_DISPLAY_PROPERTY(CurrentOrientation),
WINRT_DISPLAY_PROPERTY(NativeOrientation),
WINRT_DISPLAY_PROPERTY(AutoRotationPreferences),
window->Bounds.X,
window->Bounds.Y,
window->Bounds.Width,
window->Bounds.Height);
#endif
window->SizeChanged +=
ref new TypedEventHandler<CoreWindow^, WindowSizeChangedEventArgs^>(this, &SDL_WinRTApp::OnWindowSizeChanged);
window->VisibilityChanged +=
ref new TypedEventHandler<CoreWindow^, VisibilityChangedEventArgs^>(this, &SDL_WinRTApp::OnVisibilityChanged);
window->Activated +=
ref new TypedEventHandler<CoreWindow^, WindowActivatedEventArgs^>(this, &SDL_WinRTApp::OnWindowActivated);
window->Closed +=
ref new TypedEventHandler<CoreWindow^, CoreWindowEventArgs^>(this, &SDL_WinRTApp::OnWindowClosed);
#if WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP
window->PointerCursor = ref new CoreCursor(CoreCursorType::Arrow, 0);
#endif
window->PointerPressed +=
ref new TypedEventHandler<CoreWindow^, PointerEventArgs^>(this, &SDL_WinRTApp::OnPointerPressed);
window->PointerMoved +=
ref new TypedEventHandler<CoreWindow^, PointerEventArgs^>(this, &SDL_WinRTApp::OnPointerMoved);
window->PointerReleased +=
ref new TypedEventHandler<CoreWindow^, PointerEventArgs^>(this, &SDL_WinRTApp::OnPointerReleased);
window->PointerEntered +=
ref new TypedEventHandler<CoreWindow^, PointerEventArgs^>(this, &SDL_WinRTApp::OnPointerEntered);
window->PointerExited +=
ref new TypedEventHandler<CoreWindow^, PointerEventArgs^>(this, &SDL_WinRTApp::OnPointerExited);
window->PointerWheelChanged +=
ref new TypedEventHandler<CoreWindow^, PointerEventArgs^>(this, &SDL_WinRTApp::OnPointerWheelChanged);
#if WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP
// Retrieves relative-only mouse movements:
Windows::Devices::Input::MouseDevice::GetForCurrentView()->MouseMoved +=
ref new TypedEventHandler<MouseDevice^, MouseEventArgs^>(this, &SDL_WinRTApp::OnMouseMoved);
#endif
window->KeyDown +=
ref new TypedEventHandler<CoreWindow^, KeyEventArgs^>(this, &SDL_WinRTApp::OnKeyDown);
window->KeyUp +=
ref new TypedEventHandler<CoreWindow^, KeyEventArgs^>(this, &SDL_WinRTApp::OnKeyUp);
window->CharacterReceived +=
ref new TypedEventHandler<CoreWindow^, CharacterReceivedEventArgs^>(this, &SDL_WinRTApp::OnCharacterReceived);
#if NTDDI_VERSION >= NTDDI_WIN10
Windows::UI::Core::SystemNavigationManager::GetForCurrentView()->BackRequested +=
ref new EventHandler<BackRequestedEventArgs^>(this, &SDL_WinRTApp::OnBackButtonPressed);
#elif WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
HardwareButtons::BackPressed +=
ref new EventHandler<BackPressedEventArgs^>(this, &SDL_WinRTApp::OnBackButtonPressed);
#endif
#if NTDDI_VERSION > NTDDI_WIN8
DisplayInformation::GetForCurrentView()->OrientationChanged +=
ref new TypedEventHandler<Windows::Graphics::Display::DisplayInformation^, Object^>(this, &SDL_WinRTApp::OnOrientationChanged);
#else
DisplayProperties::OrientationChanged +=
ref new DisplayPropertiesEventHandler(this, &SDL_WinRTApp::OnOrientationChanged);
#endif
#if (WINAPI_FAMILY == WINAPI_FAMILY_APP) && (NTDDI_VERSION < NTDDI_WIN10) // for Windows 8/8.1/RT apps... (and not Phone apps)
// Make sure we know when a user has opened the app's settings pane.
// This is needed in order to display a privacy policy, which needs
// to be done for network-enabled apps, as per Windows Store requirements.
using namespace Windows::UI::ApplicationSettings;
SettingsPane::GetForCurrentView()->CommandsRequested +=
ref new TypedEventHandler<SettingsPane^, SettingsPaneCommandsRequestedEventArgs^>
(this, &SDL_WinRTApp::OnSettingsPaneCommandsRequested);
#endif
}
void SDL_WinRTApp::Load(Platform::String^ entryPoint)
{
}
void SDL_WinRTApp::Run()
{
SDL_SetMainReady();
if (WINRT_SDLAppEntryPoint)
{
// TODO, WinRT: pass the C-style main() a reasonably realistic
// representation of command line arguments.
int argc = 1;
char **argv = (char **)SDL_malloc(2 * sizeof(*argv));
if (!argv) {
return;
}
argv[0] = SDL_strdup("WinRTApp");
argv[1] = NULL;
WINRT_SDLAppEntryPoint(argc, argv);
SDL_free(argv[0]);
SDL_free(argv);
}
}
static bool IsSDLWindowEventPending(SDL_WindowEventID windowEventID)
{
SDL_Event events[128];
const int count = SDL_PeepEvents(events, sizeof(events)/sizeof(SDL_Event), SDL_PEEKEVENT, SDL_WINDOWEVENT, SDL_WINDOWEVENT);
for (int i = 0; i < count; ++i) {
if (events[i].window.event == windowEventID) {
return true;
}
}
return false;
}
bool SDL_WinRTApp::ShouldWaitForAppResumeEvents()
{
/* Don't wait if the app is visible: */
if (m_windowVisible) {
return false;
}
/* Don't wait until the window-hide events finish processing.
* Do note that if an app-suspend event is sent (as indicated
* by SDL_APP_WILLENTERBACKGROUND and SDL_APP_DIDENTERBACKGROUND
* events), then this code may be a moot point, as WinRT's
* own event pump (aka ProcessEvents()) will pause regardless
* of what we do here. This happens on Windows Phone 8, to note.
* Windows 8.x apps, on the other hand, may get a chance to run
* these.
*/
if (IsSDLWindowEventPending(SDL_WINDOWEVENT_HIDDEN)) {
return false;
} else if (IsSDLWindowEventPending(SDL_WINDOWEVENT_FOCUS_LOST)) {
return false;
} else if (IsSDLWindowEventPending(SDL_WINDOWEVENT_MINIMIZED)) {
return false;
}
return true;
}
void SDL_WinRTApp::PumpEvents()
{
if (!m_windowClosed) {
if (!ShouldWaitForAppResumeEvents()) {
/* This is the normal way in which events should be pumped.
* 'ProcessAllIfPresent' will make ProcessEvents() process anywhere
* from zero to N events, and will then return.
*/
CoreWindow::GetForCurrentThread()->Dispatcher->ProcessEvents(CoreProcessEventsOption::ProcessAllIfPresent);
} else {
/* This style of event-pumping, with 'ProcessOneAndAllPending',
* will cause anywhere from one to N events to be processed. If
* at least one event is processed, the call will return. If
* no events are pending, then the call will wait until one is
* available, and will not return (to the caller) until this
* happens! This should only occur when the app is hidden.
*/
CoreWindow::GetForCurrentThread()->Dispatcher->ProcessEvents(CoreProcessEventsOption::ProcessOneAndAllPending);
}
}
}
void SDL_WinRTApp::Uninitialize()
{
}
#if (WINAPI_FAMILY == WINAPI_FAMILY_APP) && (NTDDI_VERSION < NTDDI_WIN10)
void SDL_WinRTApp::OnSettingsPaneCommandsRequested(
Windows::UI::ApplicationSettings::SettingsPane ^p,
Windows::UI::ApplicationSettings::SettingsPaneCommandsRequestedEventArgs ^args)
{
using namespace Platform;
using namespace Windows::UI::ApplicationSettings;
using namespace Windows::UI::Popups;
String ^privacyPolicyURL = nullptr; // a URL to an app's Privacy Policy
String ^privacyPolicyLabel = nullptr; // label/link text
const char *tmpHintValue = NULL; // SDL_GetHint-retrieved value, used immediately
wchar_t *tmpStr = NULL; // used for UTF8 to UCS2 conversion
// Setup a 'Privacy Policy' link, if one is available (via SDL_GetHint):
tmpHintValue = SDL_GetHint(SDL_HINT_WINRT_PRIVACY_POLICY_URL);
if (tmpHintValue && tmpHintValue[0] != '\0') {
// Convert the privacy policy's URL to UCS2:
tmpStr = WIN_UTF8ToString(tmpHintValue);
privacyPolicyURL = ref new String(tmpStr);
SDL_free(tmpStr);
// Optionally retrieve custom label-text for the link. If this isn't
// available, a default value will be used instead.
tmpHintValue = SDL_GetHint(SDL_HINT_WINRT_PRIVACY_POLICY_LABEL);
if (tmpHintValue && tmpHintValue[0] != '\0') {
tmpStr = WIN_UTF8ToString(tmpHintValue);
privacyPolicyLabel = ref new String(tmpStr);
SDL_free(tmpStr);
} else {
privacyPolicyLabel = ref new String(L"Privacy Policy");
}
// Register the link, along with a handler to be called if and when it is
// clicked:
auto cmd = ref new SettingsCommand(L"privacyPolicy", privacyPolicyLabel,
ref new UICommandInvokedHandler([=](IUICommand ^) {
Windows::System::Launcher::LaunchUriAsync(ref new Uri(privacyPolicyURL));
}));
args->Request->ApplicationCommands->Append(cmd);
}
}
#endif // if (WINAPI_FAMILY == WINAPI_FAMILY_APP) && (NTDDI_VERSION < NTDDI_WIN10)
void SDL_WinRTApp::OnWindowSizeChanged(CoreWindow^ sender, WindowSizeChangedEventArgs^ args)
{
#if LOG_WINDOW_EVENTS==1
SDL_Log("%s, size={%f,%f}, bounds={%f,%f,%f,%f}, current orientation=%d, native orientation=%d, auto rot. pref=%d, WINRT_GlobalSDLWindow?=%s\n",
__FUNCTION__,
args->Size.Width, args->Size.Height,
sender->Bounds.X, sender->Bounds.Y, sender->Bounds.Width, sender->Bounds.Height,
WINRT_DISPLAY_PROPERTY(CurrentOrientation),
WINRT_DISPLAY_PROPERTY(NativeOrientation),
WINRT_DISPLAY_PROPERTY(AutoRotationPreferences),
(WINRT_GlobalSDLWindow ? "yes" : "no"));
#endif
WINRT_ProcessWindowSizeChange();
}
void SDL_WinRTApp::OnVisibilityChanged(CoreWindow^ sender, VisibilityChangedEventArgs^ args)
{
#if LOG_WINDOW_EVENTS==1
SDL_Log("%s, visible?=%s, bounds={%f,%f,%f,%f}, WINRT_GlobalSDLWindow?=%s\n",
__FUNCTION__,
(args->Visible ? "yes" : "no"),
sender->Bounds.X, sender->Bounds.Y,
sender->Bounds.Width, sender->Bounds.Height,
(WINRT_GlobalSDLWindow ? "yes" : "no"));
#endif
m_windowVisible = args->Visible;
if (WINRT_GlobalSDLWindow) {
SDL_bool wasSDLWindowSurfaceValid = WINRT_GlobalSDLWindow->surface_valid;
Uint32 latestWindowFlags = WINRT_DetectWindowFlags(WINRT_GlobalSDLWindow);
if (args->Visible) {
SDL_SendWindowEvent(WINRT_GlobalSDLWindow, SDL_WINDOWEVENT_SHOWN, 0, 0);
SDL_SendWindowEvent(WINRT_GlobalSDLWindow, SDL_WINDOWEVENT_FOCUS_GAINED, 0, 0);
if (latestWindowFlags & SDL_WINDOW_MAXIMIZED) {
SDL_SendWindowEvent(WINRT_GlobalSDLWindow, SDL_WINDOWEVENT_MAXIMIZED, 0, 0);
} else {
SDL_SendWindowEvent(WINRT_GlobalSDLWindow, SDL_WINDOWEVENT_RESTORED, 0, 0);
}
} else {
SDL_SendWindowEvent(WINRT_GlobalSDLWindow, SDL_WINDOWEVENT_HIDDEN, 0, 0);
SDL_SendWindowEvent(WINRT_GlobalSDLWindow, SDL_WINDOWEVENT_FOCUS_LOST, 0, 0);
SDL_SendWindowEvent(WINRT_GlobalSDLWindow, SDL_WINDOWEVENT_MINIMIZED, 0, 0);
}
// HACK: Prevent SDL's window-hide handling code, which currently
// triggers a fake window resize (possibly erronously), from
// marking the SDL window's surface as invalid.
//
// A better solution to this probably involves figuring out if the
// fake window resize can be prevented.
WINRT_GlobalSDLWindow->surface_valid = wasSDLWindowSurfaceValid;
}
}
void SDL_WinRTApp::OnWindowActivated(CoreWindow^ sender, WindowActivatedEventArgs^ args)
{
#if LOG_WINDOW_EVENTS==1
SDL_Log("%s, WINRT_GlobalSDLWindow?=%s\n\n",
__FUNCTION__,
(WINRT_GlobalSDLWindow ? "yes" : "no"));
#endif
/* There's no property in Win 8.x to tell whether a window is active or
not. [De]activation events are, however, sent to the app. We'll just
record those, in case the CoreWindow gets wrapped by an SDL_Window at
some future time.
*/
sender->CustomProperties->Insert("SDLHelperWindowActivationState", args->WindowActivationState);
SDL_Window * window = WINRT_GlobalSDLWindow;
if (window) {
if (args->WindowActivationState != CoreWindowActivationState::Deactivated) {
SDL_SendWindowEvent(window, SDL_WINDOWEVENT_SHOWN, 0, 0);
if (SDL_GetKeyboardFocus() != window) {
SDL_SetKeyboardFocus(window);
}
/* Send a mouse-motion event as appropriate.
This doesn't work when called from OnPointerEntered, at least
not in WinRT CoreWindow apps (as OnPointerEntered doesn't
appear to be called after window-reactivation, at least not
in Windows 10, Build 10586.3 (November 2015 update, non-beta).
Don't do it on WinPhone 8.0 though, as CoreWindow's 'PointerPosition'
property isn't available.
*/
#if (WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP) || (NTDDI_VERSION >= NTDDI_WINBLUE)
Point cursorPos = WINRT_TransformCursorPosition(window, sender->PointerPosition, TransformToSDLWindowSize);
SDL_SendMouseMotion(window, 0, 0, (int)cursorPos.X, (int)cursorPos.Y);
#endif
/* TODO, WinRT: see if the Win32 bugfix from https://hg.libsdl.org/SDL/rev/d278747da408 needs to be applied (on window activation) */
//WIN_CheckAsyncMouseRelease(data);
/* TODO, WinRT: implement clipboard support, if possible */
///*
// * FIXME: Update keyboard state
// */
//WIN_CheckClipboardUpdate(data->videodata);
// HACK: Resetting the mouse-cursor here seems to fix
// https://bugzilla.libsdl.org/show_bug.cgi?id=3217, whereby a
// WinRT app's mouse cursor may switch to Windows' 'wait' cursor,
// after a user alt-tabs back into a full-screened SDL app.
// This bug does not appear to reproduce 100% of the time.
// It may be a bug in Windows itself (v.10.0.586.36, as tested,
// and the most-recent as of this writing).
SDL_SetCursor(NULL);
} else {
if (SDL_GetKeyboardFocus() == window) {
SDL_SetKeyboardFocus(NULL);
}
}
}
}
void SDL_WinRTApp::OnWindowClosed(CoreWindow^ sender, CoreWindowEventArgs^ args)
{
#if LOG_WINDOW_EVENTS==1
SDL_Log("%s\n", __FUNCTION__);
#endif
m_windowClosed = true;
}
void SDL_WinRTApp::OnAppActivated(CoreApplicationView^ applicationView, IActivatedEventArgs^ args)
{
CoreWindow::GetForCurrentThread()->Activate();
}
void SDL_WinRTApp::OnSuspending(Platform::Object^ sender, SuspendingEventArgs^ args)
{
// Save app state asynchronously after requesting a deferral. Holding a deferral
// indicates that the application is busy performing suspending operations. Be
// aware that a deferral may not be held indefinitely. After about five seconds,
// the app will be forced to exit.
// ... but first, let the app know it's about to go to the background.
// The separation of events may be important, given that the deferral
// runs in a separate thread. This'll make SDL_APP_WILLENTERBACKGROUND
// the only event among the two that runs in the main thread. Given
// that a few WinRT operations can only be done from the main thread
// (things that access the WinRT CoreWindow are one example of this),
// this could be important.
SDL_SendAppEvent(SDL_APP_WILLENTERBACKGROUND);
SuspendingDeferral^ deferral = args->SuspendingOperation->GetDeferral();
create_task([this, deferral]()
{
// Send an app did-enter-background event immediately to observers.
// CoreDispatcher::ProcessEvents, which is the backbone on which
// SDL_WinRTApp::PumpEvents is built, will not return to its caller
// once it sends out a suspend event. Any events posted to SDL's
// event queue won't get received until the WinRT app is resumed.
// SDL_AddEventWatch() may be used to receive app-suspend events on
// WinRT.
SDL_SendAppEvent(SDL_APP_DIDENTERBACKGROUND);
// Let the Direct3D 11 renderer prepare for the app to be backgrounded.
// This is necessary for Windows 8.1, possibly elsewhere in the future.
// More details at: http://msdn.microsoft.com/en-us/library/windows/apps/Hh994929.aspx
#if SDL_VIDEO_RENDER_D3D11 && !SDL_RENDER_DISABLED
if (WINRT_GlobalSDLWindow) {
SDL_Renderer * renderer = SDL_GetRenderer(WINRT_GlobalSDLWindow);
if (renderer && (SDL_strcmp(renderer->info.name, "direct3d11") == 0)) {
D3D11_Trim(renderer);
}
}
#endif
deferral->Complete();
});
}
void SDL_WinRTApp::OnResuming(Platform::Object^ sender, Platform::Object^ args)
{
// Restore any data or state that was unloaded on suspend. By default, data
// and state are persisted when resuming from suspend. Note that these events
// do not occur if the app was previously terminated.
SDL_SendAppEvent(SDL_APP_WILLENTERFOREGROUND);
SDL_SendAppEvent(SDL_APP_DIDENTERFOREGROUND);
}
void SDL_WinRTApp::OnExiting(Platform::Object^ sender, Platform::Object^ args)
{
SDL_SendAppEvent(SDL_APP_TERMINATING);
}
static void
WINRT_LogPointerEvent(const char * header, Windows::UI::Core::PointerEventArgs ^ args, Windows::Foundation::Point transformedPoint)
{
Uint8 button, pressed;
Windows::UI::Input::PointerPoint ^ pt = args->CurrentPoint;
WINRT_GetSDLButtonForPointerPoint(pt, &button, &pressed);
SDL_Log("%s: Position={%f,%f}, Transformed Pos={%f, %f}, MouseWheelDelta=%d, FrameId=%d, PointerId=%d, SDL button=%d pressed=%d\n",
header,
pt->Position.X, pt->Position.Y,
transformedPoint.X, transformedPoint.Y,
pt->Properties->MouseWheelDelta,
pt->FrameId,
pt->PointerId,
button,
pressed);
}
void SDL_WinRTApp::OnPointerPressed(CoreWindow^ sender, PointerEventArgs^ args)
{
#if LOG_POINTER_EVENTS
WINRT_LogPointerEvent("pointer pressed", args, WINRT_TransformCursorPosition(WINRT_GlobalSDLWindow, args->CurrentPoint->Position, TransformToSDLWindowSize));
#endif
WINRT_ProcessPointerPressedEvent(WINRT_GlobalSDLWindow, args->CurrentPoint);
}
void SDL_WinRTApp::OnPointerMoved(CoreWindow^ sender, PointerEventArgs^ args)
{
#if LOG_POINTER_EVENTS
WINRT_LogPointerEvent("pointer moved", args, WINRT_TransformCursorPosition(WINRT_GlobalSDLWindow, args->CurrentPoint->Position, TransformToSDLWindowSize));
#endif
WINRT_ProcessPointerMovedEvent(WINRT_GlobalSDLWindow, args->CurrentPoint);
}
void SDL_WinRTApp::OnPointerReleased(CoreWindow^ sender, PointerEventArgs^ args)
{
#if LOG_POINTER_EVENTS
WINRT_LogPointerEvent("pointer released", args, WINRT_TransformCursorPosition(WINRT_GlobalSDLWindow, args->CurrentPoint->Position, TransformToSDLWindowSize));
#endif
WINRT_ProcessPointerReleasedEvent(WINRT_GlobalSDLWindow, args->CurrentPoint);
}
void SDL_WinRTApp::OnPointerEntered(CoreWindow^ sender, PointerEventArgs^ args)
{
#if LOG_POINTER_EVENTS
WINRT_LogPointerEvent("pointer entered", args, WINRT_TransformCursorPosition(WINRT_GlobalSDLWindow, args->CurrentPoint->Position, TransformToSDLWindowSize));
#endif
WINRT_ProcessPointerEnteredEvent(WINRT_GlobalSDLWindow, args->CurrentPoint);
}
void SDL_WinRTApp::OnPointerExited(CoreWindow^ sender, PointerEventArgs^ args)
{
#if LOG_POINTER_EVENTS
WINRT_LogPointerEvent("pointer exited", args, WINRT_TransformCursorPosition(WINRT_GlobalSDLWindow, args->CurrentPoint->Position, TransformToSDLWindowSize));
#endif
WINRT_ProcessPointerExitedEvent(WINRT_GlobalSDLWindow, args->CurrentPoint);
}
void SDL_WinRTApp::OnPointerWheelChanged(CoreWindow^ sender, PointerEventArgs^ args)
{
#if LOG_POINTER_EVENTS
WINRT_LogPointerEvent("pointer wheel changed", args, WINRT_TransformCursorPosition(WINRT_GlobalSDLWindow, args->CurrentPoint->Position, TransformToSDLWindowSize));
#endif
WINRT_ProcessPointerWheelChangedEvent(WINRT_GlobalSDLWindow, args->CurrentPoint);
}
void SDL_WinRTApp::OnMouseMoved(MouseDevice^ mouseDevice, MouseEventArgs^ args)
{
WINRT_ProcessMouseMovedEvent(WINRT_GlobalSDLWindow, args);
}
void SDL_WinRTApp::OnKeyDown(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::KeyEventArgs^ args)
{
WINRT_ProcessKeyDownEvent(args);
}
void SDL_WinRTApp::OnKeyUp(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::KeyEventArgs^ args)
{
WINRT_ProcessKeyUpEvent(args);
}
void SDL_WinRTApp::OnCharacterReceived(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::CharacterReceivedEventArgs^ args)
{
WINRT_ProcessCharacterReceivedEvent(args);
}
template <typename BackButtonEventArgs>
static void WINRT_OnBackButtonPressed(BackButtonEventArgs ^ args)
{
SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_AC_BACK);
SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_AC_BACK);
if (SDL_GetHintBoolean(SDL_HINT_WINRT_HANDLE_BACK_BUTTON, SDL_FALSE)) {
args->Handled = true;
}
}
#if NTDDI_VERSION >= NTDDI_WIN10
void SDL_WinRTApp::OnBackButtonPressed(Platform::Object^ sender, Windows::UI::Core::BackRequestedEventArgs^ args)
{
WINRT_OnBackButtonPressed(args);
}
#elif WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
void SDL_WinRTApp::OnBackButtonPressed(Platform::Object^ sender, Windows::Phone::UI::Input::BackPressedEventArgs^ args)
{
WINRT_OnBackButtonPressed(args);
}
#endif
#if NTDDI_VERSION >= NTDDI_WIN10
void SDL_WinRTApp::OnGamepadAdded(Platform::Object ^sender, Windows::Gaming::Input::Gamepad ^gamepad)
{
/* HACK ALERT: Nothing needs to be done here, as this method currently
only exists to allow something to be registered with Win10's
GamepadAdded event, an operation that seems to be necessary to get
Xinput-based detection to work on Xbox One.
*/
}
#endif
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -1,92 +0,0 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2022 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 <Windows.h>
extern int SDL_WinRTInitNonXAMLApp(int (*mainFunction)(int, char **));
ref class SDL_WinRTApp sealed : public Windows::ApplicationModel::Core::IFrameworkView
{
public:
SDL_WinRTApp();
// IFrameworkView Methods.
virtual void Initialize(Windows::ApplicationModel::Core::CoreApplicationView^ applicationView);
virtual void SetWindow(Windows::UI::Core::CoreWindow^ window);
virtual void Load(Platform::String^ entryPoint);
virtual void Run();
virtual void Uninitialize();
internal:
// SDL-specific methods
void PumpEvents();
protected:
bool ShouldWaitForAppResumeEvents();
// Event Handlers.
#if (WINAPI_FAMILY == WINAPI_FAMILY_APP) && (NTDDI_VERSION < NTDDI_WIN10) // for Windows 8/8.1/RT apps... (and not Phone apps)
void OnSettingsPaneCommandsRequested(
Windows::UI::ApplicationSettings::SettingsPane ^p,
Windows::UI::ApplicationSettings::SettingsPaneCommandsRequestedEventArgs ^args);
#endif // if (WINAPI_FAMILY == WINAPI_FAMILY_APP) && (NTDDI_VERSION < NTDDI_WIN10)
#if NTDDI_VERSION > NTDDI_WIN8
void OnOrientationChanged(Windows::Graphics::Display::DisplayInformation^ sender, Platform::Object^ args);
#else
void OnOrientationChanged(Platform::Object^ sender);
#endif
void OnWindowSizeChanged(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::WindowSizeChangedEventArgs^ args);
void OnLogicalDpiChanged(Platform::Object^ sender);
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);
void OnCharacterReceived(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::CharacterReceivedEventArgs^ args);
#if NTDDI_VERSION >= NTDDI_WIN10
void OnBackButtonPressed(Platform::Object^ sender, Windows::UI::Core::BackRequestedEventArgs^ args);
#elif WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
void OnBackButtonPressed(Platform::Object^ sender, Windows::Phone::UI::Input::BackPressedEventArgs^ args);
#endif
#if NTDDI_VERSION >= NTDDI_WIN10
void OnGamepadAdded(Platform::Object ^sender, Windows::Gaming::Input::Gamepad ^gamepad);
#endif
private:
bool m_windowClosed;
bool m_windowVisible;
};
extern SDL_WinRTApp ^ SDL_WinRTGlobalApp;

View File

@@ -1,160 +0,0 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2022 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.
*/
/* Windows includes */
#include <agile.h>
#include <Windows.h>
#if WINAPI_FAMILY == WINAPI_FAMILY_APP
#include <windows.ui.xaml.media.dxinterop.h>
#endif
/* SDL includes */
#include "../../SDL_internal.h"
#include "SDL.h"
#include "../../video/winrt/SDL_winrtevents_c.h"
#include "../../video/winrt/SDL_winrtvideo_cpp.h"
#include "SDL_winrtapp_common.h"
#include "SDL_winrtapp_xaml.h"
/* SDL-internal globals: */
SDL_bool WINRT_XAMLWasEnabled = SDL_FALSE;
#if WINAPI_FAMILY == WINAPI_FAMILY_APP
extern "C"
ISwapChainBackgroundPanelNative * WINRT_GlobalSwapChainBackgroundPanelNative = NULL;
static Windows::Foundation::EventRegistrationToken WINRT_XAMLAppEventToken;
#endif
/*
* Input event handlers (XAML)
*/
#if WINAPI_FAMILY == WINAPI_FAMILY_APP
static void
WINRT_OnPointerPressedViaXAML(Platform::Object^ sender, Windows::UI::Xaml::Input::PointerRoutedEventArgs^ args)
{
WINRT_ProcessPointerPressedEvent(WINRT_GlobalSDLWindow, args->GetCurrentPoint(nullptr));
}
static void
WINRT_OnPointerMovedViaXAML(Platform::Object^ sender, Windows::UI::Xaml::Input::PointerRoutedEventArgs^ args)
{
WINRT_ProcessPointerMovedEvent(WINRT_GlobalSDLWindow, args->GetCurrentPoint(nullptr));
}
static void
WINRT_OnPointerReleasedViaXAML(Platform::Object^ sender, Windows::UI::Xaml::Input::PointerRoutedEventArgs^ args)
{
WINRT_ProcessPointerReleasedEvent(WINRT_GlobalSDLWindow, args->GetCurrentPoint(nullptr));
}
static void
WINRT_OnPointerWheelChangedViaXAML(Platform::Object^ sender, Windows::UI::Xaml::Input::PointerRoutedEventArgs^ args)
{
WINRT_ProcessPointerWheelChangedEvent(WINRT_GlobalSDLWindow, args->GetCurrentPoint(nullptr));
}
#endif // WINAPI_FAMILY == WINAPI_FAMILY_APP
/*
* XAML-to-SDL Rendering Callback
*/
#if WINAPI_FAMILY == WINAPI_FAMILY_APP
static void
WINRT_OnRenderViaXAML(_In_ Platform::Object^ sender, _In_ Platform::Object^ args)
{
WINRT_CycleXAMLThread();
}
#endif // WINAPI_FAMILY == WINAPI_FAMILY_APP
/*
* SDL + XAML Initialization
*/
int
SDL_WinRTInitXAMLApp(int (*mainFunction)(int, char **), void * backgroundPanelAsIInspectable)
{
#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
return SDL_SetError("XAML support is not yet available in Windows Phone.");
#else
// Declare C++/CX namespaces:
using namespace Platform;
using namespace Windows::Foundation;
using namespace Windows::UI::Core;
using namespace Windows::UI::Xaml;
using namespace Windows::UI::Xaml::Controls;
using namespace Windows::UI::Xaml::Input;
using namespace Windows::UI::Xaml::Media;
// Make sure we have a valid XAML element (to draw onto):
if ( ! backgroundPanelAsIInspectable) {
return SDL_InvalidParamError("backgroundPanelAsIInspectable");
}
Platform::Object ^ backgroundPanel = reinterpret_cast<Object ^>((IInspectable *) backgroundPanelAsIInspectable);
SwapChainBackgroundPanel ^swapChainBackgroundPanel = dynamic_cast<SwapChainBackgroundPanel ^>(backgroundPanel);
if ( ! swapChainBackgroundPanel) {
return SDL_SetError("An unknown or unsupported type of XAML control was specified.");
}
// Setup event handlers:
swapChainBackgroundPanel->PointerPressed += ref new PointerEventHandler(WINRT_OnPointerPressedViaXAML);
swapChainBackgroundPanel->PointerReleased += ref new PointerEventHandler(WINRT_OnPointerReleasedViaXAML);
swapChainBackgroundPanel->PointerWheelChanged += ref new PointerEventHandler(WINRT_OnPointerWheelChangedViaXAML);
swapChainBackgroundPanel->PointerMoved += ref new PointerEventHandler(WINRT_OnPointerMovedViaXAML);
// Setup for rendering:
IInspectable *panelInspectable = (IInspectable*) reinterpret_cast<IInspectable*>(swapChainBackgroundPanel);
panelInspectable->QueryInterface(__uuidof(ISwapChainBackgroundPanelNative), (void **)&WINRT_GlobalSwapChainBackgroundPanelNative);
WINRT_XAMLAppEventToken = CompositionTarget::Rendering::add(ref new EventHandler<Object^>(WINRT_OnRenderViaXAML));
// Make sure the app is ready to call the SDL-centric main() function:
WINRT_SDLAppEntryPoint = mainFunction;
SDL_SetMainReady();
// Make sure video-init knows that we're initializing XAML:
SDL_bool oldXAMLWasEnabledValue = WINRT_XAMLWasEnabled;
WINRT_XAMLWasEnabled = SDL_TRUE;
// Make sure video modes are detected now, while we still have access to the WinRT
// CoreWindow. WinRT will not allow the app's CoreWindow to be accessed via the
// SDL/WinRT thread.
if (SDL_InitSubSystem(SDL_INIT_VIDEO) < 0) {
// SDL_InitSubSystem will, on error, set the SDL error. Let that propogate to
// the caller to here:
WINRT_XAMLWasEnabled = oldXAMLWasEnabledValue;
return -1;
}
// All done, for now.
return 0;
#endif // WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP / else
}

View File

@@ -1,33 +0,0 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2022 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_config.h"
#ifndef SDL_winrtapp_xaml_h_
#define SDL_winrtapp_xaml_h_
#include "SDL_stdinc.h"
#ifdef __cplusplus
extern SDL_bool WINRT_XAMLWasEnabled;
extern int SDL_WinRTInitXAMLApp(int (*mainFunction)(int, char **), void * backgroundPanelAsIInspectable);
#endif // ifdef __cplusplus
#endif // SDL_winrtapp_xaml_h_

View File

@@ -24,7 +24,7 @@
#include "../SDL_internal.h"
#endif
#if defined(__WIN32__) || defined(__WINRT__) || defined(__GDK__)
#if defined(__WIN32__) || defined(__GDK__)
#include "../core/windows/SDL_windows.h"
#endif
@@ -444,7 +444,7 @@ CPU_haveNEON(void)
query the OS kernel in a platform-specific way. :/ */
#if defined(SDL_CPUINFO_DISABLED)
return 0; /* disabled */
#elif (defined(__WINDOWS__) || defined(__WINRT__) || defined(__GDK__)) && (defined(_M_ARM) || defined(_M_ARM64))
#elif (defined(__WINDOWS__) || defined(__GDK__)) && (defined(_M_ARM) || defined(_M_ARM64))
/* Visual Studio, for ARM, doesn't define __ARM_ARCH. Handle this first. */
/* Seems to have been removed */
# if !defined(PF_ARM_NEON_INSTRUCTIONS_AVAILABLE)

View File

@@ -49,8 +49,6 @@
#define SDL_DYNAMIC_API 0
#elif defined(__EMSCRIPTEN__) && __EMSCRIPTEN__ /* probably not useful on Emscripten. */
#define SDL_DYNAMIC_API 0
#elif defined(SDL_BUILDING_WINRT) && SDL_BUILDING_WINRT /* probably not useful on WinRT, given current .dll loading restrictions */
#define SDL_DYNAMIC_API 0
#elif defined(__PS2__) && __PS2__
#define SDL_DYNAMIC_API 0
#elif defined(__PSP__) && __PSP__

View File

@@ -571,10 +571,7 @@
#define SDL_GetAssertionHandler SDL_GetAssertionHandler_REAL
#define SDL_DXGIGetOutputInfo SDL_DXGIGetOutputInfo_REAL
#define SDL_RenderIsClipEnabled SDL_RenderIsClipEnabled_REAL
#define SDL_WinRTRunApp SDL_WinRTRunApp_REAL
#define SDL_WarpMouseGlobal SDL_WarpMouseGlobal_REAL
#define SDL_WinRTGetFSPathUNICODE SDL_WinRTGetFSPathUNICODE_REAL
#define SDL_WinRTGetFSPathUTF8 SDL_WinRTGetFSPathUTF8_REAL
#define SDL_sqrtf SDL_sqrtf_REAL
#define SDL_tan SDL_tan_REAL
#define SDL_tanf SDL_tanf_REAL
@@ -663,7 +660,6 @@
#define SDL_RenderGetMetalLayer SDL_RenderGetMetalLayer_REAL
#define SDL_RenderGetMetalCommandEncoder SDL_RenderGetMetalCommandEncoder_REAL
#define SDL_IsAndroidTV SDL_IsAndroidTV_REAL
#define SDL_WinRTGetDeviceFamily SDL_WinRTGetDeviceFamily_REAL
#define SDL_log10 SDL_log10_REAL
#define SDL_log10f SDL_log10f_REAL
#define SDL_GameControllerMappingForDeviceIndex SDL_GameControllerMappingForDeviceIndex_REAL

View File

@@ -604,11 +604,6 @@ SDL_DYNAPI_PROC(SDL_AssertionHandler,SDL_GetAssertionHandler,(void **a),(a),retu
SDL_DYNAPI_PROC(SDL_bool,SDL_DXGIGetOutputInfo,(int a,int *b, int *c),(a,b,c),return)
#endif
SDL_DYNAPI_PROC(SDL_bool,SDL_RenderIsClipEnabled,(SDL_Renderer *a),(a),return)
#ifdef __WINRT__
SDL_DYNAPI_PROC(int,SDL_WinRTRunApp,(int a, char **b, void *c),(a,b,c),return)
SDL_DYNAPI_PROC(const wchar_t*,SDL_WinRTGetFSPathUNICODE,(SDL_WinRT_Path a),(a),return)
SDL_DYNAPI_PROC(const char*,SDL_WinRTGetFSPathUTF8,(SDL_WinRT_Path a),(a),return)
#endif
SDL_DYNAPI_PROC(int,SDL_WarpMouseGlobal,(int a, int b),(a,b),return)
SDL_DYNAPI_PROC(float,SDL_sqrtf,(float a),(a),return)
SDL_DYNAPI_PROC(double,SDL_tan,(double a),(a),return)
@@ -700,9 +695,6 @@ SDL_DYNAPI_PROC(SDL_YUV_CONVERSION_MODE,SDL_GetYUVConversionMode,(void),(),retur
SDL_DYNAPI_PROC(SDL_YUV_CONVERSION_MODE,SDL_GetYUVConversionModeForResolution,(int a, int b),(a,b),return)
SDL_DYNAPI_PROC(void*,SDL_RenderGetMetalLayer,(SDL_Renderer *a),(a),return)
SDL_DYNAPI_PROC(void*,SDL_RenderGetMetalCommandEncoder,(SDL_Renderer *a),(a),return)
#ifdef __WINRT__
SDL_DYNAPI_PROC(SDL_WinRT_DeviceFamily,SDL_WinRTGetDeviceFamily,(void),(),return)
#endif
#ifdef __ANDROID__
SDL_DYNAPI_PROC(SDL_bool,SDL_IsAndroidTV,(void),(),return)
#endif

View File

@@ -593,9 +593,6 @@ SDL_RWFromFile(const char *file, const char *mode)
{
#if __APPLE__ && !SDL_FILE_DISABLED // TODO: add dummy?
FILE *fp = SDL_OpenFPFromBundleOrFallback(file, mode);
#elif __WINRT__
FILE *fp = NULL;
fopen_s(&fp, file, mode);
#elif __3DS__
FILE *fp = N3DS_FileOpen(file, mode);
#else

View File

@@ -1,242 +0,0 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2022 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"
/* TODO, WinRT: remove the need to compile this with C++/CX (/ZW) extensions, and if possible, without C++ at all
*/
#ifdef __WINRT__
extern "C" {
#include "SDL_filesystem.h"
#include "SDL_error.h"
#include "SDL_hints.h"
#include "SDL_stdinc.h"
#include "SDL_system.h"
#include "../../core/windows/SDL_windows.h"
}
#include <string>
#include <unordered_map>
using namespace std;
using namespace Windows::Storage;
extern "C" const wchar_t *
SDL_WinRTGetFSPathUNICODE(SDL_WinRT_Path pathType)
{
switch (pathType) {
case SDL_WINRT_PATH_INSTALLED_LOCATION:
{
static wstring path;
if (path.empty()) {
#if defined(NTDDI_WIN10_19H1) && (NTDDI_VERSION >= NTDDI_WIN10_19H1) && (WINAPI_FAMILY == WINAPI_FAMILY_PC_APP) /* Only PC supports mods */
/* Windows 1903 supports mods, via the EffectiveLocation API */
if (Windows::Foundation::Metadata::ApiInformation::IsApiContractPresent("Windows.Foundation.UniversalApiContract", 8, 0)) {
path = Windows::ApplicationModel::Package::Current->EffectiveLocation->Path->Data();
} else {
path = Windows::ApplicationModel::Package::Current->InstalledLocation->Path->Data();
}
#else
path = Windows::ApplicationModel::Package::Current->InstalledLocation->Path->Data();
#endif
}
return path.c_str();
}
case SDL_WINRT_PATH_LOCAL_FOLDER:
{
static wstring path;
if (path.empty()) {
path = ApplicationData::Current->LocalFolder->Path->Data();
}
return path.c_str();
}
#if (WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP) || (NTDDI_VERSION > NTDDI_WIN8)
case SDL_WINRT_PATH_ROAMING_FOLDER:
{
static wstring path;
if (path.empty()) {
path = ApplicationData::Current->RoamingFolder->Path->Data();
}
return path.c_str();
}
case SDL_WINRT_PATH_TEMP_FOLDER:
{
static wstring path;
if (path.empty()) {
path = ApplicationData::Current->TemporaryFolder->Path->Data();
}
return path.c_str();
}
#endif
default:
break;
}
SDL_Unsupported();
return NULL;
}
extern "C" const char *
SDL_WinRTGetFSPathUTF8(SDL_WinRT_Path pathType)
{
typedef unordered_map<SDL_WinRT_Path, string> UTF8PathMap;
static UTF8PathMap utf8Paths;
UTF8PathMap::iterator searchResult = utf8Paths.find(pathType);
if (searchResult != utf8Paths.end()) {
return searchResult->second.c_str();
}
const wchar_t * ucs2Path = SDL_WinRTGetFSPathUNICODE(pathType);
if (!ucs2Path) {
return NULL;
}
char * utf8Path = WIN_StringToUTF8(ucs2Path);
utf8Paths[pathType] = utf8Path;
SDL_free(utf8Path);
return utf8Paths[pathType].c_str();
}
extern "C" char *
SDL_GetBasePath(void)
{
const char * srcPath = SDL_WinRTGetFSPathUTF8(SDL_WINRT_PATH_INSTALLED_LOCATION);
size_t destPathLen;
char * destPath = NULL;
if (!srcPath) {
SDL_SetError("Couldn't locate our basepath: %s", SDL_GetError());
return NULL;
}
destPathLen = SDL_strlen(srcPath) + 2;
destPath = (char *) SDL_malloc(destPathLen);
if (!destPath) {
SDL_OutOfMemory();
return NULL;
}
SDL_snprintf(destPath, destPathLen, "%s\\", srcPath);
return destPath;
}
extern "C" char *
SDL_GetPrefPath(const char *org, const char *app)
{
/* WinRT note: The 'SHGetFolderPath' API that is used in Windows 7 and
* earlier is not available on WinRT or Windows Phone. WinRT provides
* a similar API, but SHGetFolderPath can't be called, at least not
* without violating Microsoft's app-store requirements.
*/
const WCHAR * srcPath = NULL;
WCHAR path[MAX_PATH];
char *retval = NULL;
WCHAR* worg = NULL;
WCHAR* wapp = NULL;
size_t new_wpath_len = 0;
BOOL api_result = FALSE;
if (!app) {
SDL_InvalidParamError("app");
return NULL;
}
if (!org) {
org = "";
}
srcPath = SDL_WinRTGetFSPathUNICODE(SDL_WINRT_PATH_LOCAL_FOLDER);
if ( ! srcPath) {
SDL_SetError("Unable to find a source path");
return NULL;
}
if (SDL_wcslen(srcPath) >= MAX_PATH) {
SDL_SetError("Path too long.");
return NULL;
}
SDL_wcslcpy(path, srcPath, SDL_arraysize(path));
worg = WIN_UTF8ToString(org);
if (worg == NULL) {
SDL_OutOfMemory();
return NULL;
}
wapp = WIN_UTF8ToString(app);
if (wapp == NULL) {
SDL_free(worg);
SDL_OutOfMemory();
return NULL;
}
new_wpath_len = SDL_wcslen(worg) + SDL_wcslen(wapp) + SDL_wcslen(path) + 3;
if ((new_wpath_len + 1) > MAX_PATH) {
SDL_free(worg);
SDL_free(wapp);
SDL_SetError("Path too long.");
return NULL;
}
if (*worg) {
SDL_wcslcat(path, L"\\", new_wpath_len + 1);
SDL_wcslcat(path, worg, new_wpath_len + 1);
SDL_free(worg);
}
api_result = CreateDirectoryW(path, NULL);
if (api_result == FALSE) {
if (GetLastError() != ERROR_ALREADY_EXISTS) {
SDL_free(wapp);
WIN_SetError("Couldn't create a prefpath.");
return NULL;
}
}
SDL_wcslcat(path, L"\\", new_wpath_len + 1);
SDL_wcslcat(path, wapp, new_wpath_len + 1);
SDL_free(wapp);
api_result = CreateDirectoryW(path, NULL);
if (api_result == FALSE) {
if (GetLastError() != ERROR_ALREADY_EXISTS) {
WIN_SetError("Couldn't create a prefpath.");
return NULL;
}
}
SDL_wcslcat(path, L"\\", new_wpath_len + 1);
retval = WIN_StringToUTF8(path);
return retval;
}
#endif /* __WINRT__ */
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -436,9 +436,6 @@ SDL_JoystickGetDevicePlayerIndex(int device_index)
static SDL_bool
SDL_JoystickAxesCenteredAtZero(SDL_Joystick *joystick)
{
#ifdef __WINRT__
return SDL_TRUE;
#else
static Uint32 zero_centered_joysticks[] = {
MAKE_VIDPID(0x0e8f, 0x3013), /* HuiJia SNES USB adapter */
MAKE_VIDPID(0x05a0, 0x3232), /* 8Bitdo Zero Gamepad */
@@ -461,7 +458,6 @@ SDL_JoystickAxesCenteredAtZero(SDL_Joystick *joystick)
}
}
return SDL_FALSE;
#endif /* __WINRT__ */
}
/*

View File

@@ -577,13 +577,8 @@ RAWINPUT_InitWindowsGamingInput(RAWINPUT_DeviceContext *ctx)
typedef HRESULT (WINAPI *WindowsCreateStringReference_t)(PCWSTR sourceString, UINT32 length, HSTRING_HEADER *hstringHeader, HSTRING* string);
typedef HRESULT (WINAPI *RoGetActivationFactory_t)(HSTRING activatableClassId, REFIID iid, void** factory);
#ifdef __WINRT__
WindowsCreateStringReference_t WindowsCreateStringReferenceFunc = WindowsCreateStringReference;
RoGetActivationFactory_t RoGetActivationFactoryFunc = RoGetActivationFactory;
#else
WindowsCreateStringReference_t WindowsCreateStringReferenceFunc = (WindowsCreateStringReference_t)WIN_LoadComBaseFunction("WindowsCreateStringReference");
RoGetActivationFactory_t RoGetActivationFactoryFunc = (RoGetActivationFactory_t)WIN_LoadComBaseFunction("RoGetActivationFactory");
#endif
if (WindowsCreateStringReferenceFunc && RoGetActivationFactoryFunc) {
PCWSTR pNamespace = L"Windows.Gaming.Input.Gamepad";
HSTRING_HEADER hNamespaceStringHeader;

View File

@@ -282,17 +282,9 @@ static HRESULT STDMETHODCALLTYPE IEventHandler_CRawGameControllerVtbl_InvokeAdde
typedef PCWSTR (WINAPI *WindowsGetStringRawBuffer_t)(HSTRING string, UINT32 *length);
typedef HRESULT (WINAPI *WindowsDeleteString_t)(HSTRING string);
WindowsGetStringRawBuffer_t WindowsGetStringRawBufferFunc = NULL;
WindowsDeleteString_t WindowsDeleteStringFunc = NULL;
#ifdef __WINRT__
WindowsGetStringRawBufferFunc = WindowsGetStringRawBuffer;
WindowsDeleteStringFunc = WindowsDeleteString;
#else
{
WindowsGetStringRawBufferFunc = (WindowsGetStringRawBuffer_t)WIN_LoadComBaseFunction("WindowsGetStringRawBuffer");
WindowsDeleteStringFunc = (WindowsDeleteString_t)WIN_LoadComBaseFunction("WindowsDeleteString");
}
#endif /* __WINRT__ */
WindowsGetStringRawBuffer_t WindowsGetStringRawBufferFunc = (WindowsGetStringRawBuffer_t)WIN_LoadComBaseFunction("WindowsGetStringRawBuffer");
WindowsDeleteString_t WindowsDeleteStringFunc = (WindowsDeleteString_t)WIN_LoadComBaseFunction("WindowsDeleteString");
if (WindowsGetStringRawBufferFunc && WindowsDeleteStringFunc) {
HSTRING hString;
hr = __x_ABI_CWindows_CGaming_CInput_CIRawGameController2_get_DisplayName(controller2, &hString);
@@ -484,7 +476,6 @@ WGI_JoystickInit(void)
}
wgi.ro_initialized = SDL_TRUE;
#ifndef __WINRT__
{
/* There seems to be a bug in Windows where a dependency of WGI can be unloaded from memory prior to WGI itself.
* This results in Windows_Gaming_Input!GameController::~GameController() invoking an unloaded DLL and crashing.
@@ -505,17 +496,9 @@ WGI_JoystickInit(void)
}
}
}
#endif
#ifdef __WINRT__
WindowsCreateStringReferenceFunc = WindowsCreateStringReference;
RoGetActivationFactoryFunc = RoGetActivationFactory;
#else
{
WindowsCreateStringReferenceFunc = (WindowsCreateStringReference_t)WIN_LoadComBaseFunction("WindowsCreateStringReference");
RoGetActivationFactoryFunc = (RoGetActivationFactory_t)WIN_LoadComBaseFunction("RoGetActivationFactory");
}
#endif /* __WINRT__ */
WindowsCreateStringReferenceFunc = (WindowsCreateStringReference_t)WIN_LoadComBaseFunction("WindowsCreateStringReference");
RoGetActivationFactoryFunc = (RoGetActivationFactory_t)WIN_LoadComBaseFunction("RoGetActivationFactory");
if (WindowsCreateStringReferenceFunc && RoGetActivationFactoryFunc) {
PCWSTR pNamespace;
HSTRING_HEADER hNamespaceStringHeader;

View File

@@ -41,7 +41,7 @@
#include "../SDL_sysjoystick.h"
#include "../../thread/SDL_systhread.h"
#include "../../core/windows/SDL_windows.h"
#if !defined(__WINRT__) && !defined(__XBOXONE__) && !defined(__XBOXSERIES__)
#if !defined(__XBOXONE__) && !defined(__XBOXSERIES__)
#include <dbt.h>
#endif
@@ -146,7 +146,7 @@ static GUID GUID_DEVINTERFACE_HID = { 0x4D1E55B2L, 0xF16F, 0x11CF, { 0x88, 0xCB,
JoyStick_DeviceData *SYS_Joystick; /* array to hold joystick ID values */
#if !defined(__WINRT__) && !defined(__XBOXONE__) && !defined(__XBOXSERIES__)
#if !defined(__XBOXONE__) && !defined(__XBOXSERIES__)
static HMODULE cfgmgr32_lib_handle;
static CM_Register_NotificationFunc CM_Register_Notification;
static CM_Unregister_NotificationFunc CM_Unregister_Notification;
@@ -332,11 +332,9 @@ SDL_WaitForDeviceNotification(SDL_DeviceNotificationData *data, SDL_mutex *mutex
return (lastret != -1) ? SDL_TRUE : SDL_FALSE;
}
#endif /* !defined(__WINRT__) && !defined(__XBOXONE__) && !defined(__XBOXSERIES__) */
#endif /* !defined(__XBOXONE__) && !defined(__XBOXSERIES__) */
#if !defined(__WINRT__)
#if !defined(__XBOXONE__) && !defined(__XBOXSERIES__)
static SDL_DeviceNotificationData s_notification_data;
#endif
@@ -445,8 +443,6 @@ SDL_StopJoystickThread(void)
s_joystickThread = NULL;
}
#endif /* !defined(__WINRT__) */
void WINDOWS_AddJoystickDevice(JoyStick_DeviceData *device)
{
device->send_add_event = SDL_TRUE;
@@ -479,7 +475,7 @@ WINDOWS_JoystickInit(void)
WINDOWS_JoystickDetect();
#if !defined(__WINRT__) && !defined(__XBOXONE__) && !defined(__XBOXSERIES__)
#if !defined(__XBOXONE__) && !defined(__XBOXSERIES__)
SDL_CreateDeviceNotificationFunc();
s_bJoystickThread = SDL_GetHintBoolean(SDL_HINT_JOYSTICK_THREAD, SDL_FALSE);
@@ -771,7 +767,7 @@ WINDOWS_JoystickQuit(void)
}
SYS_Joystick = NULL;
#if !defined(__WINRT__) && !defined(__XBOXONE__) && !defined(__XBOXSERIES__)
#if !defined(__XBOXONE__) && !defined(__XBOXSERIES__)
if (s_bJoystickThread) {
SDL_StopJoystickThread();
} else {

View File

@@ -46,11 +46,7 @@ static char *s_arrXInputDevicePath[XUSER_MAX_COUNT];
static SDL_bool
SDL_XInputUseOldJoystickMapping()
{
#ifdef __WINRT__
/* TODO: remove this __WINRT__ block, but only after integrating with UWP/WinRT's HID API */
/* FIXME: Why are Win8/10 different here? -flibit */
return (NTDDI_VERSION < NTDDI_WIN10);
#elif defined(__XBOXONE__) || defined(__XBOXSERIES__)
#if defined(__XBOXONE__) || defined(__XBOXSERIES__)
return SDL_FALSE;
#else
static int s_XInputUseOldJoystickMapping = -1;
@@ -133,7 +129,7 @@ GetXInputName(const Uint8 userid, BYTE SubType)
static void
GuessXInputDevice(Uint8 userid, Uint16 *pVID, Uint16 *pPID, Uint16 *pVersion)
{
#if !defined(__WINRT__) && !defined(__XBOXONE__) && !defined(__XBOXSERIES__) /* TODO: remove this ifndef __WINRT__ block, but only after integrating with UWP/WinRT's HID API */
#if !defined(__XBOXONE__) && !defined(__XBOXSERIES__) /* TODO: remove this ifndef __WINRT__ block, but only after integrating with UWP/WinRT's HID API */
PRAWINPUTDEVICELIST devices = NULL;
UINT i, j, device_count = 0;
@@ -231,7 +227,7 @@ GuessXInputDevice(Uint8 userid, Uint16 *pVID, Uint16 *pPID, Uint16 *pVersion)
}
}
SDL_free(devices);
#endif /* !__WINRT__ */
#endif
/* The device wasn't in the raw HID device list, it's probably Bluetooth */
*pVID = 0x045e; /* Microsoft */

View File

@@ -40,15 +40,7 @@ SDL_LoadObject(const char *sofile)
return NULL;
}
tstr = WIN_UTF8ToString(sofile);
#ifdef __WINRT__
/* WinRT only publicly supports LoadPackagedLibrary() for loading .dll
files. LoadLibrary() is a private API, and not available for apps
(that can be published to MS' Windows Store.)
*/
handle = (void *) LoadPackagedLibrary(tstr, 0);
#else
handle = (void *) LoadLibrary(tstr);
#endif
SDL_free(tstr);
/* Generate an error message if all loads failed */

View File

@@ -1,58 +0,0 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2022 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 <Windows.h>
#include "../../SDL_internal.h"
#include "../SDL_syslocale.h"
/*using namespace Windows::Graphics::Display;*/
#include <wchar.h>
void
SDL_SYS_GetPreferredLocales(char *buf, size_t buflen)
{
WCHAR wbuffer[128] = L"";
int ret = 0;
/* !!! FIXME: do we not have GetUserPreferredUILanguages on WinPhone or UWP? */
# if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
ret = GetLocaleInfoEx(LOCALE_NAME_SYSTEM_DEFAULT, LOCALE_SNAME, wbuffer, SDL_arraysize(wbuffer));
# else
ret = GetSystemDefaultLocaleName(wbuffer, SDL_arraysize(wbuffer));
# endif
if (ret > 0)
{
/* Need to convert LPWSTR to LPSTR, that is wide char to char. */
int i;
if ( ((size_t) ret) >= (buflen - 1) ) {
ret = (int) (buflen - 1);
}
for (i = 0; i < ret; i++) {
buf[i] = (char) wbuffer[i]; /* assume this was ASCII anyhow. */
}
}
}
/* vi: set ts=4 sw=4 expandtab: */

Binary file not shown.

Before

Width:  |  Height:  |  Size: 326 B

View File

@@ -1,3 +0,0 @@
#include "winres.h"
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
5000 CURSOR "SDL3-WinRTResource_BlankCursor.cur"

View File

@@ -1,54 +0,0 @@
/*
SDL_winrt_main_NonXAML.cpp, placed in the public domain by David Ludwig 3/13/14
*/
#include "SDL_main.h"
#include <wrl.h>
/* At least one file in any SDL/WinRT app appears to require compilation
with C++/CX, otherwise a Windows Metadata file won't get created, and
an APPX0702 build error can appear shortly after linking.
The following set of preprocessor code forces this file to be compiled
as C++/CX, which appears to cause Visual C++ 2012's build tools to
create this .winmd file, and will help allow builds of SDL/WinRT apps
to proceed without error.
If other files in an app's project enable C++/CX compilation, then it might
be possible for SDL_winrt_main_NonXAML.cpp to be compiled without /ZW,
for Visual C++'s build tools to create a winmd file, and for the app to
build without APPX0702 errors. In this case, if
SDL_WINRT_METADATA_FILE_AVAILABLE is defined as a C/C++ macro, then
the #error (to force C++/CX compilation) will be disabled.
Please note that /ZW can be specified on a file-by-file basis. To do this,
right click on the file in Visual C++, click Properties, then change the
setting through the dialog that comes up.
*/
#ifndef SDL_WINRT_METADATA_FILE_AVAILABLE
#ifndef __cplusplus_winrt
#error SDL_winrt_main_NonXAML.cpp must be compiled with /ZW, otherwise build errors due to missing .winmd files can occur.
#endif
#endif
/* Prevent MSVC++ from warning about threading models when defining our
custom WinMain. The threading model will instead be set via a direct
call to Windows::Foundation::Initialize (rather than via an attributed
function).
To note, this warning (C4447) does not seem to come up unless this file
is compiled with C++/CX enabled (via the /ZW compiler flag).
*/
#ifdef _MSC_VER
#pragma warning(disable:4447)
#endif
/* Make sure the function to initialize the Windows Runtime gets linked in. */
#ifdef _MSC_VER
#pragma comment(lib, "runtimeobject.lib")
#endif
int CALLBACK WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
return SDL_WinRTRunApp(SDL_main, NULL);
}

View File

@@ -1,41 +0,0 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2022 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_sysurl.h"
#include "../../core/windows/SDL_windows.h"
int
SDL_SYS_OpenURL(const char *url)
{
WCHAR *wurl = WIN_UTF8ToStringW(url);
if (!wurl) {
return SDL_OutOfMemory();
}
auto strurl = ref new Platform::String(wurl);
SDL_free(wurl);
auto uri = ref new Windows::Foundation::Uri(strurl);
Windows::System::Launcher::LaunchUriAsync(uri);
return 0; // oh well, we're not waiting on an async task here.
}
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -74,9 +74,6 @@ static SDL_GetPowerInfo_Impl implementations[] = {
#ifdef SDL_POWER_N3DS /* handles N3DS. */
SDL_GetPowerInfo_N3DS,
#endif
#ifdef SDL_POWER_WINRT /* handles WinRT */
SDL_GetPowerInfo_WinRT,
#endif
#ifdef SDL_POWER_EMSCRIPTEN /* handles Emscripten */
SDL_GetPowerInfo_Emscripten,
#endif

View File

@@ -40,7 +40,6 @@ SDL_bool SDL_GetPowerInfo_Android(SDL_PowerState *, int *, int *);
SDL_bool SDL_GetPowerInfo_PSP(SDL_PowerState *, int *, int *);
SDL_bool SDL_GetPowerInfo_VITA(SDL_PowerState *, int *, int *);
SDL_bool SDL_GetPowerInfo_N3DS(SDL_PowerState *, int *, int *);
SDL_bool SDL_GetPowerInfo_WinRT(SDL_PowerState *, int *, int *);
SDL_bool SDL_GetPowerInfo_Emscripten(SDL_PowerState *, int *, int *);
/* this one is static in SDL_power.c */

View File

@@ -1,44 +0,0 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2022 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"
#ifndef SDL_POWER_DISABLED
#if SDL_POWER_WINRT
#include "SDL_power.h"
extern "C"
SDL_bool
SDL_GetPowerInfo_WinRT(SDL_PowerState * state, int *seconds, int *percent)
{
/* TODO, WinRT: Battery info is available on at least one WinRT platform (Windows Phone 8). Implement SDL_GetPowerInfo_WinRT as appropriate. */
/* Notes:
- the Win32 function, GetSystemPowerStatus, is not available for use on WinRT
- Windows Phone 8 has a 'Battery' class, which is documented as available for C++
- More info on WP8's Battery class can be found at http://msdn.microsoft.com/library/windowsphone/develop/jj207231
*/
return SDL_FALSE;
}
#endif /* SDL_POWER_WINRT */
#endif /* SDL_POWER_DISABLED */
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -27,9 +27,7 @@
#define COBJMACROS
#include "../../core/windows/SDL_windows.h"
#if !defined(__WINRT__)
#include "../../video/windows/SDL_windowswindow.h"
#endif
#include "SDL_hints.h"
#include "SDL_loadso.h"
#include "SDL_syswm.h"
@@ -40,22 +38,6 @@
#include "SDL_shaders_d3d11.h"
#ifdef __WINRT__
#if NTDDI_VERSION > NTDDI_WIN8
#include <DXGI1_3.h>
#endif
#include "SDL_render_winrt.h"
#if WINAPI_FAMILY == WINAPI_FAMILY_APP
#include <windows.ui.xaml.media.dxinterop.h>
/* TODO, WinRT, XAML: get the ISwapChainBackgroundPanelNative from something other than a global var */
extern ISwapChainBackgroundPanelNative * WINRT_GlobalSwapChainBackgroundPanelNative;
#endif /* WINAPI_FAMILY == WINAPI_FAMILY_APP */
#endif /* __WINRT__ */
#if defined(_MSC_VER) && !defined(__clang__)
#define SDL_COMPOSE_ERROR(str) __FUNCTION__ ", " str
@@ -187,9 +169,6 @@ typedef struct
static const GUID SDL_IID_IDXGIFactory2 = { 0x50c83a1c, 0xe072, 0x4c48, { 0x87, 0xb0, 0x36, 0x30, 0xfa, 0x36, 0xa6, 0xd0 } };
static const GUID SDL_IID_IDXGIDevice1 = { 0x77db970f, 0x6276, 0x48ba, { 0xba, 0x28, 0x07, 0x01, 0x43, 0xb4, 0x39, 0x2c } };
#if defined(__WINRT__) && NTDDI_VERSION > NTDDI_WIN8
static const GUID SDL_IID_IDXGIDevice3 = { 0x6007896c, 0x3244, 0x4afd, { 0xbf, 0x18, 0xa6, 0xd3, 0xbe, 0xda, 0x50, 0x23 } };
#endif
static const GUID SDL_IID_ID3D11Texture2D = { 0x6f15aaf2, 0xd208, 0x4e89, { 0x9a, 0xb4, 0x48, 0x95, 0x35, 0xd3, 0x4f, 0x9c } };
static const GUID SDL_IID_ID3D11Device1 = { 0xa04bfb29, 0x08ef, 0x43d6, { 0xa4, 0x9c, 0xa9, 0xbd, 0xbd, 0xcb, 0xe6, 0x86 } };
static const GUID SDL_IID_ID3D11DeviceContext1 = { 0xbb2c6faa, 0xb5fb, 0x4082, { 0x8e, 0x6b, 0x38, 0x8b, 0x8c, 0xfa, 0x90, 0xe1 } };
@@ -439,10 +418,6 @@ D3D11_CreateDeviceResources(SDL_Renderer * renderer)
D3D11_SAMPLER_DESC samplerDesc;
D3D11_RASTERIZER_DESC rasterDesc;
#ifdef __WINRT__
CreateDXGIFactoryFunc = CreateDXGIFactory1;
D3D11CreateDeviceFunc = D3D11CreateDevice;
#else
data->hDXGIMod = SDL_LoadObject("dxgi.dll");
if (!data->hDXGIMod) {
result = E_FAIL;
@@ -466,7 +441,6 @@ D3D11_CreateDeviceResources(SDL_Renderer * renderer)
result = E_FAIL;
goto done;
}
#endif /* __WINRT__ */
result = CreateDXGIFactoryFunc(&SDL_IID_IDXGIFactory2, (void **)&data->dxgiFactory);
if (FAILED(result)) {
@@ -754,13 +728,8 @@ static HRESULT
D3D11_CreateSwapChain(SDL_Renderer * renderer, int w, int h)
{
D3D11_RenderData *data = (D3D11_RenderData *)renderer->driverdata;
#ifdef __WINRT__
IUnknown *coreWindow = D3D11_GetCoreWindowFromSDLRenderer(renderer);
const BOOL usingXAML = (coreWindow == NULL);
#else
IUnknown *coreWindow = NULL;
const BOOL usingXAML = FALSE;
#endif
HRESULT result = S_OK;
/* Create a swap chain using the same adapter as the existing Direct3D device. */
@@ -913,11 +882,7 @@ D3D11_CreateWindowSizeDependentResources(SDL_Renderer * renderer)
/* The width and height of the swap chain must be based on the display's
* non-rotated size.
*/
#if defined(__WINRT__)
SDL_GetWindowSize(renderer->window, &w, &h);
#else
SDL_GetWindowSizeInPixels(renderer->window, &w, &h);
#endif
data->rotation = D3D11_GetCurrentRotation();
/* SDL_Log("%s: windowSize={%d,%d}, orientation=%d\n", __FUNCTION__, w, h, (int)data->rotation); */
if (D3D11_IsDisplayRotated90Degrees(data->rotation)) {
@@ -928,7 +893,7 @@ D3D11_CreateWindowSizeDependentResources(SDL_Renderer * renderer)
if (data->swapChain) {
/* IDXGISwapChain::ResizeBuffers is not available on Windows Phone 8. */
#if !defined(__WINRT__) || (WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP)
#if (WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP)
/* If the swap chain already exists, resize it. */
result = IDXGISwapChain_ResizeBuffers(data->swapChain,
0,
@@ -1032,22 +997,6 @@ D3D11_UpdateForWindowSizeChange(SDL_Renderer * renderer)
void
D3D11_Trim(SDL_Renderer * renderer)
{
#ifdef __WINRT__
#if NTDDI_VERSION > NTDDI_WIN8
D3D11_RenderData *data = (D3D11_RenderData *)renderer->driverdata;
HRESULT result = S_OK;
IDXGIDevice3 *dxgiDevice = NULL;
result = ID3D11Device_QueryInterface(data->d3dDevice, &SDL_IID_IDXGIDevice3, &dxgiDevice);
if (FAILED(result)) {
//WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device to IDXGIDevice3", result);
return;
}
IDXGIDevice3_Trim(dxgiDevice);
SAFE_RELEASE(dxgiDevice);
#endif
#endif
}
static void
@@ -1058,14 +1007,12 @@ D3D11_WindowEvent(SDL_Renderer * renderer, const SDL_WindowEvent *event)
}
}
#if !defined(__WINRT__)
static int
D3D11_GetOutputSize(SDL_Renderer * renderer, int *w, int *h)
{
SDL_GetWindowSizeInPixels(renderer->window, w, h);
return 0;
}
#endif
static SDL_bool
D3D11_SupportsBlendMode(SDL_Renderer * renderer, SDL_BlendMode blendMode)
@@ -2384,9 +2331,7 @@ D3D11_CreateRenderer(SDL_Window * window, Uint32 flags)
data->identity = MatrixIdentity();
renderer->WindowEvent = D3D11_WindowEvent;
#if !defined(__WINRT__)
renderer->GetOutputSize = D3D11_GetOutputSize;
#endif
renderer->SupportsBlendMode = D3D11_SupportsBlendMode;
renderer->CreateTexture = D3D11_CreateTexture;
renderer->UpdateTexture = D3D11_UpdateTexture;

View File

@@ -1,116 +0,0 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2022 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_RENDER_D3D11 && !SDL_RENDER_DISABLED
#include "SDL_syswm.h"
#include "../../video/winrt/SDL_winrtvideo_cpp.h"
extern "C" {
#include "../SDL_sysrender.h"
}
#include <windows.ui.core.h>
#include <windows.graphics.display.h>
#if WINAPI_FAMILY == WINAPI_FAMILY_APP
#include <windows.ui.xaml.media.dxinterop.h>
#endif
using namespace Windows::UI::Core;
using namespace Windows::Graphics::Display;
#include <DXGI.h>
#include "SDL_render_winrt.h"
extern "C" void *
D3D11_GetCoreWindowFromSDLRenderer(SDL_Renderer * renderer)
{
SDL_Window * sdlWindow = renderer->window;
if ( ! renderer->window ) {
return NULL;
}
SDL_SysWMinfo sdlWindowInfo;
SDL_VERSION(&sdlWindowInfo.version);
if ( ! SDL_GetWindowWMInfo(sdlWindow, &sdlWindowInfo) ) {
return NULL;
}
if (sdlWindowInfo.subsystem != SDL_SYSWM_WINRT) {
return NULL;
}
if (!sdlWindowInfo.info.winrt.window) {
return NULL;
}
ABI::Windows::UI::Core::ICoreWindow *coreWindow = NULL;
if (FAILED(sdlWindowInfo.info.winrt.window->QueryInterface(&coreWindow))) {
return NULL;
}
IUnknown *coreWindowAsIUnknown = NULL;
coreWindow->QueryInterface(&coreWindowAsIUnknown);
coreWindow->Release();
return coreWindowAsIUnknown;
}
extern "C" DXGI_MODE_ROTATION
D3D11_GetCurrentRotation()
{
const DisplayOrientations currentOrientation = WINRT_DISPLAY_PROPERTY(CurrentOrientation);
switch (currentOrientation) {
#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
/* Windows Phone rotations */
case DisplayOrientations::Landscape:
return DXGI_MODE_ROTATION_ROTATE90;
case DisplayOrientations::Portrait:
return DXGI_MODE_ROTATION_IDENTITY;
case DisplayOrientations::LandscapeFlipped:
return DXGI_MODE_ROTATION_ROTATE270;
case DisplayOrientations::PortraitFlipped:
return DXGI_MODE_ROTATION_ROTATE180;
#else
/* Non-Windows-Phone rotations (ex: Windows 8, Windows RT) */
case DisplayOrientations::Landscape:
return DXGI_MODE_ROTATION_IDENTITY;
case DisplayOrientations::Portrait:
return DXGI_MODE_ROTATION_ROTATE270;
case DisplayOrientations::LandscapeFlipped:
return DXGI_MODE_ROTATION_ROTATE180;
case DisplayOrientations::PortraitFlipped:
return DXGI_MODE_ROTATION_ROTATE90;
#endif /* WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP */
}
return DXGI_MODE_ROTATION_IDENTITY;
}
#endif /* SDL_VIDEO_RENDER_D3D11 && !SDL_RENDER_DISABLED */
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -1,40 +0,0 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2022 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_RENDER_D3D11 && !SDL_RENDER_DISABLED
#include "SDL_render.h"
#ifdef __cplusplus
extern "C" {
#endif
void * D3D11_GetCoreWindowFromSDLRenderer(SDL_Renderer * renderer);
DXGI_MODE_ROTATION D3D11_GetCurrentRotation();
#ifdef __cplusplus
}
#endif
#endif /* SDL_VIDEO_RENDER_D3D11 && !SDL_RENDER_DISABLED */
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -2152,14 +2152,6 @@ GLES2_CreateRenderer(SDL_Window *window, Uint32 flags)
goto error;
}
#if __WINRT__
/* DLudwig, 2013-11-29: ANGLE for WinRT doesn't seem to work unless VSync
* is turned on. Not doing so will freeze the screen's contents to that
* of the first drawn frame.
*/
flags |= SDL_RENDERER_PRESENTVSYNC;
#endif
if (flags & SDL_RENDERER_PRESENTVSYNC) {
SDL_GL_SetSwapInterval(1);
} else {

View File

@@ -32,10 +32,6 @@ extern "C" {
#include <thread>
#include <system_error>
#ifdef __WINRT__
#include <Windows.h>
#endif
static void
RunThread(void *args)
{
@@ -71,9 +67,6 @@ extern "C"
SDL_threadID
SDL_ThreadID(void)
{
#ifdef __WINRT__
return GetCurrentThreadId();
#else
// HACK: Mimick a thread ID, if one isn't otherwise available.
static thread_local SDL_threadID current_thread_id = 0;
static SDL_threadID next_thread_id = 1;
@@ -86,37 +79,13 @@ SDL_ThreadID(void)
}
return current_thread_id;
#endif
}
extern "C"
int
SDL_SYS_SetThreadPriority(SDL_ThreadPriority priority)
{
#ifdef __WINRT__
int value;
if (priority == SDL_THREAD_PRIORITY_LOW) {
value = THREAD_PRIORITY_LOWEST;
}
else if (priority == SDL_THREAD_PRIORITY_HIGH) {
value = THREAD_PRIORITY_HIGHEST;
}
else if (priority == SDL_THREAD_PRIORITY_TIME_CRITICAL) {
// FIXME: WinRT does not support TIME_CRITICAL! -flibit
SDL_LogWarn(SDL_LOG_CATEGORY_SYSTEM, "TIME_CRITICAL unsupported, falling back to HIGHEST");
value = THREAD_PRIORITY_HIGHEST;
}
else {
value = THREAD_PRIORITY_NORMAL;
}
if (!SetThreadPriority(GetCurrentThread(), value)) {
return WIN_SetError("SetThreadPriority()");
}
return 0;
#else
return SDL_Unsupported();
#endif
}
extern "C"

View File

@@ -58,12 +58,6 @@ typedef struct CONDITION_VARIABLE {
} CONDITION_VARIABLE, *PCONDITION_VARIABLE;
#endif
#if __WINRT__
#define pWakeConditionVariable WakeConditionVariable
#define pWakeAllConditionVariable WakeAllConditionVariable
#define pSleepConditionVariableSRW SleepConditionVariableSRW
#define pSleepConditionVariableCS SleepConditionVariableCS
#else
typedef VOID(WINAPI *pfnWakeConditionVariable)(PCONDITION_VARIABLE);
typedef VOID(WINAPI *pfnWakeAllConditionVariable)(PCONDITION_VARIABLE);
typedef BOOL(WINAPI *pfnSleepConditionVariableSRW)(PCONDITION_VARIABLE, PSRWLOCK, DWORD, ULONG);
@@ -73,7 +67,6 @@ static pfnWakeConditionVariable pWakeConditionVariable = NULL;
static pfnWakeAllConditionVariable pWakeAllConditionVariable = NULL;
static pfnSleepConditionVariableSRW pSleepConditionVariableSRW = NULL;
static pfnSleepConditionVariableCS pSleepConditionVariableCS = NULL;
#endif
typedef struct SDL_cond_cv
{
@@ -242,10 +235,6 @@ SDL_CreateCond(void)
SDL_assert(SDL_mutex_impl_active.Type != SDL_MUTEX_INVALID);
}
#if __WINRT__
/* Link statically on this platform */
impl = &SDL_cond_impl_cv;
#else
{
HMODULE kernel32 = GetModuleHandle(TEXT("kernel32.dll"));
if (kernel32) {
@@ -259,7 +248,6 @@ SDL_CreateCond(void)
}
}
}
#endif
SDL_copyp(&SDL_cond_impl_active, impl);
}

View File

@@ -44,19 +44,12 @@ SDL_mutex_impl_t SDL_mutex_impl_active = {0};
* Implementation based on Slim Reader/Writer (SRW) Locks for Win 7 and newer.
*/
#if __WINRT__
/* Functions are guaranteed to be available */
#define pReleaseSRWLockExclusive ReleaseSRWLockExclusive
#define pAcquireSRWLockExclusive AcquireSRWLockExclusive
#define pTryAcquireSRWLockExclusive TryAcquireSRWLockExclusive
#else
typedef VOID(WINAPI *pfnReleaseSRWLockExclusive)(PSRWLOCK);
typedef VOID(WINAPI *pfnAcquireSRWLockExclusive)(PSRWLOCK);
typedef BOOLEAN(WINAPI *pfnTryAcquireSRWLockExclusive)(PSRWLOCK);
static pfnReleaseSRWLockExclusive pReleaseSRWLockExclusive = NULL;
static pfnAcquireSRWLockExclusive pAcquireSRWLockExclusive = NULL;
static pfnTryAcquireSRWLockExclusive pTryAcquireSRWLockExclusive = NULL;
#endif
static SDL_mutex *
SDL_CreateMutex_srw(void)
@@ -180,11 +173,7 @@ SDL_CreateMutex_cs(void)
if (mutex) {
/* Initialize */
/* On SMP systems, a non-zero spin count generally helps performance */
#if __WINRT__
InitializeCriticalSectionEx(&mutex->cs, 2000, 0);
#else
InitializeCriticalSectionAndSpinCount(&mutex->cs, 2000);
#endif
} else {
SDL_OutOfMemory();
}
@@ -267,10 +256,6 @@ SDL_CreateMutex(void)
const SDL_mutex_impl_t * impl = &SDL_mutex_impl_cs;
if (!SDL_GetHintBoolean(SDL_HINT_WINDOWS_FORCE_MUTEX_CRITICAL_SECTIONS, SDL_FALSE)) {
#if __WINRT__
/* Link statically on this platform */
impl = &SDL_mutex_impl_srw;
#else
/* Try faster implementation for Windows 7 and newer */
HMODULE kernel32 = GetModuleHandle(TEXT("kernel32.dll"));
if (kernel32) {
@@ -283,7 +268,6 @@ SDL_CreateMutex(void)
impl = &SDL_mutex_impl_srw;
}
}
#endif
}
/* Copy instead of using pointer to save one level of indirection */

View File

@@ -76,17 +76,11 @@ static SDL_sem_impl_t SDL_sem_impl_active = {0};
#endif
#if !SDL_WINAPI_FAMILY_PHONE
#if __WINRT__
/* Functions are guaranteed to be available */
#define pWaitOnAddress WaitOnAddress
#define pWakeByAddressSingle WakeByAddressSingle
#else
typedef BOOL(WINAPI *pfnWaitOnAddress)(volatile VOID*, PVOID, SIZE_T, DWORD);
typedef VOID(WINAPI *pfnWakeByAddressSingle)(PVOID);
static pfnWaitOnAddress pWaitOnAddress = NULL;
static pfnWakeByAddressSingle pWakeByAddressSingle = NULL;
#endif
typedef struct SDL_semaphore_atom
{
@@ -274,11 +268,7 @@ SDL_CreateSemaphore_kern(Uint32 initial_value)
sem = (SDL_sem_kern *) SDL_malloc(sizeof(*sem));
if (sem) {
/* Create the semaphore, with max value 32K */
#if __WINRT__
sem->id = CreateSemaphoreEx(NULL, initial_value, 32 * 1024, NULL, 0, SEMAPHORE_ALL_ACCESS);
#else
sem->id = CreateSemaphore(NULL, initial_value, 32 * 1024, NULL);
#endif
sem->count = initial_value;
if (!sem->id) {
SDL_SetError("Couldn't create semaphore");
@@ -405,10 +395,6 @@ SDL_CreateSemaphore(Uint32 initial_value)
#if !SDL_WINAPI_FAMILY_PHONE
if (!SDL_GetHintBoolean(SDL_HINT_WINDOWS_FORCE_SEMAPHORE_KERNEL, SDL_FALSE)) {
#if __WINRT__
/* Link statically on this platform */
impl = &SDL_sem_impl_atom;
#else
/* We already statically link to features from this Api
* Set (e.g. WaitForSingleObject). Dynamically loading
* API Sets is not explicitly documented but according to
@@ -425,7 +411,6 @@ SDL_CreateSemaphore(Uint32 initial_value)
impl = &SDL_sem_impl_atom;
}
}
#endif
}
#endif

View File

@@ -87,7 +87,7 @@ SDL_SYS_CreateThread(SDL_Thread * thread,
pfnSDL_CurrentBeginThread pfnBeginThread,
pfnSDL_CurrentEndThread pfnEndThread)
{
#elif defined(__CYGWIN__) || defined(__WINRT__)
#elif defined(__CYGWIN__)
int
SDL_SYS_CreateThread(SDL_Thread * thread)
{
@@ -141,7 +141,6 @@ void
SDL_SYS_SetupThread(const char *name)
{
if (name != NULL) {
#ifndef __WINRT__ /* !!! FIXME: There's no LoadLibrary() in WinRT; don't know if SetThreadDescription is available there at all at the moment. */
static pfnSetThreadDescription pSetThreadDescription = NULL;
static HMODULE kernel32 = 0;
@@ -159,7 +158,6 @@ SDL_SYS_SetupThread(const char *name)
SDL_free(strw);
}
}
#endif
/* Presumably some version of Visual Studio will understand SetThreadDescription(),
but we still need to deal with older OSes and debuggers. Set it with the arcane

View File

@@ -28,18 +28,6 @@
#include "SDL_thread.h"
#include "../SDL_thread_c.h"
#if WINAPI_FAMILY_WINRT
#include <fibersapi.h>
#ifndef TLS_OUT_OF_INDEXES
#define TLS_OUT_OF_INDEXES FLS_OUT_OF_INDEXES
#endif
#define TlsAlloc() FlsAlloc(NULL)
#define TlsSetValue FlsSetValue
#define TlsGetValue FlsGetValue
#endif
static DWORD thread_local_storage = TLS_OUT_OF_INDEXES;
static SDL_bool generic_local_storage = SDL_FALSE;

View File

@@ -41,7 +41,7 @@ static LARGE_INTEGER ticks_per_second;
static void
SDL_SetSystemTimerResolution(const UINT uPeriod)
{
#if !defined(__WINRT__) && !defined(__XBOXONE__) && !defined(__XBOXSERIES__)
#if !defined(__XBOXONE__) && !defined(__XBOXSERIES__)
static UINT timer_period = 0;
if (uPeriod != timer_period) {
@@ -146,31 +146,11 @@ SDL_GetPerformanceFrequency(void)
void
SDL_Delay(Uint32 ms)
{
/* Sleep() is not publicly available to apps in early versions of WinRT.
*
* Visual C++ 2013 Update 4 re-introduced Sleep() for Windows 8.1 and
* Windows Phone 8.1.
*
* Use the compiler version to determine availability.
*
* NOTE #1: _MSC_FULL_VER == 180030723 for Visual C++ 2013 Update 3.
* NOTE #2: Visual C++ 2013, when compiling for Windows 8.0 and
* Windows Phone 8.0, uses the Visual C++ 2012 compiler to build
* apps and libraries.
*/
#if defined(__WINRT__) && defined(_MSC_FULL_VER) && (_MSC_FULL_VER <= 180030723)
static HANDLE mutex = 0;
if (!mutex) {
mutex = CreateEventEx(0, 0, 0, EVENT_ALL_ACCESS);
}
WaitForSingleObjectEx(mutex, ms, FALSE);
#else
if (!ticks_started) {
SDL_TicksInit();
}
Sleep(ms);
#endif
}
#endif /* SDL_TIMER_WINDOWS */

View File

@@ -22,7 +22,7 @@
#if SDL_VIDEO_OPENGL_EGL
#if SDL_VIDEO_DRIVER_WINDOWS || SDL_VIDEO_DRIVER_WINRT
#if SDL_VIDEO_DRIVER_WINDOWS
#include "../core/windows/SDL_windows.h"
#endif
#if SDL_VIDEO_DRIVER_ANDROID
@@ -73,7 +73,7 @@
#define DEFAULT_OGL_ES_PVR "libGLES_CM.so"
#define DEFAULT_OGL_ES "libGLESv1_CM.so"
#elif SDL_VIDEO_DRIVER_WINDOWS || SDL_VIDEO_DRIVER_WINRT
#elif SDL_VIDEO_DRIVER_WINDOWS
/* EGL AND OpenGL ES support via ANGLE */
#define DEFAULT_EGL "libEGL.dll"
#define DEFAULT_OGL_ES2 "libGLESv2.dll"
@@ -297,14 +297,14 @@ SDL_EGL_LoadLibraryInternal(_THIS, const char *egl_path)
{
void *egl_dll_handle = NULL, *opengl_dll_handle = NULL;
const char *path = NULL;
#if SDL_VIDEO_DRIVER_WINDOWS || SDL_VIDEO_DRIVER_WINRT
#if SDL_VIDEO_DRIVER_WINDOWS
const char *d3dcompiler;
#endif
#if SDL_VIDEO_DRIVER_RPI
SDL_bool vc4 = (0 == access("/sys/module/vc4/", F_OK));
#endif
#if SDL_VIDEO_DRIVER_WINDOWS || SDL_VIDEO_DRIVER_WINRT
#if SDL_VIDEO_DRIVER_WINDOWS
d3dcompiler = SDL_GetHint(SDL_HINT_VIDEO_WIN_D3DCOMPILER);
if (d3dcompiler) {
if (SDL_strcasecmp(d3dcompiler, "none") != 0) {
@@ -510,7 +510,6 @@ SDL_EGL_LoadLibrary(_THIS, const char *egl_path, NativeDisplayType native_displa
_this->egl_data->egl_display = EGL_NO_DISPLAY;
#if !defined(__WINRT__)
#if !defined(SDL_VIDEO_DRIVER_VITA)
if (platform) {
/* EGL 1.5 allows querying for client version with EGL_NO_DISPLAY
@@ -552,7 +551,6 @@ SDL_EGL_LoadLibrary(_THIS, const char *egl_path, NativeDisplayType native_displa
*_this->gl_config.driver_path = '\0';
return SDL_SetError("Could not initialize EGL");
}
#endif
/* Get the EGL version with a valid egl_display, for EGL <= 1.4 */
SDL_EGL_GetVersion(_this);

View File

@@ -352,7 +352,7 @@ scale_mat(const Uint32 *src, int src_w, int src_h, int src_pitch,
# define CAST_uint32x2_t (uint32x2_t)
#endif
#if defined(__WINRT__) || defined(_MSC_VER)
#if defined(_MSC_VER)
# if defined(HAVE_NEON_INTRINSICS)
# undef CAST_uint8x8_t
# undef CAST_uint32x2_t

View File

@@ -451,7 +451,6 @@ typedef struct VideoBootStrap
extern VideoBootStrap COCOA_bootstrap;
extern VideoBootStrap X11_bootstrap;
extern VideoBootStrap WINDOWS_bootstrap;
extern VideoBootStrap WINRT_bootstrap;
extern VideoBootStrap HAIKU_bootstrap;
extern VideoBootStrap PND_bootstrap;
extern VideoBootStrap UIKIT_bootstrap;

View File

@@ -76,9 +76,6 @@ static VideoBootStrap *bootstrap[] = {
#if SDL_VIDEO_DRIVER_WINDOWS
&WINDOWS_bootstrap,
#endif
#if SDL_VIDEO_DRIVER_WINRT
&WINRT_bootstrap,
#endif
#if SDL_VIDEO_DRIVER_HAIKU
&HAIKU_bootstrap,
#endif
@@ -1335,10 +1332,6 @@ 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)
{
@@ -1381,30 +1374,6 @@ SDL_UpdateFullscreenMode(SDL_Window * window, SDL_bool fullscreen)
return 0;
}
}
#elif __WINRT__ && (NTDDI_VERSION < NTDDI_WIN10)
/* 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);
@@ -1758,18 +1727,6 @@ SDL_CreateWindow(const char *title, int x, int y, int w, int h, Uint32 flags)
}
#endif
#if __WINRT__ && (NTDDI_VERSION < NTDDI_WIN10)
/* 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);
}
@@ -4417,9 +4374,6 @@ SDL_GetMessageBoxCount(void)
#if SDL_VIDEO_DRIVER_WINDOWS
#include "windows/SDL_windowsmessagebox.h"
#endif
#if SDL_VIDEO_DRIVER_WINRT
#include "winrt/SDL_winrtmessagebox.h"
#endif
#if SDL_VIDEO_DRIVER_COCOA
#include "cocoa/SDL_cocoamessagebox.h"
#endif
@@ -4442,7 +4396,7 @@ SDL_GetMessageBoxCount(void)
#include "vita/SDL_vitamessagebox.h"
#endif
#if SDL_VIDEO_DRIVER_WINDOWS || SDL_VIDEO_DRIVER_WINRT || SDL_VIDEO_DRIVER_COCOA || SDL_VIDEO_DRIVER_UIKIT || SDL_VIDEO_DRIVER_X11 || SDL_VIDEO_DRIVER_WAYLAND || SDL_VIDEO_DRIVER_HAIKU || SDL_VIDEO_DRIVER_RISCOS
#if SDL_VIDEO_DRIVER_WINDOWS || SDL_VIDEO_DRIVER_COCOA || SDL_VIDEO_DRIVER_UIKIT || SDL_VIDEO_DRIVER_X11 || SDL_VIDEO_DRIVER_WAYLAND || SDL_VIDEO_DRIVER_HAIKU || SDL_VIDEO_DRIVER_RISCOS
static SDL_bool SDL_MessageboxValidForDriver(const SDL_MessageBoxData *messageboxdata, SDL_SYSWM_TYPE drivertype)
{
SDL_SysWMinfo info;
@@ -4515,13 +4469,6 @@ SDL_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid)
retval = 0;
}
#endif
#if SDL_VIDEO_DRIVER_WINRT
if (retval == -1 &&
SDL_MessageboxValidForDriver(messageboxdata, SDL_SYSWM_WINRT) &&
WINRT_ShowMessageBox(messageboxdata, buttonid) == 0) {
retval = 0;
}
#endif
#if SDL_VIDEO_DRIVER_COCOA
if (retval == -1 &&
SDL_MessageboxValidForDriver(messageboxdata, SDL_SYSWM_COCOA) &&

View File

@@ -1,153 +0,0 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2022 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
/*
* Windows includes:
*/
#include <Windows.h>
using namespace Windows::UI::Core;
using Windows::UI::Core::CoreCursor;
/*
* SDL includes:
*/
#include "SDL_winrtevents_c.h"
#include "../../core/winrt/SDL_winrtapp_common.h"
#include "../../core/winrt/SDL_winrtapp_direct3d.h"
#include "../../core/winrt/SDL_winrtapp_xaml.h"
#include "SDL_system.h"
extern "C" {
#include "../../thread/SDL_systhread.h"
#include "../SDL_sysvideo.h"
#include "../../events/SDL_events_c.h"
}
/* Forward declarations */
static void WINRT_YieldXAMLThread();
/* Global event management */
void
WINRT_PumpEvents(_THIS)
{
if (SDL_WinRTGlobalApp) {
SDL_WinRTGlobalApp->PumpEvents();
} else if (WINRT_XAMLWasEnabled) {
WINRT_YieldXAMLThread();
}
}
/* XAML Thread management */
enum SDL_XAMLAppThreadState
{
ThreadState_NotLaunched = 0,
ThreadState_Running,
ThreadState_Yielding
};
static SDL_XAMLAppThreadState _threadState = ThreadState_NotLaunched;
static SDL_Thread * _XAMLThread = nullptr;
static SDL_mutex * _mutex = nullptr;
static SDL_cond * _cond = nullptr;
static void
WINRT_YieldXAMLThread()
{
SDL_LockMutex(_mutex);
SDL_assert(_threadState == ThreadState_Running);
_threadState = ThreadState_Yielding;
SDL_UnlockMutex(_mutex);
SDL_CondSignal(_cond);
SDL_LockMutex(_mutex);
while (_threadState != ThreadState_Running) {
SDL_CondWait(_cond, _mutex);
}
SDL_UnlockMutex(_mutex);
}
static int
WINRT_XAMLThreadMain(void * userdata)
{
// TODO, WinRT: pass the C-style main() a reasonably realistic
// representation of command line arguments.
int argc = 0;
char **argv = NULL;
return WINRT_SDLAppEntryPoint(argc, argv);
}
void
WINRT_CycleXAMLThread(void)
{
switch (_threadState) {
case ThreadState_NotLaunched:
{
_cond = SDL_CreateCond();
_mutex = SDL_CreateMutex();
_threadState = ThreadState_Running;
_XAMLThread = SDL_CreateThreadInternal(WINRT_XAMLThreadMain, "SDL/XAML App Thread", 0, nullptr);
SDL_LockMutex(_mutex);
while (_threadState != ThreadState_Yielding) {
SDL_CondWait(_cond, _mutex);
}
SDL_UnlockMutex(_mutex);
break;
}
case ThreadState_Running:
{
SDL_assert(false);
break;
}
case ThreadState_Yielding:
{
SDL_LockMutex(_mutex);
SDL_assert(_threadState == ThreadState_Yielding);
_threadState = ThreadState_Running;
SDL_UnlockMutex(_mutex);
SDL_CondSignal(_cond);
SDL_LockMutex(_mutex);
while (_threadState != ThreadState_Yielding) {
SDL_CondWait(_cond, _mutex);
}
SDL_UnlockMutex(_mutex);
}
}
}
#endif /* SDL_VIDEO_DRIVER_WINRT */
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -1,83 +0,0 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2022 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_config.h"
extern "C" {
#include "../SDL_sysvideo.h"
}
/*
* Internal-use, C-style functions:
*/
#ifdef __cplusplus
extern "C" {
#endif
extern void WINRT_InitTouch(_THIS);
extern void WINRT_PumpEvents(_THIS);
#ifdef __cplusplus
}
#endif
/*
* Internal-use, C++/CX functions:
*/
#ifdef __cplusplus_winrt
/* Pointers (Mice, Touch, etc.) */
typedef enum {
NormalizeZeroToOne,
TransformToSDLWindowSize
} WINRT_CursorNormalizationType;
extern Windows::Foundation::Point WINRT_TransformCursorPosition(SDL_Window * window,
Windows::Foundation::Point rawPosition,
WINRT_CursorNormalizationType normalization);
extern SDL_bool WINRT_GetSDLButtonForPointerPoint(Windows::UI::Input::PointerPoint ^pt, Uint8 *button, Uint8 *pressed);
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);
/* Keyboard */
extern void WINRT_ProcessKeyDownEvent(Windows::UI::Core::KeyEventArgs ^args);
extern void WINRT_ProcessKeyUpEvent(Windows::UI::Core::KeyEventArgs ^args);
extern void WINRT_ProcessCharacterReceivedEvent(Windows::UI::Core::CharacterReceivedEventArgs ^args);
#if NTDDI_VERSION >= NTDDI_WIN10
extern void WINTRT_InitialiseInputPaneEvents(_THIS);
extern SDL_bool WINRT_HasScreenKeyboardSupport(_THIS);
extern void WINRT_ShowScreenKeyboard(_THIS, SDL_Window *window);
extern void WINRT_HideScreenKeyboard(_THIS, SDL_Window *window);
extern SDL_bool WINRT_IsScreenKeyboardShown(_THIS, SDL_Window *window);
#endif // NTDDI_VERSION >= ...
/* XAML Thread Management */
extern void WINRT_CycleXAMLThread(void);
#endif // ifdef __cplusplus_winrt
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -1,196 +0,0 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2022 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
/* Windows includes */
#include <roapi.h>
#include <windows.foundation.h>
#include <windows.system.h>
/* SDL includes */
extern "C" {
#include "SDL_mouse.h"
#include "../SDL_sysvideo.h"
}
#include "SDL_winrtvideo_cpp.h"
/* Game Bar events can come in off the main thread. Use the following
WinRT CoreDispatcher to deal with them on SDL's thread.
*/
static Platform::WeakReference WINRT_MainThreadDispatcher;
/* Win10's initial SDK (the 10.0.10240.0 release) does not include references
to Game Bar APIs, as the Game Bar was released via Win10 10.0.10586.0.
Declare its WinRT/COM interface here, to allow compilation with earlier
Windows SDKs.
*/
MIDL_INTERFACE("1DB9A292-CC78-4173-BE45-B61E67283EA7")
IGameBarStatics_ : public IInspectable
{
public:
virtual HRESULT STDMETHODCALLTYPE add_VisibilityChanged(
__FIEventHandler_1_IInspectable *handler,
Windows::Foundation::EventRegistrationToken *token) = 0;
virtual HRESULT STDMETHODCALLTYPE remove_VisibilityChanged(
Windows::Foundation::EventRegistrationToken token) = 0;
virtual HRESULT STDMETHODCALLTYPE add_IsInputRedirectedChanged(
__FIEventHandler_1_IInspectable *handler,
Windows::Foundation::EventRegistrationToken *token) = 0;
virtual HRESULT STDMETHODCALLTYPE remove_IsInputRedirectedChanged(
Windows::Foundation::EventRegistrationToken token) = 0;
virtual HRESULT STDMETHODCALLTYPE get_Visible(
boolean *value) = 0;
virtual HRESULT STDMETHODCALLTYPE get_IsInputRedirected(
boolean *value) = 0;
};
/* Declare the game bar's COM GUID */
static GUID IID_IGameBarStatics_ = { MAKELONG(0xA292, 0x1DB9), 0xCC78, 0x4173, { 0xBE, 0x45, 0xB6, 0x1E, 0x67, 0x28, 0x3E, 0xA7 } };
/* Retrieves a pointer to the game bar, or NULL if it is not available.
If a pointer is returned, it's ->Release() method must be called
after the caller has finished using it.
*/
static IGameBarStatics_ *
WINRT_GetGameBar()
{
wchar_t *wClassName = L"Windows.Gaming.UI.GameBar";
HSTRING hClassName;
IActivationFactory *pActivationFactory = NULL;
IGameBarStatics_ *pGameBar = NULL;
HRESULT hr;
hr = ::WindowsCreateString(wClassName, (UINT32)SDL_wcslen(wClassName), &hClassName);
if (FAILED(hr)) {
goto done;
}
hr = Windows::Foundation::GetActivationFactory(hClassName, &pActivationFactory);
if (FAILED(hr)) {
goto done;
}
pActivationFactory->QueryInterface(IID_IGameBarStatics_, (void **) &pGameBar);
done:
if (pActivationFactory) {
pActivationFactory->Release();
}
if (hClassName) {
::WindowsDeleteString(hClassName);
}
return pGameBar;
}
static void
WINRT_HandleGameBarIsInputRedirected_MainThread()
{
IGameBarStatics_ *gameBar;
boolean isInputRedirected = 0;
if (!WINRT_MainThreadDispatcher) {
/* The game bar event handler has been deregistered! */
return;
}
gameBar = WINRT_GetGameBar();
if (!gameBar) {
/* Shouldn't happen, but just in case... */
return;
}
if (SUCCEEDED(gameBar->get_IsInputRedirected(&isInputRedirected))) {
if ( ! isInputRedirected) {
/* Input-control is now back to the SDL app. Restore the cursor,
in case Windows does not (it does not in either Win10
10.0.10240.0 or 10.0.10586.0, maybe later version(s) too.
*/
SDL_Cursor *cursor = SDL_GetCursor();
SDL_SetCursor(cursor);
}
}
gameBar->Release();
}
static void
WINRT_HandleGameBarIsInputRedirected_NonMainThread(Platform::Object ^ o1, Platform::Object ^o2)
{
Windows::UI::Core::CoreDispatcher ^dispatcher = WINRT_MainThreadDispatcher.Resolve<Windows::UI::Core::CoreDispatcher>();
if (dispatcher) {
dispatcher->RunAsync(
Windows::UI::Core::CoreDispatcherPriority::Normal,
ref new Windows::UI::Core::DispatchedHandler(&WINRT_HandleGameBarIsInputRedirected_MainThread));
}
}
void
WINRT_InitGameBar(_THIS)
{
SDL_VideoData *driverdata = (SDL_VideoData *)_this->driverdata;
IGameBarStatics_ *gameBar = WINRT_GetGameBar();
if (gameBar) {
/* GameBar.IsInputRedirected events can come in via something other than
the main/SDL thread.
Get a WinRT 'CoreDispatcher' that can be used to call back into the
SDL thread.
*/
WINRT_MainThreadDispatcher = Windows::UI::Core::CoreWindow::GetForCurrentThread()->Dispatcher;
Windows::Foundation::EventHandler<Platform::Object ^> ^handler = \
ref new Windows::Foundation::EventHandler<Platform::Object ^>(&WINRT_HandleGameBarIsInputRedirected_NonMainThread);
__FIEventHandler_1_IInspectable * pHandler = reinterpret_cast<__FIEventHandler_1_IInspectable *>(handler);
gameBar->add_IsInputRedirectedChanged(pHandler, &driverdata->gameBarIsInputRedirectedToken);
gameBar->Release();
}
}
void
WINRT_QuitGameBar(_THIS)
{
SDL_VideoData *driverdata;
IGameBarStatics_ *gameBar;
if (!_this || !_this->driverdata) {
return;
}
gameBar = WINRT_GetGameBar();
if (!gameBar) {
return;
}
driverdata = (SDL_VideoData *)_this->driverdata;
if (driverdata->gameBarIsInputRedirectedToken.Value) {
gameBar->remove_IsInputRedirectedChanged(driverdata->gameBarIsInputRedirectedToken);
driverdata->gameBarIsInputRedirectedToken.Value = 0;
}
WINRT_MainThreadDispatcher = nullptr;
gameBar->Release();
}
#endif /* SDL_VIDEO_DRIVER_WINRT */
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -1,35 +0,0 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2022 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_config.h"
#ifndef SDL_winrtgamebar_h_
#define SDL_winrtgamebar_h_
#ifdef __cplusplus
/* These are exported as C++ functions, rather than C, to fix a compilation
bug with MSVC 2013, for Windows 8.x builds. */
extern void WINRT_InitGameBar(_THIS);
extern void WINRT_QuitGameBar(_THIS);
#endif
#endif /* SDL_winrtgamebar_h_ */
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -1,466 +0,0 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2022 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
/* Windows-specific includes */
#include <Windows.h>
#include <agile.h>
/* SDL-specific includes */
#include "SDL.h"
#include "SDL_winrtevents_c.h"
extern "C" {
#include "../../events/scancodes_windows.h"
#include "../../events/SDL_keyboard_c.h"
}
static SDL_Scancode WinRT_Official_Keycodes[] = {
SDL_SCANCODE_UNKNOWN, /* VirtualKey.None -- 0 */
SDL_SCANCODE_UNKNOWN, /* VirtualKey.LeftButton -- 1 */
SDL_SCANCODE_UNKNOWN, /* VirtualKey.RightButton -- 2 */
SDL_SCANCODE_CANCEL, /* VirtualKey.Cancel -- 3 */
SDL_SCANCODE_UNKNOWN, /* VirtualKey.MiddleButton -- 4 */
SDL_SCANCODE_UNKNOWN, /* VirtualKey.XButton1 -- 5 */
SDL_SCANCODE_UNKNOWN, /* VirtualKey.XButton2 -- 6 */
SDL_SCANCODE_UNKNOWN, /* -- 7 */
SDL_SCANCODE_BACKSPACE, /* VirtualKey.Back -- 8 */
SDL_SCANCODE_TAB, /* VirtualKey.Tab -- 9 */
SDL_SCANCODE_UNKNOWN, /* -- 10 */
SDL_SCANCODE_UNKNOWN, /* -- 11 */
SDL_SCANCODE_CLEAR, /* VirtualKey.Clear -- 12 */
SDL_SCANCODE_RETURN, /* VirtualKey.Enter -- 13 */
SDL_SCANCODE_UNKNOWN, /* -- 14 */
SDL_SCANCODE_UNKNOWN, /* -- 15 */
SDL_SCANCODE_LSHIFT, /* VirtualKey.Shift -- 16 */
SDL_SCANCODE_LCTRL, /* VirtualKey.Control -- 17 */
SDL_SCANCODE_MENU, /* VirtualKey.Menu -- 18 */
SDL_SCANCODE_PAUSE, /* VirtualKey.Pause -- 19 */
SDL_SCANCODE_CAPSLOCK, /* VirtualKey.CapitalLock -- 20 */
SDL_SCANCODE_UNKNOWN, /* VirtualKey.Kana or VirtualKey.Hangul -- 21 */
SDL_SCANCODE_UNKNOWN, /* -- 22 */
SDL_SCANCODE_UNKNOWN, /* VirtualKey.Junja -- 23 */
SDL_SCANCODE_UNKNOWN, /* VirtualKey.Final -- 24 */
SDL_SCANCODE_UNKNOWN, /* VirtualKey.Hanja or VirtualKey.Kanji -- 25 */
SDL_SCANCODE_UNKNOWN, /* -- 26 */
SDL_SCANCODE_ESCAPE, /* VirtualKey.Escape -- 27 */
SDL_SCANCODE_UNKNOWN, /* VirtualKey.Convert -- 28 */
SDL_SCANCODE_UNKNOWN, /* VirtualKey.NonConvert -- 29 */
SDL_SCANCODE_UNKNOWN, /* VirtualKey.Accept -- 30 */
SDL_SCANCODE_UNKNOWN, /* VirtualKey.ModeChange -- 31 (maybe SDL_SCANCODE_MODE ?) */
SDL_SCANCODE_SPACE, /* VirtualKey.Space -- 32 */
SDL_SCANCODE_PAGEUP, /* VirtualKey.PageUp -- 33 */
SDL_SCANCODE_PAGEDOWN, /* VirtualKey.PageDown -- 34 */
SDL_SCANCODE_END, /* VirtualKey.End -- 35 */
SDL_SCANCODE_HOME, /* VirtualKey.Home -- 36 */
SDL_SCANCODE_LEFT, /* VirtualKey.Left -- 37 */
SDL_SCANCODE_UP, /* VirtualKey.Up -- 38 */
SDL_SCANCODE_RIGHT, /* VirtualKey.Right -- 39 */
SDL_SCANCODE_DOWN, /* VirtualKey.Down -- 40 */
SDL_SCANCODE_SELECT, /* VirtualKey.Select -- 41 */
SDL_SCANCODE_UNKNOWN, /* VirtualKey.Print -- 42 (maybe SDL_SCANCODE_PRINTSCREEN ?) */
SDL_SCANCODE_EXECUTE, /* VirtualKey.Execute -- 43 */
SDL_SCANCODE_UNKNOWN, /* VirtualKey.Snapshot -- 44 */
SDL_SCANCODE_INSERT, /* VirtualKey.Insert -- 45 */
SDL_SCANCODE_DELETE, /* VirtualKey.Delete -- 46 */
SDL_SCANCODE_HELP, /* VirtualKey.Help -- 47 */
SDL_SCANCODE_0, /* VirtualKey.Number0 -- 48 */
SDL_SCANCODE_1, /* VirtualKey.Number1 -- 49 */
SDL_SCANCODE_2, /* VirtualKey.Number2 -- 50 */
SDL_SCANCODE_3, /* VirtualKey.Number3 -- 51 */
SDL_SCANCODE_4, /* VirtualKey.Number4 -- 52 */
SDL_SCANCODE_5, /* VirtualKey.Number5 -- 53 */
SDL_SCANCODE_6, /* VirtualKey.Number6 -- 54 */
SDL_SCANCODE_7, /* VirtualKey.Number7 -- 55 */
SDL_SCANCODE_8, /* VirtualKey.Number8 -- 56 */
SDL_SCANCODE_9, /* VirtualKey.Number9 -- 57 */
SDL_SCANCODE_UNKNOWN, /* -- 58 */
SDL_SCANCODE_UNKNOWN, /* -- 59 */
SDL_SCANCODE_UNKNOWN, /* -- 60 */
SDL_SCANCODE_UNKNOWN, /* -- 61 */
SDL_SCANCODE_UNKNOWN, /* -- 62 */
SDL_SCANCODE_UNKNOWN, /* -- 63 */
SDL_SCANCODE_UNKNOWN, /* -- 64 */
SDL_SCANCODE_A, /* VirtualKey.A -- 65 */
SDL_SCANCODE_B, /* VirtualKey.B -- 66 */
SDL_SCANCODE_C, /* VirtualKey.C -- 67 */
SDL_SCANCODE_D, /* VirtualKey.D -- 68 */
SDL_SCANCODE_E, /* VirtualKey.E -- 69 */
SDL_SCANCODE_F, /* VirtualKey.F -- 70 */
SDL_SCANCODE_G, /* VirtualKey.G -- 71 */
SDL_SCANCODE_H, /* VirtualKey.H -- 72 */
SDL_SCANCODE_I, /* VirtualKey.I -- 73 */
SDL_SCANCODE_J, /* VirtualKey.J -- 74 */
SDL_SCANCODE_K, /* VirtualKey.K -- 75 */
SDL_SCANCODE_L, /* VirtualKey.L -- 76 */
SDL_SCANCODE_M, /* VirtualKey.M -- 77 */
SDL_SCANCODE_N, /* VirtualKey.N -- 78 */
SDL_SCANCODE_O, /* VirtualKey.O -- 79 */
SDL_SCANCODE_P, /* VirtualKey.P -- 80 */
SDL_SCANCODE_Q, /* VirtualKey.Q -- 81 */
SDL_SCANCODE_R, /* VirtualKey.R -- 82 */
SDL_SCANCODE_S, /* VirtualKey.S -- 83 */
SDL_SCANCODE_T, /* VirtualKey.T -- 84 */
SDL_SCANCODE_U, /* VirtualKey.U -- 85 */
SDL_SCANCODE_V, /* VirtualKey.V -- 86 */
SDL_SCANCODE_W, /* VirtualKey.W -- 87 */
SDL_SCANCODE_X, /* VirtualKey.X -- 88 */
SDL_SCANCODE_Y, /* VirtualKey.Y -- 89 */
SDL_SCANCODE_Z, /* VirtualKey.Z -- 90 */
SDL_SCANCODE_UNKNOWN, /* VirtualKey.LeftWindows -- 91 (maybe SDL_SCANCODE_APPLICATION or SDL_SCANCODE_LGUI ?) */
SDL_SCANCODE_UNKNOWN, /* VirtualKey.RightWindows -- 92 (maybe SDL_SCANCODE_APPLICATION or SDL_SCANCODE_RGUI ?) */
SDL_SCANCODE_APPLICATION, /* VirtualKey.Application -- 93 */
SDL_SCANCODE_UNKNOWN, /* -- 94 */
SDL_SCANCODE_SLEEP, /* VirtualKey.Sleep -- 95 */
SDL_SCANCODE_KP_0, /* VirtualKey.NumberPad0 -- 96 */
SDL_SCANCODE_KP_1, /* VirtualKey.NumberPad1 -- 97 */
SDL_SCANCODE_KP_2, /* VirtualKey.NumberPad2 -- 98 */
SDL_SCANCODE_KP_3, /* VirtualKey.NumberPad3 -- 99 */
SDL_SCANCODE_KP_4, /* VirtualKey.NumberPad4 -- 100 */
SDL_SCANCODE_KP_5, /* VirtualKey.NumberPad5 -- 101 */
SDL_SCANCODE_KP_6, /* VirtualKey.NumberPad6 -- 102 */
SDL_SCANCODE_KP_7, /* VirtualKey.NumberPad7 -- 103 */
SDL_SCANCODE_KP_8, /* VirtualKey.NumberPad8 -- 104 */
SDL_SCANCODE_KP_9, /* VirtualKey.NumberPad9 -- 105 */
SDL_SCANCODE_KP_MULTIPLY, /* VirtualKey.Multiply -- 106 */
SDL_SCANCODE_KP_PLUS, /* VirtualKey.Add -- 107 */
SDL_SCANCODE_UNKNOWN, /* VirtualKey.Separator -- 108 */
SDL_SCANCODE_KP_MINUS, /* VirtualKey.Subtract -- 109 */
SDL_SCANCODE_UNKNOWN, /* VirtualKey.Decimal -- 110 (maybe SDL_SCANCODE_DECIMALSEPARATOR, SDL_SCANCODE_KP_DECIMAL, or SDL_SCANCODE_KP_PERIOD ?) */
SDL_SCANCODE_KP_DIVIDE, /* VirtualKey.Divide -- 111 */
SDL_SCANCODE_F1, /* VirtualKey.F1 -- 112 */
SDL_SCANCODE_F2, /* VirtualKey.F2 -- 113 */
SDL_SCANCODE_F3, /* VirtualKey.F3 -- 114 */
SDL_SCANCODE_F4, /* VirtualKey.F4 -- 115 */
SDL_SCANCODE_F5, /* VirtualKey.F5 -- 116 */
SDL_SCANCODE_F6, /* VirtualKey.F6 -- 117 */
SDL_SCANCODE_F7, /* VirtualKey.F7 -- 118 */
SDL_SCANCODE_F8, /* VirtualKey.F8 -- 119 */
SDL_SCANCODE_F9, /* VirtualKey.F9 -- 120 */
SDL_SCANCODE_F10, /* VirtualKey.F10 -- 121 */
SDL_SCANCODE_F11, /* VirtualKey.F11 -- 122 */
SDL_SCANCODE_F12, /* VirtualKey.F12 -- 123 */
SDL_SCANCODE_F13, /* VirtualKey.F13 -- 124 */
SDL_SCANCODE_F14, /* VirtualKey.F14 -- 125 */
SDL_SCANCODE_F15, /* VirtualKey.F15 -- 126 */
SDL_SCANCODE_F16, /* VirtualKey.F16 -- 127 */
SDL_SCANCODE_F17, /* VirtualKey.F17 -- 128 */
SDL_SCANCODE_F18, /* VirtualKey.F18 -- 129 */
SDL_SCANCODE_F19, /* VirtualKey.F19 -- 130 */
SDL_SCANCODE_F20, /* VirtualKey.F20 -- 131 */
SDL_SCANCODE_F21, /* VirtualKey.F21 -- 132 */
SDL_SCANCODE_F22, /* VirtualKey.F22 -- 133 */
SDL_SCANCODE_F23, /* VirtualKey.F23 -- 134 */
SDL_SCANCODE_F24, /* VirtualKey.F24 -- 135 */
SDL_SCANCODE_UNKNOWN, /* -- 136 */
SDL_SCANCODE_UNKNOWN, /* -- 137 */
SDL_SCANCODE_UNKNOWN, /* -- 138 */
SDL_SCANCODE_UNKNOWN, /* -- 139 */
SDL_SCANCODE_UNKNOWN, /* -- 140 */
SDL_SCANCODE_UNKNOWN, /* -- 141 */
SDL_SCANCODE_UNKNOWN, /* -- 142 */
SDL_SCANCODE_UNKNOWN, /* -- 143 */
SDL_SCANCODE_NUMLOCKCLEAR, /* VirtualKey.NumberKeyLock -- 144 */
SDL_SCANCODE_SCROLLLOCK, /* VirtualKey.Scroll -- 145 */
SDL_SCANCODE_UNKNOWN, /* -- 146 */
SDL_SCANCODE_UNKNOWN, /* -- 147 */
SDL_SCANCODE_UNKNOWN, /* -- 148 */
SDL_SCANCODE_UNKNOWN, /* -- 149 */
SDL_SCANCODE_UNKNOWN, /* -- 150 */
SDL_SCANCODE_UNKNOWN, /* -- 151 */
SDL_SCANCODE_UNKNOWN, /* -- 152 */
SDL_SCANCODE_UNKNOWN, /* -- 153 */
SDL_SCANCODE_UNKNOWN, /* -- 154 */
SDL_SCANCODE_UNKNOWN, /* -- 155 */
SDL_SCANCODE_UNKNOWN, /* -- 156 */
SDL_SCANCODE_UNKNOWN, /* -- 157 */
SDL_SCANCODE_UNKNOWN, /* -- 158 */
SDL_SCANCODE_UNKNOWN, /* -- 159 */
SDL_SCANCODE_LSHIFT, /* VirtualKey.LeftShift -- 160 */
SDL_SCANCODE_RSHIFT, /* VirtualKey.RightShift -- 161 */
SDL_SCANCODE_LCTRL, /* VirtualKey.LeftControl -- 162 */
SDL_SCANCODE_RCTRL, /* VirtualKey.RightControl -- 163 */
SDL_SCANCODE_MENU, /* VirtualKey.LeftMenu -- 164 */
SDL_SCANCODE_MENU, /* VirtualKey.RightMenu -- 165 */
SDL_SCANCODE_AC_BACK, /* VirtualKey.GoBack -- 166 : The go back key. */
SDL_SCANCODE_AC_FORWARD, /* VirtualKey.GoForward -- 167 : The go forward key. */
SDL_SCANCODE_AC_REFRESH, /* VirtualKey.Refresh -- 168 : The refresh key. */
SDL_SCANCODE_AC_STOP, /* VirtualKey.Stop -- 169 : The stop key. */
SDL_SCANCODE_AC_SEARCH, /* VirtualKey.Search -- 170 : The search key. */
SDL_SCANCODE_AC_BOOKMARKS, /* VirtualKey.Favorites -- 171 : The favorites key. */
SDL_SCANCODE_AC_HOME /* VirtualKey.GoHome -- 172 : The go home key. */
};
/* Attempt to translate a keycode that isn't listed in WinRT's VirtualKey enum.
*/
static SDL_Scancode
WINRT_TranslateUnofficialKeycode(int keycode)
{
switch (keycode) {
case 173: return SDL_SCANCODE_MUTE; /* VK_VOLUME_MUTE */
case 174: return SDL_SCANCODE_VOLUMEDOWN; /* VK_VOLUME_DOWN */
case 175: return SDL_SCANCODE_VOLUMEUP; /* VK_VOLUME_UP */
case 176: return SDL_SCANCODE_AUDIONEXT; /* VK_MEDIA_NEXT_TRACK */
case 177: return SDL_SCANCODE_AUDIOPREV; /* VK_MEDIA_PREV_TRACK */
// case 178: return ; /* VK_MEDIA_STOP */
case 179: return SDL_SCANCODE_AUDIOPLAY; /* VK_MEDIA_PLAY_PAUSE */
case 180: return SDL_SCANCODE_MAIL; /* VK_LAUNCH_MAIL */
case 181: return SDL_SCANCODE_MEDIASELECT; /* VK_LAUNCH_MEDIA_SELECT */
// case 182: return ; /* VK_LAUNCH_APP1 */
case 183: return SDL_SCANCODE_CALCULATOR; /* VK_LAUNCH_APP2 */
// case 184: return ; /* ... reserved ... */
// case 185: return ; /* ... reserved ... */
case 186: return SDL_SCANCODE_SEMICOLON; /* VK_OEM_1, ';:' key on US standard keyboards */
case 187: return SDL_SCANCODE_EQUALS; /* VK_OEM_PLUS */
case 188: return SDL_SCANCODE_COMMA; /* VK_OEM_COMMA */
case 189: return SDL_SCANCODE_MINUS; /* VK_OEM_MINUS */
case 190: return SDL_SCANCODE_PERIOD; /* VK_OEM_PERIOD */
case 191: return SDL_SCANCODE_SLASH; /* VK_OEM_2, '/?' key on US standard keyboards */
case 192: return SDL_SCANCODE_GRAVE; /* VK_OEM_3, '`~' key on US standard keyboards */
// ?
// ... reserved or unassigned ...
// ?
case 219: return SDL_SCANCODE_LEFTBRACKET; /* VK_OEM_4, '[{' key on US standard keyboards */
case 220: return SDL_SCANCODE_BACKSLASH; /* VK_OEM_5, '\|' key on US standard keyboards */
case 221: return SDL_SCANCODE_RIGHTBRACKET; /* VK_OEM_6, ']}' key on US standard keyboards */
case 222: return SDL_SCANCODE_APOSTROPHE; /* VK_OEM_7, 'single/double quote' on US standard keyboards */
default: break;
}
return SDL_SCANCODE_UNKNOWN;
}
static SDL_Scancode
WINRT_TranslateKeycode(int keycode, unsigned int nativeScancode)
{
// TODO, WinRT: try filling out the WinRT keycode table as much as possible, using the Win32 table for interpretation hints
SDL_Scancode scancode = SDL_SCANCODE_UNKNOWN;
/* HACK ALERT: At least one VirtualKey constant (Shift) with a left/right
* designation might not get reported with its correct handedness, however
* its hardware scan code can fill in the gaps. If this is detected,
* use the hardware scan code to try telling if the left, or the right
* side's key was used.
*
* If Microsoft ever allows MapVirtualKey or MapVirtualKeyEx to be used
* in WinRT apps, or something similar to these (it doesn't appear to be,
* at least not for Windows [Phone] 8/8.1, as of Oct 24, 2014), then this
* hack might become deprecated, or obsolete.
*/
if (nativeScancode < SDL_arraysize(windows_scancode_table)) {
switch (keycode) {
case 16: // VirtualKey.Shift
switch (windows_scancode_table[nativeScancode]) {
case SDL_SCANCODE_LSHIFT:
case SDL_SCANCODE_RSHIFT:
return windows_scancode_table[nativeScancode];
}
break;
// Add others, as necessary.
//
// Unfortunately, this hack doesn't seem to work in determining
// handedness with Control keys.
default:
break;
}
}
/* Try to get a documented, WinRT, 'VirtualKey' next (as documented at
http://msdn.microsoft.com/en-us/library/windows/apps/windows.system.virtualkey.aspx ).
If that fails, fall back to a Win32 virtual key.
If that fails, attempt to fall back to a scancode-derived key.
*/
if (keycode < SDL_arraysize(WinRT_Official_Keycodes)) {
scancode = WinRT_Official_Keycodes[keycode];
}
if (scancode == SDL_SCANCODE_UNKNOWN) {
scancode = WINRT_TranslateUnofficialKeycode(keycode);
}
if (scancode == SDL_SCANCODE_UNKNOWN) {
if (nativeScancode < SDL_arraysize(windows_scancode_table)) {
scancode = windows_scancode_table[nativeScancode];
}
}
/*
if (scancode == SDL_SCANCODE_UNKNOWN) {
SDL_Log("WinRT TranslateKeycode, unknown keycode=%d\n", (int)keycode);
}
*/
return scancode;
}
void
WINRT_ProcessKeyDownEvent(Windows::UI::Core::KeyEventArgs ^args)
{
SDL_Scancode sdlScancode = WINRT_TranslateKeycode((int)args->VirtualKey, args->KeyStatus.ScanCode);
#if 0
SDL_Keycode keycode = SDL_GetKeyFromScancode(sdlScancode);
SDL_Log("key down, handled=%s, ext?=%s, released?=%s, menu key down?=%s, "
"repeat count=%d, native scan code=0x%x, was down?=%s, vkey=%d, "
"sdl scan code=%d (%s), sdl key code=%d (%s)\n",
(args->Handled ? "1" : "0"),
(args->KeyStatus.IsExtendedKey ? "1" : "0"),
(args->KeyStatus.IsKeyReleased ? "1" : "0"),
(args->KeyStatus.IsMenuKeyDown ? "1" : "0"),
args->KeyStatus.RepeatCount,
args->KeyStatus.ScanCode,
(args->KeyStatus.WasKeyDown ? "1" : "0"),
args->VirtualKey,
sdlScancode,
SDL_GetScancodeName(sdlScancode),
keycode,
SDL_GetKeyName(keycode));
//args->Handled = true;
#endif
SDL_SendKeyboardKey(SDL_PRESSED, sdlScancode);
}
void
WINRT_ProcessKeyUpEvent(Windows::UI::Core::KeyEventArgs ^args)
{
SDL_Scancode sdlScancode = WINRT_TranslateKeycode((int)args->VirtualKey, args->KeyStatus.ScanCode);
#if 0
SDL_Keycode keycode = SDL_GetKeyFromScancode(sdlScancode);
SDL_Log("key up, handled=%s, ext?=%s, released?=%s, menu key down?=%s, "
"repeat count=%d, native scan code=0x%x, was down?=%s, vkey=%d, "
"sdl scan code=%d (%s), sdl key code=%d (%s)\n",
(args->Handled ? "1" : "0"),
(args->KeyStatus.IsExtendedKey ? "1" : "0"),
(args->KeyStatus.IsKeyReleased ? "1" : "0"),
(args->KeyStatus.IsMenuKeyDown ? "1" : "0"),
args->KeyStatus.RepeatCount,
args->KeyStatus.ScanCode,
(args->KeyStatus.WasKeyDown ? "1" : "0"),
args->VirtualKey,
sdlScancode,
SDL_GetScancodeName(sdlScancode),
keycode,
SDL_GetKeyName(keycode));
//args->Handled = true;
#endif
SDL_SendKeyboardKey(SDL_RELEASED, sdlScancode);
}
void
WINRT_ProcessCharacterReceivedEvent(Windows::UI::Core::CharacterReceivedEventArgs ^args)
{
wchar_t src_ucs2[2];
char dest_utf8[16];
int result;
/* Setup src */
src_ucs2[0] = args->KeyCode;
src_ucs2[1] = L'\0';
/* Convert the text, then send an SDL_TEXTINPUT event. */
result = WideCharToMultiByte(CP_UTF8, 0, (LPCWSTR)&src_ucs2, -1, (LPSTR)dest_utf8, sizeof(dest_utf8), NULL, NULL);
if (result > 0) {
SDL_SendKeyboardText(dest_utf8);
}
}
#if NTDDI_VERSION >= NTDDI_WIN10
static bool WINRT_InputPaneVisible = false;
void WINTRT_OnInputPaneShowing(Windows::UI::ViewManagement::InputPane ^ sender, Windows::UI::ViewManagement::InputPaneVisibilityEventArgs ^ args)
{
WINRT_InputPaneVisible = true;
}
void WINTRT_OnInputPaneHiding(Windows::UI::ViewManagement::InputPane ^ sender, Windows::UI::ViewManagement::InputPaneVisibilityEventArgs ^ args)
{
WINRT_InputPaneVisible = false;
}
void WINTRT_InitialiseInputPaneEvents(_THIS)
{
using namespace Windows::UI::ViewManagement;
InputPane ^ inputPane = InputPane::GetForCurrentView();
if (inputPane) {
inputPane->Showing += ref new Windows::Foundation::TypedEventHandler<Windows::UI::ViewManagement::InputPane ^,
Windows::UI::ViewManagement::InputPaneVisibilityEventArgs ^>(&WINTRT_OnInputPaneShowing);
inputPane->Hiding += ref new Windows::Foundation::TypedEventHandler<Windows::UI::ViewManagement::InputPane ^,
Windows::UI::ViewManagement::InputPaneVisibilityEventArgs ^>(&WINTRT_OnInputPaneHiding);
}
}
SDL_bool WINRT_HasScreenKeyboardSupport(_THIS)
{
return SDL_TRUE;
}
void WINRT_ShowScreenKeyboard(_THIS, SDL_Window *window)
{
using namespace Windows::UI::ViewManagement;
InputPane ^ inputPane = InputPane::GetForCurrentView();
if (inputPane) {
inputPane->TryShow();
}
}
void WINRT_HideScreenKeyboard(_THIS, SDL_Window *window)
{
using namespace Windows::UI::ViewManagement;
InputPane ^ inputPane = InputPane::GetForCurrentView();
if (inputPane) {
inputPane->TryHide();
}
}
SDL_bool WINRT_IsScreenKeyboardShown(_THIS, SDL_Window *window)
{
using namespace Windows::UI::ViewManagement;
InputPane ^ inputPane = InputPane::GetForCurrentView();
if (inputPane) {
switch (SDL_WinRTGetDeviceFamily()) {
case SDL_WINRT_DEVICEFAMILY_XBOX:
//Documentation recommends using inputPane->Visible
//https://learn.microsoft.com/en-us/uwp/api/windows.ui.viewmanagement.inputpane.visible?view=winrt-22621
//This does not seem to work on latest UWP/Xbox.
//Workaround: Listen to Showing/Hiding events
if (WINRT_InputPaneVisible) {
return SDL_TRUE;
}
break;
default:
//OccludedRect is recommend on universal apps per docs
//https://learn.microsoft.com/en-us/uwp/api/windows.ui.viewmanagement.inputpane.visible?view=winrt-22621
Windows::Foundation::Rect rect = inputPane->OccludedRect;
if (rect.Width > 0 && rect.Height > 0) {
return SDL_TRUE;
}
break;
}
}
return SDL_FALSE;
}
#endif // NTDDI_VERSION >= ...
#endif // SDL_VIDEO_DRIVER_WINRT

View File

@@ -1,118 +0,0 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2022 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
extern "C" {
#include "SDL_messagebox.h"
#include "../../core/windows/SDL_windows.h"
}
#include "SDL_winrtevents_c.h"
#include <windows.ui.popups.h>
using namespace Platform;
using namespace Windows::Foundation;
using namespace Windows::UI::Popups;
static String ^
WINRT_UTF8ToPlatformString(const char * str)
{
wchar_t * wstr = WIN_UTF8ToString(str);
String ^ rtstr = ref new String(wstr);
SDL_free(wstr);
return rtstr;
}
extern "C" int
WINRT_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid)
{
#if (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) && (NTDDI_VERSION == NTDDI_WIN8)
/* Sadly, Windows Phone 8 doesn't include the MessageDialog class that
* Windows 8.x/RT does, even though MSDN's reference documentation for
* Windows Phone 8 mentions it.
*
* The .NET runtime on Windows Phone 8 does, however, include a
* MessageBox class. Perhaps this could be called, somehow?
*/
return SDL_SetError("SDL_messagebox support is not available for Windows Phone 8.0");
#else
SDL_VideoDevice *_this = SDL_GetVideoDevice();
#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
const int maxbuttons = 2;
const char * platform = "Windows Phone 8.1+";
#else
const int maxbuttons = 3;
const char * platform = "Windows 8.x";
#endif
if (messageboxdata->numbuttons > maxbuttons) {
return SDL_SetError("WinRT's MessageDialog only supports %d buttons, at most, on %s. %d were requested.",
maxbuttons, platform, messageboxdata->numbuttons);
}
/* Build a MessageDialog object and its buttons */
MessageDialog ^ dialog = ref new MessageDialog(WINRT_UTF8ToPlatformString(messageboxdata->message));
dialog->Title = WINRT_UTF8ToPlatformString(messageboxdata->title);
for (int i = 0; i < messageboxdata->numbuttons; ++i) {
const SDL_MessageBoxButtonData *sdlButton;
if (messageboxdata->flags & SDL_MESSAGEBOX_BUTTONS_RIGHT_TO_LEFT) {
sdlButton = &messageboxdata->buttons[messageboxdata->numbuttons - 1 - i];
} else {
sdlButton = &messageboxdata->buttons[i];
}
UICommand ^ button = ref new UICommand(WINRT_UTF8ToPlatformString(sdlButton->text));
button->Id = IntPtr((int)((size_t)(sdlButton - messageboxdata->buttons)));
dialog->Commands->Append(button);
if (sdlButton->flags & SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT) {
dialog->CancelCommandIndex = i;
}
if (sdlButton->flags & SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT) {
dialog->DefaultCommandIndex = i;
}
}
/* Display the MessageDialog, then wait for it to be closed */
/* TODO, WinRT: Find a way to redraw MessageDialog instances if a GPU device-reset occurs during the following event-loop */
auto operation = dialog->ShowAsync();
while (operation->Status == Windows::Foundation::AsyncStatus::Started) {
WINRT_PumpEvents(_this);
}
/* Retrieve results from the MessageDialog and process them accordingly */
if (operation->Status != Windows::Foundation::AsyncStatus::Completed) {
return SDL_SetError("An unknown error occurred in displaying the WinRT MessageDialog");
}
if (buttonid) {
IntPtr results = safe_cast<IntPtr>(operation->GetResults()->Id);
int clicked_index = results.ToInt32();
*buttonid = messageboxdata->buttons[clicked_index].buttonid;
}
return 0;
#endif /* if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP / else */
}
#endif /* SDL_VIDEO_DRIVER_WINRT */
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -1,29 +0,0 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2022 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
extern int WINRT_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid);
#endif /* SDL_VIDEO_DRIVER_WINRT */
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -1,222 +0,0 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2022 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
/*
* Windows includes:
*/
#include <Windows.h>
#include <windows.ui.core.h>
using namespace Windows::UI::Core;
using Windows::UI::Core::CoreCursor;
/*
* SDL includes:
*/
extern "C" {
#include "../../events/SDL_mouse_c.h"
#include "../../events/SDL_touch_c.h"
#include "../SDL_sysvideo.h"
#include "SDL_events.h"
}
#include "../../core/winrt/SDL_winrtapp_direct3d.h"
#include "SDL_winrtvideo_cpp.h"
#include "SDL_winrtmouse_c.h"
extern "C" SDL_bool WINRT_UsingRelativeMouseMode = SDL_FALSE;
static SDL_Cursor *
WINRT_CreateSystemCursor(SDL_SystemCursor id)
{
SDL_Cursor *cursor;
CoreCursorType cursorType = CoreCursorType::Arrow;
switch(id)
{
default:
SDL_assert(0);
return NULL;
case SDL_SYSTEM_CURSOR_ARROW: cursorType = CoreCursorType::Arrow; break;
case SDL_SYSTEM_CURSOR_IBEAM: cursorType = CoreCursorType::IBeam; break;
case SDL_SYSTEM_CURSOR_WAIT: cursorType = CoreCursorType::Wait; break;
case SDL_SYSTEM_CURSOR_CROSSHAIR: cursorType = CoreCursorType::Cross; break;
case SDL_SYSTEM_CURSOR_WAITARROW: cursorType = CoreCursorType::Wait; break;
case SDL_SYSTEM_CURSOR_SIZENWSE: cursorType = CoreCursorType::SizeNorthwestSoutheast; break;
case SDL_SYSTEM_CURSOR_SIZENESW: cursorType = CoreCursorType::SizeNortheastSouthwest; break;
case SDL_SYSTEM_CURSOR_SIZEWE: cursorType = CoreCursorType::SizeWestEast; break;
case SDL_SYSTEM_CURSOR_SIZENS: cursorType = CoreCursorType::SizeNorthSouth; break;
case SDL_SYSTEM_CURSOR_SIZEALL: cursorType = CoreCursorType::SizeAll; break;
case SDL_SYSTEM_CURSOR_NO: cursorType = CoreCursorType::UniversalNo; break;
case SDL_SYSTEM_CURSOR_HAND: cursorType = CoreCursorType::Hand; break;
}
cursor = (SDL_Cursor *) SDL_calloc(1, sizeof(*cursor));
if (cursor) {
/* Create a pointer to a COM reference to a cursor. The extra
pointer is used (on top of the COM reference) to allow the cursor
to be referenced by the SDL_cursor's driverdata field, which is
a void pointer.
*/
CoreCursor ^* theCursor = new CoreCursor^(nullptr);
*theCursor = ref new CoreCursor(cursorType, 0);
cursor->driverdata = (void *) theCursor;
} else {
SDL_OutOfMemory();
}
return cursor;
}
static SDL_Cursor *
WINRT_CreateDefaultCursor()
{
return WINRT_CreateSystemCursor(SDL_SYSTEM_CURSOR_ARROW);
}
static void
WINRT_FreeCursor(SDL_Cursor * cursor)
{
if (cursor->driverdata) {
CoreCursor ^* theCursor = (CoreCursor ^*) cursor->driverdata;
*theCursor = nullptr; // Release the COM reference to the CoreCursor
delete theCursor; // Delete the pointer to the COM reference
}
SDL_free(cursor);
}
static int
WINRT_ShowCursor(SDL_Cursor * cursor)
{
// TODO, WinRT, XAML: make WINRT_ShowCursor work when XAML support is enabled.
if ( ! CoreWindow::GetForCurrentThread()) {
return 0;
}
CoreWindow ^ coreWindow = CoreWindow::GetForCurrentThread();
if (cursor) {
CoreCursor ^* theCursor = (CoreCursor ^*) cursor->driverdata;
coreWindow->PointerCursor = *theCursor;
} else {
// HACK ALERT: TL;DR - Hiding the cursor in WinRT/UWP apps is weird, and
// a Win32-style cursor resource file must be directly included in apps,
// otherwise hiding the cursor will cause mouse-motion data to never be
// received.
//
// Here's the lengthy explanation:
//
// There are two ways to hide a cursor in WinRT/UWP apps.
// Both involve setting the WinRT CoreWindow's (which is somewhat analogous
// to a Win32 HWND) 'PointerCursor' property.
//
// The first way to hide a cursor sets PointerCursor to nullptr. This
// is, arguably, the easiest to implement for an app. It does have an
// unfortunate side-effect: it'll prevent mouse-motion events from being
// sent to the app (via CoreWindow).
//
// The second way to hide a cursor sets PointerCursor to a transparent
// cursor. This allows mouse-motion events to be sent to the app, but is
// more difficult to set up, as:
// 1. WinRT/UWP, while providing a few stock cursors, does not provide
// a completely transparent cursor.
// 2. WinRT/UWP allows apps to provide custom-built cursors, but *ONLY*
// if they are linked directly inside the app, via Win32-style
// cursor resource files. APIs to create cursors at runtime are
// not provided to apps, and attempting to link-to or use Win32
// cursor-creation APIs could cause an app to fail Windows Store
// certification.
//
// SDL can use either means of hiding the cursor. It provides a Win32-style
// set of cursor resource files in its source distribution, inside
// src/main/winrt/. If those files are linked to an SDL-for-WinRT/UWP app
// (by including them in a MSVC project, for example), SDL will attempt to
// use those, if and when the cursor is hidden via SDL APIs. If those
// files are not linked in, SDL will attempt to hide the cursor via the
// 'set PointerCursor to nullptr' means (which, if you recall, causes
// mouse-motion data to NOT be sent to the app!).
//
// Tech notes:
// - SDL's blank cursor resource uses a resource ID of 5000.
// - SDL's cursor resources consist of the following two files:
// - src/main/winrt/SDL3-WinRTResource_BlankCursor.cur -- cursor pixel data
// - src/main/winrt/SDL3-WinRTResources.rc -- declares the cursor resource, and its ID (of 5000)
//
const unsigned int win32CursorResourceID = 5000;
CoreCursor ^ blankCursor = ref new CoreCursor(CoreCursorType::Custom, win32CursorResourceID);
// Set 'PointerCursor' to 'blankCursor' in a way that shouldn't throw
// an exception if the app hasn't loaded that resource.
ABI::Windows::UI::Core::ICoreCursor * iblankCursor = reinterpret_cast<ABI::Windows::UI::Core::ICoreCursor *>(blankCursor);
ABI::Windows::UI::Core::ICoreWindow * icoreWindow = reinterpret_cast<ABI::Windows::UI::Core::ICoreWindow *>(coreWindow);
HRESULT hr = icoreWindow->put_PointerCursor(iblankCursor);
if (FAILED(hr)) {
// The app doesn't contain the cursor resource, or some other error
// occurred. Just use the other, but mouse-motion-preventing, means of
// hiding the cursor.
coreWindow->PointerCursor = nullptr;
}
}
return 0;
}
static int
WINRT_SetRelativeMouseMode(SDL_bool enabled)
{
WINRT_UsingRelativeMouseMode = enabled;
return 0;
}
void
WINRT_InitMouse(_THIS)
{
SDL_Mouse *mouse = SDL_GetMouse();
/* DLudwig, Dec 3, 2012: WinRT does not currently provide APIs for
the following features, AFAIK:
- custom cursors (multiple system cursors are, however, available)
- programmatically moveable cursors
*/
#if WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP
//mouse->CreateCursor = WINRT_CreateCursor;
mouse->CreateSystemCursor = WINRT_CreateSystemCursor;
mouse->ShowCursor = WINRT_ShowCursor;
mouse->FreeCursor = WINRT_FreeCursor;
//mouse->WarpMouse = WINRT_WarpMouse;
mouse->SetRelativeMouseMode = WINRT_SetRelativeMouseMode;
SDL_SetDefaultCursor(WINRT_CreateDefaultCursor());
#endif
}
void
WINRT_QuitMouse(_THIS)
{
}
#endif /* SDL_VIDEO_DRIVER_WINRT */
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -1,40 +0,0 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2022 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_config.h"
#ifndef SDL_winrtmouse_h_
#define SDL_winrtmouse_h_
#ifdef __cplusplus
extern "C" {
#endif
extern void WINRT_InitMouse(_THIS);
extern void WINRT_QuitMouse(_THIS);
extern SDL_bool WINRT_UsingRelativeMouseMode;
#ifdef __cplusplus
}
#endif
#endif /* SDL_winrtmouse_h_ */
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -1,203 +0,0 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2022 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 && SDL_VIDEO_OPENGL_EGL
/* EGL implementation of SDL OpenGL support */
#include "SDL_winrtvideo_cpp.h"
extern "C" {
#include "SDL_winrtopengles.h"
#include "SDL_loadso.h"
#include "../SDL_egl_c.h"
}
/* Windows includes */
#include <wrl/client.h>
using namespace Windows::UI::Core;
/* ANGLE/WinRT constants */
static const int ANGLE_D3D_FEATURE_LEVEL_ANY = 0;
#define EGL_PLATFORM_ANGLE_ANGLE 0x3202
#define EGL_PLATFORM_ANGLE_TYPE_ANGLE 0x3203
#define EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE 0x3204
#define EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE 0x3205
#define EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE 0x3208
#define EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE 0x3209
#define EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE 0x320B
#define EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE 0x320F
#define EGL_ANGLE_DISPLAY_ALLOW_RENDER_TO_BACK_BUFFER 0x320B
/*
* SDL/EGL top-level implementation
*/
extern "C" int
WINRT_GLES_LoadLibrary(_THIS, const char *path)
{
SDL_VideoData *video_data = (SDL_VideoData *)_this->driverdata;
if (SDL_EGL_LoadLibrary(_this, path, EGL_DEFAULT_DISPLAY, 0) != 0) {
return -1;
}
/* Load ANGLE/WinRT-specific functions */
CreateWinrtEglWindow_Old_Function CreateWinrtEglWindow = (CreateWinrtEglWindow_Old_Function) SDL_LoadFunction(_this->egl_data->opengl_dll_handle, "CreateWinrtEglWindow");
if (CreateWinrtEglWindow) {
/* 'CreateWinrtEglWindow' was found, which means that an an older
* version of ANGLE/WinRT is being used. Continue setting up EGL,
* as appropriate to this version of ANGLE.
*/
/* Create an ANGLE/WinRT EGL-window */
/* TODO, WinRT: check for XAML usage before accessing the CoreWindow, as not doing so could lead to a crash */
CoreWindow ^ native_win = CoreWindow::GetForCurrentThread();
Microsoft::WRL::ComPtr<IUnknown> cpp_win = reinterpret_cast<IUnknown *>(native_win);
HRESULT result = CreateWinrtEglWindow(cpp_win, ANGLE_D3D_FEATURE_LEVEL_ANY, &(video_data->winrtEglWindow));
if (FAILED(result)) {
return -1;
}
/* Call eglGetDisplay and eglInitialize as appropriate. On other
* platforms, this would probably get done by SDL_EGL_LoadLibrary,
* however ANGLE/WinRT's current implementation (as of Mar 22, 2014) of
* eglGetDisplay requires that a C++ object be passed into it, so the
* call will be made in this file, a C++ file, instead.
*/
Microsoft::WRL::ComPtr<IUnknown> cpp_display = video_data->winrtEglWindow;
_this->egl_data->egl_display = ((eglGetDisplay_Old_Function)_this->egl_data->eglGetDisplay)(cpp_display);
if (!_this->egl_data->egl_display) {
return SDL_EGL_SetError("Could not get Windows 8.0 EGL display", "eglGetDisplay");
}
if (_this->egl_data->eglInitialize(_this->egl_data->egl_display, NULL, NULL) != EGL_TRUE) {
return SDL_EGL_SetError("Could not initialize Windows 8.0 EGL", "eglInitialize");
}
} else {
/* Declare some ANGLE/EGL initialization property-sets, as suggested by
* MSOpenTech's ANGLE-for-WinRT template apps:
*/
const EGLint defaultDisplayAttributes[] =
{
EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE,
EGL_ANGLE_DISPLAY_ALLOW_RENDER_TO_BACK_BUFFER, EGL_TRUE,
EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE, EGL_TRUE,
EGL_NONE,
};
const EGLint fl9_3DisplayAttributes[] =
{
EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE,
EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE, 9,
EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE, 3,
EGL_ANGLE_DISPLAY_ALLOW_RENDER_TO_BACK_BUFFER, EGL_TRUE,
EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE, EGL_TRUE,
EGL_NONE,
};
const EGLint warpDisplayAttributes[] =
{
EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE,
EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE,
EGL_ANGLE_DISPLAY_ALLOW_RENDER_TO_BACK_BUFFER, EGL_TRUE,
EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE, EGL_TRUE,
EGL_NONE,
};
/* 'CreateWinrtEglWindow' was NOT found, which either means that a
* newer version of ANGLE/WinRT is being used, or that we don't have
* a valid copy of ANGLE.
*
* Try loading ANGLE as if it were the newer version.
*/
eglGetPlatformDisplayEXT_Function eglGetPlatformDisplayEXT = (eglGetPlatformDisplayEXT_Function)_this->egl_data->eglGetProcAddress("eglGetPlatformDisplayEXT");
if (!eglGetPlatformDisplayEXT) {
return SDL_EGL_SetError("Could not retrieve ANGLE/WinRT display function(s)", "eglGetProcAddress");
}
#if (WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP)
/* Try initializing EGL at D3D11 Feature Level 10_0+ (which is not
* supported on WinPhone 8.x.
*/
_this->egl_data->egl_display = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, EGL_DEFAULT_DISPLAY, defaultDisplayAttributes);
if (!_this->egl_data->egl_display) {
return SDL_EGL_SetError("Could not get EGL display for Direct3D 10_0+", "eglGetPlatformDisplayEXT");
}
if (_this->egl_data->eglInitialize(_this->egl_data->egl_display, NULL, NULL) != EGL_TRUE)
#endif
{
/* Try initializing EGL at D3D11 Feature Level 9_3, in case the
* 10_0 init fails, or we're on Windows Phone (which only supports
* 9_3).
*/
_this->egl_data->egl_display = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, EGL_DEFAULT_DISPLAY, fl9_3DisplayAttributes);
if (!_this->egl_data->egl_display) {
return SDL_EGL_SetError("Could not get EGL display for Direct3D 9_3", "eglGetPlatformDisplayEXT");
}
if (_this->egl_data->eglInitialize(_this->egl_data->egl_display, NULL, NULL) != EGL_TRUE) {
/* Try initializing EGL at D3D11 Feature Level 11_0 on WARP
* (a Windows-provided, software rasterizer) if all else fails.
*/
_this->egl_data->egl_display = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, EGL_DEFAULT_DISPLAY, warpDisplayAttributes);
if (!_this->egl_data->egl_display) {
return SDL_EGL_SetError("Could not get EGL display for Direct3D WARP", "eglGetPlatformDisplayEXT");
}
if (_this->egl_data->eglInitialize(_this->egl_data->egl_display, NULL, NULL) != EGL_TRUE) {
return SDL_EGL_SetError("Could not initialize WinRT 8.x+ EGL", "eglInitialize");
}
}
}
}
return 0;
}
extern "C" void
WINRT_GLES_UnloadLibrary(_THIS)
{
SDL_VideoData *video_data = (SDL_VideoData *)_this->driverdata;
/* Release SDL's own COM reference to the ANGLE/WinRT IWinrtEglWindow */
if (video_data->winrtEglWindow) {
video_data->winrtEglWindow->Release();
video_data->winrtEglWindow = nullptr;
}
/* Perform the bulk of the unloading */
SDL_EGL_UnloadLibrary(_this);
}
extern "C" {
SDL_EGL_CreateContext_impl(WINRT)
SDL_EGL_SwapWindow_impl(WINRT)
SDL_EGL_MakeCurrent_impl(WINRT)
}
#endif /* SDL_VIDEO_DRIVER_WINRT && SDL_VIDEO_OPENGL_EGL */
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -1,70 +0,0 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2022 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_config.h"
#ifndef SDL_winrtopengles_h_
#define SDL_winrtopengles_h_
#if SDL_VIDEO_DRIVER_WINRT && SDL_VIDEO_OPENGL_EGL
#include "../SDL_sysvideo.h"
#include "../SDL_egl_c.h"
/* OpenGLES functions */
#define WINRT_GLES_GetAttribute SDL_EGL_GetAttribute
#define WINRT_GLES_GetProcAddress SDL_EGL_GetProcAddress
#define WINRT_GLES_SetSwapInterval SDL_EGL_SetSwapInterval
#define WINRT_GLES_GetSwapInterval SDL_EGL_GetSwapInterval
#define WINRT_GLES_DeleteContext SDL_EGL_DeleteContext
extern int WINRT_GLES_LoadLibrary(_THIS, const char *path);
extern void WINRT_GLES_UnloadLibrary(_THIS);
extern SDL_GLContext WINRT_GLES_CreateContext(_THIS, SDL_Window * window);
extern int WINRT_GLES_SwapWindow(_THIS, SDL_Window * window);
extern int WINRT_GLES_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context);
#ifdef __cplusplus
/* Typedefs for ANGLE/WinRT's C++-based native-display and native-window types,
* which are used when calling eglGetDisplay and eglCreateWindowSurface.
*/
typedef Microsoft::WRL::ComPtr<IUnknown> WINRT_EGLNativeWindowType_Old;
/* Function pointer typedefs for 'old' ANGLE/WinRT's functions, which may
* require that C++ objects be passed in:
*/
typedef EGLDisplay (EGLAPIENTRY *eglGetDisplay_Old_Function)(WINRT_EGLNativeWindowType_Old);
typedef EGLSurface (EGLAPIENTRY *eglCreateWindowSurface_Old_Function)(EGLDisplay, EGLConfig, WINRT_EGLNativeWindowType_Old, const EGLint *);
typedef HRESULT (EGLAPIENTRY *CreateWinrtEglWindow_Old_Function)(Microsoft::WRL::ComPtr<IUnknown>, int, IUnknown ** result);
#endif /* __cplusplus */
/* Function pointer typedefs for 'new' ANGLE/WinRT functions, which, unlike
* the old functions, do not require C++ support and work with plain C.
*/
typedef EGLDisplay (EGLAPIENTRY *eglGetPlatformDisplayEXT_Function)(EGLenum, void *, const EGLint *);
#endif /* SDL_VIDEO_DRIVER_WINRT && SDL_VIDEO_OPENGL_EGL */
#endif /* SDL_winrtopengles_h_ */
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -1,407 +0,0 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2022 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
/* SDL includes */
#include "SDL_winrtevents_c.h"
#include "SDL_winrtmouse_c.h"
#include "SDL_winrtvideo_cpp.h"
#include "SDL_system.h"
extern "C" {
#include "../SDL_sysvideo.h"
#include "../../events/SDL_events_c.h"
#include "../../events/SDL_mouse_c.h"
#include "../../events/SDL_touch_c.h"
}
/* File-specific globals: */
static SDL_TouchID WINRT_TouchID = 1;
void
WINRT_InitTouch(_THIS)
{
SDL_AddTouch(WINRT_TouchID, SDL_TOUCH_DEVICE_DIRECT, "");
}
//
// Applies necessary geometric transformations to raw cursor positions:
//
Windows::Foundation::Point
WINRT_TransformCursorPosition(SDL_Window * window,
Windows::Foundation::Point rawPosition,
WINRT_CursorNormalizationType normalization)
{
using namespace Windows::UI::Core;
using namespace Windows::Graphics::Display;
if (!window) {
return rawPosition;
}
SDL_WindowData * windowData = (SDL_WindowData *) window->driverdata;
if (windowData->coreWindow == nullptr) {
// For some reason, the window isn't associated with a CoreWindow.
// This might end up being the case as XAML support is extended.
// For now, if there's no CoreWindow attached to the SDL_Window,
// don't do any transforms.
// TODO, WinRT: make sure touch input coordinate ranges are correct when using XAML support
return rawPosition;
}
// The CoreWindow can only be accessed on certain thread(s).
SDL_assert(CoreWindow::GetForCurrentThread() != nullptr);
CoreWindow ^ nativeWindow = windowData->coreWindow.Get();
Windows::Foundation::Point outputPosition;
// Compute coordinates normalized from 0..1.
// If the coordinates need to be sized to the SDL window,
// we'll do that after.
#if (WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP) || (NTDDI_VERSION > NTDDI_WIN8)
outputPosition.X = rawPosition.X / nativeWindow->Bounds.Width;
outputPosition.Y = rawPosition.Y / nativeWindow->Bounds.Height;
#else
switch (WINRT_DISPLAY_PROPERTY(CurrentOrientation))
{
case DisplayOrientations::Portrait:
outputPosition.X = rawPosition.X / nativeWindow->Bounds.Width;
outputPosition.Y = rawPosition.Y / nativeWindow->Bounds.Height;
break;
case DisplayOrientations::PortraitFlipped:
outputPosition.X = 1.0f - (rawPosition.X / nativeWindow->Bounds.Width);
outputPosition.Y = 1.0f - (rawPosition.Y / nativeWindow->Bounds.Height);
break;
case DisplayOrientations::Landscape:
outputPosition.X = rawPosition.Y / nativeWindow->Bounds.Height;
outputPosition.Y = 1.0f - (rawPosition.X / nativeWindow->Bounds.Width);
break;
case DisplayOrientations::LandscapeFlipped:
outputPosition.X = 1.0f - (rawPosition.Y / nativeWindow->Bounds.Height);
outputPosition.Y = rawPosition.X / nativeWindow->Bounds.Width;
break;
default:
break;
}
#endif
if (normalization == TransformToSDLWindowSize) {
outputPosition.X *= ((float32) window->w);
outputPosition.Y *= ((float32) window->h);
}
return outputPosition;
}
SDL_bool
WINRT_GetSDLButtonForPointerPoint(Windows::UI::Input::PointerPoint ^pt, Uint8 *button, Uint8 *pressed)
{
using namespace Windows::UI::Input;
#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
*button = SDL_BUTTON_LEFT;
return SDL_TRUE;
#else
switch (pt->Properties->PointerUpdateKind)
{
case PointerUpdateKind::LeftButtonPressed:
case PointerUpdateKind::LeftButtonReleased:
*button = SDL_BUTTON_LEFT;
*pressed = (pt->Properties->PointerUpdateKind == PointerUpdateKind::LeftButtonPressed);
return SDL_TRUE;
case PointerUpdateKind::RightButtonPressed:
case PointerUpdateKind::RightButtonReleased:
*button = SDL_BUTTON_RIGHT;
*pressed = (pt->Properties->PointerUpdateKind == PointerUpdateKind::RightButtonPressed);
return SDL_TRUE;
case PointerUpdateKind::MiddleButtonPressed:
case PointerUpdateKind::MiddleButtonReleased:
*button = SDL_BUTTON_MIDDLE;
*pressed = (pt->Properties->PointerUpdateKind == PointerUpdateKind::MiddleButtonPressed);
return SDL_TRUE;
case PointerUpdateKind::XButton1Pressed:
case PointerUpdateKind::XButton1Released:
*button = SDL_BUTTON_X1;
*pressed = (pt->Properties->PointerUpdateKind == PointerUpdateKind::XButton1Pressed);
return SDL_TRUE;
case PointerUpdateKind::XButton2Pressed:
case PointerUpdateKind::XButton2Released:
*button = SDL_BUTTON_X2;
*pressed = (pt->Properties->PointerUpdateKind == PointerUpdateKind::XButton2Pressed);
return SDL_TRUE;
default:
break;
}
#endif
*button = 0;
*pressed = 0;
return SDL_FALSE;
}
//const char *
//WINRT_ConvertPointerUpdateKindToString(Windows::UI::Input::PointerUpdateKind kind)
//{
// using namespace Windows::UI::Input;
//
// switch (kind)
// {
// case PointerUpdateKind::Other:
// return "Other";
// case PointerUpdateKind::LeftButtonPressed:
// return "LeftButtonPressed";
// case PointerUpdateKind::LeftButtonReleased:
// return "LeftButtonReleased";
// case PointerUpdateKind::RightButtonPressed:
// return "RightButtonPressed";
// case PointerUpdateKind::RightButtonReleased:
// return "RightButtonReleased";
// case PointerUpdateKind::MiddleButtonPressed:
// return "MiddleButtonPressed";
// case PointerUpdateKind::MiddleButtonReleased:
// return "MiddleButtonReleased";
// case PointerUpdateKind::XButton1Pressed:
// return "XButton1Pressed";
// case PointerUpdateKind::XButton1Released:
// return "XButton1Released";
// case PointerUpdateKind::XButton2Pressed:
// return "XButton2Pressed";
// case PointerUpdateKind::XButton2Released:
// return "XButton2Released";
// }
//
// return "";
//}
static bool
WINRT_IsTouchEvent(Windows::UI::Input::PointerPoint ^pointerPoint)
{
#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
return true;
#else
using namespace Windows::Devices::Input;
switch (pointerPoint->PointerDevice->PointerDeviceType) {
case PointerDeviceType::Touch:
case PointerDeviceType::Pen:
return true;
default:
return false;
}
#endif
}
void WINRT_ProcessPointerPressedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint)
{
if (!window) {
return;
}
if ( ! WINRT_IsTouchEvent(pointerPoint)) {
Uint8 button, pressed;
WINRT_GetSDLButtonForPointerPoint(pointerPoint, &button, &pressed);
SDL_assert(pressed == 1);
SDL_SendMouseButton(window, 0, SDL_PRESSED, button);
} else {
Windows::Foundation::Point normalizedPoint = WINRT_TransformCursorPosition(window, pointerPoint->Position, NormalizeZeroToOne);
Windows::Foundation::Point windowPoint = WINRT_TransformCursorPosition(window, pointerPoint->Position, TransformToSDLWindowSize);
SDL_SendTouch(
WINRT_TouchID,
(SDL_FingerID) pointerPoint->PointerId,
window,
SDL_TRUE,
normalizedPoint.X,
normalizedPoint.Y,
pointerPoint->Properties->Pressure);
}
}
void
WINRT_ProcessPointerMovedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint)
{
if (!window || WINRT_UsingRelativeMouseMode) {
return;
}
Windows::Foundation::Point normalizedPoint = WINRT_TransformCursorPosition(window, pointerPoint->Position, NormalizeZeroToOne);
Windows::Foundation::Point windowPoint = WINRT_TransformCursorPosition(window, pointerPoint->Position, TransformToSDLWindowSize);
if ( ! WINRT_IsTouchEvent(pointerPoint)) {
/* For some odd reason Moved events are used for multiple mouse buttons */
Uint8 button, pressed;
if (WINRT_GetSDLButtonForPointerPoint(pointerPoint, &button, &pressed)) {
SDL_SendMouseButton(window, 0, pressed, button);
}
SDL_SendMouseMotion(window, 0, 0, (int)windowPoint.X, (int)windowPoint.Y);
} else {
SDL_SendTouchMotion(
WINRT_TouchID,
(SDL_FingerID) pointerPoint->PointerId,
window,
normalizedPoint.X,
normalizedPoint.Y,
pointerPoint->Properties->Pressure);
}
}
void WINRT_ProcessPointerReleasedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint)
{
if (!window) {
return;
}
if (!WINRT_IsTouchEvent(pointerPoint)) {
Uint8 button, pressed;
WINRT_GetSDLButtonForPointerPoint(pointerPoint, &button, &pressed);
SDL_assert(pressed == 0);
SDL_SendMouseButton(window, 0, SDL_RELEASED, button);
} else {
Windows::Foundation::Point normalizedPoint = WINRT_TransformCursorPosition(window, pointerPoint->Position, NormalizeZeroToOne);
SDL_SendTouch(
WINRT_TouchID,
(SDL_FingerID) pointerPoint->PointerId,
window,
SDL_FALSE,
normalizedPoint.X,
normalizedPoint.Y,
pointerPoint->Properties->Pressure);
}
}
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)
{
if (!window) {
return;
}
float motion = (float) pointerPoint->Properties->MouseWheelDelta / WHEEL_DELTA;
SDL_SendMouseWheel(window, 0, 0, (float) motion, SDL_MOUSEWHEEL_NORMAL);
}
void
WINRT_ProcessMouseMovedEvent(SDL_Window * window, Windows::Devices::Input::MouseEventArgs ^args)
{
if (!window || !WINRT_UsingRelativeMouseMode) {
return;
}
// DLudwig, 2012-12-28: On some systems, namely Visual Studio's Windows
// Simulator, as well as Windows 8 in a Parallels 8 VM, MouseEventArgs'
// MouseDelta field often reports very large values. More information
// on this can be found at the following pages on MSDN:
// - http://social.msdn.microsoft.com/Forums/en-US/winappswithnativecode/thread/a3c789fa-f1c5-49c4-9c0a-7db88d0f90f8
// - https://connect.microsoft.com/VisualStudio/Feedback/details/756515
//
// The values do not appear to be as large when running on some systems,
// most notably a Surface RT. Furthermore, the values returned by
// CoreWindow's PointerMoved event, and sent to this class' OnPointerMoved
// method, do not ever appear to be large, even when MouseEventArgs'
// MouseDelta is reporting to the contrary.
//
// On systems with the large-values behavior, it appears that the values
// get reported as if the screen's size is 65536 units in both the X and Y
// dimensions. This can be viewed by using Windows' now-private, "Raw Input"
// APIs. (GetRawInputData, RegisterRawInputDevices, WM_INPUT, etc.)
//
// MSDN's documentation on MouseEventArgs' MouseDelta field (at
// http://msdn.microsoft.com/en-us/library/windows/apps/windows.devices.input.mouseeventargs.mousedelta ),
// does not seem to indicate (to me) that its values should be so large. It
// says that its values should be a "change in screen location". I could
// be misinterpreting this, however a post on MSDN from a Microsoft engineer (see:
// http://social.msdn.microsoft.com/Forums/en-US/winappswithnativecode/thread/09a9868e-95bb-4858-ba1a-cb4d2c298d62 ),
// indicates that these values are in DIPs, which is the same unit used
// by CoreWindow's PointerMoved events (via the Position field in its CurrentPoint
// property. See http://msdn.microsoft.com/en-us/library/windows/apps/windows.ui.input.pointerpoint.position.aspx
// for details.)
//
// To note, PointerMoved events are sent a 'RawPosition' value (via the
// CurrentPoint property in MouseEventArgs), however these do not seem
// to exhibit the same large-value behavior.
//
// The values passed via PointerMoved events can't always be used for relative
// mouse motion, unfortunately. Its values are bound to the cursor's position,
// which stops when it hits one of the screen's edges. This can be a problem in
// first person shooters, whereby it is normal for mouse motion to travel far
// along any one axis for a period of time. MouseMoved events do not have the
// screen-bounding limitation, and can be used regardless of where the system's
// cursor is.
//
// One possible workaround would be to programmatically set the cursor's
// position to the screen's center (when SDL's relative mouse mode is enabled),
// however WinRT does not yet seem to have the ability to set the cursor's
// position via a public API. Win32 did this via an API call, SetCursorPos,
// however WinRT makes this function be private. Apps that use it won't get
// approved for distribution in the Windows Store. I've yet to be able to find
// a suitable, store-friendly counterpart for WinRT.
//
// There may be some room for a workaround whereby OnPointerMoved's values
// are compared to the values from OnMouseMoved in order to detect
// when this bug is active. A suitable transformation could then be made to
// OnMouseMoved's values. For now, however, the system-reported values are sent
// to SDL with minimal transformation: from native screen coordinates (in DIPs)
// to SDL window coordinates.
//
const Windows::Foundation::Point mouseDeltaInDIPs((float)args->MouseDelta.X, (float)args->MouseDelta.Y);
const Windows::Foundation::Point mouseDeltaInSDLWindowCoords = WINRT_TransformCursorPosition(window, mouseDeltaInDIPs, TransformToSDLWindowSize);
SDL_SendMouseMotion(
window,
0,
1,
SDL_lroundf(mouseDeltaInSDLWindowCoords.X),
SDL_lroundf(mouseDeltaInSDLWindowCoords.Y));
}
#endif // SDL_VIDEO_DRIVER_WINRT

View File

@@ -1,907 +0,0 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2022 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.
*/
/* Standard C++11 includes */
#include <functional>
#include <string>
#include <sstream>
using namespace std;
/* 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 SDL_IID_IDisplayRequest = { 0xe5732044, 0xf49f, 0x4b60, { 0x8d, 0xd4, 0x5e, 0x7e, 0x3a, 0x63, 0x2a, 0xc0 } };
static const GUID SDL_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_hints.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 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(void)
{
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;
WINTRT_InitialiseInputPaneEvents(device);
#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_CreateDevice
};
static void SDLCALL
WINRT_SetDisplayOrientationsPreference(void *userdata, const char *name, const char *oldValue, const char *newValue)
{
SDL_assert(SDL_strcmp(name, SDL_HINT_ORIENTATIONS) == 0);
/* HACK: prevent SDL from altering an app's .appxmanifest-set orientation
* from being changed on startup, by detecting when SDL_HINT_ORIENTATIONS
* is getting registered.
*
* TODO, WinRT: consider reading in an app's .appxmanifest file, and apply its orientation when 'newValue == NULL'.
*/
if ((oldValue == NULL) && (newValue == NULL)) {
return;
}
// Start with no orientation flags, then add each in as they're parsed
// from newValue.
unsigned int orientationFlags = 0;
if (newValue) {
std::istringstream tokenizer(newValue);
while (!tokenizer.eof()) {
std::string orientationName;
std::getline(tokenizer, orientationName, ' ');
if (orientationName == "LandscapeLeft") {
orientationFlags |= (unsigned int) DisplayOrientations::LandscapeFlipped;
} else if (orientationName == "LandscapeRight") {
orientationFlags |= (unsigned int) DisplayOrientations::Landscape;
} else if (orientationName == "Portrait") {
orientationFlags |= (unsigned int) DisplayOrientations::Portrait;
} else if (orientationName == "PortraitUpsideDown") {
orientationFlags |= (unsigned int) DisplayOrientations::PortraitFlipped;
}
}
}
// If no valid orientation flags were specified, use a reasonable set of defaults:
if (!orientationFlags) {
// TODO, WinRT: consider seeing if an app's default orientation flags can be found out via some API call(s).
orientationFlags = (unsigned int) ( \
DisplayOrientations::Landscape |
DisplayOrientations::LandscapeFlipped |
DisplayOrientations::Portrait |
DisplayOrientations::PortraitFlipped);
}
// Set the orientation/rotation preferences. Please note that this does
// not constitute a 100%-certain lock of a given set of possible
// orientations. According to Microsoft's documentation on WinRT [1]
// when a device is not capable of being rotated, Windows may ignore
// the orientation preferences, and stick to what the device is capable of
// displaying.
//
// [1] Documentation on the 'InitialRotationPreference' setting for a
// Windows app's manifest file describes how some orientation/rotation
// preferences may be ignored. See
// http://msdn.microsoft.com/en-us/library/windows/apps/hh700343.aspx
// for details. Microsoft's "Display orientation sample" also gives an
// outline of how Windows treats device rotation
// (http://code.msdn.microsoft.com/Display-Orientation-Sample-19a58e93).
WINRT_DISPLAY_PROPERTY(AutoRotationPreferences) = (DisplayOrientations) orientationFlags;
}
int
WINRT_VideoInit(_THIS)
{
SDL_VideoData * driverdata = (SDL_VideoData *) _this->driverdata;
if (WINRT_InitModes(_this) < 0) {
return -1;
}
// Register the hint, SDL_HINT_ORIENTATIONS, with SDL.
// TODO, WinRT: see if an app's default orientation can be found out via WinRT API(s), then set the initial value of SDL_HINT_ORIENTATIONS accordingly.
SDL_AddHintCallback(SDL_HINT_ORIENTATIONS, WINRT_SetDisplayOrientationsPreference, NULL);
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, SDL_FALSE) < 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, SDL_FALSE) < 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(SDL_IID_IDXGIFactory2, (void **)&dxgiFactory2);
if (FAILED(hr)) {
return WIN_SetErrorFromHRESULT(__FUNCTION__ ", CreateDXGIFactory1() failed", hr);
}
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->IsFullScreenMode;
}
#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) {
return SDL_SetError("WinRT only supports one window");
}
SDL_WindowData *data = new SDL_WindowData; /* use 'new' here as SDL_WindowData may use WinRT/C++ types */
if (!data) {
return SDL_OutOfMemory();
}
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) {
/* SDL_EGL_ChooseConfig failed, SDL_GetError() should have info */
return -1;
}
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,
(NativeWindowType)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",
SDL_MAJOR_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)SDL_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(SDL_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: */

View File

@@ -1,106 +0,0 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2022 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.
*/
/* Windows includes: */
#include <windows.h>
#ifdef __cplusplus_winrt
#include <agile.h>
#endif
/* SDL includes: */
#include "SDL_video.h"
#include "SDL_events.h"
#if NTDDI_VERSION >= NTDDI_WINBLUE /* ApplicationView's functionality only becomes
useful for SDL in Win[Phone] 8.1 and up.
Plus, it is not available at all in WinPhone 8.0. */
#define SDL_WINRT_USE_APPLICATIONVIEW 1
#endif
extern "C" {
#include "../SDL_sysvideo.h"
#include "../SDL_egl_c.h"
}
/* Private display data */
typedef struct SDL_VideoData {
/* An object created by ANGLE/WinRT (OpenGL ES 2 for WinRT) that gets
* passed to eglGetDisplay and eglCreateWindowSurface:
*/
IUnknown *winrtEglWindow;
/* Event token(s), for unregistering WinRT event handler(s).
These are just a struct with a 64-bit integer inside them
*/
Windows::Foundation::EventRegistrationToken gameBarIsInputRedirectedToken;
/* A WinRT DisplayRequest, used for implementing SDL_*ScreenSaver() functions.
* This is really a pointer to a 'ABI::Windows::System::Display::IDisplayRequest *',
* It's casted to 'IUnknown *', to help with building SDL.
*/
IUnknown *displayRequest;
} SDL_VideoData;
/* The global, WinRT, SDL Window.
For now, SDL/WinRT only supports one window (due to platform limitations of
WinRT.
*/
extern SDL_Window * WINRT_GlobalSDLWindow;
/* Updates one or more SDL_Window flags, by querying the OS' native windowing APIs.
SDL_Window flags that can be updated should be specified in 'mask'.
*/
extern void WINRT_UpdateWindowFlags(SDL_Window * window, Uint32 mask);
extern "C" Uint32 WINRT_DetectWindowFlags(SDL_Window * window); /* detects flags w/o applying them */
/* Display mode internals */
//typedef struct
//{
// Windows::Graphics::Display::DisplayOrientations currentOrientation;
//} SDL_DisplayModeData;
#ifdef __cplusplus_winrt
/* A convenience macro to get a WinRT display property */
#if NTDDI_VERSION > NTDDI_WIN8
#define WINRT_DISPLAY_PROPERTY(NAME) (Windows::Graphics::Display::DisplayInformation::GetForCurrentView()->NAME)
#else
#define WINRT_DISPLAY_PROPERTY(NAME) (Windows::Graphics::Display::DisplayProperties::NAME)
#endif
/* Converts DIPS to/from physical pixels */
#define WINRT_DIPS_TO_PHYSICAL_PIXELS(DIPS) ((int)(0.5f + (((float)(DIPS) * (float)WINRT_DISPLAY_PROPERTY(LogicalDpi)) / 96.f)))
#define WINRT_PHYSICAL_PIXELS_TO_DIPS(PHYSPIX) (((float)(PHYSPIX) * 96.f)/WINRT_DISPLAY_PROPERTY(LogicalDpi))
/* Internal window data */
struct SDL_WindowData
{
SDL_Window *sdlWindow;
Platform::Agile<Windows::UI::Core::CoreWindow> coreWindow;
#ifdef SDL_VIDEO_OPENGL_EGL
EGLSurface egl_surface;
#endif
#if SDL_WINRT_USE_APPLICATIONVIEW
Windows::UI::ViewManagement::ApplicationView ^ appView;
#endif
};
#endif // ifdef __cplusplus_winrt