GUACAMOLE-518: Merge correct Caps Lock and Shift behavior within RDP keymap translation system.
This commit is contained in:
commit
5f5080994f
@ -241,7 +241,7 @@ rdp_keymaps = \
|
||||
$(srcdir)/keymaps/da_dk_qwerty.keymap \
|
||||
$(srcdir)/keymaps/tr_tr_qwerty.keymap
|
||||
|
||||
_generated_keymaps.c: $(rdp_keymaps)
|
||||
_generated_keymaps.c: $(rdp_keymaps) $(srcdir)/keymaps/generate.pl
|
||||
$(AM_V_GEN) $(srcdir)/keymaps/generate.pl $(rdp_keymaps)
|
||||
|
||||
_generated_channel_entry_wrappers.c: $(srcdir)/plugins/channels.h $(srcdir)/plugins/generate-entry-wrappers.pl
|
||||
|
@ -162,12 +162,12 @@ int guac_rdp_decompose_keysym(guac_rdp_keyboard* keyboard, int keysym) {
|
||||
return 1;
|
||||
|
||||
/* Press dead key */
|
||||
guac_rdp_keyboard_send_event(keyboard, key->dead_keysym, 1);
|
||||
guac_rdp_keyboard_send_event(keyboard, key->dead_keysym, 0);
|
||||
guac_rdp_keyboard_update_keysym(keyboard, key->dead_keysym, 1, GUAC_RDP_KEY_SOURCE_SYNTHETIC);
|
||||
guac_rdp_keyboard_update_keysym(keyboard, key->dead_keysym, 0, GUAC_RDP_KEY_SOURCE_SYNTHETIC);
|
||||
|
||||
/* Press base key */
|
||||
guac_rdp_keyboard_send_event(keyboard, key->base_keysym, 1);
|
||||
guac_rdp_keyboard_send_event(keyboard, key->base_keysym, 0);
|
||||
guac_rdp_keyboard_update_keysym(keyboard, key->base_keysym, 1, GUAC_RDP_KEY_SOURCE_SYNTHETIC);
|
||||
guac_rdp_keyboard_update_keysym(keyboard, key->base_keysym, 0, GUAC_RDP_KEY_SOURCE_SYNTHETIC);
|
||||
|
||||
/* Decomposed key successfully typed */
|
||||
return 0;
|
||||
|
@ -141,7 +141,7 @@ int guac_rdp_user_key_handler(guac_user* user, int keysym, int pressed) {
|
||||
|
||||
/* Update keysym state */
|
||||
retval = guac_rdp_keyboard_update_keysym(rdp_client->keyboard,
|
||||
keysym, pressed);
|
||||
keysym, pressed, GUAC_RDP_KEY_SOURCE_CLIENT);
|
||||
|
||||
complete:
|
||||
pthread_rwlock_unlock(&(rdp_client->lock));
|
||||
|
@ -28,6 +28,39 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
/**
|
||||
* Translates the given keysym into the corresponding modifier flag, as defined
|
||||
* by keymap.h. If the given keysym does not represent a modifier key, zero is
|
||||
* returned.
|
||||
*
|
||||
* @param keysym
|
||||
* The keysym to translate into a modifier flag.
|
||||
*
|
||||
* @return
|
||||
* The modifier flag which corresponds to the given keysym, or zero if the
|
||||
* given keysym does not represent a modifier key.
|
||||
*/
|
||||
static int guac_rdp_keyboard_modifier_flag(int keysym) {
|
||||
|
||||
/* Translate keysym into corresponding modifier flag */
|
||||
switch (keysym) {
|
||||
|
||||
/* Shift */
|
||||
case 0xFFE1:
|
||||
case 0xFFE2:
|
||||
return GUAC_RDP_KEYMAP_MODIFIER_SHIFT;
|
||||
|
||||
/* AltGr */
|
||||
case 0xFE03:
|
||||
return GUAC_RDP_KEYMAP_MODIFIER_ALTGR;
|
||||
|
||||
}
|
||||
|
||||
/* Not a modifier */
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Translates the given keysym into the corresponding lock flag, as would be
|
||||
* required by the RDP synchronize event. If the given keysym does not
|
||||
@ -153,7 +186,7 @@ static void guac_rdp_send_unicode_event(guac_rdp_client* rdp_client,
|
||||
* lock keys will be active.
|
||||
*/
|
||||
static void guac_rdp_send_synchronize_event(guac_rdp_client* rdp_client,
|
||||
int flags) {
|
||||
UINT32 flags) {
|
||||
|
||||
/* Skip if not yet connected */
|
||||
freerdp* rdp_inst = rdp_client->rdp_inst;
|
||||
@ -166,10 +199,10 @@ static void guac_rdp_send_synchronize_event(guac_rdp_client* rdp_client,
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a keyboard instance and X11 keysym, returns a pointer to the key
|
||||
* structure that represents or can represent the key having that keysym within
|
||||
* the keyboard, regardless of whether the key is currently defined. If no such
|
||||
* key can exist (the keysym cannot be mapped or is out of range), NULL is
|
||||
* Given a keyboard instance and X11 keysym, returns a pointer to the
|
||||
* keys_by_keysym entry that represents the key having that keysym within the
|
||||
* keyboard, regardless of whether the key is currently defined. If no such key
|
||||
* can exist (the keysym cannot be mapped or is out of range), NULL is
|
||||
* returned.
|
||||
*
|
||||
* @param keyboard
|
||||
@ -179,11 +212,11 @@ static void guac_rdp_send_synchronize_event(guac_rdp_client* rdp_client,
|
||||
* The keysym of the key to lookup within the given keyboard.
|
||||
*
|
||||
* @return
|
||||
* A pointer to the guac_rdp_key structure which represents or can
|
||||
* represent the key having the given keysym, or NULL if no such keysym can
|
||||
* be defined within a guac_rdp_keyboard structure.
|
||||
* A pointer to the keys_by_keysym entry which represents or can represent
|
||||
* the key having the given keysym, or NULL if no such keysym can be
|
||||
* defined within a guac_rdp_keyboard structure.
|
||||
*/
|
||||
static guac_rdp_key* guac_rdp_keyboard_map_key(guac_rdp_keyboard* keyboard,
|
||||
static guac_rdp_key** guac_rdp_keyboard_map_key(guac_rdp_keyboard* keyboard,
|
||||
int keysym) {
|
||||
|
||||
int index;
|
||||
@ -201,14 +234,79 @@ static guac_rdp_key* guac_rdp_keyboard_map_key(guac_rdp_keyboard* keyboard,
|
||||
return NULL;
|
||||
|
||||
/* Corresponding key mapping (defined or not) has been located */
|
||||
return &(keyboard->keys[index]);
|
||||
return &(keyboard->keys_by_keysym[index]);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a pointer to the guac_rdp_key structure representing the definition
|
||||
* and state of the key having the given keysym. If no such key is defined
|
||||
* within the keyboard layout of the RDP server, NULL is returned.
|
||||
* Returns the number of bits that are set within the given integer (the number
|
||||
* of 1s in the binary expansion of the given integer).
|
||||
*
|
||||
* @param value
|
||||
* The integer to read.
|
||||
*
|
||||
* @return
|
||||
* The number of bits that are set within the given integer.
|
||||
*/
|
||||
static int guac_rdp_count_bits(unsigned int value) {
|
||||
|
||||
int bits = 0;
|
||||
|
||||
while (value) {
|
||||
bits += value & 1;
|
||||
value >>= 1;
|
||||
}
|
||||
|
||||
return bits;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an estimated cost for sending the necessary RDP events to type the
|
||||
* key described by the given guac_rdp_keysym_desc, given the current lock and
|
||||
* modifier state of the keyboard. A higher cost value indicates that a greater
|
||||
* number of events are expected to be required.
|
||||
*
|
||||
* Lower-cost approaches should be preferred when multiple alternatives exist
|
||||
* for typing a particular key, as the lower cost implies fewer additional key
|
||||
* events required to produce the expected behavior. For example, if Caps Lock
|
||||
* is enabled, typing an uppercase "A" by pressing the "A" key has a lower cost
|
||||
* than disabling Caps Lock and pressing Shift+A.
|
||||
*
|
||||
* @param keyboard
|
||||
* The guac_rdp_keyboard associated with the current RDP session.
|
||||
*
|
||||
* @param def
|
||||
* The guac_rdp_keysym_desc that describes the key being pressed, as well
|
||||
* as any requirements that must be satisfied for the key to be interpreted
|
||||
* as expected.
|
||||
*
|
||||
* @return
|
||||
* An arbitrary integer value which indicates the overall estimated
|
||||
* complexity of typing the given key.
|
||||
*/
|
||||
static int guac_rdp_keyboard_get_cost(guac_rdp_keyboard* keyboard,
|
||||
const guac_rdp_keysym_desc* def) {
|
||||
|
||||
/* Each change to any key requires one event, by definition */
|
||||
int cost = 1;
|
||||
|
||||
/* Each change to a lock requires roughly two key events */
|
||||
unsigned int update_locks = (def->set_locks & ~keyboard->lock_flags) | (def->clear_locks & keyboard->lock_flags);
|
||||
cost += guac_rdp_count_bits(update_locks) * 2;
|
||||
|
||||
/* Each change to a modifier requires one key event */
|
||||
unsigned int update_modifiers = (def->clear_modifiers & keyboard->modifier_flags) | (def->set_modifiers & ~keyboard->modifier_flags);
|
||||
cost += guac_rdp_count_bits(update_modifiers);
|
||||
|
||||
return cost;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a pointer to the guac_rdp_key structure representing the
|
||||
* definition(s) and state of the key having the given keysym. If no such key
|
||||
* is defined within the keyboard layout of the RDP server, NULL is returned.
|
||||
*
|
||||
* @param keyboard
|
||||
* The guac_rdp_keyboard associated with the current RDP session.
|
||||
@ -217,20 +315,120 @@ static guac_rdp_key* guac_rdp_keyboard_map_key(guac_rdp_keyboard* keyboard,
|
||||
* The keysym of the key to lookup within the given keyboard.
|
||||
*
|
||||
* @return
|
||||
* A pointer to the guac_rdp_key structure representing the definition and
|
||||
* state of the key having the given keysym, or NULL if no such key is
|
||||
* A pointer to the guac_rdp_key structure representing the definition(s)
|
||||
* and state of the key having the given keysym, or NULL if no such key is
|
||||
* defined within the keyboard layout of the RDP server.
|
||||
*/
|
||||
static guac_rdp_key* guac_rdp_keyboard_get_key(guac_rdp_keyboard* keyboard,
|
||||
int keysym) {
|
||||
|
||||
/* Verify that the key is actually defined */
|
||||
guac_rdp_key* key = guac_rdp_keyboard_map_key(keyboard, keysym);
|
||||
if (key == NULL || key->definition == NULL)
|
||||
guac_rdp_key** key_by_keysym = guac_rdp_keyboard_map_key(keyboard, keysym);
|
||||
if (key_by_keysym == NULL)
|
||||
return NULL;
|
||||
|
||||
/* Key is defined within keyboard */
|
||||
return key;
|
||||
return *key_by_keysym;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a key which may have multiple possible definitions, returns the
|
||||
* definition that currently has the lowest cost, taking into account the
|
||||
* current keyboard lock and modifier states.
|
||||
*
|
||||
* @param keyboard
|
||||
* The guac_rdp_keyboard associated with the current RDP session.
|
||||
*
|
||||
* @param key
|
||||
* The key whose lowest-cost possible definition should be retrieved.
|
||||
*
|
||||
* @return
|
||||
* A pointer to the guac_rdp_keysym_desc which defines the current
|
||||
* lowest-cost method of typing the given key.
|
||||
*/
|
||||
static const guac_rdp_keysym_desc* guac_rdp_keyboard_get_definition(guac_rdp_keyboard* keyboard,
|
||||
guac_rdp_key* key) {
|
||||
|
||||
/* Consistently map the same entry so long as the key is held */
|
||||
if (key->pressed != NULL)
|
||||
return key->pressed;
|
||||
|
||||
/* Calculate cost of first definition of key (there must always be at least
|
||||
* one definition) */
|
||||
const guac_rdp_keysym_desc* best_def = key->definitions[0];
|
||||
int best_cost = guac_rdp_keyboard_get_cost(keyboard, best_def);
|
||||
|
||||
/* If further definitions exist, choose the definition with the lowest
|
||||
* overall cost */
|
||||
for (int i = 1; i < key->num_definitions; i++) {
|
||||
|
||||
const guac_rdp_keysym_desc* def = key->definitions[i];
|
||||
int cost = guac_rdp_keyboard_get_cost(keyboard, def);
|
||||
|
||||
if (cost < best_cost) {
|
||||
best_def = def;
|
||||
best_cost = cost;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return best_def;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the keysym/scancode mapping described by the given guac_rdp_keysym_desc
|
||||
* to the internal mapping of the keyboard. If insufficient space remains for
|
||||
* additional keysyms, or the given keysym has already reached the maximum
|
||||
* number of possible definitions, the mapping is ignored and the failure is
|
||||
* logged.
|
||||
*
|
||||
* @param keyboard
|
||||
* The guac_rdp_keyboard associated with the current RDP session.
|
||||
*
|
||||
* @param mapping
|
||||
* The keysym/scancode mapping that should be added to the given keyboard.
|
||||
*/
|
||||
static void guac_rdp_keyboard_add_mapping(guac_rdp_keyboard* keyboard,
|
||||
const guac_rdp_keysym_desc* mapping) {
|
||||
|
||||
/* Locate corresponding keysym-to-key translation entry within keyboard
|
||||
* structure */
|
||||
guac_rdp_key** key_by_keysym = guac_rdp_keyboard_map_key(keyboard, mapping->keysym);
|
||||
if (key_by_keysym == NULL) {
|
||||
guac_client_log(keyboard->client, GUAC_LOG_DEBUG, "Ignoring unmappable keysym 0x%X", mapping->keysym);
|
||||
return;
|
||||
}
|
||||
|
||||
/* If not yet pointing to a key, point keysym-to-key translation entry at
|
||||
* next available storage */
|
||||
if (*key_by_keysym == NULL) {
|
||||
|
||||
if (keyboard->num_keys == GUAC_RDP_KEYBOARD_MAX_KEYSYMS) {
|
||||
guac_client_log(keyboard->client, GUAC_LOG_DEBUG, "Key definition "
|
||||
"for keysym 0x%X dropped: Keymap exceeds maximum "
|
||||
"supported number of keysyms",
|
||||
mapping->keysym);
|
||||
return;
|
||||
}
|
||||
|
||||
*key_by_keysym = &keyboard->keys[keyboard->num_keys++];
|
||||
|
||||
}
|
||||
|
||||
guac_rdp_key* key = *key_by_keysym;
|
||||
|
||||
/* Add new definition only if sufficient space remains */
|
||||
if (key->num_definitions == GUAC_RDP_KEY_MAX_DEFINITIONS) {
|
||||
guac_client_log(keyboard->client, GUAC_LOG_DEBUG, "Key definition "
|
||||
"for keysym 0x%X dropped: Maximum number of possible "
|
||||
"definitions has been reached for this keysym",
|
||||
mapping->keysym);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Store new possible definition of key */
|
||||
key->definitions[key->num_definitions++] = mapping;
|
||||
|
||||
}
|
||||
|
||||
@ -248,37 +446,21 @@ static guac_rdp_key* guac_rdp_keyboard_get_key(guac_rdp_keyboard* keyboard,
|
||||
* The keymap to use to populate the given client's keysym/scancode
|
||||
* mapping.
|
||||
*/
|
||||
static void __guac_rdp_keyboard_load_keymap(guac_rdp_keyboard* keyboard,
|
||||
static void guac_rdp_keyboard_load_keymap(guac_rdp_keyboard* keyboard,
|
||||
const guac_rdp_keymap* keymap) {
|
||||
|
||||
/* Get mapping */
|
||||
const guac_rdp_keysym_desc* mapping = keymap->mapping;
|
||||
|
||||
/* If parent exists, load parent first */
|
||||
if (keymap->parent != NULL)
|
||||
__guac_rdp_keyboard_load_keymap(keyboard, keymap->parent);
|
||||
guac_rdp_keyboard_load_keymap(keyboard, keymap->parent);
|
||||
|
||||
/* Log load */
|
||||
guac_client_log(keyboard->client, GUAC_LOG_INFO,
|
||||
"Loading keymap \"%s\"", keymap->name);
|
||||
|
||||
/* Load mapping into keymap */
|
||||
/* Copy mapping into keymap */
|
||||
const guac_rdp_keysym_desc* mapping = keymap->mapping;
|
||||
while (mapping->keysym != 0) {
|
||||
|
||||
/* Locate corresponding key definition within keyboard */
|
||||
guac_rdp_key* key = guac_rdp_keyboard_map_key(keyboard,
|
||||
mapping->keysym);
|
||||
|
||||
/* Copy mapping (if key is mappable) */
|
||||
if (key != NULL)
|
||||
key->definition = mapping;
|
||||
else
|
||||
guac_client_log(keyboard->client, GUAC_LOG_DEBUG,
|
||||
"Ignoring unmappable keysym 0x%X", mapping->keysym);
|
||||
|
||||
/* Next keysym */
|
||||
mapping++;
|
||||
|
||||
guac_rdp_keyboard_add_mapping(keyboard, mapping++);
|
||||
}
|
||||
|
||||
}
|
||||
@ -290,7 +472,7 @@ guac_rdp_keyboard* guac_rdp_keyboard_alloc(guac_client* client,
|
||||
keyboard->client = client;
|
||||
|
||||
/* Load keymap into keyboard */
|
||||
__guac_rdp_keyboard_load_keymap(keyboard, keymap);
|
||||
guac_rdp_keyboard_load_keymap(keyboard, keymap);
|
||||
|
||||
return keyboard;
|
||||
|
||||
@ -307,127 +489,104 @@ int guac_rdp_keyboard_is_defined(guac_rdp_keyboard* keyboard, int keysym) {
|
||||
|
||||
}
|
||||
|
||||
int guac_rdp_keyboard_send_event(guac_rdp_keyboard* keyboard,
|
||||
int keysym, int pressed) {
|
||||
/**
|
||||
* Presses/releases the requested key by sending one or more RDP key events, as
|
||||
* defined within the keymap defining that key.
|
||||
*
|
||||
* @param keyboard
|
||||
* The guac_rdp_keyboard associated with the current RDP session.
|
||||
*
|
||||
* @param key
|
||||
* The guac_rdp_keysym_desc of the key being pressed or released, as
|
||||
* retrieved from the relevant keymap.
|
||||
*
|
||||
* @param pressed
|
||||
* Zero if the key is being released, non-zero otherwise.
|
||||
*
|
||||
* @return
|
||||
* Zero if the key was successfully pressed/released, non-zero if the key
|
||||
* cannot be sent using RDP key events.
|
||||
*/
|
||||
static const guac_rdp_keysym_desc* guac_rdp_keyboard_send_defined_key(guac_rdp_keyboard* keyboard,
|
||||
guac_rdp_key* key, int pressed) {
|
||||
|
||||
guac_client* client = keyboard->client;
|
||||
guac_rdp_client* rdp_client = (guac_rdp_client*) client->data;
|
||||
|
||||
/* If keysym is actually defined within keyboard */
|
||||
guac_rdp_key* key = guac_rdp_keyboard_get_key(keyboard, keysym);
|
||||
if (key != NULL) {
|
||||
const guac_rdp_keysym_desc* keysym_desc = guac_rdp_keyboard_get_definition(keyboard, key);
|
||||
if (keysym_desc->scancode == 0)
|
||||
return NULL;
|
||||
|
||||
/* Look up scancode mapping */
|
||||
const guac_rdp_keysym_desc* keysym_desc = key->definition;
|
||||
|
||||
/* If defined, send event */
|
||||
if (keysym_desc->scancode != 0) {
|
||||
|
||||
/* Update remote lock state as necessary */
|
||||
guac_rdp_keyboard_update_locks(keyboard,
|
||||
keysym_desc->set_locks,
|
||||
keysym_desc->clear_locks);
|
||||
|
||||
/* If defined, send any prerequesite keys that must be set */
|
||||
if (keysym_desc->set_keysyms != NULL)
|
||||
guac_rdp_keyboard_send_events(keyboard,
|
||||
keysym_desc->set_keysyms,
|
||||
GUAC_RDP_KEY_RELEASED,
|
||||
GUAC_RDP_KEY_PRESSED);
|
||||
|
||||
/* If defined, release any keys that must be cleared */
|
||||
if (keysym_desc->clear_keysyms != NULL)
|
||||
guac_rdp_keyboard_send_events(keyboard,
|
||||
keysym_desc->clear_keysyms,
|
||||
GUAC_RDP_KEY_PRESSED,
|
||||
GUAC_RDP_KEY_RELEASED);
|
||||
|
||||
/* Fire actual key event for target key */
|
||||
guac_rdp_send_key_event(rdp_client, keysym_desc->scancode,
|
||||
keysym_desc->flags, pressed);
|
||||
|
||||
/* If defined, release any keys that were originally released */
|
||||
if (keysym_desc->set_keysyms != NULL)
|
||||
guac_rdp_keyboard_send_events(keyboard,
|
||||
keysym_desc->set_keysyms,
|
||||
GUAC_RDP_KEY_RELEASED,
|
||||
GUAC_RDP_KEY_RELEASED);
|
||||
|
||||
/* If defined, send any keys that were originally set */
|
||||
if (keysym_desc->clear_keysyms != NULL)
|
||||
guac_rdp_keyboard_send_events(keyboard,
|
||||
keysym_desc->clear_keysyms,
|
||||
GUAC_RDP_KEY_PRESSED,
|
||||
GUAC_RDP_KEY_PRESSED);
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/* Fall back to dead keys or Unicode events if otherwise undefined inside
|
||||
* current keymap (note that we only handle "pressed" here, as neither
|
||||
* Unicode events nor dead keys can have a pressed/released state) */
|
||||
/* Update state of required locks and modifiers only when key is just
|
||||
* now being pressed */
|
||||
if (pressed) {
|
||||
guac_rdp_keyboard_update_locks(keyboard,
|
||||
keysym_desc->set_locks,
|
||||
keysym_desc->clear_locks);
|
||||
|
||||
/* Attempt to type using dead keys */
|
||||
if (!guac_rdp_decompose_keysym(keyboard, keysym))
|
||||
return 0;
|
||||
|
||||
guac_client_log(client, GUAC_LOG_DEBUG,
|
||||
"Sending keysym 0x%x as Unicode", keysym);
|
||||
|
||||
/* Translate keysym into codepoint */
|
||||
int codepoint;
|
||||
if (keysym <= 0xFF)
|
||||
codepoint = keysym;
|
||||
else if (keysym >= 0x1000000)
|
||||
codepoint = keysym & 0xFFFFFF;
|
||||
else {
|
||||
guac_client_log(client, GUAC_LOG_DEBUG,
|
||||
"Unmapped keysym has no equivalent unicode "
|
||||
"value: 0x%x", keysym);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Send as Unicode event */
|
||||
guac_rdp_send_unicode_event(rdp_client, codepoint);
|
||||
|
||||
guac_rdp_keyboard_update_modifiers(keyboard,
|
||||
keysym_desc->set_modifiers,
|
||||
keysym_desc->clear_modifiers);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
/* Fire actual key event for target key */
|
||||
guac_rdp_send_key_event(rdp_client, keysym_desc->scancode,
|
||||
keysym_desc->flags, pressed);
|
||||
|
||||
return keysym_desc;
|
||||
|
||||
}
|
||||
|
||||
void guac_rdp_keyboard_send_events(guac_rdp_keyboard* keyboard,
|
||||
const int* keysym_string, guac_rdp_key_state from,
|
||||
guac_rdp_key_state to) {
|
||||
/**
|
||||
* Presses and releases the requested key by sending one or more RDP events,
|
||||
* without relying on a keymap for that key. This will typically involve either
|
||||
* sending the key using a Unicode event or decomposing the key into a series
|
||||
* of keypresses involving deadkeys.
|
||||
*
|
||||
* @param keyboard
|
||||
* The guac_rdp_keyboard associated with the current RDP session.
|
||||
*
|
||||
* @param keysym
|
||||
* The keysym of the key to press and release.
|
||||
*/
|
||||
static void guac_rdp_keyboard_send_missing_key(guac_rdp_keyboard* keyboard,
|
||||
int keysym) {
|
||||
|
||||
int keysym;
|
||||
guac_client* client = keyboard->client;
|
||||
guac_rdp_client* rdp_client = (guac_rdp_client*) client->data;
|
||||
|
||||
/* Send all keysyms in string, NULL terminated */
|
||||
while ((keysym = *keysym_string) != 0) {
|
||||
/* Attempt to type using dead keys */
|
||||
if (!guac_rdp_decompose_keysym(keyboard, keysym))
|
||||
return;
|
||||
|
||||
/* If key is currently in given state, send event for changing it to
|
||||
* specified "to" state */
|
||||
guac_rdp_key* key = guac_rdp_keyboard_get_key(keyboard, keysym);
|
||||
if (key != NULL && key->state == from)
|
||||
guac_rdp_keyboard_send_event(keyboard, *keysym_string, to);
|
||||
|
||||
/* Next keysym */
|
||||
keysym_string++;
|
||||
guac_client_log(client, GUAC_LOG_DEBUG, "Sending keysym 0x%x as "
|
||||
"Unicode", keysym);
|
||||
|
||||
/* Translate keysym into codepoint */
|
||||
int codepoint;
|
||||
if (keysym <= 0xFF)
|
||||
codepoint = keysym;
|
||||
else if (keysym >= 0x1000000)
|
||||
codepoint = keysym & 0xFFFFFF;
|
||||
else {
|
||||
guac_client_log(client, GUAC_LOG_DEBUG, "Unmapped keysym has no "
|
||||
"equivalent unicode value: 0x%x", keysym);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Send as Unicode event */
|
||||
guac_rdp_send_unicode_event(rdp_client, codepoint);
|
||||
|
||||
}
|
||||
|
||||
void guac_rdp_keyboard_update_locks(guac_rdp_keyboard* keyboard,
|
||||
int set_flags, int clear_flags) {
|
||||
unsigned int set_flags, unsigned int clear_flags) {
|
||||
|
||||
guac_client* client = keyboard->client;
|
||||
guac_rdp_client* rdp_client = (guac_rdp_client*) client->data;
|
||||
|
||||
/* Calculate updated lock flags */
|
||||
int lock_flags = (keyboard->lock_flags | set_flags) & ~clear_flags;
|
||||
unsigned int lock_flags = (keyboard->lock_flags | set_flags) & ~clear_flags;
|
||||
|
||||
/* Synchronize remote side only if lock flags have changed */
|
||||
if (lock_flags != keyboard->lock_flags) {
|
||||
@ -437,8 +596,36 @@ void guac_rdp_keyboard_update_locks(guac_rdp_keyboard* keyboard,
|
||||
|
||||
}
|
||||
|
||||
void guac_rdp_keyboard_update_modifiers(guac_rdp_keyboard* keyboard,
|
||||
unsigned int set_flags, unsigned int clear_flags) {
|
||||
|
||||
/* Only clear modifiers that are set */
|
||||
clear_flags &= keyboard->modifier_flags;
|
||||
|
||||
/* Only set modifiers that are currently cleared */
|
||||
set_flags &= ~keyboard->modifier_flags;
|
||||
|
||||
/* Press/release Shift as needed */
|
||||
if (set_flags & GUAC_RDP_KEYMAP_MODIFIER_SHIFT) {
|
||||
guac_rdp_keyboard_update_keysym(keyboard, 0xFFE1, 1, GUAC_RDP_KEY_SOURCE_SYNTHETIC);
|
||||
}
|
||||
else if (clear_flags & GUAC_RDP_KEYMAP_MODIFIER_SHIFT) {
|
||||
guac_rdp_keyboard_update_keysym(keyboard, 0xFFE1, 0, GUAC_RDP_KEY_SOURCE_SYNTHETIC);
|
||||
guac_rdp_keyboard_update_keysym(keyboard, 0xFFE2, 0, GUAC_RDP_KEY_SOURCE_SYNTHETIC);
|
||||
}
|
||||
|
||||
/* Press/release AltGr as needed */
|
||||
if (set_flags & GUAC_RDP_KEYMAP_MODIFIER_ALTGR) {
|
||||
guac_rdp_keyboard_update_keysym(keyboard, 0xFE03, 1, GUAC_RDP_KEY_SOURCE_SYNTHETIC);
|
||||
}
|
||||
else if (clear_flags & GUAC_RDP_KEYMAP_MODIFIER_ALTGR) {
|
||||
guac_rdp_keyboard_update_keysym(keyboard, 0xFE03, 0, GUAC_RDP_KEY_SOURCE_SYNTHETIC);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int guac_rdp_keyboard_update_keysym(guac_rdp_keyboard* keyboard,
|
||||
int keysym, int pressed) {
|
||||
int keysym, int pressed, guac_rdp_key_source source) {
|
||||
|
||||
/* Synchronize lock keys states, if this has not yet been done */
|
||||
if (!keyboard->synchronized) {
|
||||
@ -452,16 +639,94 @@ int guac_rdp_keyboard_update_keysym(guac_rdp_keyboard* keyboard,
|
||||
|
||||
}
|
||||
|
||||
/* Toggle lock flag, if any */
|
||||
if (pressed)
|
||||
keyboard->lock_flags ^= guac_rdp_keyboard_lock_flag(keysym);
|
||||
|
||||
/* Update keysym state */
|
||||
/* If key is known, ignoring the key event entirely if state is not
|
||||
* actually changing */
|
||||
guac_rdp_key* key = guac_rdp_keyboard_get_key(keyboard, keysym);
|
||||
if (key != NULL)
|
||||
key->state = pressed ? GUAC_RDP_KEY_PRESSED : GUAC_RDP_KEY_RELEASED;
|
||||
if (key != NULL) {
|
||||
if ((!pressed && key->pressed == NULL) || (pressed && key->pressed != NULL))
|
||||
return 0;
|
||||
}
|
||||
|
||||
return guac_rdp_keyboard_send_event(keyboard, keysym, pressed);
|
||||
/* Toggle locks and set modifiers on keydown */
|
||||
if (pressed) {
|
||||
keyboard->lock_flags ^= guac_rdp_keyboard_lock_flag(keysym);
|
||||
keyboard->modifier_flags |= guac_rdp_keyboard_modifier_flag(keysym);
|
||||
}
|
||||
|
||||
/* Clear modifiers on keyup */
|
||||
else {
|
||||
keyboard->modifier_flags &= ~guac_rdp_keyboard_modifier_flag(keysym);
|
||||
}
|
||||
|
||||
/* If key is known, update state and attempt to send using normal RDP key
|
||||
* events */
|
||||
const guac_rdp_keysym_desc* definition = NULL;
|
||||
if (key != NULL) {
|
||||
definition = guac_rdp_keyboard_send_defined_key(keyboard, key, pressed);
|
||||
key->pressed = pressed ? definition : NULL;
|
||||
}
|
||||
|
||||
/* Fall back to dead keys or Unicode events if otherwise undefined inside
|
||||
* current keymap (note that we only handle "pressed" here, as neither
|
||||
* Unicode events nor dead keys can have a pressed/released state) */
|
||||
if (definition == NULL && pressed) {
|
||||
guac_rdp_keyboard_send_missing_key(keyboard, keysym);
|
||||
}
|
||||
|
||||
if (source == GUAC_RDP_KEY_SOURCE_CLIENT) {
|
||||
|
||||
/* Update tracking of client-side keyboard state but only for keys
|
||||
* which are tracked server-side, as well (to ensure that the key count
|
||||
* remains correct, even if a user sends extra unbalanced or excessive
|
||||
* press and release events) */
|
||||
if (key != NULL) {
|
||||
if (pressed)
|
||||
keyboard->user_pressed_keys++;
|
||||
else
|
||||
keyboard->user_pressed_keys--;
|
||||
}
|
||||
|
||||
/* Reset RDP server keyboard state (releasing any automatically pressed
|
||||
* keys) once all keys have been released on the client side */
|
||||
if (keyboard->user_pressed_keys == 0)
|
||||
guac_rdp_keyboard_reset(keyboard);
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
void guac_rdp_keyboard_reset(guac_rdp_keyboard* keyboard) {
|
||||
|
||||
/* Release all pressed keys */
|
||||
for (int i = 0; i < keyboard->num_keys; i++) {
|
||||
guac_rdp_key* key = &keyboard->keys[i];
|
||||
if (key->pressed != NULL)
|
||||
guac_rdp_keyboard_update_keysym(keyboard, key->pressed->keysym, 0,
|
||||
GUAC_RDP_KEY_SOURCE_SYNTHETIC);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
BOOL guac_rdp_keyboard_set_indicators(rdpContext* context, UINT16 flags) {
|
||||
|
||||
guac_client* client = ((rdp_freerdp_context*) context)->client;
|
||||
guac_rdp_client* rdp_client = (guac_rdp_client*) client->data;
|
||||
|
||||
pthread_rwlock_rdlock(&(rdp_client->lock));
|
||||
|
||||
/* Skip if keyboard not yet ready */
|
||||
guac_rdp_keyboard* keyboard = rdp_client->keyboard;
|
||||
if (keyboard == NULL)
|
||||
goto complete;
|
||||
|
||||
/* Update with received locks */
|
||||
guac_client_log(client, GUAC_LOG_DEBUG, "Received updated keyboard lock flags from RDP server: 0x%X", flags);
|
||||
keyboard->lock_flags = flags;
|
||||
|
||||
complete:
|
||||
pthread_rwlock_unlock(&(rdp_client->lock));
|
||||
return TRUE;
|
||||
|
||||
}
|
||||
|
@ -22,25 +22,39 @@
|
||||
|
||||
#include "keymap.h"
|
||||
|
||||
#include <freerdp/freerdp.h>
|
||||
#include <guacamole/client.h>
|
||||
|
||||
/**
|
||||
* The current local state of a key - either pressed or released.
|
||||
* The maximum number of distinct keysyms that any particular keyboard may support.
|
||||
*/
|
||||
typedef enum guac_rdp_key_state {
|
||||
#define GUAC_RDP_KEYBOARD_MAX_KEYSYMS 1024
|
||||
|
||||
/**
|
||||
* The maximum number of unique modifier variations that any particular keysym
|
||||
* may define. For example, on a US English keyboard, an uppercase "A" may be
|
||||
* typed by pressing Shift+A with Caps Lock unset, or by pressing A with Caps
|
||||
* Lock set (two variations).
|
||||
*/
|
||||
#define GUAC_RDP_KEY_MAX_DEFINITIONS 4
|
||||
|
||||
/**
|
||||
* All possible sources of RDP key events tracked by guac_rdp_keyboard.
|
||||
*/
|
||||
typedef enum guac_rdp_key_source {
|
||||
|
||||
/**
|
||||
* The state associated with a key that is released (not currently
|
||||
* pressed / held down).
|
||||
* The key event was received directly from the Guacamole client via a
|
||||
* "key" instruction.
|
||||
*/
|
||||
GUAC_RDP_KEY_RELEASED = 0,
|
||||
GUAC_RDP_KEY_SOURCE_CLIENT = 0,
|
||||
|
||||
/**
|
||||
* The state associated with a key that is currently pressed (held down).
|
||||
* The key event is being synthesized internally within the RDP support.
|
||||
*/
|
||||
GUAC_RDP_KEY_PRESSED = 1
|
||||
GUAC_RDP_KEY_SOURCE_SYNTHETIC = 1
|
||||
|
||||
} guac_rdp_key_state;
|
||||
} guac_rdp_key_source;
|
||||
|
||||
/**
|
||||
* A representation of a single key within the overall local keyboard,
|
||||
@ -50,21 +64,25 @@ typedef enum guac_rdp_key_state {
|
||||
typedef struct guac_rdp_key {
|
||||
|
||||
/**
|
||||
* The definition of this key within the RDP server's keymap (keyboard
|
||||
* layout). This definition describes which scancode corresponds to this
|
||||
* All definitions of this key within the RDP server's keymap (keyboard
|
||||
* layout). Each definition describes which scancode corresponds to this
|
||||
* key from the perspective of the RDP server, as well as which other
|
||||
* scancodes must be pressed/released for this key to have the desired
|
||||
* meaning. If this key does not exist within the RDP server's keymap, this
|
||||
* will be NULL.
|
||||
* meaning.
|
||||
*/
|
||||
const guac_rdp_keysym_desc* definition;
|
||||
const guac_rdp_keysym_desc* definitions[GUAC_RDP_KEY_MAX_DEFINITIONS];
|
||||
|
||||
/**
|
||||
* The local state of this key. For the sake of simplicity, it is assumed
|
||||
* that this state is also an accurate representation of the remote state
|
||||
* of this key within the RDP session.
|
||||
* The number of definitions within the definitions array. If this key does
|
||||
* not exist within the RDP server's keymap, this will be 0.
|
||||
*/
|
||||
guac_rdp_key_state state;
|
||||
int num_definitions;
|
||||
|
||||
/**
|
||||
* The definition of this key that is currently pressed. If this key is not
|
||||
* currently pressed, this will be NULL.
|
||||
*/
|
||||
const guac_rdp_keysym_desc* pressed;
|
||||
|
||||
} guac_rdp_key;
|
||||
|
||||
@ -79,12 +97,21 @@ typedef struct guac_rdp_keyboard {
|
||||
*/
|
||||
guac_client* client;
|
||||
|
||||
/**
|
||||
* The local state of all known modifier keys, as a bitwise OR of the
|
||||
* modified flags used by the keymaps.
|
||||
*
|
||||
* @see GUAC_RDP_KEYMAP_MODIFIER_SHIFT
|
||||
* @see GUAC_RDP_KEYMAP_MODIFIER_ALTGR
|
||||
*/
|
||||
unsigned int modifier_flags;
|
||||
|
||||
/**
|
||||
* The local state of all known lock keys, as a bitwise OR of all RDP lock
|
||||
* key flags. Legal flags are KBD_SYNC_SCROLL_LOCK, KBD_SYNC_NUM_LOCK,
|
||||
* KBD_SYNC_CAPS_LOCK, and KBD_SYNC_KANA_LOCK.
|
||||
*/
|
||||
int lock_flags;
|
||||
UINT32 lock_flags;
|
||||
|
||||
/**
|
||||
* Whether the states of remote lock keys (Caps lock, Num lock, etc.) have
|
||||
@ -92,6 +119,11 @@ typedef struct guac_rdp_keyboard {
|
||||
*/
|
||||
int synchronized;
|
||||
|
||||
/**
|
||||
* The number of keys stored within the keys array.
|
||||
*/
|
||||
unsigned int num_keys;
|
||||
|
||||
/**
|
||||
* The local state of all keys, as well as the necessary information to
|
||||
* translate received keysyms into scancodes or sequences of scancodes for
|
||||
@ -99,13 +131,31 @@ typedef struct guac_rdp_keyboard {
|
||||
* events, while the information describing the behavior and scancode
|
||||
* mapping of each key is populated based on an associated keymap.
|
||||
*
|
||||
* Keys within this array are in arbitrary order.
|
||||
*/
|
||||
guac_rdp_key keys[GUAC_RDP_KEYBOARD_MAX_KEYSYMS];
|
||||
|
||||
/**
|
||||
* Lookup table into the overall keys array, locating the guac_rdp_key
|
||||
* associated with any particular keysym. If a keysym has no corresponding
|
||||
* guac_rdp_key within the keys array, its entry within this lookuptable
|
||||
* will be NULL.
|
||||
*
|
||||
* The index of the key for a given keysym is determined based on a
|
||||
* simple transformation of the keysym itself. Keysyms between 0x0000 and
|
||||
* 0xFFFF inclusive are mapped to 0x00000 through 0x0FFFF, while keysyms
|
||||
* between 0x1000000 and 0x100FFFF inclusive (keysyms which are derived
|
||||
* from Unicode) are mapped to 0x10000 through 0x1FFFF.
|
||||
*/
|
||||
guac_rdp_key keys[0x20000];
|
||||
guac_rdp_key* keys_by_keysym[0x20000];
|
||||
|
||||
/**
|
||||
* The total number of keys that the user of the connection is currently
|
||||
* holding down. This value indicates only the client-side keyboard state.
|
||||
* It DOES NOT indicate the number of keys currently pressed within the RDP
|
||||
* server.
|
||||
*/
|
||||
int user_pressed_keys;
|
||||
|
||||
} guac_rdp_keyboard;
|
||||
|
||||
@ -157,53 +207,6 @@ void guac_rdp_keyboard_free(guac_rdp_keyboard* keyboard);
|
||||
*/
|
||||
int guac_rdp_keyboard_is_defined(guac_rdp_keyboard* keyboard, int keysym);
|
||||
|
||||
/**
|
||||
* Sends one or more RDP key events, effectively pressing or releasing the
|
||||
* given keysym on the remote side. The key events sent will depend on the
|
||||
* current keymap. The locally-stored state of each key is remains untouched.
|
||||
*
|
||||
* @param keyboard
|
||||
* The guac_rdp_keyboard associated with the current RDP session.
|
||||
*
|
||||
* @param keysym
|
||||
* The keysym being pressed or released.
|
||||
*
|
||||
* @param pressed
|
||||
* Zero if the keysym is being released, non-zero otherwise.
|
||||
*
|
||||
* @return
|
||||
* Zero if the keys were successfully sent, non-zero otherwise.
|
||||
*/
|
||||
int guac_rdp_keyboard_send_event(guac_rdp_keyboard* keyboard,
|
||||
int keysym, int pressed);
|
||||
|
||||
/**
|
||||
* For every keysym in the given NULL-terminated array of keysyms, send the RDP
|
||||
* key events required to update the remote state of those keys as specified,
|
||||
* depending on the current local state of those keysyms. For each key in the
|
||||
* "from" state, that key will be updated to the "to" state. The locally-stored
|
||||
* state of each key is remains untouched.
|
||||
*
|
||||
* @param keyboard
|
||||
* The guac_rdp_keyboard associated with the current RDP session.
|
||||
*
|
||||
* @param keysym_string
|
||||
* A NULL-terminated array of keysyms, each of which will be updated.
|
||||
*
|
||||
* @param from
|
||||
* GUAC_RDP_KEY_RELEASED if the state of currently-released keys should be
|
||||
* updated, or GUAC_RDP_KEY_PRESSED if the state of currently-pressed keys
|
||||
* should be updated.
|
||||
*
|
||||
* @param to
|
||||
* GUAC_RDP_KEY_RELEASED if the keys being updated should be marked as
|
||||
* released, or GUAC_RDP_KEY_PRESSED if the keys being updated should be
|
||||
* marked as pressed.
|
||||
*/
|
||||
void guac_rdp_keyboard_send_events(guac_rdp_keyboard* keyboard,
|
||||
const int* keysym_string, guac_rdp_key_state from,
|
||||
guac_rdp_key_state to);
|
||||
|
||||
/**
|
||||
* Updates the local state of the lock keys (such as Caps lock or Num lock),
|
||||
* synchronizing the remote state of those keys if it is expected to differ.
|
||||
@ -222,7 +225,27 @@ void guac_rdp_keyboard_send_events(guac_rdp_keyboard* keyboard,
|
||||
* KBD_SYNC_KANA_LOCK.
|
||||
*/
|
||||
void guac_rdp_keyboard_update_locks(guac_rdp_keyboard* keyboard,
|
||||
int set_flags, int clear_flags);
|
||||
unsigned int set_flags, unsigned int clear_flags);
|
||||
|
||||
/**
|
||||
* Updates the local state of the modifier keys (such as Shift or AltGr),
|
||||
* synchronizing the remote state of those keys if it is expected to differ.
|
||||
* Valid modifier flags are defined by keymap.h.
|
||||
*
|
||||
* @see GUAC_RDP_KEYMAP_MODIFIER_SHIFT
|
||||
* @see GUAC_RDP_KEYMAP_MODIFIER_ALTGR
|
||||
*
|
||||
* @param keyboard
|
||||
* The guac_rdp_keyboard associated with the current RDP session.
|
||||
*
|
||||
* @param set_flags
|
||||
* The modifier key flags which should be set.
|
||||
*
|
||||
* @param clear_flags
|
||||
* The modifier key flags which should be cleared.
|
||||
*/
|
||||
void guac_rdp_keyboard_update_modifiers(guac_rdp_keyboard* keyboard,
|
||||
unsigned int set_flags, unsigned int clear_flags);
|
||||
|
||||
/**
|
||||
* Updates the local state of the given keysym, sending the key events required
|
||||
@ -238,11 +261,41 @@ void guac_rdp_keyboard_update_locks(guac_rdp_keyboard* keyboard,
|
||||
* @param pressed
|
||||
* Zero if the keysym is being released, non-zero otherwise.
|
||||
*
|
||||
* @param source
|
||||
* The source of the key event represented by this call to
|
||||
* guac_rdp_keyboard_update_keysym().
|
||||
*
|
||||
* @return
|
||||
* Zero if the keys were successfully sent, non-zero otherwise.
|
||||
*/
|
||||
int guac_rdp_keyboard_update_keysym(guac_rdp_keyboard* keyboard,
|
||||
int keysym, int pressed);
|
||||
int keysym, int pressed, guac_rdp_key_source source);
|
||||
|
||||
/**
|
||||
* Releases all currently pressed keys, sending key release events to the RDP
|
||||
* server as necessary. Lock states (Caps Lock, etc.) are not affected.
|
||||
*
|
||||
* @param keyboard
|
||||
* The guac_rdp_keyboard associated with the current RDP session.
|
||||
*/
|
||||
void guac_rdp_keyboard_reset(guac_rdp_keyboard* keyboard);
|
||||
|
||||
/**
|
||||
* Callback which is invoked by FreeRDP when the RDP server reports changes to
|
||||
* keyboard lock status using a Server Set Keyboard Indicators PDU.
|
||||
*
|
||||
* @param context
|
||||
* The rdpContext associated with the current RDP session.
|
||||
*
|
||||
* @param flags
|
||||
* The remote state of all lock keys, as a bitwise OR of all RDP lock key
|
||||
* flags. Legal flags are KBD_SYNC_SCROLL_LOCK, KBD_SYNC_NUM_LOCK,
|
||||
* KBD_SYNC_CAPS_LOCK, and KBD_SYNC_KANA_LOCK.
|
||||
*
|
||||
* @return
|
||||
* TRUE if successful, FALSE otherwise.
|
||||
*/
|
||||
BOOL guac_rdp_keyboard_set_indicators(rdpContext* context, UINT16 flags);
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -22,6 +22,16 @@
|
||||
|
||||
#include <winpr/wtypes.h>
|
||||
|
||||
/**
|
||||
* Bitwise flag value representing the Shift modifier.
|
||||
*/
|
||||
#define GUAC_RDP_KEYMAP_MODIFIER_SHIFT 1
|
||||
|
||||
/**
|
||||
* Bitwise flag value representing the AltGr modifier.
|
||||
*/
|
||||
#define GUAC_RDP_KEYMAP_MODIFIER_ALTGR 2
|
||||
|
||||
/**
|
||||
* Represents a keysym-to-scancode mapping for RDP, with extra information
|
||||
* about the state of prerequisite keysyms.
|
||||
@ -39,29 +49,44 @@ typedef struct guac_rdp_keysym_desc {
|
||||
int scancode;
|
||||
|
||||
/**
|
||||
* Required RDP-specific flags.
|
||||
* Required RDP-specific flags that must be sent along with the scancode.
|
||||
*/
|
||||
int flags;
|
||||
|
||||
/**
|
||||
* Null-terminated list of keysyms which must be down for this keysym
|
||||
* to be properly typed.
|
||||
* Bitwise-OR of the flags of any modifiers that must be active for the
|
||||
* associated scancode to be interpreted as this keysym.
|
||||
*
|
||||
* If the associated keysym is pressed, and any of these modifiers are not
|
||||
* currently active, Guacamole's RDP support must send additional events to
|
||||
* activate these modifiers prior to sending the scancode for this keysym.
|
||||
*
|
||||
* @see GUAC_RDP_KEYMAP_MODIFIER_SHIFT
|
||||
* @see GUAC_RDP_KEYMAP_MODIFIER_ALTGR
|
||||
*/
|
||||
const int* set_keysyms;
|
||||
const unsigned int set_modifiers;
|
||||
|
||||
/**
|
||||
* Null-terminated list of keysyms which must be up for this keysym
|
||||
* to be properly typed.
|
||||
* Bitwise-OR of the flags of any modifiers that must NOT be active for the
|
||||
* associated scancode to be interpreted as this keysym.
|
||||
*
|
||||
* If the associated keysym is pressed, and any of these modifiers are
|
||||
* currently active, Guacamole's RDP support must send additional events to
|
||||
* deactivate these modifiers prior to sending the scancode for this
|
||||
* keysym.
|
||||
*
|
||||
* @see GUAC_RDP_KEYMAP_MODIFIER_SHIFT
|
||||
* @see GUAC_RDP_KEYMAP_MODIFIER_ALTGR
|
||||
*/
|
||||
const int* clear_keysyms;
|
||||
const unsigned int clear_modifiers;
|
||||
|
||||
/**
|
||||
* Bitwise OR of the flags of all lock keys (ie: Caps lock, Num lock, etc.)
|
||||
* which must be active for this keysym to be properly typed. Legal flags
|
||||
* are KBD_SYNC_SCROLL_LOCK, KBD_SYNC_NUM_LOCK, KBD_SYNC_CAPS_LOCK, and
|
||||
* KBD_SYNC_KANA_LOCK.
|
||||
*/
|
||||
int set_locks;
|
||||
*/
|
||||
const unsigned int set_locks;
|
||||
|
||||
/**
|
||||
* Bitwise OR of the flags of all lock keys (ie: Caps lock, Num lock, etc.)
|
||||
@ -69,7 +94,7 @@ typedef struct guac_rdp_keysym_desc {
|
||||
* are KBD_SYNC_SCROLL_LOCK, KBD_SYNC_NUM_LOCK, KBD_SYNC_CAPS_LOCK, and
|
||||
* KBD_SYNC_KANA_LOCK.
|
||||
*/
|
||||
int clear_locks;
|
||||
const unsigned int clear_locks;
|
||||
|
||||
} guac_rdp_keysym_desc;
|
||||
|
||||
@ -110,63 +135,6 @@ struct guac_rdp_keymap {
|
||||
*/
|
||||
#define GUAC_DEFAULT_KEYMAP "en-us-qwerty"
|
||||
|
||||
/**
|
||||
* Keysym string containing only the left "shift" key.
|
||||
*/
|
||||
extern const int GUAC_KEYSYMS_SHIFT[];
|
||||
|
||||
/**
|
||||
* Keysym string containing both "shift" keys.
|
||||
*/
|
||||
extern const int GUAC_KEYSYMS_ALL_SHIFT[];
|
||||
|
||||
/**
|
||||
* Keysym string containing only the right "alt" key (AltGr).
|
||||
*/
|
||||
extern const int GUAC_KEYSYMS_ALTGR[];
|
||||
|
||||
/**
|
||||
* Keysym string containing the right "alt" key (AltGr) and
|
||||
* left shift.
|
||||
*/
|
||||
extern const int GUAC_KEYSYMS_SHIFT_ALTGR[];
|
||||
|
||||
/**
|
||||
* Keysym string containing the right "alt" key (AltGr) and
|
||||
* both shift keys.
|
||||
*/
|
||||
extern const int GUAC_KEYSYMS_ALL_SHIFT_ALTGR[];
|
||||
|
||||
/**
|
||||
* Keysym string containing only the left "ctrl" key.
|
||||
*/
|
||||
extern const int GUAC_KEYSYMS_CTRL[];
|
||||
|
||||
/**
|
||||
* Keysym string containing both "ctrl" keys.
|
||||
*/
|
||||
extern const int GUAC_KEYSYMS_ALL_CTRL[];
|
||||
|
||||
/**
|
||||
* Keysym string containing only the left "alt" key.
|
||||
*/
|
||||
extern const int GUAC_KEYSYMS_ALT[];
|
||||
|
||||
/**
|
||||
* Keysym string containing both "alt" keys.
|
||||
*/
|
||||
extern const int GUAC_KEYSYMS_ALL_ALT[];
|
||||
|
||||
/**
|
||||
* Keysym string containing the left "alt" and left "ctrl" keys
|
||||
*/
|
||||
extern const int GUAC_KEYSYMS_CTRL_ALT[];
|
||||
|
||||
/**
|
||||
* Keysym string containing all modifier keys.
|
||||
*/
|
||||
extern const int GUAC_KEYSYMS_ALL_MODIFIERS[];
|
||||
|
||||
/**
|
||||
* NULL-terminated array of all keymaps.
|
||||
*/
|
||||
|
@ -25,15 +25,25 @@ freerdp "KBD_DANISH"
|
||||
# Basic keys
|
||||
#
|
||||
|
||||
map -altgr -shift 0x29 0x02..0x0C ~ "§1234567890+"
|
||||
map -altgr -shift 0x10..0x1A ~ "qwertyuiopå"
|
||||
map -altgr -shift 0x1E..0x28 0x2B ~ "asdfghjklæø'"
|
||||
map -altgr -shift 0x56 0x2C..0x35 ~ "<zxcvbnm,.-"
|
||||
map -caps -altgr -shift 0x29 0x02..0x0C ~ "§1234567890+"
|
||||
map -caps -altgr -shift 0x10..0x1A ~ "qwertyuiopå"
|
||||
map -caps -altgr -shift 0x1E..0x28 0x2B ~ "asdfghjklæø'"
|
||||
map -caps -altgr -shift 0x56 0x2C..0x35 ~ "<zxcvbnm,.-"
|
||||
|
||||
map -altgr +shift 0x29 0x02..0x0C ~ "½!"#¤%&/()=?"
|
||||
map -altgr +shift 0x10..0x1A ~ "QWERTYUIOPÅ"
|
||||
map -altgr +shift 0x1E..0x28 0x2B ~ "ASDFGHJKLÆØ*"
|
||||
map -altgr +shift 0x56 0x2C..0x35 ~ ">ZXCVBNM;:_"
|
||||
map -caps -altgr +shift 0x29 0x02..0x0C ~ "½!"#¤%&/()=?"
|
||||
map -caps -altgr +shift 0x10..0x1A ~ "QWERTYUIOPÅ"
|
||||
map -caps -altgr +shift 0x1E..0x28 0x2B ~ "ASDFGHJKLÆØ*"
|
||||
map -caps -altgr +shift 0x56 0x2C..0x35 ~ ">ZXCVBNM;:_"
|
||||
|
||||
map +caps -altgr -shift 0x29 0x02..0x0C ~ "§1234567890+"
|
||||
map +caps -altgr -shift 0x10..0x1A ~ "QWERTYUIOPÅ"
|
||||
map +caps -altgr -shift 0x1E..0x28 0x2B ~ "ASDFGHJKLÆØ'"
|
||||
map +caps -altgr -shift 0x56 0x2C..0x35 ~ "<ZXCVBNM,.-"
|
||||
|
||||
map +caps -altgr +shift 0x29 0x02..0x0C ~ "½!"#¤%&/()=?"
|
||||
map +caps -altgr +shift 0x10..0x1A ~ "qwertyuiopå"
|
||||
map +caps -altgr +shift 0x1E..0x28 0x2B ~ "asdfghjklæø*"
|
||||
map +caps -altgr +shift 0x56 0x2C..0x35 ~ ">zxcvbnm;:_"
|
||||
|
||||
#
|
||||
# Keys requiring AltGr
|
||||
|
@ -25,15 +25,25 @@ freerdp "KBD_SWISS_GERMAN"
|
||||
# Basic keys
|
||||
#
|
||||
|
||||
map -altgr -shift 0x29 0x02..0x0C ~ "§1234567890'"
|
||||
map -altgr -shift 0x10..0x1A ~ "qwertzuiopü"
|
||||
map -altgr -shift 0x1E..0x28 0x2B ~ "asdfghjklöä$"
|
||||
map -altgr -shift 0x56 0x2C..0x35 ~ "<yxcvbnm,.-"
|
||||
map -caps -altgr -shift 0x29 0x02..0x0C ~ "§1234567890'"
|
||||
map -caps -altgr -shift 0x10..0x1A ~ "qwertzuiopü"
|
||||
map -caps -altgr -shift 0x1E..0x28 0x2B ~ "asdfghjklöä$"
|
||||
map -caps -altgr -shift 0x56 0x2C..0x35 ~ "<yxcvbnm,.-"
|
||||
|
||||
map -altgr +shift 0x29 0x02..0x0C ~ "°+"*ç%&/()=?"
|
||||
map -altgr +shift 0x10..0x1B ~ "QWERTZUIOPè!"
|
||||
map -altgr +shift 0x1E..0x28 0x2B ~ "ASDFGHJKLéà£"
|
||||
map -altgr +shift 0x56 0x2C..0x35 ~ ">YXCVBNM;:_"
|
||||
map -caps -altgr +shift 0x29 0x02..0x0C ~ "°+"*ç%&/()=?"
|
||||
map -caps -altgr +shift 0x10..0x1B ~ "QWERTZUIOPè!"
|
||||
map -caps -altgr +shift 0x1E..0x28 0x2B ~ "ASDFGHJKLéà£"
|
||||
map -caps -altgr +shift 0x56 0x2C..0x35 ~ ">YXCVBNM;:_"
|
||||
|
||||
map +caps -altgr -shift 0x29 0x02..0x0C ~ "§1234567890'"
|
||||
map +caps -altgr -shift 0x10..0x1A ~ "QWERTZUIOPÜ"
|
||||
map +caps -altgr -shift 0x1E..0x28 0x2B ~ "ASDFGHJKLÖÄ$"
|
||||
map +caps -altgr -shift 0x56 0x2C..0x35 ~ "<YXCVBNM,.-"
|
||||
|
||||
map +caps -altgr +shift 0x29 0x02..0x0C ~ "°+"*ç%&/()=?"
|
||||
map +caps -altgr +shift 0x10..0x1B ~ "qwertzuiopÈ!"
|
||||
map +caps -altgr +shift 0x1E..0x28 0x2B ~ "asdfghjklÉÀ£"
|
||||
map +caps -altgr +shift 0x56 0x2C..0x35 ~ ">yxcvbnm;:_"
|
||||
|
||||
#
|
||||
# Keys requiring AltGr
|
||||
@ -55,4 +65,4 @@ map +altgr -shift 0x0C ~ 0xFE51 # Dead acute
|
||||
map -altgr -shift 0x0D ~ 0xFE52 # Dead circumflex
|
||||
map -altgr +shift 0x0D ~ 0xFE50 # Dead grave
|
||||
map +altgr -shift 0x0D ~ 0xFE53 # Dead tilde
|
||||
map -altgr -shift 0x1B ~ 0xFE57 # Dead umlaut
|
||||
map -altgr -shift 0x1B ~ 0xFE57 # Dead umlaut
|
||||
|
@ -25,15 +25,25 @@ freerdp "KBD_GERMAN"
|
||||
# Basic keys
|
||||
#
|
||||
|
||||
map -altgr -shift 0x02..0x0C ~ "1234567890ß"
|
||||
map -altgr -shift 0x10..0x1B ~ "qwertzuiopü+"
|
||||
map -altgr -shift 0x1E..0x28 0x2B ~ "asdfghjklöä#"
|
||||
map -altgr -shift 0x56 0x2C..0x35 ~ "<yxcvbnm,.-"
|
||||
map -caps -altgr -shift 0x02..0x0C ~ "1234567890ß"
|
||||
map -caps -altgr -shift 0x10..0x1B ~ "qwertzuiopü+"
|
||||
map -caps -altgr -shift 0x1E..0x28 0x2B ~ "asdfghjklöä#"
|
||||
map -caps -altgr -shift 0x56 0x2C..0x35 ~ "<yxcvbnm,.-"
|
||||
|
||||
map -altgr +shift 0x29 0x02..0x0C ~ "°!"§$%&/()=?"
|
||||
map -altgr +shift 0x10..0x1B ~ "QWERTZUIOPÜ*"
|
||||
map -altgr +shift 0x1E..0x28 0x2B ~ "ASDFGHJKLÖÄ'"
|
||||
map -altgr +shift 0x56 0x2C..0x35 ~ ">YXCVBNM;:_"
|
||||
map -caps -altgr +shift 0x29 0x02..0x0C ~ "°!"§$%&/()=?"
|
||||
map -caps -altgr +shift 0x10..0x1B ~ "QWERTZUIOPÜ*"
|
||||
map -caps -altgr +shift 0x1E..0x28 0x2B ~ "ASDFGHJKLÖÄ'"
|
||||
map -caps -altgr +shift 0x56 0x2C..0x35 ~ ">YXCVBNM;:_"
|
||||
|
||||
map +caps -altgr -shift 0x02..0x0C ~ "!"§$%&/()=?"
|
||||
map +caps -altgr -shift 0x10..0x1B ~ "QWERTZUIOPÜ*"
|
||||
map +caps -altgr -shift 0x1E..0x28 0x2B ~ "ASDFGHJKLÖÄ'"
|
||||
map +caps -altgr -shift 0x56 0x2C..0x35 ~ "<YXCVBNM;:-"
|
||||
|
||||
map +caps -altgr +shift 0x29 0x02..0x0C ~ "°1234567890ß"
|
||||
map +caps -altgr +shift 0x10..0x1B ~ "qwertzuiopü+"
|
||||
map +caps -altgr +shift 0x1E..0x28 0x2B ~ "asdfghjklöä#"
|
||||
map +caps -altgr +shift 0x56 0x2C..0x35 ~ ">yxcvbnm,._"
|
||||
|
||||
#
|
||||
# Keys requiring AltGr
|
||||
|
@ -25,32 +25,56 @@ freerdp "KBD_UNITED_KINGDOM"
|
||||
# Basic keys
|
||||
#
|
||||
|
||||
map -altgr -shift 0x29 0x02..0x0D ~ "`1234567890-="
|
||||
map -altgr -shift 0x10..0x1B ~ "qwertyuiop[]"
|
||||
map -altgr -shift 0x1E..0x28 0x2B ~ "asdfghjkl;'#"
|
||||
map -altgr -shift 0x56 0x2C..0x35 ~ "\zxcvbnm,./"
|
||||
map -caps -altgr -shift 0x29 0x02..0x0D ~ "`1234567890-="
|
||||
map -caps -altgr -shift 0x10..0x1B ~ "qwertyuiop[]"
|
||||
map -caps -altgr -shift 0x1E..0x28 0x2B ~ "asdfghjkl;'#"
|
||||
map -caps -altgr -shift 0x56 0x2C..0x35 ~ "\zxcvbnm,./"
|
||||
|
||||
map -altgr +shift 0x29 0x02..0x0D ~ "¬!"£$%^&*()_+"
|
||||
map -altgr +shift 0x10..0x1B ~ "QWERTYUIOP{}"
|
||||
map -altgr +shift 0x1E..0x28 0x2B ~ "ASDFGHJKL:@~"
|
||||
map -altgr +shift 0x56 0x2C..0x35 ~ "|ZXCVBNM<>?"
|
||||
map -caps -altgr +shift 0x29 0x02..0x0D ~ "¬!"£$%^&*()_+"
|
||||
map -caps -altgr +shift 0x10..0x1B ~ "QWERTYUIOP{}"
|
||||
map -caps -altgr +shift 0x1E..0x28 0x2B ~ "ASDFGHJKL:@~"
|
||||
map -caps -altgr +shift 0x56 0x2C..0x35 ~ "|ZXCVBNM<>?"
|
||||
|
||||
map +caps -altgr -shift 0x29 0x02..0x0D ~ "`1234567890-="
|
||||
map +caps -altgr -shift 0x10..0x1B ~ "QWERTYUIOP[]"
|
||||
map +caps -altgr -shift 0x1E..0x28 0x2B ~ "ASDFGHJKL;'#"
|
||||
map +caps -altgr -shift 0x56 0x2C..0x35 ~ "\ZXCVBNM,./"
|
||||
|
||||
map +caps -altgr +shift 0x29 0x02..0x0D ~ "¬!"£$%^&*()_+"
|
||||
map +caps -altgr +shift 0x10..0x1B ~ "qwertyuiop{}"
|
||||
map +caps -altgr +shift 0x1E..0x28 0x2B ~ "asdfghjkl:@~"
|
||||
map +caps -altgr +shift 0x56 0x2C..0x35 ~ "|zxcvbnm<>?"
|
||||
|
||||
#
|
||||
# Keys requiring AltGr
|
||||
# Keys requiring AltGr (some of which are affected by Caps Lock)
|
||||
#
|
||||
|
||||
map +altgr -shift 0x29 ~ "¦"
|
||||
map +altgr -shift 0x05 ~ "€"
|
||||
map +altgr -shift 0x12 ~ "é"
|
||||
map +altgr +shift 0x12 ~ "É"
|
||||
map +altgr -shift 0x16 ~ "ú"
|
||||
map +altgr +shift 0x16 ~ "Ú"
|
||||
map +altgr -shift 0x17 ~ "í"
|
||||
map +altgr +shift 0x17 ~ "Í"
|
||||
map +altgr -shift 0x18 ~ "ó"
|
||||
map +altgr +shift 0x18 ~ "Ó"
|
||||
map +altgr -shift 0x1E ~ "á"
|
||||
map +altgr +shift 0x1E ~ "Á"
|
||||
map +altgr -shift 0x2E ~ "ç"
|
||||
map +altgr +shift 0x2E ~ "Ç"
|
||||
|
||||
map -caps +altgr -shift 0x12 ~ "é"
|
||||
map -caps +altgr +shift 0x12 ~ "É"
|
||||
map -caps +altgr -shift 0x16 ~ "ú"
|
||||
map -caps +altgr +shift 0x16 ~ "Ú"
|
||||
map -caps +altgr -shift 0x17 ~ "í"
|
||||
map -caps +altgr +shift 0x17 ~ "Í"
|
||||
map -caps +altgr -shift 0x18 ~ "ó"
|
||||
map -caps +altgr +shift 0x18 ~ "Ó"
|
||||
map -caps +altgr -shift 0x1E ~ "á"
|
||||
map -caps +altgr +shift 0x1E ~ "Á"
|
||||
map -caps +altgr -shift 0x2E ~ "ç"
|
||||
map -caps +altgr +shift 0x2E ~ "Ç"
|
||||
|
||||
map +caps +altgr +shift 0x12 ~ "é"
|
||||
map +caps +altgr -shift 0x12 ~ "É"
|
||||
map +caps +altgr +shift 0x16 ~ "ú"
|
||||
map +caps +altgr -shift 0x16 ~ "Ú"
|
||||
map +caps +altgr +shift 0x17 ~ "í"
|
||||
map +caps +altgr -shift 0x17 ~ "Í"
|
||||
map +caps +altgr +shift 0x18 ~ "ó"
|
||||
map +caps +altgr -shift 0x18 ~ "Ó"
|
||||
map +caps +altgr +shift 0x1E ~ "á"
|
||||
map +caps +altgr -shift 0x1E ~ "Á"
|
||||
map +caps +altgr +shift 0x2E ~ "ç"
|
||||
map +caps +altgr -shift 0x2E ~ "Ç"
|
||||
|
||||
|
@ -21,13 +21,23 @@ parent "base"
|
||||
name "en-us-qwerty"
|
||||
freerdp "KBD_US"
|
||||
|
||||
map -shift 0x29 0x02..0x0D ~ "`1234567890-="
|
||||
map -shift 0x10..0x1B 0x2B ~ "qwertyuiop[]\"
|
||||
map -shift 0x1E..0x28 ~ "asdfghjkl;'"
|
||||
map -shift 0x2C..0x35 ~ "zxcvbnm,./"
|
||||
map -caps -shift 0x29 0x02..0x0D ~ "`1234567890-="
|
||||
map -caps -shift 0x10..0x1B 0x2B ~ "qwertyuiop[]\"
|
||||
map -caps -shift 0x1E..0x28 ~ "asdfghjkl;'"
|
||||
map -caps -shift 0x2C..0x35 ~ "zxcvbnm,./"
|
||||
|
||||
map +shift 0x29 0x02..0x0D ~ "~!@#$%^&*()_+"
|
||||
map +shift 0x10..0x1B 0x2B ~ "QWERTYUIOP{}|"
|
||||
map +shift 0x1E..0x28 ~ "ASDFGHJKL:""
|
||||
map +shift 0x2C..0x35 ~ "ZXCVBNM<>?"
|
||||
map -caps +shift 0x29 0x02..0x0D ~ "~!@#$%^&*()_+"
|
||||
map -caps +shift 0x10..0x1B 0x2B ~ "QWERTYUIOP{}|"
|
||||
map -caps +shift 0x1E..0x28 ~ "ASDFGHJKL:""
|
||||
map -caps +shift 0x2C..0x35 ~ "ZXCVBNM<>?"
|
||||
|
||||
map +caps -shift 0x29 0x02..0x0D ~ "`1234567890-="
|
||||
map +caps -shift 0x10..0x1B 0x2B ~ "QWERTYUIOP[]\"
|
||||
map +caps -shift 0x1E..0x28 ~ "ASDFGHJKL;'"
|
||||
map +caps -shift 0x2C..0x35 ~ "ZXCVBNM,./"
|
||||
|
||||
map +caps +shift 0x29 0x02..0x0D ~ "~!@#$%^&*()_+"
|
||||
map +caps +shift 0x10..0x1B 0x2B ~ "qwertyuiop{}|"
|
||||
map +caps +shift 0x1E..0x28 ~ "asdfghjkl:""
|
||||
map +caps +shift 0x2C..0x35 ~ "zxcvbnm<>?"
|
||||
|
||||
|
@ -25,15 +25,25 @@ freerdp "KBD_SPANISH"
|
||||
# Basic keys
|
||||
#
|
||||
|
||||
map -altgr -shift 0x29 0x02..0x0D ~ "º1234567890'¡"
|
||||
map -altgr -shift 0x10..0x19 0x1B ~ "qwertyuiop+"
|
||||
map -altgr -shift 0x1E..0x27 0x2B ~ "asdfghjklñç"
|
||||
map -altgr -shift 0x56 0x2C..0x35 ~ "<zxcvbnm,.-"
|
||||
map -caps -altgr -shift 0x29 0x02..0x0D ~ "º1234567890'¡"
|
||||
map -caps -altgr -shift 0x10..0x19 0x1B ~ "qwertyuiop+"
|
||||
map -caps -altgr -shift 0x1E..0x27 0x2B ~ "asdfghjklñç"
|
||||
map -caps -altgr -shift 0x56 0x2C..0x35 ~ "<zxcvbnm,.-"
|
||||
|
||||
map -altgr +shift 0x29 0x02..0x0D ~ "ª!"·$%&/()=?¿"
|
||||
map -altgr +shift 0x10..0x19 0x1B ~ "QWERTYUIOP*"
|
||||
map -altgr +shift 0x1E..0x27 0x2B ~ "ASDFGHJKLÑÇ"
|
||||
map -altgr +shift 0x56 0x2C..0x35 ~ ">ZXCVBNM;:_"
|
||||
map -caps -altgr +shift 0x29 0x02..0x0D ~ "ª!"·$%&/()=?¿"
|
||||
map -caps -altgr +shift 0x10..0x19 0x1B ~ "QWERTYUIOP*"
|
||||
map -caps -altgr +shift 0x1E..0x27 0x2B ~ "ASDFGHJKLÑÇ"
|
||||
map -caps -altgr +shift 0x56 0x2C..0x35 ~ ">ZXCVBNM;:_"
|
||||
|
||||
map +caps -altgr -shift 0x29 0x02..0x0D ~ "º1234567890'¡"
|
||||
map +caps -altgr -shift 0x10..0x19 0x1B ~ "QWERTYUIOP+"
|
||||
map +caps -altgr -shift 0x1E..0x27 0x2B ~ "ASDFGHJKLÑÇ"
|
||||
map +caps -altgr -shift 0x56 0x2C..0x35 ~ "<ZXCVBNM,.-"
|
||||
|
||||
map +caps -altgr +shift 0x29 0x02..0x0D ~ "ª!"·$%&/()=?¿"
|
||||
map +caps -altgr +shift 0x10..0x19 0x1B ~ "qwertyuiop*"
|
||||
map +caps -altgr +shift 0x1E..0x27 0x2B ~ "asdfghjklñç"
|
||||
map +caps -altgr +shift 0x56 0x2C..0x35 ~ ">zxcvbnm;:_"
|
||||
|
||||
#
|
||||
# Keys requiring AltGr
|
||||
|
@ -25,15 +25,25 @@ freerdp "KBD_LATIN_AMERICAN"
|
||||
# Basic keys
|
||||
#
|
||||
|
||||
map -altgr -shift 0x29 0x02..0x0D ~ "|1234567890'¿"
|
||||
map -altgr -shift 0x10..0x19 0x1B ~ "qwertyuiop+"
|
||||
map -altgr -shift 0x1E..0x28 0x2B ~ "asdfghjklñ{}"
|
||||
map -altgr -shift 0x56 0x2C..0x35 ~ "<zxcvbnm,.-"
|
||||
map -caps -altgr -shift 0x29 0x02..0x0D ~ "|1234567890'¿"
|
||||
map -caps -altgr -shift 0x10..0x19 0x1B ~ "qwertyuiop+"
|
||||
map -caps -altgr -shift 0x1E..0x28 0x2B ~ "asdfghjklñ{}"
|
||||
map -caps -altgr -shift 0x56 0x2C..0x35 ~ "<zxcvbnm,.-"
|
||||
|
||||
map -altgr +shift 0x29 0x02..0x0D ~ "º!"#$%&/()=?¡"
|
||||
map -altgr +shift 0x10..0x19 0x1B ~ "QWERTYUIOP*"
|
||||
map -altgr +shift 0x1E..0x28 0x2B ~ "ASDFGHJKLÑ[]"
|
||||
map -altgr +shift 0x56 0x2C..0x35 ~ ">ZXCVBNM;:_"
|
||||
map -caps -altgr +shift 0x29 0x02..0x0D ~ "º!"#$%&/()=?¡"
|
||||
map -caps -altgr +shift 0x10..0x19 0x1B ~ "QWERTYUIOP*"
|
||||
map -caps -altgr +shift 0x1E..0x28 0x2B ~ "ASDFGHJKLÑ[]"
|
||||
map -caps -altgr +shift 0x56 0x2C..0x35 ~ ">ZXCVBNM;:_"
|
||||
|
||||
map +caps -altgr -shift 0x29 0x02..0x0D ~ "|1234567890'¿"
|
||||
map +caps -altgr -shift 0x10..0x19 0x1B ~ "QWERTYUIOP+"
|
||||
map +caps -altgr -shift 0x1E..0x28 0x2B ~ "ASDFGHJKLÑ{}"
|
||||
map +caps -altgr -shift 0x56 0x2C..0x35 ~ "<ZXCVBNM,.-"
|
||||
|
||||
map +caps -altgr +shift 0x29 0x02..0x0D ~ "º!"#$%&/()=?¡"
|
||||
map +caps -altgr +shift 0x10..0x19 0x1B ~ "qwertyuiop*"
|
||||
map +caps -altgr +shift 0x1E..0x28 0x2B ~ "asdfghjklñ[]"
|
||||
map +caps -altgr +shift 0x56 0x2C..0x35 ~ ">zxcvbnm;:_"
|
||||
|
||||
#
|
||||
# Keys requiring AltGr
|
||||
|
@ -25,18 +25,28 @@ freerdp "KBD_BELGIAN_FRENCH"
|
||||
# Basic keys
|
||||
#
|
||||
|
||||
map -altgr -shift 0x29 0x02..0x0D ~ "²&é"'(§è!çà)_"
|
||||
map -altgr -shift 0x10..0x19 0x1B ~ "azertyuiop$"
|
||||
map -altgr -shift 0x1E..0x28 0x2B ~ "qsdfghjklmùµ"
|
||||
map -altgr -shift 0x56 0x2C..0x35 ~ "<wxcvbn,;:="
|
||||
map -caps -altgr -shift 0x29 0x02..0x0D ~ "²&é"'(§è!çà)_"
|
||||
map -caps -altgr -shift 0x10..0x19 0x1B ~ "azertyuiop$"
|
||||
map -caps -altgr -shift 0x1E..0x28 0x2B ~ "qsdfghjklmùµ"
|
||||
map -caps -altgr -shift 0x56 0x2C..0x35 ~ "<wxcvbn,;:="
|
||||
|
||||
map -altgr +shift 0x29 0x02..0x0D ~ "³1234567890°-"
|
||||
map -altgr +shift 0x10..0x19 0x1B ~ "AZERTYUIOP£"
|
||||
map -altgr +shift 0x1E..0x28 0x2B ~ "QSDFGHJKLM%£"
|
||||
map -altgr +shift 0x56 0x2C..0x35 ~ ">WXCVBN?./+"
|
||||
map -caps -altgr +shift 0x29 0x02..0x0D ~ "³1234567890°-"
|
||||
map -caps -altgr +shift 0x10..0x19 0x1B ~ "AZERTYUIOP£"
|
||||
map -caps -altgr +shift 0x1E..0x28 0x2B ~ "QSDFGHJKLM%£"
|
||||
map -caps -altgr +shift 0x56 0x2C..0x35 ~ ">WXCVBN?./+"
|
||||
|
||||
map +caps -altgr -shift 0x29 0x02..0x0D ~ "²1234567890°-"
|
||||
map +caps -altgr -shift 0x10..0x19 0x1B ~ "AZERTYUIOP£"
|
||||
map +caps -altgr -shift 0x1E..0x28 0x2B ~ "QSDFGHJKLM%£"
|
||||
map +caps -altgr -shift 0x56 0x2C..0x35 ~ "<WXCVBN?./+"
|
||||
|
||||
map +caps -altgr +shift 0x29 0x02..0x0D ~ "³&é"'(§è!çà)_"
|
||||
map +caps -altgr +shift 0x10..0x19 0x1B ~ "azertyuiop$"
|
||||
map +caps -altgr +shift 0x1E..0x28 0x2B ~ "qsdfghjklmùµ"
|
||||
map +caps -altgr +shift 0x56 0x2C..0x35 ~ ">wxcvbn,;:="
|
||||
|
||||
#
|
||||
# Keys requiring AltGr
|
||||
# Keys requiring AltGr (unaffected by Caps Lock, but Shift must not be pressed)
|
||||
#
|
||||
|
||||
map +altgr -shift 0x02..0x04 ~ "|@#"
|
||||
@ -48,11 +58,20 @@ map +altgr -shift 0x56 ~ "\"
|
||||
map +altgr -shift 0x07 ~ "^"
|
||||
|
||||
#
|
||||
# Dead keys
|
||||
# Dead keys requiring AltGr (unaffected by Caps Lock or Shift)
|
||||
#
|
||||
|
||||
map -altgr -shift 0x1A ~ 0xFE52 # Dead circumflex
|
||||
map -altgr +shift 0x1A ~ 0xFE57 # Dead umlaut
|
||||
map +altgr -shift 0x35 ~ 0xFE53 # Dead tilde
|
||||
map +altgr -shift 0x28 ~ 0xFE51 # Dead acute
|
||||
map +altgr -shift 0x2B ~ 0xFE50 # Dead grave
|
||||
map +altgr 0x35 ~ 0xFE53 # Dead tilde
|
||||
map +altgr 0x28 ~ 0xFE51 # Dead acute
|
||||
map +altgr 0x2B ~ 0xFE50 # Dead grave
|
||||
|
||||
#
|
||||
# Dead keys (affected by Caps Lock and Shift)
|
||||
#
|
||||
|
||||
map -caps -altgr -shift 0x1A ~ 0xFE52 # Dead circumflex
|
||||
map -caps -altgr +shift 0x1A ~ 0xFE57 # Dead umlaut
|
||||
|
||||
map +caps -altgr -shift 0x1A ~ 0xFE57 # Dead umlaut
|
||||
map +caps -altgr +shift 0x1A ~ 0xFE52 # Dead circumflex
|
||||
|
||||
|
@ -25,15 +25,25 @@ freerdp "KBD_SWISS_FRENCH"
|
||||
# Basic keys
|
||||
#
|
||||
|
||||
map -altgr -shift 0x29 0x02..0x0C ~ "§1234567890'"
|
||||
map -altgr -shift 0x10..0x1A ~ "qwertzuiopè"
|
||||
map -altgr -shift 0x1E..0x28 0x2B ~ "asdfghjkléà$"
|
||||
map -altgr -shift 0x56 0x2C..0x35 ~ "<yxcvbnm,.-"
|
||||
map -caps -altgr -shift 0x29 0x02..0x0C ~ "§1234567890'"
|
||||
map -caps -altgr -shift 0x10..0x1A ~ "qwertzuiopè"
|
||||
map -caps -altgr -shift 0x1E..0x28 0x2B ~ "asdfghjkléà$"
|
||||
map -caps -altgr -shift 0x56 0x2C..0x35 ~ "<yxcvbnm,.-"
|
||||
|
||||
map -altgr +shift 0x29 0x02..0x0C ~ "°+"*ç%&/()=?"
|
||||
map -altgr +shift 0x10..0x1B ~ "QWERTZUIOPü!"
|
||||
map -altgr +shift 0x1E..0x28 0x2B ~ "ASDFGHJKLöä£"
|
||||
map -altgr +shift 0x56 0x2C..0x35 ~ ">YXCVBNM;:_"
|
||||
map -caps -altgr +shift 0x29 0x02..0x0C ~ "°+"*ç%&/()=?"
|
||||
map -caps -altgr +shift 0x10..0x1B ~ "QWERTZUIOPü!"
|
||||
map -caps -altgr +shift 0x1E..0x28 0x2B ~ "ASDFGHJKLöä£"
|
||||
map -caps -altgr +shift 0x56 0x2C..0x35 ~ ">YXCVBNM;:_"
|
||||
|
||||
map +caps -altgr -shift 0x29 0x02..0x0C ~ "§1234567890'"
|
||||
map +caps -altgr -shift 0x10..0x1A ~ "QWERTZUIOPè"
|
||||
map +caps -altgr -shift 0x1E..0x28 0x2B ~ "ASDFGHJKLéà$"
|
||||
map +caps -altgr -shift 0x56 0x2C..0x35 ~ "<YXCVBNM,.-"
|
||||
|
||||
map +caps -altgr +shift 0x29 0x02..0x0C ~ "°+"*ç%&/()=?"
|
||||
map +caps -altgr +shift 0x10..0x1B ~ "qwertzuiopü!"
|
||||
map +caps -altgr +shift 0x1E..0x28 0x2B ~ "asdfghjklöä£"
|
||||
map +caps -altgr +shift 0x56 0x2C..0x35 ~ ">yxcvbnm;:_"
|
||||
|
||||
#
|
||||
# Keys requiring AltGr
|
||||
|
@ -25,18 +25,28 @@ freerdp "KBD_FRENCH"
|
||||
# Basic keys
|
||||
#
|
||||
|
||||
map -altgr -shift 0x29 0x02..0x0D ~ "²&é"'(-è_çà)="
|
||||
map -altgr -shift 0x10..0x19 0x1B ~ "azertyuiop$"
|
||||
map -altgr -shift 0x1E..0x28 0x2B ~ "qsdfghjklmù*"
|
||||
map -altgr -shift 0x56 0x2C..0x35 ~ "<wxcvbn,;:!"
|
||||
map -caps -altgr -shift 0x29 0x02..0x0D ~ "²&é"'(-è_çà)="
|
||||
map -caps -altgr -shift 0x10..0x19 0x1B ~ "azertyuiop$"
|
||||
map -caps -altgr -shift 0x1E..0x28 0x2B ~ "qsdfghjklmù*"
|
||||
map -caps -altgr -shift 0x56 0x2C..0x35 ~ "<wxcvbn,;:!"
|
||||
|
||||
map -altgr +shift 0x02..0x0D ~ "1234567890°+"
|
||||
map -altgr +shift 0x10..0x19 0x1B ~ "AZERTYUIOP£"
|
||||
map -altgr +shift 0x1E..0x28 0x2B ~ "QSDFGHJKLM%µ"
|
||||
map -altgr +shift 0x56 0x2C..0x35 ~ ">WXCVBN?./§"
|
||||
map -caps -altgr +shift 0x02..0x0D ~ "1234567890°+"
|
||||
map -caps -altgr +shift 0x10..0x19 0x1B ~ "AZERTYUIOP£"
|
||||
map -caps -altgr +shift 0x1E..0x28 0x2B ~ "QSDFGHJKLM%µ"
|
||||
map -caps -altgr +shift 0x56 0x2C..0x35 ~ ">WXCVBN?./§"
|
||||
|
||||
map +caps -altgr -shift 0x29 0x02..0x0D ~ "²1234567890°+"
|
||||
map +caps -altgr -shift 0x10..0x19 0x1B ~ "AZERTYUIOP£"
|
||||
map +caps -altgr -shift 0x1E..0x28 0x2B ~ "QSDFGHJKLM%µ"
|
||||
map +caps -altgr -shift 0x56 0x2C..0x35 ~ "<WXCVBN?./§"
|
||||
|
||||
map +caps -altgr +shift 0x02..0x0D ~ "&é"'(-è_çà)="
|
||||
map +caps -altgr +shift 0x10..0x19 0x1B ~ "azertyuiop$"
|
||||
map +caps -altgr +shift 0x1E..0x28 0x2B ~ "qsdfghjklmù*"
|
||||
map +caps -altgr +shift 0x56 0x2C..0x35 ~ ">wxcvbn,;:!"
|
||||
|
||||
#
|
||||
# Keys requiring AltGr
|
||||
# Keys requiring AltGr (unaffected by Caps Lock, but Shift must not be pressed)
|
||||
#
|
||||
|
||||
map +altgr -shift 0x03..0x0D ~ "~#{[|`\^@]}"
|
||||
@ -45,9 +55,12 @@ map +altgr -shift 0x12 ~ "€"
|
||||
map +altgr -shift 0x1B ~ "¤"
|
||||
|
||||
#
|
||||
# Dead keys
|
||||
# Dead keys (affected by Caps Lock and Shift)
|
||||
#
|
||||
|
||||
map -altgr -shift 0x1A ~ 0xFE52 # Dead circumflex
|
||||
map -altgr +shift 0x1A ~ 0xFE57 # Dead umlaut
|
||||
map -caps -altgr -shift 0x1A ~ 0xFE52 # Dead circumflex
|
||||
map -caps -altgr +shift 0x1A ~ 0xFE57 # Dead umlaut
|
||||
|
||||
map +caps -altgr -shift 0x1A ~ 0xFE57 # Dead umlaut
|
||||
map +caps -altgr +shift 0x1A ~ 0xFE52 # Dead circumflex
|
||||
|
||||
|
@ -92,10 +92,12 @@ for my $filename (@ARGV) {
|
||||
my $ext_flags = 0;
|
||||
my $set_shift = 0;
|
||||
my $set_altgr = 0;
|
||||
my $set_caps = 0;
|
||||
my $set_num = 0;
|
||||
|
||||
my $clear_shift = 0;
|
||||
my $clear_altgr = 0;
|
||||
my $clear_caps = 0;
|
||||
my $clear_num = 0;
|
||||
|
||||
# Parse ranges and options
|
||||
@ -105,6 +107,7 @@ for my $filename (@ARGV) {
|
||||
if ((my $opt) = m/^\+([a-z]+)$/) {
|
||||
if ($opt eq "shift") { $set_shift = 1; }
|
||||
elsif ($opt eq "altgr") { $set_altgr = 1; }
|
||||
elsif ($opt eq "caps") { $set_caps = 1; }
|
||||
elsif ($opt eq "num") { $set_num = 1; }
|
||||
elsif ($opt eq "ext") { $ext_flags = 1; }
|
||||
else {
|
||||
@ -117,6 +120,7 @@ for my $filename (@ARGV) {
|
||||
elsif ((my $opt) = m/^-([a-z]+)$/) {
|
||||
if ($opt eq "shift") { $clear_shift = 1; }
|
||||
elsif ($opt eq "altgr") { $clear_altgr = 1; }
|
||||
elsif ($opt eq "caps") { $clear_caps = 1; }
|
||||
elsif ($opt eq "num") { $clear_num = 1; }
|
||||
else {
|
||||
die "$filename: $.: ERROR: "
|
||||
@ -175,37 +179,25 @@ for my $filename (@ARGV) {
|
||||
. " .keysym = " . $keysyms[$i] . ","
|
||||
. " .scancode = " . $scancodes[$i];
|
||||
|
||||
# Set requirements
|
||||
if ($set_shift && !$set_altgr) {
|
||||
$content .= ", .set_keysyms = GUAC_KEYSYMS_SHIFT";
|
||||
}
|
||||
elsif (!$set_shift && $set_altgr) {
|
||||
$content .= ", .set_keysyms = GUAC_KEYSYMS_ALTGR";
|
||||
}
|
||||
elsif ($set_shift && $set_altgr) {
|
||||
$content .= ", .set_keysyms = GUAC_KEYSYMS_SHIFT_ALTGR";
|
||||
}
|
||||
# Modifiers that must be active
|
||||
$content .= ", .set_modifiers = 0";
|
||||
$content .= " | GUAC_RDP_KEYMAP_MODIFIER_SHIFT" if $set_shift;
|
||||
$content .= " | GUAC_RDP_KEYMAP_MODIFIER_ALTGR" if $set_altgr;
|
||||
|
||||
# Clear requirements
|
||||
if ($clear_shift && !$clear_altgr) {
|
||||
$content .= ", .clear_keysyms = GUAC_KEYSYMS_ALL_SHIFT";
|
||||
}
|
||||
elsif (!$clear_shift && $clear_altgr) {
|
||||
$content .= ", .clear_keysyms = GUAC_KEYSYMS_ALTGR";
|
||||
}
|
||||
elsif ($clear_shift && $clear_altgr) {
|
||||
$content .= ", .clear_keysyms = GUAC_KEYSYMS_ALL_SHIFT_ALTGR";
|
||||
}
|
||||
# Modifiers that must be inactive
|
||||
$content .= ", .clear_modifiers = 0";
|
||||
$content .= " | GUAC_RDP_KEYMAP_MODIFIER_SHIFT" if $clear_shift;
|
||||
$content .= " | GUAC_RDP_KEYMAP_MODIFIER_ALTGR" if $clear_altgr;
|
||||
|
||||
# Set locks
|
||||
if ($set_num) {
|
||||
$content .= ", .set_locks = KBD_SYNC_NUM_LOCK";
|
||||
}
|
||||
# Locks that must be set
|
||||
$content .= ", .set_locks = 0";
|
||||
$content .= " | KBD_SYNC_NUM_LOCK" if $set_num;
|
||||
$content .= " | KBD_SYNC_CAPS_LOCK" if $set_caps;
|
||||
|
||||
# Clear locks
|
||||
if ($clear_num) {
|
||||
$content .= ", .clear_locks = KBD_SYNC_NUM_LOCK";
|
||||
}
|
||||
# Locks that must NOT be set
|
||||
$content .= ", .clear_locks = 0";
|
||||
$content .= " | KBD_SYNC_NUM_LOCK" if $clear_num;
|
||||
$content .= " | KBD_SYNC_CAPS_LOCK" if $clear_caps;
|
||||
|
||||
# Flags
|
||||
if ($ext_flags) {
|
||||
|
@ -25,16 +25,25 @@ freerdp "KBD_HUNGARIAN"
|
||||
# Basic keys
|
||||
#
|
||||
|
||||
map -altgr -shift 0x29 0x02..0x0D ~ "0123456789öüó"
|
||||
map -altgr -shift 0x10..0x1B ~ "qwertzuıopőú"
|
||||
map -altgr -shift 0x1E..0x28 0x2B ~ "asdfghjkléáű"
|
||||
map -altgr -shift 0x56 0x2C..0x35 ~ "íyxcvbnm,.-"
|
||||
map -caps -altgr -shift 0x29 0x02..0x0D ~ "0123456789öüó"
|
||||
map -caps -altgr -shift 0x10..0x1B ~ "qwertzuıopőú"
|
||||
map -caps -altgr -shift 0x1E..0x28 0x2B ~ "asdfghjkléáű"
|
||||
map -caps -altgr -shift 0x56 0x2C..0x35 ~ "íyxcvbnm,.-"
|
||||
|
||||
map -altgr +shift 0x29 0x02..0x0D ~ "§'"+!%/=()ÖÜÓ"
|
||||
map -altgr +shift 0x10..0x1B ~ "QWERTZUIOPŐÚ"
|
||||
map -altgr +shift 0x1E..0x28 0x2B ~ "ASDFGHJKLÉÁŰ"
|
||||
map -altgr +shift 0x56 0x2C..0x35 ~ "ÍYXCVBNM?:_"
|
||||
map -caps -altgr +shift 0x29 0x02..0x0D ~ "§'"+!%/=()ÖÜÓ"
|
||||
map -caps -altgr +shift 0x10..0x1B ~ "QWERTZUIOPŐÚ"
|
||||
map -caps -altgr +shift 0x1E..0x28 0x2B ~ "ASDFGHJKLÉÁŰ"
|
||||
map -caps -altgr +shift 0x56 0x2C..0x35 ~ "ÍYXCVBNM?:_"
|
||||
|
||||
map +caps -altgr -shift 0x29 0x02..0x0D ~ "0123456789ÖÜÓ"
|
||||
map +caps -altgr -shift 0x10..0x1B ~ "QWERTZUIOPŐÚ"
|
||||
map +caps -altgr -shift 0x1E..0x28 0x2B ~ "ASDFGHJKLÉÁŰ"
|
||||
map +caps -altgr -shift 0x56 0x2C..0x35 ~ "ÍYXCVBNM,.-"
|
||||
|
||||
map +caps -altgr +shift 0x29 0x02..0x0D ~ "§'"+!%/=()öüó"
|
||||
map +caps -altgr +shift 0x10..0x1B ~ "qwertzuiopőú"
|
||||
map +caps -altgr +shift 0x1E..0x28 0x2B ~ "asdfghjkléáű"
|
||||
map +caps -altgr +shift 0x56 0x2C..0x35 ~ "íyxcvbnm?:_"
|
||||
|
||||
#
|
||||
# Keys requiring AltGr
|
||||
|
@ -25,15 +25,25 @@ freerdp "KBD_ITALIAN"
|
||||
# Basic keys
|
||||
#
|
||||
|
||||
map -altgr -shift 0x29 0x02..0x0D ~ "\1234567890'ì"
|
||||
map -altgr -shift 0x10..0x1B ~ "qwertyuiopè+"
|
||||
map -altgr -shift 0x1E..0x28 0x2B ~ "asdfghjklòàù"
|
||||
map -altgr -shift 0x56 0x2C..0x35 ~ "<zxcvbnm,.-"
|
||||
map -caps -altgr -shift 0x29 0x02..0x0D ~ "\1234567890'ì"
|
||||
map -caps -altgr -shift 0x10..0x1B ~ "qwertyuiopè+"
|
||||
map -caps -altgr -shift 0x1E..0x28 0x2B ~ "asdfghjklòàù"
|
||||
map -caps -altgr -shift 0x56 0x2C..0x35 ~ "<zxcvbnm,.-"
|
||||
|
||||
map -altgr +shift 0x29 0x02..0x0D ~ "|!"£$%&/()=?^"
|
||||
map -altgr +shift 0x10..0x1B ~ "QWERTYUIOPé*"
|
||||
map -altgr +shift 0x1E..0x28 0x2B ~ "ASDFGHJKLç°§"
|
||||
map -altgr +shift 0x56 0x2C..0x35 ~ ">ZXCVBNM;:_"
|
||||
map -caps -altgr +shift 0x29 0x02..0x0D ~ "|!"£$%&/()=?^"
|
||||
map -caps -altgr +shift 0x10..0x1B ~ "QWERTYUIOPé*"
|
||||
map -caps -altgr +shift 0x1E..0x28 0x2B ~ "ASDFGHJKLç°§"
|
||||
map -caps -altgr +shift 0x56 0x2C..0x35 ~ ">ZXCVBNM;:_"
|
||||
|
||||
map +caps -altgr -shift 0x29 0x02..0x0D ~ "\1234567890'ì"
|
||||
map +caps -altgr -shift 0x10..0x1B ~ "QWERTYUIOPè+"
|
||||
map +caps -altgr -shift 0x1E..0x28 0x2B ~ "ASDFGHJKLòàù"
|
||||
map +caps -altgr -shift 0x56 0x2C..0x35 ~ "<ZXCVBNM,.-"
|
||||
|
||||
map +caps -altgr +shift 0x29 0x02..0x0D ~ "|!"£$%&/()=?^"
|
||||
map +caps -altgr +shift 0x10..0x1B ~ "qwertyuiopé*"
|
||||
map +caps -altgr +shift 0x1E..0x28 0x2B ~ "asdfghjklç°§"
|
||||
map +caps -altgr +shift 0x56 0x2C..0x35 ~ ">zxcvbnm;:_"
|
||||
|
||||
#
|
||||
# Keys requiring AltGr
|
||||
|
@ -25,15 +25,25 @@ freerdp "KBD_PORTUGUESE_BRAZILIAN_ABNT2"
|
||||
# Basic keys
|
||||
#
|
||||
|
||||
map -altgr -shift 0x29 0x02..0x0D ~ "'1234567890-="
|
||||
map -altgr -shift 0x10..0x19 0x1B ~ "qwertyuiop["
|
||||
map -altgr -shift 0x1E..0x27 0x2B ~ "asdfghjklç]"
|
||||
map -altgr -shift 0x56 0x2C..0x36 ~ "\zxcvbnm,.;/"
|
||||
map -caps -altgr -shift 0x29 0x02..0x0D ~ "'1234567890-="
|
||||
map -caps -altgr -shift 0x10..0x19 0x1B ~ "qwertyuiop["
|
||||
map -caps -altgr -shift 0x1E..0x27 0x2B ~ "asdfghjklç]"
|
||||
map -caps -altgr -shift 0x56 0x2C..0x36 ~ "\zxcvbnm,.;/"
|
||||
|
||||
map -altgr +shift 0x29 0x02..0x06 0x08..0x0D ~ ""!@#$%&*()_+"
|
||||
map -altgr +shift 0x10..0x19 0x1B ~ "QWERTYUIOP{"
|
||||
map -altgr +shift 0x1E..0x27 0x2B ~ "ASDFGHJKLÇ}"
|
||||
map -altgr +shift 0x56 0x2C..0x36 ~ "|ZXCVBNM<>:?"
|
||||
map -caps -altgr +shift 0x29 0x02..0x06 0x08..0x0D ~ ""!@#$%&*()_+"
|
||||
map -caps -altgr +shift 0x10..0x19 0x1B ~ "QWERTYUIOP{"
|
||||
map -caps -altgr +shift 0x1E..0x27 0x2B ~ "ASDFGHJKLÇ}"
|
||||
map -caps -altgr +shift 0x56 0x2C..0x36 ~ "|ZXCVBNM<>:?"
|
||||
|
||||
map +caps -altgr -shift 0x29 0x02..0x0D ~ "'1234567890-="
|
||||
map +caps -altgr -shift 0x10..0x19 0x1B ~ "QWERTYUIOP["
|
||||
map +caps -altgr -shift 0x1E..0x27 0x2B ~ "ASDFGHJKLÇ]"
|
||||
map +caps -altgr -shift 0x56 0x2C..0x36 ~ "\ZXCVBNM,.;/"
|
||||
|
||||
map +caps -altgr +shift 0x29 0x02..0x06 0x08..0x0D ~ ""!@#$%&*()_+"
|
||||
map +caps -altgr +shift 0x10..0x19 0x1B ~ "qwertyuiop{"
|
||||
map +caps -altgr +shift 0x1E..0x27 0x2B ~ "asdfghjklç}"
|
||||
map +caps -altgr +shift 0x56 0x2C..0x36 ~ "|zxcvbnm<>:?"
|
||||
|
||||
#
|
||||
# Keys requiring AltGr
|
||||
|
@ -25,15 +25,25 @@ freerdp "KBD_SWEDISH"
|
||||
# Basic keys
|
||||
#
|
||||
|
||||
map -altgr -shift 0x29 0x02..0x0C ~ "§1234567890+"
|
||||
map -altgr -shift 0x10..0x1A ~ "qwertyuiopå"
|
||||
map -altgr -shift 0x1E..0x28 0x2B ~ "asdfghjklöä'"
|
||||
map -altgr -shift 0x56 0x2C..0x35 ~ "<zxcvbnm,.-"
|
||||
map -caps -altgr -shift 0x29 0x02..0x0C ~ "§1234567890+"
|
||||
map -caps -altgr -shift 0x10..0x1A ~ "qwertyuiopå"
|
||||
map -caps -altgr -shift 0x1E..0x28 0x2B ~ "asdfghjklöä'"
|
||||
map -caps -altgr -shift 0x56 0x2C..0x35 ~ "<zxcvbnm,.-"
|
||||
|
||||
map -altgr +shift 0x29 0x02..0x0C ~ "½!"#¤%&/()=?"
|
||||
map -altgr +shift 0x10..0x1A ~ "QWERTYUIOPÅ"
|
||||
map -altgr +shift 0x1E..0x28 0x2B ~ "ASDFGHJKLÖÄ*"
|
||||
map -altgr +shift 0x56 0x2C..0x35 ~ ">ZXCVBNM;:_"
|
||||
map -caps -altgr +shift 0x29 0x02..0x0C ~ "½!"#¤%&/()=?"
|
||||
map -caps -altgr +shift 0x10..0x1A ~ "QWERTYUIOPÅ"
|
||||
map -caps -altgr +shift 0x1E..0x28 0x2B ~ "ASDFGHJKLÖÄ*"
|
||||
map -caps -altgr +shift 0x56 0x2C..0x35 ~ ">ZXCVBNM;:_"
|
||||
|
||||
map +caps -altgr -shift 0x29 0x02..0x0C ~ "§1234567890+"
|
||||
map +caps -altgr -shift 0x10..0x1A ~ "QWERTYUIOPÅ"
|
||||
map +caps -altgr -shift 0x1E..0x28 0x2B ~ "ASDFGHJKLÖÄ'"
|
||||
map +caps -altgr -shift 0x56 0x2C..0x35 ~ "<ZXCVBNM,.-"
|
||||
|
||||
map +caps -altgr +shift 0x29 0x02..0x0C ~ "½!"#¤%&/()=?"
|
||||
map +caps -altgr +shift 0x10..0x1A ~ "qwertyuiopå"
|
||||
map +caps -altgr +shift 0x1E..0x28 0x2B ~ "asdfghjklöä*"
|
||||
map +caps -altgr +shift 0x56 0x2C..0x35 ~ ">zxcvbnm;:_"
|
||||
|
||||
#
|
||||
# Keys requiring AltGr
|
||||
|
@ -25,17 +25,27 @@ freerdp "KBD_TURKISH_Q"
|
||||
# Basic keys
|
||||
#
|
||||
|
||||
map -altgr -shift 0x29 0x02..0x0D ~ ""1234567890*-"
|
||||
map -altgr -shift 0x10..0x1B ~ "qwertyuıopğü"
|
||||
map -altgr -shift 0x1E..0x28 0x2B ~ "asdfghjklşi,"
|
||||
map -altgr -shift 0x56 0x2C..0x35 ~ "<zxcvbnmöç."
|
||||
map -caps -altgr -shift 0x29 0x02..0x0D ~ ""1234567890*-"
|
||||
map -caps -altgr -shift 0x10..0x1B ~ "qwertyuıopğü"
|
||||
map -caps -altgr -shift 0x1E..0x28 0x2B ~ "asdfghjklşi,"
|
||||
map -caps -altgr -shift 0x56 0x2C..0x35 ~ "<zxcvbnmöç."
|
||||
|
||||
map -altgr +shift 0x29 0x02..0x03 ~ "é!'"
|
||||
map -altgr +shift 0x05..0x0D ~ "+%&/()=?_"
|
||||
map -altgr +shift 0x10..0x1B ~ "QWERTYUIOPĞÜ"
|
||||
map -altgr +shift 0x1E..0x28 0x2B ~ "ASDFGHJKLŞİ;"
|
||||
map -altgr +shift 0x56 0x2C..0x35 ~ ">ZXCVBNMÖÇ:"
|
||||
map -caps -altgr +shift 0x29 0x02..0x03 ~ "é!'"
|
||||
map -caps -altgr +shift 0x05..0x0D ~ "+%&/()=?_"
|
||||
map -caps -altgr +shift 0x10..0x1B ~ "QWERTYUIOPĞÜ"
|
||||
map -caps -altgr +shift 0x1E..0x28 0x2B ~ "ASDFGHJKLŞİ;"
|
||||
map -caps -altgr +shift 0x56 0x2C..0x35 ~ ">ZXCVBNMÖÇ:"
|
||||
|
||||
map +caps -altgr -shift 0x29 0x02..0x0D ~ ""1234567890*-"
|
||||
map +caps -altgr -shift 0x10..0x1B ~ "QWERTYUIOPĞÜ"
|
||||
map +caps -altgr -shift 0x1E..0x28 0x2B ~ "ASDFGHJKLŞİ,"
|
||||
map +caps -altgr -shift 0x56 0x2C..0x35 ~ "<ZXCVBNMÖÇ."
|
||||
|
||||
map +caps -altgr +shift 0x29 0x02..0x03 ~ "é!'"
|
||||
map +caps -altgr +shift 0x05..0x0D ~ "+%&/()=?_"
|
||||
map +caps -altgr +shift 0x10..0x1B ~ "qwertyuıopğü"
|
||||
map +caps -altgr +shift 0x1E..0x28 0x2B ~ "asdfghjklşi;"
|
||||
map +caps -altgr +shift 0x56 0x2C..0x35 ~ ">zxcvbnmöç:"
|
||||
|
||||
#
|
||||
# Keys requiring AltGr
|
||||
@ -47,21 +57,26 @@ map +altgr -shift 0x08..0x0D ~ "{[]}\|"
|
||||
map +altgr -shift 0x10 ~ "@"
|
||||
map +altgr -shift 0x12 ~ "€"
|
||||
map +altgr -shift 0x14 ~ "₺"
|
||||
map +altgr -shift 0x17 ~ "i"
|
||||
|
||||
map +altgr -shift 0x1E ~ "æ"
|
||||
map +altgr -shift 0x1F ~ "ß"
|
||||
|
||||
map +altgr -shift 0x56 ~ "|"
|
||||
|
||||
|
||||
#
|
||||
# Keys requiring AltGr & Shift
|
||||
# Keys requiring AltGr and vary by Shift and Caps Lock
|
||||
#
|
||||
|
||||
map +altgr +shift 0x17 ~ "İ"
|
||||
map -caps +altgr -shift 0x17 ~ "i"
|
||||
map -caps +altgr -shift 0x1E ~ "æ"
|
||||
|
||||
map +altgr +shift 0x1E ~ "Æ"
|
||||
map -caps +altgr +shift 0x17 ~ "İ"
|
||||
map -caps +altgr +shift 0x1E ~ "Æ"
|
||||
|
||||
map +caps +altgr -shift 0x17 ~ "İ"
|
||||
map +caps +altgr -shift 0x1E ~ "Æ"
|
||||
|
||||
map +caps +altgr +shift 0x1E ~ "æ"
|
||||
map +caps +altgr +shift 0x17 ~ "i"
|
||||
|
||||
#
|
||||
# Dead keys
|
||||
|
@ -173,6 +173,9 @@ BOOL rdp_freerdp_pre_connect(freerdp* instance) {
|
||||
/* Beep on receipt of Play Sound PDU */
|
||||
instance->update->PlaySound = guac_rdp_beep_play_sound;
|
||||
|
||||
/* Automatically synchronize keyboard locks when changed server-side */
|
||||
instance->update->SetKeyboardIndicators = guac_rdp_keyboard_set_indicators;
|
||||
|
||||
/* Set up GDI */
|
||||
instance->update->DesktopResize = guac_rdp_gdi_desktop_resize;
|
||||
instance->update->EndPaint = guac_rdp_gdi_end_paint;
|
||||
|
Loading…
Reference in New Issue
Block a user