21#include "sdl_disp.hpp" 
   22#include "sdl_freerdp.hpp" 
   23#include "sdl_utils.hpp" 
   24#include "sdl_prefs.hpp" 
   25#include "sdl_touch.hpp" 
   27#include <SDL3/SDL_oldnames.h> 
   31#include <freerdp/utils/string.h> 
   32#include <freerdp/scancode.h> 
   33#include <freerdp/locale/keyboard.h> 
   34#include <freerdp/locale/locale.h> 
   36#include <freerdp/log.h> 
   51static const scancode_entry_t map[] = {
 
   52  ENTRY(SDL_SCANCODE_UNKNOWN, RDP_SCANCODE_UNKNOWN),
 
   53  ENTRY(SDL_SCANCODE_A, RDP_SCANCODE_KEY_A),
 
   54  ENTRY(SDL_SCANCODE_B, RDP_SCANCODE_KEY_B),
 
   55  ENTRY(SDL_SCANCODE_C, RDP_SCANCODE_KEY_C),
 
   56  ENTRY(SDL_SCANCODE_D, RDP_SCANCODE_KEY_D),
 
   57  ENTRY(SDL_SCANCODE_E, RDP_SCANCODE_KEY_E),
 
   58  ENTRY(SDL_SCANCODE_F, RDP_SCANCODE_KEY_F),
 
   59  ENTRY(SDL_SCANCODE_G, RDP_SCANCODE_KEY_G),
 
   60  ENTRY(SDL_SCANCODE_H, RDP_SCANCODE_KEY_H),
 
   61  ENTRY(SDL_SCANCODE_I, RDP_SCANCODE_KEY_I),
 
   62  ENTRY(SDL_SCANCODE_J, RDP_SCANCODE_KEY_J),
 
   63  ENTRY(SDL_SCANCODE_K, RDP_SCANCODE_KEY_K),
 
   64  ENTRY(SDL_SCANCODE_L, RDP_SCANCODE_KEY_L),
 
   65  ENTRY(SDL_SCANCODE_M, RDP_SCANCODE_KEY_M),
 
   66  ENTRY(SDL_SCANCODE_N, RDP_SCANCODE_KEY_N),
 
   67  ENTRY(SDL_SCANCODE_O, RDP_SCANCODE_KEY_O),
 
   68  ENTRY(SDL_SCANCODE_P, RDP_SCANCODE_KEY_P),
 
   69  ENTRY(SDL_SCANCODE_Q, RDP_SCANCODE_KEY_Q),
 
   70  ENTRY(SDL_SCANCODE_R, RDP_SCANCODE_KEY_R),
 
   71  ENTRY(SDL_SCANCODE_S, RDP_SCANCODE_KEY_S),
 
   72  ENTRY(SDL_SCANCODE_T, RDP_SCANCODE_KEY_T),
 
   73  ENTRY(SDL_SCANCODE_U, RDP_SCANCODE_KEY_U),
 
   74  ENTRY(SDL_SCANCODE_V, RDP_SCANCODE_KEY_V),
 
   75  ENTRY(SDL_SCANCODE_W, RDP_SCANCODE_KEY_W),
 
   76  ENTRY(SDL_SCANCODE_X, RDP_SCANCODE_KEY_X),
 
   77  ENTRY(SDL_SCANCODE_Y, RDP_SCANCODE_KEY_Y),
 
   78  ENTRY(SDL_SCANCODE_Z, RDP_SCANCODE_KEY_Z),
 
   79  ENTRY(SDL_SCANCODE_1, RDP_SCANCODE_KEY_1),
 
   80  ENTRY(SDL_SCANCODE_2, RDP_SCANCODE_KEY_2),
 
   81  ENTRY(SDL_SCANCODE_3, RDP_SCANCODE_KEY_3),
 
   82  ENTRY(SDL_SCANCODE_4, RDP_SCANCODE_KEY_4),
 
   83  ENTRY(SDL_SCANCODE_5, RDP_SCANCODE_KEY_5),
 
   84  ENTRY(SDL_SCANCODE_6, RDP_SCANCODE_KEY_6),
 
   85  ENTRY(SDL_SCANCODE_7, RDP_SCANCODE_KEY_7),
 
   86  ENTRY(SDL_SCANCODE_8, RDP_SCANCODE_KEY_8),
 
   87  ENTRY(SDL_SCANCODE_9, RDP_SCANCODE_KEY_9),
 
   88  ENTRY(SDL_SCANCODE_0, RDP_SCANCODE_KEY_0),
 
   89  ENTRY(SDL_SCANCODE_RETURN, RDP_SCANCODE_RETURN),
 
   90  ENTRY(SDL_SCANCODE_ESCAPE, RDP_SCANCODE_ESCAPE),
 
   91  ENTRY(SDL_SCANCODE_BACKSPACE, RDP_SCANCODE_BACKSPACE),
 
   92  ENTRY(SDL_SCANCODE_TAB, RDP_SCANCODE_TAB),
 
   93  ENTRY(SDL_SCANCODE_SPACE, RDP_SCANCODE_SPACE),
 
   94  ENTRY(SDL_SCANCODE_MINUS, RDP_SCANCODE_OEM_MINUS),
 
   95  ENTRY(SDL_SCANCODE_CAPSLOCK, RDP_SCANCODE_CAPSLOCK),
 
   96  ENTRY(SDL_SCANCODE_F1, RDP_SCANCODE_F1),
 
   97  ENTRY(SDL_SCANCODE_F2, RDP_SCANCODE_F2),
 
   98  ENTRY(SDL_SCANCODE_F3, RDP_SCANCODE_F3),
 
   99  ENTRY(SDL_SCANCODE_F4, RDP_SCANCODE_F4),
 
  100  ENTRY(SDL_SCANCODE_F5, RDP_SCANCODE_F5),
 
  101  ENTRY(SDL_SCANCODE_F6, RDP_SCANCODE_F6),
 
  102  ENTRY(SDL_SCANCODE_F7, RDP_SCANCODE_F7),
 
  103  ENTRY(SDL_SCANCODE_F8, RDP_SCANCODE_F8),
 
  104  ENTRY(SDL_SCANCODE_F9, RDP_SCANCODE_F9),
 
  105  ENTRY(SDL_SCANCODE_F10, RDP_SCANCODE_F10),
 
  106  ENTRY(SDL_SCANCODE_F11, RDP_SCANCODE_F11),
 
  107  ENTRY(SDL_SCANCODE_F12, RDP_SCANCODE_F12),
 
  108  ENTRY(SDL_SCANCODE_F13, RDP_SCANCODE_F13),
 
  109  ENTRY(SDL_SCANCODE_F14, RDP_SCANCODE_F14),
 
  110  ENTRY(SDL_SCANCODE_F15, RDP_SCANCODE_F15),
 
  111  ENTRY(SDL_SCANCODE_F16, RDP_SCANCODE_F16),
 
  112  ENTRY(SDL_SCANCODE_F17, RDP_SCANCODE_F17),
 
  113  ENTRY(SDL_SCANCODE_F18, RDP_SCANCODE_F18),
 
  114  ENTRY(SDL_SCANCODE_F19, RDP_SCANCODE_F19),
 
  115  ENTRY(SDL_SCANCODE_F20, RDP_SCANCODE_F20),
 
  116  ENTRY(SDL_SCANCODE_F21, RDP_SCANCODE_F21),
 
  117  ENTRY(SDL_SCANCODE_F22, RDP_SCANCODE_F22),
 
  118  ENTRY(SDL_SCANCODE_F23, RDP_SCANCODE_F23),
 
  119  ENTRY(SDL_SCANCODE_F24, RDP_SCANCODE_F24),
 
  120  ENTRY(SDL_SCANCODE_NUMLOCKCLEAR, RDP_SCANCODE_NUMLOCK),
 
  121  ENTRY(SDL_SCANCODE_KP_DIVIDE, RDP_SCANCODE_DIVIDE),
 
  122  ENTRY(SDL_SCANCODE_KP_MULTIPLY, RDP_SCANCODE_MULTIPLY),
 
  123  ENTRY(SDL_SCANCODE_KP_MINUS, RDP_SCANCODE_SUBTRACT),
 
  124  ENTRY(SDL_SCANCODE_KP_PLUS, RDP_SCANCODE_ADD),
 
  125  ENTRY(SDL_SCANCODE_KP_ENTER, RDP_SCANCODE_RETURN_KP),
 
  126  ENTRY(SDL_SCANCODE_KP_1, RDP_SCANCODE_NUMPAD1),
 
  127  ENTRY(SDL_SCANCODE_KP_2, RDP_SCANCODE_NUMPAD2),
 
  128  ENTRY(SDL_SCANCODE_KP_3, RDP_SCANCODE_NUMPAD3),
 
  129  ENTRY(SDL_SCANCODE_KP_4, RDP_SCANCODE_NUMPAD4),
 
  130  ENTRY(SDL_SCANCODE_KP_5, RDP_SCANCODE_NUMPAD5),
 
  131  ENTRY(SDL_SCANCODE_KP_6, RDP_SCANCODE_NUMPAD6),
 
  132  ENTRY(SDL_SCANCODE_KP_7, RDP_SCANCODE_NUMPAD7),
 
  133  ENTRY(SDL_SCANCODE_KP_8, RDP_SCANCODE_NUMPAD8),
 
  134  ENTRY(SDL_SCANCODE_KP_9, RDP_SCANCODE_NUMPAD9),
 
  135  ENTRY(SDL_SCANCODE_KP_0, RDP_SCANCODE_NUMPAD0),
 
  136  ENTRY(SDL_SCANCODE_KP_PERIOD, RDP_SCANCODE_DECIMAL),
 
  137  ENTRY(SDL_SCANCODE_LCTRL, RDP_SCANCODE_LCONTROL),
 
  138  ENTRY(SDL_SCANCODE_LSHIFT, RDP_SCANCODE_LSHIFT),
 
  139  ENTRY(SDL_SCANCODE_LALT, RDP_SCANCODE_LMENU),
 
  140  ENTRY(SDL_SCANCODE_LGUI, RDP_SCANCODE_LWIN),
 
  141  ENTRY(SDL_SCANCODE_RCTRL, RDP_SCANCODE_RCONTROL),
 
  142  ENTRY(SDL_SCANCODE_RSHIFT, RDP_SCANCODE_RSHIFT),
 
  143  ENTRY(SDL_SCANCODE_RALT, RDP_SCANCODE_RMENU),
 
  144  ENTRY(SDL_SCANCODE_RGUI, RDP_SCANCODE_RWIN),
 
  145  ENTRY(SDL_SCANCODE_MODE, RDP_SCANCODE_APPS),
 
  146  ENTRY(SDL_SCANCODE_MUTE, RDP_SCANCODE_VOLUME_MUTE),
 
  147  ENTRY(SDL_SCANCODE_VOLUMEUP, RDP_SCANCODE_VOLUME_UP),
 
  148  ENTRY(SDL_SCANCODE_VOLUMEDOWN, RDP_SCANCODE_VOLUME_DOWN),
 
  149  ENTRY(SDL_SCANCODE_GRAVE, RDP_SCANCODE_OEM_3),
 
  150  ENTRY(SDL_SCANCODE_COMMA, RDP_SCANCODE_OEM_COMMA),
 
  151  ENTRY(SDL_SCANCODE_PERIOD, RDP_SCANCODE_OEM_PERIOD),
 
  152  ENTRY(SDL_SCANCODE_SLASH, RDP_SCANCODE_OEM_2),
 
  153  ENTRY(SDL_SCANCODE_BACKSLASH, RDP_SCANCODE_OEM_5),
 
  154  ENTRY(SDL_SCANCODE_SCROLLLOCK, RDP_SCANCODE_SCROLLLOCK),
 
  155  ENTRY(SDL_SCANCODE_INSERT, RDP_SCANCODE_INSERT),
 
  156  ENTRY(SDL_SCANCODE_PRINTSCREEN, RDP_SCANCODE_PRINTSCREEN),
 
  157  ENTRY(SDL_SCANCODE_HOME, RDP_SCANCODE_HOME),
 
  158  ENTRY(SDL_SCANCODE_DELETE, RDP_SCANCODE_DELETE),
 
  159  ENTRY(SDL_SCANCODE_RIGHT, RDP_SCANCODE_RIGHT),
 
  160  ENTRY(SDL_SCANCODE_LEFT, RDP_SCANCODE_LEFT),
 
  161  ENTRY(SDL_SCANCODE_DOWN, RDP_SCANCODE_DOWN),
 
  162  ENTRY(SDL_SCANCODE_UP, RDP_SCANCODE_UP),
 
  163  ENTRY(SDL_SCANCODE_SEMICOLON, RDP_SCANCODE_OEM_1),
 
  164  ENTRY(SDL_SCANCODE_PAUSE, RDP_SCANCODE_PAUSE),
 
  165  ENTRY(SDL_SCANCODE_PAGEUP, RDP_SCANCODE_PRIOR),
 
  166  ENTRY(SDL_SCANCODE_END, RDP_SCANCODE_END),
 
  167  ENTRY(SDL_SCANCODE_PAGEDOWN, RDP_SCANCODE_NEXT),
 
  168  ENTRY(SDL_SCANCODE_MEDIA_NEXT_TRACK, RDP_SCANCODE_MEDIA_NEXT_TRACK),
 
  169  ENTRY(SDL_SCANCODE_MEDIA_PREVIOUS_TRACK, RDP_SCANCODE_MEDIA_PREV_TRACK),
 
  170  ENTRY(SDL_SCANCODE_MEDIA_STOP, RDP_SCANCODE_MEDIA_STOP),
 
  171  ENTRY(SDL_SCANCODE_MEDIA_PLAY, RDP_SCANCODE_MEDIA_PLAY_PAUSE),
 
  172  ENTRY(SDL_SCANCODE_MUTE, RDP_SCANCODE_VOLUME_MUTE),
 
  173  ENTRY(SDL_SCANCODE_MEDIA_SELECT, RDP_SCANCODE_LAUNCH_MEDIA_SELECT),
 
  174  ENTRY(SDL_SCANCODE_SYSREQ, RDP_SCANCODE_SYSREQ),
 
  175  ENTRY(SDL_SCANCODE_LEFTBRACKET, RDP_SCANCODE_OEM_4),
 
  176  ENTRY(SDL_SCANCODE_RIGHTBRACKET, RDP_SCANCODE_OEM_6),
 
  177  ENTRY(SDL_SCANCODE_APOSTROPHE, RDP_SCANCODE_OEM_7),
 
  178  ENTRY(SDL_SCANCODE_NONUSBACKSLASH, RDP_SCANCODE_OEM_102),
 
  179  ENTRY(SDL_SCANCODE_SLEEP, RDP_SCANCODE_SLEEP),
 
  180  ENTRY(SDL_SCANCODE_EQUALS, RDP_SCANCODE_OEM_PLUS),
 
  181  ENTRY(SDL_SCANCODE_KP_COMMA, RDP_SCANCODE_DECIMAL),
 
  182  ENTRY(SDL_SCANCODE_FIND, RDP_SCANCODE_BROWSER_SEARCH),
 
  183  ENTRY(SDL_SCANCODE_RETURN2, RDP_SCANCODE_RETURN_KP),
 
  184  ENTRY(SDL_SCANCODE_AC_SEARCH, RDP_SCANCODE_BROWSER_SEARCH),
 
  185  ENTRY(SDL_SCANCODE_AC_HOME, RDP_SCANCODE_BROWSER_HOME),
 
  186  ENTRY(SDL_SCANCODE_AC_BACK, RDP_SCANCODE_BROWSER_BACK),
 
  187  ENTRY(SDL_SCANCODE_AC_FORWARD, RDP_SCANCODE_BROWSER_FORWARD),
 
  188  ENTRY(SDL_SCANCODE_AC_STOP, RDP_SCANCODE_BROWSER_STOP),
 
  190  ENTRY(SDL_SCANCODE_NONUSHASH, RDP_SCANCODE_UNKNOWN),
 
  191  ENTRY(SDL_SCANCODE_APPLICATION, RDP_SCANCODE_UNKNOWN),
 
  192  ENTRY(SDL_SCANCODE_POWER, RDP_SCANCODE_UNKNOWN),
 
  193  ENTRY(SDL_SCANCODE_KP_EQUALS, RDP_SCANCODE_UNKNOWN),
 
  194  ENTRY(SDL_SCANCODE_EXECUTE, RDP_SCANCODE_UNKNOWN),
 
  195  ENTRY(SDL_SCANCODE_HELP, RDP_SCANCODE_UNKNOWN),
 
  196  ENTRY(SDL_SCANCODE_MENU, RDP_SCANCODE_UNKNOWN),
 
  197  ENTRY(SDL_SCANCODE_SELECT, RDP_SCANCODE_UNKNOWN),
 
  198  ENTRY(SDL_SCANCODE_STOP, RDP_SCANCODE_UNKNOWN),
 
  199  ENTRY(SDL_SCANCODE_AGAIN, RDP_SCANCODE_UNKNOWN),
 
  200  ENTRY(SDL_SCANCODE_UNDO, RDP_SCANCODE_UNKNOWN),
 
  201  ENTRY(SDL_SCANCODE_CUT, RDP_SCANCODE_UNKNOWN),
 
  202  ENTRY(SDL_SCANCODE_COPY, RDP_SCANCODE_UNKNOWN),
 
  203  ENTRY(SDL_SCANCODE_PASTE, RDP_SCANCODE_UNKNOWN),
 
  204  ENTRY(SDL_SCANCODE_KP_EQUALSAS400, RDP_SCANCODE_UNKNOWN),
 
  205  ENTRY(SDL_SCANCODE_INTERNATIONAL1, RDP_SCANCODE_UNKNOWN),
 
  206  ENTRY(SDL_SCANCODE_INTERNATIONAL2, RDP_SCANCODE_UNKNOWN),
 
  207  ENTRY(SDL_SCANCODE_INTERNATIONAL3, RDP_SCANCODE_UNKNOWN),
 
  208  ENTRY(SDL_SCANCODE_INTERNATIONAL4, RDP_SCANCODE_UNKNOWN),
 
  209  ENTRY(SDL_SCANCODE_INTERNATIONAL5, RDP_SCANCODE_UNKNOWN),
 
  210  ENTRY(SDL_SCANCODE_INTERNATIONAL6, RDP_SCANCODE_UNKNOWN),
 
  211  ENTRY(SDL_SCANCODE_INTERNATIONAL7, RDP_SCANCODE_UNKNOWN),
 
  212  ENTRY(SDL_SCANCODE_INTERNATIONAL8, RDP_SCANCODE_UNKNOWN),
 
  213  ENTRY(SDL_SCANCODE_INTERNATIONAL9, RDP_SCANCODE_UNKNOWN),
 
  214  ENTRY(SDL_SCANCODE_LANG1, RDP_SCANCODE_UNKNOWN),
 
  215  ENTRY(SDL_SCANCODE_LANG2, RDP_SCANCODE_UNKNOWN),
 
  216  ENTRY(SDL_SCANCODE_LANG3, RDP_SCANCODE_UNKNOWN),
 
  217  ENTRY(SDL_SCANCODE_LANG4, RDP_SCANCODE_UNKNOWN),
 
  218  ENTRY(SDL_SCANCODE_LANG5, RDP_SCANCODE_UNKNOWN),
 
  219  ENTRY(SDL_SCANCODE_LANG6, RDP_SCANCODE_UNKNOWN),
 
  220  ENTRY(SDL_SCANCODE_LANG7, RDP_SCANCODE_UNKNOWN),
 
  221  ENTRY(SDL_SCANCODE_LANG8, RDP_SCANCODE_UNKNOWN),
 
  222  ENTRY(SDL_SCANCODE_LANG9, RDP_SCANCODE_UNKNOWN),
 
  223  ENTRY(SDL_SCANCODE_ALTERASE, RDP_SCANCODE_UNKNOWN),
 
  224  ENTRY(SDL_SCANCODE_CANCEL, RDP_SCANCODE_UNKNOWN),
 
  225  ENTRY(SDL_SCANCODE_CLEAR, RDP_SCANCODE_UNKNOWN),
 
  226  ENTRY(SDL_SCANCODE_PRIOR, RDP_SCANCODE_UNKNOWN),
 
  227  ENTRY(SDL_SCANCODE_SEPARATOR, RDP_SCANCODE_UNKNOWN),
 
  228  ENTRY(SDL_SCANCODE_OUT, RDP_SCANCODE_UNKNOWN),
 
  229  ENTRY(SDL_SCANCODE_OPER, RDP_SCANCODE_UNKNOWN),
 
  230  ENTRY(SDL_SCANCODE_CLEARAGAIN, RDP_SCANCODE_UNKNOWN),
 
  231  ENTRY(SDL_SCANCODE_CRSEL, RDP_SCANCODE_UNKNOWN),
 
  232  ENTRY(SDL_SCANCODE_EXSEL, RDP_SCANCODE_UNKNOWN),
 
  233  ENTRY(SDL_SCANCODE_KP_00, RDP_SCANCODE_UNKNOWN),
 
  234  ENTRY(SDL_SCANCODE_KP_000, RDP_SCANCODE_UNKNOWN),
 
  235  ENTRY(SDL_SCANCODE_THOUSANDSSEPARATOR, RDP_SCANCODE_UNKNOWN),
 
  236  ENTRY(SDL_SCANCODE_DECIMALSEPARATOR, RDP_SCANCODE_UNKNOWN),
 
  237  ENTRY(SDL_SCANCODE_CURRENCYUNIT, RDP_SCANCODE_UNKNOWN),
 
  238  ENTRY(SDL_SCANCODE_CURRENCYSUBUNIT, RDP_SCANCODE_UNKNOWN),
 
  239  ENTRY(SDL_SCANCODE_KP_LEFTPAREN, RDP_SCANCODE_UNKNOWN),
 
  240  ENTRY(SDL_SCANCODE_KP_RIGHTPAREN, RDP_SCANCODE_UNKNOWN),
 
  241  ENTRY(SDL_SCANCODE_KP_LEFTBRACE, RDP_SCANCODE_UNKNOWN),
 
  242  ENTRY(SDL_SCANCODE_KP_RIGHTBRACE, RDP_SCANCODE_UNKNOWN),
 
  243  ENTRY(SDL_SCANCODE_KP_TAB, RDP_SCANCODE_UNKNOWN),
 
  244  ENTRY(SDL_SCANCODE_KP_BACKSPACE, RDP_SCANCODE_UNKNOWN),
 
  245  ENTRY(SDL_SCANCODE_KP_A, RDP_SCANCODE_UNKNOWN),
 
  246  ENTRY(SDL_SCANCODE_KP_B, RDP_SCANCODE_UNKNOWN),
 
  247  ENTRY(SDL_SCANCODE_KP_C, RDP_SCANCODE_UNKNOWN),
 
  248  ENTRY(SDL_SCANCODE_KP_D, RDP_SCANCODE_UNKNOWN),
 
  249  ENTRY(SDL_SCANCODE_KP_E, RDP_SCANCODE_UNKNOWN),
 
  250  ENTRY(SDL_SCANCODE_KP_F, RDP_SCANCODE_UNKNOWN),
 
  251  ENTRY(SDL_SCANCODE_KP_XOR, RDP_SCANCODE_UNKNOWN),
 
  252  ENTRY(SDL_SCANCODE_KP_POWER, RDP_SCANCODE_UNKNOWN),
 
  253  ENTRY(SDL_SCANCODE_KP_PERCENT, RDP_SCANCODE_UNKNOWN),
 
  254  ENTRY(SDL_SCANCODE_KP_LESS, RDP_SCANCODE_UNKNOWN),
 
  255  ENTRY(SDL_SCANCODE_KP_GREATER, RDP_SCANCODE_UNKNOWN),
 
  256  ENTRY(SDL_SCANCODE_KP_AMPERSAND, RDP_SCANCODE_UNKNOWN),
 
  257  ENTRY(SDL_SCANCODE_KP_DBLAMPERSAND, RDP_SCANCODE_UNKNOWN),
 
  258  ENTRY(SDL_SCANCODE_KP_VERTICALBAR, RDP_SCANCODE_UNKNOWN),
 
  259  ENTRY(SDL_SCANCODE_KP_DBLVERTICALBAR, RDP_SCANCODE_UNKNOWN),
 
  260  ENTRY(SDL_SCANCODE_KP_COLON, RDP_SCANCODE_UNKNOWN),
 
  261  ENTRY(SDL_SCANCODE_KP_HASH, RDP_SCANCODE_UNKNOWN),
 
  262  ENTRY(SDL_SCANCODE_KP_SPACE, RDP_SCANCODE_UNKNOWN),
 
  263  ENTRY(SDL_SCANCODE_KP_AT, RDP_SCANCODE_UNKNOWN),
 
  264  ENTRY(SDL_SCANCODE_KP_EXCLAM, RDP_SCANCODE_UNKNOWN),
 
  265  ENTRY(SDL_SCANCODE_KP_MEMSTORE, RDP_SCANCODE_UNKNOWN),
 
  266  ENTRY(SDL_SCANCODE_KP_MEMRECALL, RDP_SCANCODE_UNKNOWN),
 
  267  ENTRY(SDL_SCANCODE_KP_MEMCLEAR, RDP_SCANCODE_UNKNOWN),
 
  268  ENTRY(SDL_SCANCODE_KP_MEMADD, RDP_SCANCODE_UNKNOWN),
 
  269  ENTRY(SDL_SCANCODE_KP_MEMSUBTRACT, RDP_SCANCODE_UNKNOWN),
 
  270  ENTRY(SDL_SCANCODE_KP_MEMMULTIPLY, RDP_SCANCODE_UNKNOWN),
 
  271  ENTRY(SDL_SCANCODE_KP_MEMDIVIDE, RDP_SCANCODE_UNKNOWN),
 
  272  ENTRY(SDL_SCANCODE_KP_PLUSMINUS, RDP_SCANCODE_UNKNOWN),
 
  273  ENTRY(SDL_SCANCODE_KP_CLEAR, RDP_SCANCODE_UNKNOWN),
 
  274  ENTRY(SDL_SCANCODE_KP_CLEARENTRY, RDP_SCANCODE_UNKNOWN),
 
  275  ENTRY(SDL_SCANCODE_KP_BINARY, RDP_SCANCODE_UNKNOWN),
 
  276  ENTRY(SDL_SCANCODE_KP_OCTAL, RDP_SCANCODE_UNKNOWN),
 
  277  ENTRY(SDL_SCANCODE_KP_DECIMAL, RDP_SCANCODE_DECIMAL),
 
  278  ENTRY(SDL_SCANCODE_KP_HEXADECIMAL, RDP_SCANCODE_UNKNOWN),
 
  279  ENTRY(SDL_SCANCODE_AC_REFRESH, RDP_SCANCODE_UNKNOWN),
 
  280  ENTRY(SDL_SCANCODE_AC_BOOKMARKS, RDP_SCANCODE_UNKNOWN),
 
  281  ENTRY(SDL_SCANCODE_MEDIA_EJECT, RDP_SCANCODE_UNKNOWN),
 
  282  ENTRY(SDL_SCANCODE_MEDIA_REWIND, RDP_SCANCODE_UNKNOWN),
 
  283  ENTRY(SDL_SCANCODE_MEDIA_FAST_FORWARD, RDP_SCANCODE_UNKNOWN)
 
  286static UINT32 sdl_get_kbd_flags()
 
  290  SDL_Keymod mod = SDL_GetModState();
 
  291  if ((mod & SDL_KMOD_NUM) != 0)
 
  292    flags |= KBD_SYNC_NUM_LOCK;
 
  293  if ((mod & SDL_KMOD_CAPS) != 0)
 
  294    flags |= KBD_SYNC_CAPS_LOCK;
 
  295  if ((mod & SDL_KMOD_SCROLL) != 0)
 
  296    flags |= KBD_SYNC_SCROLL_LOCK;
 
  303BOOL sdlInput::keyboard_sync_state()
 
  305  const UINT32 syncFlags = sdl_get_kbd_flags();
 
  306  return freerdp_input_send_synchronize_event(_sdl->context()->input, syncFlags);
 
  309BOOL sdlInput::keyboard_focus_in()
 
  311  auto input = _sdl->context()->input;
 
  314  auto syncFlags = sdl_get_kbd_flags();
 
  315  freerdp_input_send_focus_in_event(input, WINPR_ASSERTING_INT_CAST(uint16_t, syncFlags));
 
  321  if (_sdl->fullscreen)
 
  323    SDL_GetGlobalMouseState(&fx, &fy);
 
  327    SDL_GetMouseState(&fx, &fy);
 
  329  auto x = 
static_cast<int32_t
>(fx);
 
  330  auto y = 
static_cast<int32_t
>(fy);
 
  331  auto w = SDL_GetMouseFocus();
 
  334    auto id = SDL_GetWindowID(w);
 
  335    sdl_scale_coordinates(_sdl, 
id, &x, &y, TRUE, TRUE);
 
  337  return freerdp_client_send_button_event(_sdl->common(), FALSE, PTR_FLAGS_MOVE, x, y);
 
  341BOOL sdlInput::keyboard_set_indicators(rdpContext* context, UINT16 led_flags)
 
  343  WINPR_UNUSED(context);
 
  345  SDL_Keymod state = SDL_KMOD_NONE;
 
  347  if ((led_flags & KBD_SYNC_NUM_LOCK) != 0)
 
  348    state |= SDL_KMOD_NUM;
 
  349  if ((led_flags & KBD_SYNC_CAPS_LOCK) != 0)
 
  350    state |= SDL_KMOD_CAPS;
 
  351  if ((led_flags & KBD_SYNC_SCROLL_LOCK) != 0)
 
  352    state |= SDL_KMOD_SCROLL;
 
  353  if ((led_flags & KBD_SYNC_KANA_LOCK) != 0)
 
  354    state |= SDL_KMOD_LEVEL5;
 
  356  SDL_SetModState(state);
 
  362BOOL sdlInput::keyboard_set_ime_status(rdpContext* context, UINT16 imeId, UINT32 imeState,
 
  365  auto sdl = 
reinterpret_cast<SdlContext*
>(context);
 
  369  WLog_Print(sdl->log, WLOG_WARN,
 
  370             "KeyboardSetImeStatus(unitId=%04" PRIx16 
", imeState=%08" PRIx32
 
  371             ", imeConvMode=%08" PRIx32 
") ignored",
 
  372             imeId, imeState, imeConvMode);
 
  376static const std::map<std::string, uint32_t>& getSdlMap()
 
  378  static std::map<std::string, uint32_t> s_map = {
 
  379    { 
"KMOD_LSHIFT", SDL_KMOD_LSHIFT },     { 
"KMOD_RSHIFT", SDL_KMOD_RSHIFT },
 
  380    { 
"KMOD_LCTRL", SDL_KMOD_LCTRL },       { 
"KMOD_RCTRL", SDL_KMOD_RCTRL },
 
  381    { 
"KMOD_LALT", SDL_KMOD_LALT },         { 
"KMOD_RALT", SDL_KMOD_RALT },
 
  382    { 
"KMOD_LGUI", SDL_KMOD_LGUI },         { 
"KMOD_RGUI", SDL_KMOD_RGUI },
 
  383    { 
"KMOD_NUM", SDL_KMOD_NUM },           { 
"KMOD_CAPS", SDL_KMOD_CAPS },
 
  384    { 
"KMOD_MODE", SDL_KMOD_MODE },         { 
"KMOD_SCROLL", SDL_KMOD_SCROLL },
 
  385    { 
"KMOD_CTRL", SDL_KMOD_CTRL },         { 
"KMOD_SHIFT", SDL_KMOD_SHIFT },
 
  386    { 
"KMOD_ALT", SDL_KMOD_ALT },           { 
"KMOD_GUI", SDL_KMOD_GUI },
 
  387    { 
"KMOD_NONE", SDL_KMOD_NONE },         { 
"SDL_KMOD_LSHIFT", SDL_KMOD_LSHIFT },
 
  388    { 
"SDL_KMOD_RSHIFT", SDL_KMOD_RSHIFT }, { 
"SDL_KMOD_LCTRL", SDL_KMOD_LCTRL },
 
  389    { 
"SDL_KMOD_RCTRL", SDL_KMOD_RCTRL },   { 
"SDL_KMOD_LALT", SDL_KMOD_LALT },
 
  390    { 
"SDL_KMOD_RALT", SDL_KMOD_RALT },     { 
"SDL_KMOD_LGUI", SDL_KMOD_LGUI },
 
  391    { 
"SDL_KMOD_RGUI", SDL_KMOD_RGUI },     { 
"SDL_KMOD_NUM", SDL_KMOD_NUM },
 
  392    { 
"SDL_KMOD_CAPS", SDL_KMOD_CAPS },     { 
"SDL_KMOD_MODE", SDL_KMOD_MODE },
 
  393    { 
"SDL_KMOD_SCROLL", SDL_KMOD_SCROLL }, { 
"SDL_KMOD_CTRL", SDL_KMOD_CTRL },
 
  394    { 
"SDL_KMOD_SHIFT", SDL_KMOD_SHIFT },   { 
"SDL_KMOD_ALT", SDL_KMOD_ALT },
 
  395    { 
"SDL_KMOD_GUI", SDL_KMOD_GUI },       { 
"SDL_KMOD_NONE", SDL_KMOD_NONE }
 
  401static std::string modbyvalue(uint32_t val)
 
  403  for (
const auto& v : getSdlMap())
 
  410  return "KMOD_UNKNONW";
 
  413static std::string masktostr(uint32_t mask)
 
  418  std::string str = 
"<";
 
  419  for (uint32_t x = 0; x < 32; x++)
 
  421    uint32_t cmask = 1 << x;
 
  422    if ((mask & cmask) != 0)
 
  424      auto s = modbyvalue(cmask);
 
  436bool sdlInput::prefToEnabled()
 
  439  const auto& m = getSdlMap();
 
  440  for (
const auto& val : 
SdlPref::instance()->get_array(
"SDL_KeyModMask", { 
"KMOD_RSHIFT" }))
 
  442    auto it = m.find(val);
 
  445      if (it->second == SDL_KMOD_NONE)
 
  450      WLog_Print(_sdl->log, WLOG_WARN,
 
  451                 "Invalid config::SDL_KeyModMask entry value '%s', disabling hotkeys",
 
  459uint32_t sdlInput::prefToMask()
 
  461  const auto& m = getSdlMap();
 
  462  uint32_t mod = SDL_KMOD_NONE;
 
  463  for (
const auto& val : 
SdlPref::instance()->get_array(
"SDL_KeyModMask", { 
"KMOD_RSHIFT" }))
 
  465    auto it = m.find(val);
 
  472static const char* sdl_scancode_name(Uint32 scancode)
 
  474  for (
const auto& cur : map)
 
  476    if (cur.sdl == scancode)
 
  480  return "SDL_SCANCODE_UNKNOWN";
 
  483static Uint32 sdl_scancode_val(
const char* scancodeName)
 
  485  for (
const auto& cur : map)
 
  487    if (strcmp(cur.sdl_name, scancodeName) == 0)
 
  491  return SDL_SCANCODE_UNKNOWN;
 
  494#if defined(WITH_DEBUG_SDL_KBD_EVENTS) 
  495static const char* sdl_rdp_scancode_name(UINT32 scancode)
 
  497  for (
const auto& cur : map)
 
  499    if (cur.rdp == scancode)
 
  503  return "RDP_SCANCODE_UNKNOWN";
 
  506static UINT32 sdl_rdp_scancode_val(
const char* scancodeName)
 
  508  for (
const auto& cur : map)
 
  510    if (strcmp(cur.rdp_name, scancodeName) == 0)
 
  514  return RDP_SCANCODE_UNKNOWN;
 
  518UINT32 sdlInput::scancode_to_rdp(Uint32 scancode)
 
  520  UINT32 rdp = RDP_SCANCODE_UNKNOWN;
 
  522  for (
const auto& cur : map)
 
  524    if (cur.sdl == scancode)
 
  531#if defined(WITH_DEBUG_SDL_KBD_EVENTS) 
  532  auto code = 
static_cast<SDL_Scancode
>(scancode);
 
  533  WLog_Print(_sdl->log, WLOG_DEBUG, 
"got %s [%s] -> [%s]", SDL_GetScancodeName(code),
 
  534             sdl_scancode_name(scancode), sdl_rdp_scancode_name(rdp));
 
  539uint32_t sdlInput::prefKeyValue(
const std::string& key, uint32_t fallback)
 
  541  auto item = SdlPref::instance()->get_string(key);
 
  544  auto val = sdl_scancode_val(item.c_str());
 
  545  if (val == SDL_SCANCODE_UNKNOWN)
 
  550std::list<std::string> sdlInput::tokenize(
const std::string& data, 
const std::string& delimiter)
 
  554  std::list<std::string> list;
 
  555  while ((pos = data.find(delimiter, lastpos)) != std::string::npos)
 
  557    auto token = data.substr(lastpos, pos);
 
  559    list.push_back(std::move(token));
 
  561  auto token = data.substr(lastpos);
 
  562  list.push_back(std::move(token));
 
  566bool sdlInput::extract(
const std::string& token, uint32_t& key, uint32_t& value)
 
  568  return freerdp_extract_key_value(token.c_str(), &key, &value);
 
  571BOOL sdlInput::keyboard_handle_event(
const SDL_KeyboardEvent* ev)
 
  574  const UINT32 rdp_scancode = scancode_to_rdp(ev->scancode);
 
  575  const SDL_Keymod mods = SDL_GetModState();
 
  577  if (_hotkeysEnabled && (mods & _hotkeyModmask) == _hotkeyModmask)
 
  579    if (ev->type == SDL_EVENT_KEY_DOWN)
 
  581      if (ev->scancode == _hotkeyFullscreen)
 
  583        WLog_Print(_sdl->log, WLOG_INFO, 
"%s+<%s> pressed, toggling fullscreen state",
 
  584                   masktostr(_hotkeyModmask).c_str(), sdl_scancode_name(_hotkeyFullscreen));
 
  585        keyboard_sync_state();
 
  586        return _sdl->update_fullscreen(!_sdl->fullscreen);
 
  588      if (ev->scancode == _hotkeyResizable)
 
  590        WLog_Print(_sdl->log, WLOG_INFO, 
"%s+<%s> pressed, toggling resizeable state",
 
  591                   masktostr(_hotkeyModmask).c_str(), sdl_scancode_name(_hotkeyResizable));
 
  592        keyboard_sync_state();
 
  593        return _sdl->update_resizeable(!_sdl->resizeable);
 
  596      if (ev->scancode == _hotkeyGrab)
 
  598        WLog_Print(_sdl->log, WLOG_INFO, 
"%s+<%s> pressed, toggling grab state",
 
  599                   masktostr(_hotkeyModmask).c_str(), sdl_scancode_name(_hotkeyGrab));
 
  600        keyboard_sync_state();
 
  601        keyboard_grab(ev->windowID, !_sdl->grab_kbd);
 
  604      if (ev->scancode == _hotkeyDisconnect)
 
  606        WLog_Print(_sdl->log, WLOG_INFO, 
"%s+<%s> pressed, disconnecting RDP session",
 
  607                   masktostr(_hotkeyModmask).c_str(), sdl_scancode_name(_hotkeyDisconnect));
 
  608        keyboard_sync_state();
 
  609        freerdp_abort_connect_context(_sdl->context());
 
  612      if (ev->scancode == _hotkeyMinimize)
 
  614        WLog_Print(_sdl->log, WLOG_INFO, 
"%s+<%s> pressed, minimizing client",
 
  615                   masktostr(_hotkeyModmask).c_str(), sdl_scancode_name(_hotkeyMinimize));
 
  616        keyboard_sync_state();
 
  617        return _sdl->update_minimize();
 
  622#if defined(WITH_DEBUG_KBD) 
  624    const BOOL ex = RDP_SCANCODE_EXTENDED(rdp_scancode);
 
  625    const DWORD sc = RDP_SCANCODE_CODE(rdp_scancode);
 
  626    WLog_Print(_sdl->log, WLOG_DEBUG,
 
  627               "SDL keycode: %02" PRIX32 
" -> rdp code: [%04" PRIx16 
"] %02" PRIX8 
"%s",
 
  628               ev->scancode, rdp_scancode, sc, ex ? 
" extended" : 
"");
 
  632  auto scancode = freerdp_keyboard_remap_key(_remapTable, rdp_scancode);
 
  633#if defined(WITH_DEBUG_KBD) 
  635    const BOOL ex = RDP_SCANCODE_EXTENDED(scancode);
 
  636    const DWORD sc = RDP_SCANCODE_CODE(scancode);
 
  637    WLog_Print(_sdl->log, WLOG_DEBUG,
 
  638               "SDL keycode: %02" PRIX32 
" -> remapped rdp code: [%04" PRIx16 
"] %02" PRIX8
 
  640               ev->scancode, scancode, sc, ex ? 
" extended" : 
"");
 
  643  return freerdp_input_send_keyboard_event_ex(
 
  644      _sdl->context()->input, ev->type == SDL_EVENT_KEY_DOWN, ev->repeat, scancode);
 
  647BOOL sdlInput::keyboard_grab(Uint32 windowID, 
bool enable)
 
  649  auto it = _sdl->windows.find(windowID);
 
  650  if (it == _sdl->windows.end())
 
  653  auto settings = _sdl->context()->settings;
 
  655  auto status = enable && kbd_enabled;
 
  656  _sdl->grab_kbd = status;
 
  657  return it->second.grabKeyboard(status);
 
  660BOOL sdlInput::mouse_focus(Uint32 windowID)
 
  662  if (_lastWindowID != windowID)
 
  664    _lastWindowID = windowID;
 
  665    auto it = _sdl->windows.find(windowID);
 
  666    if (it == _sdl->windows.end())
 
  674BOOL sdlInput::mouse_grab(Uint32 windowID, 
bool enable)
 
  676  auto it = _sdl->windows.find(windowID);
 
  677  if (it == _sdl->windows.end())
 
  679  _sdl->grab_mouse = enable;
 
  680  return it->second.grabMouse(enable);
 
  684    : _sdl(sdl), _lastWindowID(UINT32_MAX), _hotkeysEnabled(prefToEnabled()),
 
  685      _hotkeyModmask(prefToMask())
 
  687  _hotkeyFullscreen = prefKeyValue(
"SDL_Fullscreen", SDL_SCANCODE_RETURN);
 
  688  _hotkeyResizable = prefKeyValue(
"SDL_Resizeable", SDL_SCANCODE_R);
 
  689  _hotkeyGrab = prefKeyValue(
"SDL_Grab", SDL_SCANCODE_G);
 
  690  _hotkeyDisconnect = prefKeyValue(
"SDL_Disconnect", SDL_SCANCODE_D);
 
  691  _hotkeyMinimize = prefKeyValue(
"SDL_Minimize", SDL_SCANCODE_M);
 
  696  freerdp_keyboard_remap_free(_remapTable);
 
  699BOOL sdlInput::initialize()
 
  701  auto settings = _sdl->context()->settings;
 
  702  WINPR_ASSERT(settings);
 
  703  WINPR_ASSERT(!_remapTable);
 
  707    _remapTable = freerdp_keyboard_remap_string_to_list(list);
 
  714    DWORD KeyboardLayout = 0;
 
  716    freerdp_detect_keyboard_layout_from_system_locale(&KeyboardLayout);
 
  717    if (KeyboardLayout == 0)
 
  718      KeyboardLayout = ENGLISH_UNITED_STATES;
 
FREERDP_API UINT32 freerdp_settings_get_uint32(const rdpSettings *settings, FreeRDP_Settings_Keys_UInt32 id)
Returns a UINT32 settings value.
 
FREERDP_API BOOL freerdp_settings_get_bool(const rdpSettings *settings, FreeRDP_Settings_Keys_Bool id)
Returns a boolean settings value.
 
FREERDP_API BOOL freerdp_settings_set_uint32(rdpSettings *settings, FreeRDP_Settings_Keys_UInt32 id, UINT32 param)
Sets a UINT32 settings value.
 
FREERDP_API const char * freerdp_settings_get_string(const rdpSettings *settings, FreeRDP_Settings_Keys_String id)
Returns a immutable string settings value.