rdp: Korean keyboard support

Korean keyboards are keyboard type 8:
https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getkeyboardtype

While type 8 is not explicitly mentioned in the RDP documentation,
it can be sent over the wire. Let's support the variants we can.

Co-authored-by: Steve Pronovost <spronovo@microsoft.com>
Co-authored-by: Brenton DeGeer <brdegeer@microsoft.com>
Signed-off-by: Hideyuki Nagase <hideyukn@microsoft.com>
Signed-off-by: Steve Pronovost <spronovo@microsoft.com>
Signed-off-by: Brenton DeGeer <brdegeer@microsoft.com>
dev
Hideyuki Nagase 3 years ago committed by Derek Foreman
parent 4d5605b3a0
commit 5d939bc636
  1. 53
      libweston/backend-rdp/rdp.c
  2. 14
      libweston/backend-rdp/rdp.h

@ -836,6 +836,20 @@ convert_rdp_keyboard_to_xkb_rule_names(UINT32 KeyboardType,
} }
} }
/* Korean keyboard support (KeyboardType 8, LangID 0x412) */
if (KeyboardType == KBD_TYPE_KOREAN && ((KeyboardLayout & 0xFFFF) == 0x412)) {
/* TODO: PC/AT 101 Enhanced Korean Keyboard (Type B) and (Type C) are not supported yet
because default Xkb settings for Korean layout don't have corresponding
configuration.
(Type B): KeyboardSubType:4: rctrl_hangul/ratl_hanja
(Type C): KeyboardSubType:5: shift_space_hangul/crtl_space_hanja
*/
if (KeyboardSubType == 0 ||
KeyboardSubType == 3) /* PC/AT 101 Enhanced Korean Keyboard (Type A) */
xkbRuleNames->variant = "kr104"; /* kr(ralt_hangul)/kr(rctrl_hanja) */
else if (KeyboardSubType == 6) /* PC/AT 103 Enhanced Korean Keyboard */
xkbRuleNames->variant = "kr106"; /* kr(hw_keys) */
}
weston_log("%s: matching model=%s layout=%s variant=%s options=%s\n", weston_log("%s: matching model=%s layout=%s variant=%s options=%s\n",
__func__, xkbRuleNames->model, xkbRuleNames->layout, __func__, xkbRuleNames->model, xkbRuleNames->layout,
xkbRuleNames->variant, xkbRuleNames->options); xkbRuleNames->variant, xkbRuleNames->options);
@ -1244,7 +1258,9 @@ xf_input_keyboard_event(rdpInput *input, UINT16 flags, UINT16 code)
{ {
uint32_t scan_code, vk_code, full_code; uint32_t scan_code, vk_code, full_code;
enum wl_keyboard_key_state keyState; enum wl_keyboard_key_state keyState;
freerdp_peer *client = input->context->peer;
RdpPeerContext *peerContext = (RdpPeerContext *)input->context; RdpPeerContext *peerContext = (RdpPeerContext *)input->context;
bool send_release_key = false;
int notify = 0; int notify = 0;
struct timespec time; struct timespec time;
@ -1264,7 +1280,35 @@ xf_input_keyboard_event(rdpInput *input, UINT16 flags, UINT16 code)
if (flags & KBD_FLAGS_EXTENDED) if (flags & KBD_FLAGS_EXTENDED)
full_code |= KBD_FLAGS_EXTENDED; full_code |= KBD_FLAGS_EXTENDED;
vk_code = GetVirtualKeyCodeFromVirtualScanCode(full_code, 4); /* Korean keyboard support:
* WinPR's GetVirtualKeyCodeFromVirtualScanCode() can't handle hangul/hanja keys
* hanja and hangeul keys are only present on Korean 103 keyboard (Type 8:SubType 6) */
if (client->settings->KeyboardType == 8 &&
client->settings->KeyboardSubType == 6 &&
((full_code == (KBD_FLAGS_EXTENDED | ATKBD_RET_HANJA)) ||
(full_code == (KBD_FLAGS_EXTENDED | ATKBD_RET_HANGEUL)))) {
if (full_code == (KBD_FLAGS_EXTENDED | ATKBD_RET_HANJA))
vk_code = VK_HANJA;
else if (full_code == (KBD_FLAGS_EXTENDED | ATKBD_RET_HANGEUL))
vk_code = VK_HANGUL;
/* From Linux's keyboard driver at drivers/input/keyboard/atkbd.c */
/*
* HANGEUL and HANJA keys do not send release events so we need to
* generate such events ourselves
*/
/* Similarly, for RDP there is no release for those 2 Korean keys,
* thus generate release right after press. */
if (keyState != WL_KEYBOARD_KEY_STATE_PRESSED) {
weston_log("RDP: Received invalid key release\n");
return TRUE;
}
send_release_key = true;
} else {
vk_code = GetVirtualKeyCodeFromVirtualScanCode(full_code, client->settings->KeyboardType);
}
/* Korean keyboard support */
/* WinPR's GetKeycodeFromVirtualKeyCode() expects no extended bit for VK_HANGUL and VK_HANJA */
if (vk_code != VK_HANGUL && vk_code != VK_HANJA)
if (flags & KBD_FLAGS_EXTENDED) if (flags & KBD_FLAGS_EXTENDED)
vk_code |= KBDEXT; vk_code |= KBDEXT;
@ -1275,6 +1319,13 @@ xf_input_keyboard_event(rdpInput *input, UINT16 flags, UINT16 code)
weston_compositor_get_time(&time); weston_compositor_get_time(&time);
notify_key(peerContext->item.seat, &time, notify_key(peerContext->item.seat, &time,
scan_code - 8, keyState, STATE_UPDATE_AUTOMATIC); scan_code - 8, keyState, STATE_UPDATE_AUTOMATIC);
if (send_release_key) {
notify_key(peerContext->item.seat, &time,
scan_code - 8,
WL_KEYBOARD_KEY_STATE_RELEASED,
STATE_UPDATE_AUTOMATIC);
}
} }
return TRUE; return TRUE;

@ -51,6 +51,20 @@
#define DEFAULT_AXIS_STEP_DISTANCE 10 #define DEFAULT_AXIS_STEP_DISTANCE 10
#define DEFAULT_PIXEL_FORMAT PIXEL_FORMAT_BGRA32 #define DEFAULT_PIXEL_FORMAT PIXEL_FORMAT_BGRA32
/* https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getkeyboardtype
* defines a keyboard type that isn't currently defined in FreeRDP, but is
* available for RDP connections */
#ifndef KBD_TYPE_KOREAN
#define KBD_TYPE_KOREAN 8
#endif
/* WinPR's GetVirtualKeyCodeFromVirtualScanCode() can't handle hangul/hanja keys */
/* 0x1f1 and 0x1f2 keys are only exists on Korean 103 keyboard (Type 8:SubType 6) */
/* From Linux's keyboard driver at drivers/input/keyboard/atkbd.c */
#define ATKBD_RET_HANJA 0xf1
#define ATKBD_RET_HANGEUL 0xf2
struct rdp_output; struct rdp_output;
struct rdp_backend { struct rdp_backend {

Loading…
Cancel
Save