mirror of
https://github.com/FreeRDP/FreeRDP.git
synced 2024-11-27 03:44:06 +08:00
[client,sdl] implement key remapping
This commit is contained in:
parent
8779ebf8d4
commit
3cf4bac0e8
@ -142,6 +142,8 @@ static BOOL sdl_disp_check_context(void* context, SdlContext** ppsdl, sdlDispCon
|
||||
return FALSE;
|
||||
|
||||
auto sdl = get_context(context);
|
||||
if (!sdl)
|
||||
return FALSE;
|
||||
|
||||
if (!sdl->context()->settings)
|
||||
return FALSE;
|
||||
@ -200,6 +202,9 @@ Uint32 sdlDispContext::OnTimer(Uint32 interval, void* param)
|
||||
return 0;
|
||||
|
||||
SdlContext* sdl = ctx->_sdl;
|
||||
if (!sdl)
|
||||
return 0;
|
||||
|
||||
sdlDispContext* sdlDisp = nullptr;
|
||||
rdpSettings* settings = nullptr;
|
||||
|
||||
|
@ -488,6 +488,66 @@ uint32_t sdlInput::prefKeyValue(const std::string& key, uint32_t fallback)
|
||||
return val;
|
||||
}
|
||||
|
||||
std::list<std::string> sdlInput::tokenize(const std::string& data, const std::string& delimiter)
|
||||
{
|
||||
size_t lastpos = 0;
|
||||
size_t pos = 0;
|
||||
std::list<std::string> list;
|
||||
while ((pos = data.find(delimiter, lastpos)) != std::string::npos)
|
||||
{
|
||||
auto token = data.substr(lastpos, pos);
|
||||
lastpos = pos + 1;
|
||||
list.push_back(token);
|
||||
}
|
||||
auto token = data.substr(lastpos);
|
||||
list.push_back(token);
|
||||
return list;
|
||||
}
|
||||
|
||||
bool sdlInput::extract(const std::string& token, uint32_t& key, uint32_t& value)
|
||||
{
|
||||
int rc = sscanf(token.c_str(), "%" PRIu32 "=%" PRIu32, &key, &value);
|
||||
if (rc != 2)
|
||||
rc = sscanf(token.c_str(), "%" PRIx32 "=%" PRIx32 "", &key, &value);
|
||||
if (rc != 2)
|
||||
rc = sscanf(token.c_str(), "%" PRIu32 "=%" PRIx32, &key, &value);
|
||||
if (rc != 2)
|
||||
rc = sscanf(token.c_str(), "%" PRIx32 "=%" PRIu32, &key, &value);
|
||||
return (rc == 2);
|
||||
}
|
||||
|
||||
uint32_t sdlInput::remapScancode(uint32_t scancode)
|
||||
{
|
||||
if (!_remapInitialized.exchange(true))
|
||||
remapInitialize();
|
||||
auto it = _remapList.find(scancode);
|
||||
if (it != _remapList.end())
|
||||
return it->second;
|
||||
return scancode;
|
||||
}
|
||||
|
||||
void sdlInput::remapInitialize()
|
||||
{
|
||||
WINPR_ASSERT(_sdl);
|
||||
|
||||
auto context = _sdl->context();
|
||||
WINPR_ASSERT(context);
|
||||
auto KeyboardRemappingList =
|
||||
freerdp_settings_get_string(context->settings, FreeRDP_KeyboardRemappingList);
|
||||
if (!KeyboardRemappingList)
|
||||
return;
|
||||
|
||||
auto list = tokenize(KeyboardRemappingList);
|
||||
for (auto& token : list)
|
||||
{
|
||||
uint32_t key = 0;
|
||||
uint32_t value = 0;
|
||||
if (!extract(token, key, value))
|
||||
continue;
|
||||
_remapList.emplace(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
BOOL sdlInput::keyboard_handle_event(const SDL_KeyboardEvent* ev)
|
||||
{
|
||||
WINPR_ASSERT(ev);
|
||||
@ -526,8 +586,10 @@ BOOL sdlInput::keyboard_handle_event(const SDL_KeyboardEvent* ev)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto scancode = remapScancode(rdp_scancode);
|
||||
return freerdp_input_send_keyboard_event_ex(_sdl->context()->input, ev->type == SDL_KEYDOWN,
|
||||
ev->repeat, rdp_scancode);
|
||||
ev->repeat, scancode);
|
||||
}
|
||||
|
||||
BOOL sdlInput::keyboard_grab(Uint32 windowID, SDL_bool enable)
|
||||
@ -564,5 +626,4 @@ BOOL sdlInput::mouse_grab(Uint32 windowID, SDL_bool enable)
|
||||
|
||||
sdlInput::sdlInput(SdlContext* sdl) : _sdl(sdl), _lastWindowID(UINT32_MAX)
|
||||
{
|
||||
WINPR_ASSERT(_sdl);
|
||||
}
|
||||
|
@ -20,6 +20,9 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <list>
|
||||
#include <atomic>
|
||||
|
||||
#include <winpr/wtypes.h>
|
||||
#include <freerdp/freerdp.h>
|
||||
@ -50,7 +53,17 @@ class sdlInput
|
||||
static uint32_t prefToMask();
|
||||
static uint32_t prefKeyValue(const std::string& key, uint32_t fallback = SDL_SCANCODE_UNKNOWN);
|
||||
|
||||
private:
|
||||
static std::list<std::string> tokenize(const std::string& data,
|
||||
const std::string& delimiter = ",");
|
||||
static bool extract(const std::string& token, uint32_t& key, uint32_t& value);
|
||||
|
||||
uint32_t remapScancode(uint32_t scancode);
|
||||
void remapInitialize();
|
||||
|
||||
private:
|
||||
SdlContext* _sdl;
|
||||
Uint32 _lastWindowID;
|
||||
std::map<uint32_t, uint32_t> _remapList;
|
||||
std::atomic<bool> _remapInitialized = false;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user