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:
Michael Jumper 2012-03-21 10:45:40 -07:00
parent af4d4681e1
commit 2eb1d05704
5 changed files with 484 additions and 5428 deletions

View File

@ -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;

View File

@ -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.

View File

@ -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)) {

View File

@ -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