2022-11-23 10:41:43 -08:00
|
|
|
/*
|
|
|
|
|
Simple DirectMedia Layer
|
2023-01-09 09:41:41 -08:00
|
|
|
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
2022-11-23 10:41:43 -08:00
|
|
|
|
|
|
|
|
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.
|
|
|
|
|
*/
|
2022-11-29 18:34:15 -08:00
|
|
|
#include "SDL_internal.h"
|
2022-11-23 10:41:43 -08:00
|
|
|
|
2023-03-29 21:49:01 +00:00
|
|
|
#ifdef SDL_VIDEO_DRIVER_WINRT
|
2022-11-23 10:41:43 -08:00
|
|
|
|
|
|
|
|
/* Windows-specific includes */
|
|
|
|
|
#include <Windows.h>
|
|
|
|
|
#include <agile.h>
|
|
|
|
|
|
|
|
|
|
/* SDL-specific includes */
|
|
|
|
|
#include "SDL_winrtevents_c.h"
|
|
|
|
|
|
|
|
|
|
extern "C" {
|
|
|
|
|
#include "../../events/scancodes_windows.h"
|
|
|
|
|
#include "../../events/SDL_keyboard_c.h"
|
|
|
|
|
}
|
|
|
|
|
|
2023-11-27 16:11:20 +02:00
|
|
|
static SDL_Scancode WINRT_TranslateKeycode(Windows::UI::Core::KeyEventArgs ^ args)
|
2022-11-23 10:41:43 -08:00
|
|
|
{
|
2023-11-27 16:11:20 +02:00
|
|
|
SDL_Scancode code;
|
|
|
|
|
Uint8 index;
|
|
|
|
|
Uint16 scanCode = args->KeyStatus.ScanCode | (args->KeyStatus.IsExtendedKey ? 0xe000 : 0);
|
|
|
|
|
|
|
|
|
|
/* Pause/Break key have a special scan code with 0xe1 prefix
|
|
|
|
|
* that is not properly reported under UWP.
|
|
|
|
|
* Use Pause scan code that is used in Win32. */
|
|
|
|
|
if (args->VirtualKey == Windows::System::VirtualKey::Pause) {
|
|
|
|
|
scanCode = 0xe046;
|
2022-11-23 10:41:43 -08:00
|
|
|
}
|
|
|
|
|
|
2023-11-27 16:11:20 +02:00
|
|
|
/* Pack scan code into one byte to make the index. */
|
|
|
|
|
index = LOBYTE(scanCode) | (HIBYTE(scanCode) ? 0x80 : 0x00);
|
|
|
|
|
code = windows_scancode_table[index];
|
2022-11-23 10:41:43 -08:00
|
|
|
|
2023-11-27 16:11:20 +02:00
|
|
|
return code;
|
2022-11-23 10:41:43 -08:00
|
|
|
}
|
|
|
|
|
|
2022-11-30 12:51:59 -08:00
|
|
|
void WINRT_ProcessKeyDownEvent(Windows::UI::Core::KeyEventArgs ^ args)
|
2022-11-23 10:41:43 -08:00
|
|
|
{
|
2023-11-27 16:11:20 +02:00
|
|
|
SDL_Scancode sdlScancode = WINRT_TranslateKeycode(args);
|
|
|
|
|
|
2022-11-23 10:41:43 -08:00
|
|
|
#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
|
2022-12-02 09:03:13 -08:00
|
|
|
SDL_SendKeyboardKey(0, SDL_PRESSED, sdlScancode);
|
2022-11-23 10:41:43 -08:00
|
|
|
}
|
|
|
|
|
|
2022-11-30 12:51:59 -08:00
|
|
|
void WINRT_ProcessKeyUpEvent(Windows::UI::Core::KeyEventArgs ^ args)
|
2022-11-23 10:41:43 -08:00
|
|
|
{
|
2023-11-27 16:11:20 +02:00
|
|
|
SDL_Scancode sdlScancode = WINRT_TranslateKeycode(args);
|
2022-11-23 10:41:43 -08:00
|
|
|
#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
|
2022-12-02 09:03:13 -08:00
|
|
|
SDL_SendKeyboardKey(0, SDL_RELEASED, sdlScancode);
|
2022-11-23 10:41:43 -08:00
|
|
|
}
|
|
|
|
|
|
2022-11-30 12:51:59 -08:00
|
|
|
void WINRT_ProcessCharacterReceivedEvent(Windows::UI::Core::CharacterReceivedEventArgs ^ args)
|
2022-11-23 10:41:43 -08:00
|
|
|
{
|
|
|
|
|
wchar_t src_ucs2[2];
|
|
|
|
|
char dest_utf8[16];
|
|
|
|
|
int result;
|
|
|
|
|
|
|
|
|
|
/* Setup src */
|
|
|
|
|
src_ucs2[0] = args->KeyCode;
|
|
|
|
|
src_ucs2[1] = L'\0';
|
|
|
|
|
|
2023-01-23 17:54:09 -08:00
|
|
|
/* Convert the text, then send an SDL_EVENT_TEXT_INPUT event. */
|
2022-11-23 10:41:43 -08:00
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-09 12:55:11 +02:00
|
|
|
void WINTRT_InitialiseInputPaneEvents(SDL_VideoDevice *_this)
|
2022-11-23 10:41:43 -08:00
|
|
|
{
|
|
|
|
|
using namespace Windows::UI::ViewManagement;
|
|
|
|
|
InputPane ^ inputPane = InputPane::GetForCurrentView();
|
|
|
|
|
if (inputPane) {
|
2022-11-30 12:51:59 -08:00
|
|
|
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);
|
2022-11-23 10:41:43 -08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-09 12:55:11 +02:00
|
|
|
SDL_bool WINRT_HasScreenKeyboardSupport(SDL_VideoDevice *_this)
|
2022-11-23 10:41:43 -08:00
|
|
|
{
|
|
|
|
|
return SDL_TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-09 12:55:11 +02:00
|
|
|
void WINRT_ShowScreenKeyboard(SDL_VideoDevice *_this, SDL_Window *window)
|
2022-11-23 10:41:43 -08:00
|
|
|
{
|
|
|
|
|
using namespace Windows::UI::ViewManagement;
|
|
|
|
|
InputPane ^ inputPane = InputPane::GetForCurrentView();
|
|
|
|
|
if (inputPane) {
|
|
|
|
|
inputPane->TryShow();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-09 12:55:11 +02:00
|
|
|
void WINRT_HideScreenKeyboard(SDL_VideoDevice *_this, SDL_Window *window)
|
2022-11-23 10:41:43 -08:00
|
|
|
{
|
|
|
|
|
using namespace Windows::UI::ViewManagement;
|
|
|
|
|
InputPane ^ inputPane = InputPane::GetForCurrentView();
|
|
|
|
|
if (inputPane) {
|
|
|
|
|
inputPane->TryHide();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-09 12:55:11 +02:00
|
|
|
SDL_bool WINRT_IsScreenKeyboardShown(SDL_VideoDevice *_this, SDL_Window *window)
|
2022-11-23 10:41:43 -08:00
|
|
|
{
|
|
|
|
|
using namespace Windows::UI::ViewManagement;
|
|
|
|
|
InputPane ^ inputPane = InputPane::GetForCurrentView();
|
|
|
|
|
if (inputPane) {
|
|
|
|
|
switch (SDL_WinRTGetDeviceFamily()) {
|
|
|
|
|
case SDL_WINRT_DEVICEFAMILY_XBOX:
|
2022-11-30 12:51:59 -08:00
|
|
|
// 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
|
2022-11-23 10:41:43 -08:00
|
|
|
if (WINRT_InputPaneVisible) {
|
|
|
|
|
return SDL_TRUE;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
default:
|
2022-11-30 12:51:59 -08:00
|
|
|
// OccludedRect is recommend on universal apps per docs
|
|
|
|
|
// https://learn.microsoft.com/en-us/uwp/api/windows.ui.viewmanagement.inputpane.visible?view=winrt-22621
|
2022-11-23 10:41:43 -08:00
|
|
|
Windows::Foundation::Rect rect = inputPane->OccludedRect;
|
|
|
|
|
if (rect.Width > 0 && rect.Height > 0) {
|
|
|
|
|
return SDL_TRUE;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return SDL_FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
2022-11-30 12:51:59 -08:00
|
|
|
#endif // NTDDI_VERSION >= ...
|
2022-11-23 10:41:43 -08:00
|
|
|
|
2022-11-30 12:51:59 -08:00
|
|
|
#endif // SDL_VIDEO_DRIVER_WINRT
|