From c4b9f621649d4e2ddb05e7f396e43e2d9e0402cc Mon Sep 17 00:00:00 2001 From: Ethan Lee Date: Sun, 13 Nov 2022 12:45:13 -0500 Subject: [PATCH] x11: Add support for the Steam Deck on-screen keyboard --- src/video/x11/SDL_x11keyboard.c | 44 +++++++++++++++++++++++++++++++++ src/video/x11/SDL_x11keyboard.h | 4 +++ src/video/x11/SDL_x11video.c | 9 +++++++ src/video/x11/SDL_x11video.h | 4 +++ 4 files changed, 61 insertions(+) diff --git a/src/video/x11/SDL_x11keyboard.c b/src/video/x11/SDL_x11keyboard.c index 664c81661..f5be37ec5 100644 --- a/src/video/x11/SDL_x11keyboard.c +++ b/src/video/x11/SDL_x11keyboard.c @@ -22,6 +22,8 @@ #if SDL_VIDEO_DRIVER_X11 +#include "SDL_hints.h" +#include "SDL_misc.h" #include "SDL_x11video.h" #include "../../events/SDL_keyboard_c.h" @@ -841,6 +843,48 @@ X11_SetTextInputRect(_THIS, const SDL_Rect *rect) #endif } +SDL_bool +X11_HasScreenKeyboardSupport(_THIS) +{ + SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata; + return videodata->is_steam_deck; +} + +void +X11_ShowScreenKeyboard(_THIS, SDL_Window *window) +{ + SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata; + + if (videodata->is_steam_deck) { + /* For more documentation of the URL parameters, see: + * https://partner.steamgames.com/doc/api/ISteamUtils#ShowFloatingGamepadTextInput + */ + char deeplink[128]; + SDL_snprintf(deeplink, sizeof(deeplink), + "steam://open/keyboard?XPosition=0&YPosition=0&Width=0&Height=0&Mode=%d", + SDL_GetHintBoolean(SDL_HINT_RETURN_KEY_HIDES_IME, SDL_FALSE) ? 0 : 1); + SDL_OpenURL(deeplink); + videodata->steam_keyboard_open = SDL_TRUE; + } +} + +void X11_HideScreenKeyboard(_THIS, SDL_Window *window) +{ + SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata; + + if (videodata->is_steam_deck) { + SDL_OpenURL("steam://close/keyboard"); + videodata->steam_keyboard_open = SDL_FALSE; + } +} + +SDL_bool X11_IsScreenKeyboardShown(_THIS, SDL_Window *window) +{ + SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata; + + return videodata->steam_keyboard_open; +} + #endif /* SDL_VIDEO_DRIVER_X11 */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/x11/SDL_x11keyboard.h b/src/video/x11/SDL_x11keyboard.h index 4ce41069b..645e7ba41 100644 --- a/src/video/x11/SDL_x11keyboard.h +++ b/src/video/x11/SDL_x11keyboard.h @@ -29,6 +29,10 @@ extern void X11_QuitKeyboard(_THIS); extern void X11_StartTextInput(_THIS); extern void X11_StopTextInput(_THIS); extern void X11_SetTextInputRect(_THIS, const SDL_Rect *rect); +extern SDL_bool X11_HasScreenKeyboardSupport(_THIS); +extern void X11_ShowScreenKeyboard(_THIS, SDL_Window *window); +extern void X11_HideScreenKeyboard(_THIS, SDL_Window *window); +extern SDL_bool X11_IsScreenKeyboardShown(_THIS, SDL_Window *window); extern KeySym X11_KeyCodeToSym(_THIS, KeyCode, unsigned char group); #endif /* SDL_x11keyboard_h_ */ diff --git a/src/video/x11/SDL_x11video.c b/src/video/x11/SDL_x11video.c index 2e5e190bd..49f5c5b9b 100644 --- a/src/video/x11/SDL_x11video.c +++ b/src/video/x11/SDL_x11video.c @@ -212,6 +212,11 @@ X11_CreateDevice(void) safety_net_triggered = SDL_FALSE; orig_x11_errhandler = X11_XSetErrorHandler(X11_SafetyNetErrHandler); + /* Steam Deck will have an on-screen keyboard, so check their environment + * variable so we can make use of SDL_StartTextInput. + */ + data->is_steam_deck = SDL_GetHintBoolean("SteamDeck", SDL_FALSE); + /* Set the function pointers */ device->VideoInit = X11_VideoInit; device->VideoQuit = X11_VideoQuit; @@ -307,6 +312,10 @@ X11_CreateDevice(void) device->StartTextInput = X11_StartTextInput; device->StopTextInput = X11_StopTextInput; device->SetTextInputRect = X11_SetTextInputRect; + device->HasScreenKeyboardSupport = X11_HasScreenKeyboardSupport; + device->ShowScreenKeyboard = X11_ShowScreenKeyboard; + device->HideScreenKeyboard = X11_HideScreenKeyboard; + device->IsScreenKeyboardShown = X11_IsScreenKeyboardShown; device->free = X11_DeleteDevice; diff --git a/src/video/x11/SDL_x11video.h b/src/video/x11/SDL_x11video.h index e2edf248a..511ed365c 100644 --- a/src/video/x11/SDL_x11video.h +++ b/src/video/x11/SDL_x11video.h @@ -152,6 +152,10 @@ typedef struct SDL_VideoData PFN_XGetXCBConnection vulkan_XGetXCBConnection; #endif + /* Used to interact with the on-screen keyboard */ + SDL_bool is_steam_deck; + SDL_bool steam_keyboard_open; + } SDL_VideoData; extern SDL_bool X11_UseDirectColorVisuals(void);