Major refactor of keymap - now using simple keysym description lists, which can be hierarchical, and are loaded at connect time into the client's static keymapping.
This commit is contained in:
parent
af4d4681e1
commit
2eb1d05704
@ -65,7 +65,7 @@ typedef struct rdp_guac_client_data {
|
||||
|
||||
const guac_layer* current_surface;
|
||||
|
||||
const guac_rdp_keysym_scancode_map* keysym_scancodes;
|
||||
guac_rdp_static_keymap keymap;
|
||||
|
||||
guac_rdp_keysym_state_map keysym_state;
|
||||
|
||||
|
@ -42,7 +42,12 @@
|
||||
* Represents a keysym-to-scancode mapping for RDP, with extra information
|
||||
* about the state of prerequisite keysyms.
|
||||
*/
|
||||
typedef struct guac_rdp_scancode_map {
|
||||
typedef struct guac_rdp_keysym_desc {
|
||||
|
||||
/**
|
||||
* The keysym being mapped.
|
||||
*/
|
||||
int keysym;
|
||||
|
||||
/**
|
||||
* The scancode this keysym maps to.
|
||||
@ -50,7 +55,7 @@ typedef struct guac_rdp_scancode_map {
|
||||
int scancode;
|
||||
|
||||
/**
|
||||
* Required RDP-specific flags
|
||||
* Required RDP-specific flags.
|
||||
*/
|
||||
int flags;
|
||||
|
||||
@ -66,22 +71,47 @@ typedef struct guac_rdp_scancode_map {
|
||||
*/
|
||||
const int* clear_keysyms;
|
||||
|
||||
} guac_rdp_scancode_map;
|
||||
} guac_rdp_keysym_desc;
|
||||
|
||||
/**
|
||||
* Hierarchical keysym mapping
|
||||
*/
|
||||
typedef struct guac_rdp_keymap guac_rdp_keymap;
|
||||
struct guac_rdp_keymap {
|
||||
|
||||
/**
|
||||
* The parent mapping this map will inherit its initial mapping from.
|
||||
* Any other mapping information will add to or override the mapping
|
||||
* inherited from the parent.
|
||||
*/
|
||||
const guac_rdp_keymap* parent;
|
||||
|
||||
/**
|
||||
* Descriptive name of this keymap
|
||||
*/
|
||||
const char* name;
|
||||
|
||||
/**
|
||||
* Null-terminated array of scancode mappings.
|
||||
*/
|
||||
const guac_rdp_keysym_desc* mapping;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Static mapping from keysyms to scancodes.
|
||||
*/
|
||||
typedef guac_rdp_keysym_desc guac_rdp_static_keymap[256][256];
|
||||
|
||||
/**
|
||||
* Mapping from keysym to current state
|
||||
*/
|
||||
typedef int guac_rdp_keysym_state_map[256][256];
|
||||
|
||||
/**
|
||||
* Static mapping from keysyms to scancodes.
|
||||
*/
|
||||
typedef guac_rdp_scancode_map guac_rdp_keysym_scancode_map[256][256];
|
||||
|
||||
/**
|
||||
* Map of X11 keysyms to RDP scancodes (US English).
|
||||
*/
|
||||
extern const guac_rdp_keysym_scancode_map guac_rdp_keysym_scancode_en_us;
|
||||
extern const guac_rdp_keymap guac_rdp_keymap_en_us;
|
||||
|
||||
/**
|
||||
* Simple macro for referencing the mapped value of an altcode or scancode for a given keysym.
|
||||
|
@ -204,6 +204,35 @@ void rdp_freerdp_context_free(freerdp* instance, rdpContext* context) {
|
||||
/* EMPTY */
|
||||
}
|
||||
|
||||
void __guac_rdp_client_load_keymap(guac_client* client,
|
||||
const guac_rdp_keymap* keymap) {
|
||||
|
||||
rdp_guac_client_data* guac_client_data =
|
||||
(rdp_guac_client_data*) client->data;
|
||||
/* Get mapping */
|
||||
const guac_rdp_keysym_desc* mapping = keymap->mapping;
|
||||
|
||||
/* If parent exists, load parent first */
|
||||
if (keymap->parent != NULL)
|
||||
__guac_rdp_client_load_keymap(client, keymap->parent);
|
||||
|
||||
/* Log load */
|
||||
guac_client_log_info(client, "Loading keymap %s", keymap->name);
|
||||
|
||||
/* Load mapping into keymap */
|
||||
while (mapping->keysym != 0) {
|
||||
|
||||
/* Copy mapping */
|
||||
GUAC_RDP_KEYSYM_LOOKUP(guac_client_data->keymap, mapping->keysym) =
|
||||
*mapping;
|
||||
|
||||
/* Next keysym */
|
||||
mapping++;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int guac_client_init(guac_client* client, int argc, char** argv) {
|
||||
|
||||
rdp_guac_client_data* guac_client_data;
|
||||
@ -323,13 +352,19 @@ int guac_client_init(guac_client* client, int argc, char** argv) {
|
||||
guac_client_data->rdp_inst = rdp_inst;
|
||||
guac_client_data->mouse_button_mask = 0;
|
||||
guac_client_data->current_surface = GUAC_DEFAULT_LAYER;
|
||||
guac_client_data->keysym_scancodes = &guac_rdp_keysym_scancode_en_us;
|
||||
|
||||
/* Clear keysym state mapping */
|
||||
memset(guac_client_data->keysym_state, 0, sizeof(guac_rdp_keysym_state_map));
|
||||
/* Clear keysym state mapping and keymap */
|
||||
memset(guac_client_data->keysym_state, 0,
|
||||
sizeof(guac_rdp_keysym_state_map));
|
||||
|
||||
memset(guac_client_data->keymap, 0,
|
||||
sizeof(guac_rdp_static_keymap));
|
||||
|
||||
((rdp_freerdp_context*) rdp_inst->context)->client = client;
|
||||
client->data = guac_client_data;
|
||||
((rdp_freerdp_context*) rdp_inst->context)->client = client;
|
||||
|
||||
/* Load keymap into client */
|
||||
__guac_rdp_client_load_keymap(client, &guac_rdp_keymap_en_us);
|
||||
|
||||
/* Connect to RDP server */
|
||||
if (!freerdp_connect(rdp_inst)) {
|
||||
|
@ -231,11 +231,12 @@ void __guac_rdp_send_altcode(guac_client* client, int altcode) {
|
||||
|
||||
rdp_guac_client_data* guac_client_data = (rdp_guac_client_data*) client->data;
|
||||
freerdp* rdp_inst = guac_client_data->rdp_inst;
|
||||
const guac_rdp_keysym_scancode_map* keysym_scancodes = guac_client_data->keysym_scancodes;
|
||||
int i;
|
||||
|
||||
/* Lookup scancode for Alt */
|
||||
int alt = GUAC_RDP_KEYSYM_LOOKUP(*keysym_scancodes, 0xFFE9 /* Alt_L */).scancode;
|
||||
int alt = GUAC_RDP_KEYSYM_LOOKUP(
|
||||
guac_client_data->keymap,
|
||||
0xFFE9 /* Alt_L */).scancode;
|
||||
|
||||
/* Release all pressed modifiers */
|
||||
__guac_rdp_update_keysyms(client, GUAC_KEYSYMS_ALL_MODIFIERS, 1, 0);
|
||||
@ -248,7 +249,7 @@ void __guac_rdp_send_altcode(guac_client* client, int altcode) {
|
||||
|
||||
/* Get scancode of keypad digit */
|
||||
int scancode = GUAC_RDP_KEYSYM_LOOKUP(
|
||||
*keysym_scancodes,
|
||||
guac_client_data->keymap,
|
||||
0xFFB0 + (altcode / 1000)
|
||||
).scancode;
|
||||
|
||||
@ -273,39 +274,39 @@ int __guac_rdp_send_keysym(guac_client* client, int keysym, int pressed) {
|
||||
|
||||
rdp_guac_client_data* guac_client_data = (rdp_guac_client_data*) client->data;
|
||||
freerdp* rdp_inst = guac_client_data->rdp_inst;
|
||||
const guac_rdp_keysym_scancode_map* keysym_scancodes = guac_client_data->keysym_scancodes;
|
||||
|
||||
/* If keysym can be in lookup table */
|
||||
if (keysym <= 0xFFFF) {
|
||||
|
||||
/* Look up scancode mapping */
|
||||
const guac_rdp_scancode_map* scancode_map = &GUAC_RDP_KEYSYM_LOOKUP(*keysym_scancodes, keysym);
|
||||
const guac_rdp_keysym_desc* keysym_desc =
|
||||
&GUAC_RDP_KEYSYM_LOOKUP(guac_client_data->keymap, keysym);
|
||||
|
||||
/* If defined, send event */
|
||||
if (scancode_map->scancode != 0) {
|
||||
if (keysym_desc->scancode != 0) {
|
||||
|
||||
/* If defined, send any prerequesite keys that must be set */
|
||||
if (scancode_map->set_keysyms != NULL)
|
||||
__guac_rdp_update_keysyms(client, scancode_map->set_keysyms, 0, 1);
|
||||
if (keysym_desc->set_keysyms != NULL)
|
||||
__guac_rdp_update_keysyms(client, keysym_desc->set_keysyms, 0, 1);
|
||||
|
||||
/* If defined, release any keys that must be cleared */
|
||||
if (scancode_map->clear_keysyms != NULL)
|
||||
__guac_rdp_update_keysyms(client, scancode_map->clear_keysyms, 1, 0);
|
||||
if (keysym_desc->clear_keysyms != NULL)
|
||||
__guac_rdp_update_keysyms(client, keysym_desc->clear_keysyms, 1, 0);
|
||||
|
||||
/* Send actual key */
|
||||
rdp_inst->input->KeyboardEvent(
|
||||
rdp_inst->input,
|
||||
scancode_map->flags
|
||||
keysym_desc->flags
|
||||
| (pressed ? KBD_FLAGS_DOWN : KBD_FLAGS_RELEASE),
|
||||
scancode_map->scancode);
|
||||
keysym_desc->scancode);
|
||||
|
||||
/* If defined, release any keys that were originally released */
|
||||
if (scancode_map->set_keysyms != NULL)
|
||||
__guac_rdp_update_keysyms(client, scancode_map->set_keysyms, 0, 0);
|
||||
if (keysym_desc->set_keysyms != NULL)
|
||||
__guac_rdp_update_keysyms(client, keysym_desc->set_keysyms, 0, 0);
|
||||
|
||||
/* If defined, send any keys that were originally set */
|
||||
if (scancode_map->clear_keysyms != NULL)
|
||||
__guac_rdp_update_keysyms(client, scancode_map->clear_keysyms, 1, 1);
|
||||
if (keysym_desc->clear_keysyms != NULL)
|
||||
__guac_rdp_update_keysyms(client, keysym_desc->clear_keysyms, 1, 1);
|
||||
|
||||
}
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user