From 60944f109215c2f93db60b3a470b907c8f365bdb Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Mon, 22 Jun 2020 23:11:43 -0700 Subject: [PATCH] GUACAMOLE-518: Keep locally-tracked keyboard lock status in sync with remote changes to keyboard locks. --- src/protocols/rdp/keyboard.c | 21 +++++++++++++++++++++ src/protocols/rdp/keyboard.h | 18 ++++++++++++++++++ src/protocols/rdp/rdp.c | 3 +++ 3 files changed, 42 insertions(+) diff --git a/src/protocols/rdp/keyboard.c b/src/protocols/rdp/keyboard.c index 5bb925bf..a75b7340 100644 --- a/src/protocols/rdp/keyboard.c +++ b/src/protocols/rdp/keyboard.c @@ -709,3 +709,24 @@ void guac_rdp_keyboard_reset(guac_rdp_keyboard* keyboard) { } +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; + +} diff --git a/src/protocols/rdp/keyboard.h b/src/protocols/rdp/keyboard.h index a07312bf..425f55c8 100644 --- a/src/protocols/rdp/keyboard.h +++ b/src/protocols/rdp/keyboard.h @@ -22,6 +22,7 @@ #include "keymap.h" +#include #include /** @@ -279,5 +280,22 @@ int guac_rdp_keyboard_update_keysym(guac_rdp_keyboard* keyboard, */ 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 diff --git a/src/protocols/rdp/rdp.c b/src/protocols/rdp/rdp.c index d7fd0611..3d7702c6 100644 --- a/src/protocols/rdp/rdp.c +++ b/src/protocols/rdp/rdp.c @@ -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;