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_layer* current_surface;
|
||||||
|
|
||||||
const guac_rdp_keysym_scancode_map* keysym_scancodes;
|
guac_rdp_static_keymap keymap;
|
||||||
|
|
||||||
guac_rdp_keysym_state_map keysym_state;
|
guac_rdp_keysym_state_map keysym_state;
|
||||||
|
|
||||||
|
@ -42,7 +42,12 @@
|
|||||||
* Represents a keysym-to-scancode mapping for RDP, with extra information
|
* Represents a keysym-to-scancode mapping for RDP, with extra information
|
||||||
* about the state of prerequisite keysyms.
|
* 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.
|
* The scancode this keysym maps to.
|
||||||
@ -50,7 +55,7 @@ typedef struct guac_rdp_scancode_map {
|
|||||||
int scancode;
|
int scancode;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Required RDP-specific flags
|
* Required RDP-specific flags.
|
||||||
*/
|
*/
|
||||||
int flags;
|
int flags;
|
||||||
|
|
||||||
@ -66,22 +71,47 @@ typedef struct guac_rdp_scancode_map {
|
|||||||
*/
|
*/
|
||||||
const int* clear_keysyms;
|
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
|
* Mapping from keysym to current state
|
||||||
*/
|
*/
|
||||||
typedef int guac_rdp_keysym_state_map[256][256];
|
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).
|
* 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.
|
* 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 */
|
/* 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) {
|
int guac_client_init(guac_client* client, int argc, char** argv) {
|
||||||
|
|
||||||
rdp_guac_client_data* guac_client_data;
|
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->rdp_inst = rdp_inst;
|
||||||
guac_client_data->mouse_button_mask = 0;
|
guac_client_data->mouse_button_mask = 0;
|
||||||
guac_client_data->current_surface = GUAC_DEFAULT_LAYER;
|
guac_client_data->current_surface = GUAC_DEFAULT_LAYER;
|
||||||
guac_client_data->keysym_scancodes = &guac_rdp_keysym_scancode_en_us;
|
|
||||||
|
|
||||||
/* Clear keysym state mapping */
|
/* Clear keysym state mapping and keymap */
|
||||||
memset(guac_client_data->keysym_state, 0, sizeof(guac_rdp_keysym_state_map));
|
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;
|
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 */
|
/* Connect to RDP server */
|
||||||
if (!freerdp_connect(rdp_inst)) {
|
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;
|
rdp_guac_client_data* guac_client_data = (rdp_guac_client_data*) client->data;
|
||||||
freerdp* rdp_inst = guac_client_data->rdp_inst;
|
freerdp* rdp_inst = guac_client_data->rdp_inst;
|
||||||
const guac_rdp_keysym_scancode_map* keysym_scancodes = guac_client_data->keysym_scancodes;
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
/* Lookup scancode for Alt */
|
/* 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 */
|
/* Release all pressed modifiers */
|
||||||
__guac_rdp_update_keysyms(client, GUAC_KEYSYMS_ALL_MODIFIERS, 1, 0);
|
__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 */
|
/* Get scancode of keypad digit */
|
||||||
int scancode = GUAC_RDP_KEYSYM_LOOKUP(
|
int scancode = GUAC_RDP_KEYSYM_LOOKUP(
|
||||||
*keysym_scancodes,
|
guac_client_data->keymap,
|
||||||
0xFFB0 + (altcode / 1000)
|
0xFFB0 + (altcode / 1000)
|
||||||
).scancode;
|
).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;
|
rdp_guac_client_data* guac_client_data = (rdp_guac_client_data*) client->data;
|
||||||
freerdp* rdp_inst = guac_client_data->rdp_inst;
|
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 can be in lookup table */
|
||||||
if (keysym <= 0xFFFF) {
|
if (keysym <= 0xFFFF) {
|
||||||
|
|
||||||
/* Look up scancode mapping */
|
/* 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 defined, send event */
|
||||||
if (scancode_map->scancode != 0) {
|
if (keysym_desc->scancode != 0) {
|
||||||
|
|
||||||
/* If defined, send any prerequesite keys that must be set */
|
/* If defined, send any prerequesite keys that must be set */
|
||||||
if (scancode_map->set_keysyms != NULL)
|
if (keysym_desc->set_keysyms != NULL)
|
||||||
__guac_rdp_update_keysyms(client, scancode_map->set_keysyms, 0, 1);
|
__guac_rdp_update_keysyms(client, keysym_desc->set_keysyms, 0, 1);
|
||||||
|
|
||||||
/* If defined, release any keys that must be cleared */
|
/* If defined, release any keys that must be cleared */
|
||||||
if (scancode_map->clear_keysyms != NULL)
|
if (keysym_desc->clear_keysyms != NULL)
|
||||||
__guac_rdp_update_keysyms(client, scancode_map->clear_keysyms, 1, 0);
|
__guac_rdp_update_keysyms(client, keysym_desc->clear_keysyms, 1, 0);
|
||||||
|
|
||||||
/* Send actual key */
|
/* Send actual key */
|
||||||
rdp_inst->input->KeyboardEvent(
|
rdp_inst->input->KeyboardEvent(
|
||||||
rdp_inst->input,
|
rdp_inst->input,
|
||||||
scancode_map->flags
|
keysym_desc->flags
|
||||||
| (pressed ? KBD_FLAGS_DOWN : KBD_FLAGS_RELEASE),
|
| (pressed ? KBD_FLAGS_DOWN : KBD_FLAGS_RELEASE),
|
||||||
scancode_map->scancode);
|
keysym_desc->scancode);
|
||||||
|
|
||||||
/* If defined, release any keys that were originally released */
|
/* If defined, release any keys that were originally released */
|
||||||
if (scancode_map->set_keysyms != NULL)
|
if (keysym_desc->set_keysyms != NULL)
|
||||||
__guac_rdp_update_keysyms(client, scancode_map->set_keysyms, 0, 0);
|
__guac_rdp_update_keysyms(client, keysym_desc->set_keysyms, 0, 0);
|
||||||
|
|
||||||
/* If defined, send any keys that were originally set */
|
/* If defined, send any keys that were originally set */
|
||||||
if (scancode_map->clear_keysyms != NULL)
|
if (keysym_desc->clear_keysyms != NULL)
|
||||||
__guac_rdp_update_keysyms(client, scancode_map->clear_keysyms, 1, 1);
|
__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