You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@guacamole.apache.org by jm...@apache.org on 2016/08/17 03:19:47 UTC
[3/4] incubator-guacamole-server git commit: GUACAMOLE-51: Track and
synchronize remote lock key state.
GUACAMOLE-51: Track and synchronize remote lock key state.
Project: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/commit/0c480961
Tree: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/tree/0c480961
Diff: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/diff/0c480961
Branch: refs/heads/master
Commit: 0c48096147ae1f17609fffbedd7f4787cde86ebc
Parents: 4f4f83f
Author: Michael Jumper <mj...@apache.org>
Authored: Sun Aug 14 17:19:09 2016 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Tue Aug 16 20:00:24 2016 -0700
----------------------------------------------------------------------
src/protocols/rdp/keyboard.c | 111 ++++++++++++++++++++++++++++++++++++
src/protocols/rdp/keyboard.h | 33 +++++++++++
src/protocols/rdp/rdp_keymap.h | 16 ++++++
3 files changed, 160 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/0c480961/src/protocols/rdp/keyboard.c
----------------------------------------------------------------------
diff --git a/src/protocols/rdp/keyboard.c b/src/protocols/rdp/keyboard.c
index d7d2d51..d7e9a37 100644
--- a/src/protocols/rdp/keyboard.c
+++ b/src/protocols/rdp/keyboard.c
@@ -32,6 +32,46 @@
#include <stdlib.h>
/**
+ * Translates the given keysym into the corresponding lock flag, as would be
+ * required by the RDP synchronize event. If the given keysym does not
+ * represent a lock key, zero is returned.
+ *
+ * @param keysym
+ * The keysym to translate into a RDP lock flag.
+ *
+ * @return
+ * The RDP lock flag which corresponds to the given keysym, or zero if the
+ * given keysym does not represent a lock key.
+ */
+static int guac_rdp_keyboard_lock_flag(int keysym) {
+
+ /* Translate keysym into corresponding lock flag */
+ switch (keysym) {
+
+ /* Scroll lock */
+ case 0xFF14:
+ return KBD_SYNC_SCROLL_LOCK;
+
+ /* Kana lock */
+ case 0xFF2D:
+ return KBD_SYNC_KANA_LOCK;
+
+ /* Num lock */
+ case 0xFF7F:
+ return KBD_SYNC_NUM_LOCK;
+
+ /* Caps lock */
+ case 0xFFE5:
+ return KBD_SYNC_CAPS_LOCK;
+
+ }
+
+ /* Not a lock key */
+ return 0;
+
+}
+
+/**
* Immediately sends an RDP key event having the given scancode and flags.
*
* @param rdp_client
@@ -114,6 +154,39 @@ static void guac_rdp_send_unicode_event(guac_rdp_client* rdp_client,
}
/**
+ * Immediately sends an RDP synchonize event having the given flags. An RDP
+ * synchronize event sets the state of remote lock keys absolutely, where a
+ * lock key will be active only if its corresponding flag is set in the event.
+ *
+ * @param rdp_client
+ * The RDP client instance associated with the RDP session along which the
+ * synchronize event should be sent.
+ *
+ * @param flags
+ * Bitwise OR of the flags representing the lock keys which should be set,
+ * if any, as dictated by the RDP protocol. If no flags are set, then no
+ * lock keys will be active.
+ */
+static void guac_rdp_send_synchronize_event(guac_rdp_client* rdp_client,
+ int flags) {
+
+ pthread_mutex_lock(&(rdp_client->rdp_lock));
+
+ /* Skip if not yet connected */
+ freerdp* rdp_inst = rdp_client->rdp_inst;
+ if (rdp_inst == NULL) {
+ pthread_mutex_unlock(&(rdp_client->rdp_lock));
+ return;
+ }
+
+ /* Synchronize lock key states */
+ rdp_inst->input->SynchronizeEvent(rdp_inst->input, flags);
+
+ pthread_mutex_unlock(&(rdp_client->rdp_lock));
+
+}
+
+/**
* Loads all keysym/scancode mappings declared within the given keymap and its
* parent keymap, if any. These mappings are stored within the given
* guac_rdp_keyboard structure for future use in translating keysyms to the
@@ -187,6 +260,11 @@ int guac_rdp_keyboard_send_event(guac_rdp_keyboard* keyboard,
/* 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,
@@ -270,9 +348,42 @@ void guac_rdp_keyboard_send_events(guac_rdp_keyboard* keyboard,
}
+void guac_rdp_keyboard_update_locks(guac_rdp_keyboard* keyboard,
+ int set_flags, 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;
+
+ /* Synchronize remote side only if lock flags have changed */
+ if (lock_flags != keyboard->lock_flags) {
+ guac_rdp_send_synchronize_event(rdp_client, lock_flags);
+ keyboard->lock_flags = lock_flags;
+ }
+
+}
+
int guac_rdp_keyboard_update_keysym(guac_rdp_keyboard* keyboard,
int keysym, int pressed) {
+ /* Synchronize lock keys states, if this has not yet been done */
+ if (!keyboard->synchronized) {
+
+ guac_client* client = keyboard->client;
+ guac_rdp_client* rdp_client = (guac_rdp_client*) client->data;
+
+ /* Synchronize remote lock key states with local state */
+ guac_rdp_send_synchronize_event(rdp_client, keyboard->lock_flags);
+ keyboard->synchronized = 1;
+
+ }
+
+ /* Toggle lock flag, if any */
+ if (pressed)
+ keyboard->lock_flags ^= guac_rdp_keyboard_lock_flag(keysym);
+
/* Update keysym state */
if (GUAC_RDP_KEYSYM_STORABLE(keysym))
GUAC_RDP_KEYSYM_LOOKUP(keyboard->keysym_state, keysym) = pressed;
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/0c480961/src/protocols/rdp/keyboard.h
----------------------------------------------------------------------
diff --git a/src/protocols/rdp/keyboard.h b/src/protocols/rdp/keyboard.h
index aebc58e..8282c18 100644
--- a/src/protocols/rdp/keyboard.h
+++ b/src/protocols/rdp/keyboard.h
@@ -36,6 +36,19 @@ typedef struct guac_rdp_keyboard {
guac_client* client;
/**
+ * 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;
+
+ /**
+ * Whether the states of remote lock keys (Caps lock, Num lock, etc.) have
+ * been synchronized with local lock key states.
+ */
+ int synchronized;
+
+ /**
* The keymap to use when translating keysyms into scancodes or sequences
* of scancodes for RDP.
*/
@@ -128,6 +141,26 @@ void guac_rdp_keyboard_send_events(guac_rdp_keyboard* keyboard,
const int* keysym_string, int from, int 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.
+ *
+ * @param keyboard
+ * The guac_rdp_keyboard associated with the current RDP session.
+ *
+ * @param set_flags
+ * The lock key flags which should be set. Legal flags are
+ * KBD_SYNC_SCROLL_LOCK, KBD_SYNC_NUM_LOCK, KBD_SYNC_CAPS_LOCK, and
+ * KBD_SYNC_KANA_LOCK.
+ *
+ * @param clear_flags
+ * The lock key flags which should be cleared. Legal flags are
+ * KBD_SYNC_SCROLL_LOCK, KBD_SYNC_NUM_LOCK, KBD_SYNC_CAPS_LOCK, and
+ * KBD_SYNC_KANA_LOCK.
+ */
+void guac_rdp_keyboard_update_locks(guac_rdp_keyboard* keyboard,
+ int set_flags, int clear_flags);
+
+/**
* Updates the local state of the given keysym, sending the key events required
* to replicate that state remotely (on the RDP server). The key events sent
* will depend on the current keymap.
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/0c480961/src/protocols/rdp/rdp_keymap.h
----------------------------------------------------------------------
diff --git a/src/protocols/rdp/rdp_keymap.h b/src/protocols/rdp/rdp_keymap.h
index 01e11ef..b299bdc 100644
--- a/src/protocols/rdp/rdp_keymap.h
+++ b/src/protocols/rdp/rdp_keymap.h
@@ -62,6 +62,22 @@ typedef struct guac_rdp_keysym_desc {
*/
const int* clear_keysyms;
+ /**
+ * 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;
+
+ /**
+ * Bitwise OR of the flags of all lock keys (ie: Caps lock, Num lock, etc.)
+ * which must be inactive 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 clear_locks;
+
} guac_rdp_keysym_desc;
/**