diff --git a/VisualC-GDK/SDL/SDL.vcxproj b/VisualC-GDK/SDL/SDL.vcxproj index 53926d49a1..872aff1626 100644 --- a/VisualC-GDK/SDL/SDL.vcxproj +++ b/VisualC-GDK/SDL/SDL.vcxproj @@ -839,6 +839,7 @@ + diff --git a/VisualC-GDK/SDL/SDL.vcxproj.filters b/VisualC-GDK/SDL/SDL.vcxproj.filters index 39aac2b531..1e07dc754e 100644 --- a/VisualC-GDK/SDL/SDL.vcxproj.filters +++ b/VisualC-GDK/SDL/SDL.vcxproj.filters @@ -215,6 +215,7 @@ + diff --git a/src/video/windows/SDL_windowskeyboard.c b/src/video/windows/SDL_windowskeyboard.c index 46104649e8..7b7fa97711 100644 --- a/src/video/windows/SDL_windowskeyboard.c +++ b/src/video/windows/SDL_windowskeyboard.c @@ -210,6 +210,11 @@ void WIN_ResetDeadKeys() } } +SDL_bool WIN_HasScreenKeyboardSupport(SDL_VideoDevice *_this) +{ + return SDL_FALSE; +} + void WIN_StartTextInput(SDL_VideoDevice *_this) { #ifndef SDL_DISABLE_WINDOWS_IME diff --git a/src/video/windows/SDL_windowskeyboard.h b/src/video/windows/SDL_windowskeyboard.h index 76f8233e30..7756f7181e 100644 --- a/src/video/windows/SDL_windowskeyboard.h +++ b/src/video/windows/SDL_windowskeyboard.h @@ -34,6 +34,7 @@ extern void WIN_StopTextInput(SDL_VideoDevice *_this); extern int WIN_SetTextInputRect(SDL_VideoDevice *_this, const SDL_Rect *rect); extern void WIN_ClearComposition(SDL_VideoDevice *_this); extern SDL_bool WIN_IsTextInputShown(SDL_VideoDevice *_this); +extern SDL_bool WIN_HasScreenKeyboardSupport(SDL_VideoDevice *_this); extern SDL_bool IME_HandleMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM *lParam, struct SDL_VideoData *videodata); diff --git a/src/video/windows/SDL_windowsvideo.c b/src/video/windows/SDL_windowsvideo.c index 7100159830..b6152d3629 100644 --- a/src/video/windows/SDL_windowsvideo.c +++ b/src/video/windows/SDL_windowsvideo.c @@ -251,9 +251,10 @@ static SDL_VideoDevice *WIN_CreateDevice(void) device->Vulkan_CreateSurface = WIN_Vulkan_CreateSurface; #endif -#if !defined(SDL_PLATFORM_XBOXONE) && !defined(SDL_PLATFORM_XBOXSERIES) device->StartTextInput = WIN_StartTextInput; device->StopTextInput = WIN_StopTextInput; + device->HasScreenKeyboardSupport = WIN_HasScreenKeyboardSupport; +#if !defined(SDL_PLATFORM_XBOXONE) && !defined(SDL_PLATFORM_XBOXSERIES) device->SetTextInputRect = WIN_SetTextInputRect; device->ClearComposition = WIN_ClearComposition; device->IsTextInputShown = WIN_IsTextInputShown; diff --git a/src/video/windows/SDL_xboxkeyboard.cpp b/src/video/windows/SDL_xboxkeyboard.cpp new file mode 100644 index 0000000000..342a7cdfa2 --- /dev/null +++ b/src/video/windows/SDL_xboxkeyboard.cpp @@ -0,0 +1,109 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + 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_WINDOWS && (defined(__XBOXONE__) || defined(__XBOXSERIES__)) + +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif +#include +#include +#include +#include + +extern "C" { +#include "../../events/SDL_keyboard_c.h" +#include "SDL_windowsvideo.h" +} + +/* Max length passed to XGameUiShowTextEntryAsync */ +#define SDL_XBOX_VIRTUAL_KEYBOARD_MAX_TEXT_LENGTH 1024 + + +SDL_bool +WIN_HasScreenKeyboardSupport(SDL_VideoDevice *_this) +{ + return SDL_TRUE; +} + +void +WIN_StartTextInput(SDL_VideoDevice *_this) +{ + XAsyncBlock* asyncBlock = new XAsyncBlock; + asyncBlock->context = nullptr; + asyncBlock->queue = NULL; + asyncBlock->callback = [](XAsyncBlock* async) + { + async->context; + uint32_t textBufSize; + HRESULT hr = XGameUiShowTextEntryResultSize(async, &textBufSize); + + if (FAILED(hr)) + { + SDL_Log("XGameUiShowTextEntryResultSize failed: 0x%08X", hr); + return; + } + + if (textBufSize == 0) + { + return; + } + + char* textBuf = new char[textBufSize + 1]; + if (textBuf == nullptr) + { + SDL_Log("Allocating text buffer with size: XGameUiShowTextEntryResultSize(%ul) failed!", textBufSize); + return; + } + + hr = XGameUiShowTextEntryResult(async, textBufSize, textBuf, nullptr); + + if (FAILED(hr)) + { + SDL_Log("XGameUiShowTextEntryResult failed: 0x%08X", hr); + delete[] textBuf; + return; + } + + SDL_SendKeyboardText(textBuf); + + // Use the text buffer + delete[] textBuf; + }; + + // This can be further improved, title, description, InputScope can be exposed for the user to set. + HRESULT hr = XGameUiShowTextEntryAsync( + asyncBlock, + "Enter text", + "", + "", + XGameUiTextEntryInputScope::Default, + SDL_XBOX_VIRTUAL_KEYBOARD_MAX_TEXT_LENGTH + ); +} + +void +WIN_StopTextInput(SDL_VideoDevice *_this) +{ +} + +#endif /* SDL_VIDEO_DRIVER_WINDOWS */