Implement scancode indexing

The mapping from scancodes to the indexes used in xrdp_keymap
is not well designed and contains an implicit dependency on
keycode values.

This mapping is alse slightly different from the index used for
the 'keys' map in the xrdp_wm structure.

This commit introduces support for mapping scancodes directly
to 'scancode indexes' suitable for indexing into both structures.

Some renaming is also done; [MS-RDPBCGR] uses the terms scancode
and keyCode interchangeably. An effort is made to use key_code for a
raw value from a TS_KEYBOARD_EVENT, and scancode for a value which is
produced by the scancode module.
This commit is contained in:
matt335672 2024-06-14 15:57:13 +01:00
parent d82a172b55
commit c91ef80ca9
11 changed files with 298 additions and 144 deletions

View File

@ -326,9 +326,48 @@ const struct map_settings global_settings[] =
// Default mapping set is "evdev"
const struct map_settings *settings = &global_settings[SI_EVDEV];
/*****************************************************************************/
int
scancode_to_index(unsigned short scancode)
{
if (scancode <= 0x7f)
{
return scancode;
}
if (scancode <= 0xff)
{
// 0x80 - 0xff : Invalid code
return -1;
}
if (scancode <= 0x17f)
{
// 01x100 - 0x17f : Move bit 9 to bit 8
return (scancode & 0x7f) | 0x80;
}
return -1;
}
/*****************************************************************************/
unsigned short
scancode_to_keycode(unsigned short scancode)
scancode_from_index(int index)
{
index &= 0xff;
unsigned short result;
if (index < 0x80)
{
result = index;
}
else
{
result = (index & 0x7f) | 0x100;
}
return result;
}
/*****************************************************************************/
unsigned short
scancode_to_x11_keycode(unsigned short scancode)
{
unsigned int min = 0;
unsigned int max = settings->size;
@ -419,3 +458,12 @@ scancode_get_keycode_set(void)
{
return settings->name;
}
/*****************************************************************************/
const char *
scancode_get_xkb_rules(void)
{
// Currently supported keycods map directly to the same name for
// the rules which use them.
return settings->name;
}

View File

@ -18,13 +18,32 @@
* @file common/scancode.h
* @brief Scancode handling
*
* Convert between RDP scancodes and X11 keycodes.
* This module provides functionality for the following:-
* 1) Mapping from TS_KEYBOARD_EVENT PDU values to an 'RDP scancode'
* 2) Handling RDP scancodes
* 3) Convert between RDP scancodes and X11 keycodes.
*
* RDP scancodes are largely the same as Windows scancodes. These are
* indirectly documented in the Microsoft "Keyboard Scan Code Specification",
* Rev 1.3a (March 16th 2000) and are otherwise known as "Scan code set
* 1" scancodes. This document no longer appears to be available directly from
* the Microsoft website.
* The values received in TS_KEYBOARD_EVENT PDUs are largely the same as
* Windows scancodes. These are indirectly documented in the Microsoft
* "Keyboard Scan Code Specification", Rev 1.3a (March 16th 2000) and
* are otherwise known as "Scan code set 1" scancodes. This document no
* longer appears to be available directly from the Microsoft website.
*
* A TS_KEYBOARD_EVENT_PDU contains two important values:-
* 1) key_code This is not unique. For example, left-shift and
* right-shift share a key_code of 0x2a
* 2) keyboard_flags Among other flags, contains KBDFLAGS_EXTENDED and
* KBDFLAGS_EXTENDED1. These combine with the key_code
* to allow a specific key to be determined.
*
* An 'RDP scancode' as defined by this module is a mapping of the
* Windows key_code and keyboard_flags into a single value which
* represents a unique key. For example:-
* Left control : key_code=0x1d, KBDFLAGS_EXTENDED=0 scancode = 0x1d
* Right control : key_code=0x1d, KBDFLAGS_EXTENDED=1 scancode = 0x11d
*
* This model of unique keys more closely maps what X11 does with its
* own keycodes.
*
* X11 keycodes are the X11 equivalent of RDP scancodes. In general, these
* are specific to an X server. In practice however, these are nowadays
@ -39,15 +58,63 @@
#if !defined(SCANCODE_H)
#define SCANCODE_H
enum
{
/**
* Maximum value returned by scancode_to_index()
*/
SCANCODE_MAX_INDEX = 255
};
// Convert key_code and flags values received from a TS_KEYBOARD_EVENT
// into a value suitable for use by this module
#define SCANCODE_FROM_KBD_EVENT(key_code,keyboard_flags) \
(((key_code) & 0x7f) | ((keyboard_flags) & 0x100))
// Convert a scancode used by this module back into a
// TS_KEYBOARD_EVENT keyCode value
#define SCANCODE_TO_KBD_EVENT_KEY_CODE(scancode) ((scancode) & 0x7f)
// Convert a scancode used by this module back into a
// TS_KEYBOARD_EVENT keyboardFlags value
#define SCANCODE_TO_KBD_EVENT_KBD_FLAGS(scancode) ((scancode) & 0x100)
/**
* Looks up an RDP scancode
* Convert a scancode to an index
* @param scancode scancode in the range 0x00 - 0x1ff
* @return index in the range 0..SCANCODE_MAX_INDEX (inclusive) or -1
*
* This function converts a 9-bit scancode into an 8-bit array index,
* independent of the currently loaded keymap
*
* For scancodes in the range 0x00 - 0x7f, the index is identical to the
* scancode. This includes scancodes for all the keys affected by
* numlock.
*/
int
scancode_to_index(unsigned short scancode);
/**
* Convert an index back to a scancode.
* @param index in the range 0..SCANCODE_MAX_INDEX
*
* @result scancode which is mapped to the index value
*
* The result is always a valid scancode, even if the index is
* not valid.
*/
unsigned short
scancode_from_index(int index);
/**
* Looks up an RDP scancode and converts to an x11 keycode
*
* @param scancode Scancode. Extended scancodes have bit 9 set
* (i.e. are in 0x100 - 0x1ff)
* (i.e. are in 0x100 - 0x1ff).
* @return keycode, or 0 for no keycode
*/
unsigned short
scancode_to_keycode(unsigned short scancode);
scancode_to_x11_keycode(unsigned short scancode);
/**
* Gets the next valid scancode from the list of valid scancodes
@ -84,4 +151,13 @@ scancode_set_keycode_set(const char *kk_set);
const char *
scancode_get_keycode_set(void);
/**
* Gets the XKB rules set which can be used to access the currently
* loaded keycode set
*
* @result "evdev", or "base"
*/
const char *
scancode_get_xkb_rules(void);
#endif /* SCANCODE_H */

View File

@ -63,9 +63,6 @@
#define XRDP_MAX_BITMAP_CACHE_IDX 2000
#define XRDP_BITMAP_CACHE_ENTRIES 2048
#define XR_MIN_KEY_CODE 8
#define XR_MAX_KEY_CODE 256
/*
* Constants come from ITU-T Recommendations
*/

View File

@ -279,7 +279,7 @@ output_file_section(FILE *outf,
continue;
}
e.keycode = scancode_to_keycode(scancode);
e.keycode = scancode_to_x11_keycode(scancode);
nbytes = XLookupString(&e, text, 255, &ks, NULL);
if (ks == NoSymbol)
{

View File

@ -31,7 +31,7 @@ START_TEST(test_scancode__evdev_all_values_returned)
iter = 0;
while ((scancode = scancode_get_next(&iter)) != 0)
{
unsigned short keycode = scancode_to_keycode(scancode);
unsigned short keycode = scancode_to_x11_keycode(scancode);
ck_assert_int_ne(keycode, 0);
}
}
@ -57,7 +57,7 @@ START_TEST(test_scancode__evdev_bad_values_mapped_to_0)
{
if (!valid[scancode])
{
ck_assert_int_eq(scancode_to_keycode(scancode), 0);
ck_assert_int_eq(scancode_to_x11_keycode(scancode), 0);
}
}
}
@ -74,7 +74,7 @@ START_TEST(test_scancode__base_all_values_returned)
iter = 0;
while ((scancode = scancode_get_next(&iter)) != 0)
{
unsigned short keycode = scancode_to_keycode(scancode);
unsigned short keycode = scancode_to_x11_keycode(scancode);
ck_assert_int_ne(keycode, 0);
}
}
@ -100,7 +100,7 @@ START_TEST(test_scancode__base_bad_values_mapped_to_0)
{
if (!valid[scancode])
{
ck_assert_int_eq(scancode_to_keycode(scancode), 0);
ck_assert_int_eq(scancode_to_x11_keycode(scancode), 0);
}
}
}

View File

@ -39,58 +39,64 @@
/*****************************************************************************/
struct xrdp_key_info *
get_key_info_from_scan_code(int device_flags, int scan_code, int *keys,
get_key_info_from_kbd_event(int keyboard_flags, int key_code, int *keys,
int caps_lock, int num_lock, int scroll_lock,
struct xrdp_keymap *keymap)
{
struct xrdp_key_info *rv;
int shift;
int altgr_scancode;
int altgr;
int ext;
int index;
ext = device_flags & KBD_FLAG_EXT; /* 0x0100 */
shift = keys[42] || keys[54];
altgr = keys[56] & KBD_FLAG_EXT; /* right alt */
altgr_scancode = SCANCODE_FROM_KBD_EVENT(56, KBD_FLAG_EXT);
altgr = keys[scancode_to_index(altgr_scancode)]; /* right alt */
rv = 0;
index = INDEX_FROM_SCANCODE(scan_code, ext);
if (num_lock &&
index >= XR_RDP_SCAN_MIN_NUMLOCK && index <= XR_RDP_SCAN_MAX_NUMLOCK)
index = scancode_to_index(SCANCODE_FROM_KBD_EVENT(key_code, keyboard_flags));
if (index >= 0)
{
rv = &(keymap->keys_numlock[index - XR_RDP_SCAN_MIN_NUMLOCK]);
}
else if (shift && caps_lock && altgr)
{
rv = &(keymap->keys_shiftcapslockaltgr[index]);
}
else if (shift && caps_lock)
{
rv = &(keymap->keys_shiftcapslock[index]);
}
else if (shift && altgr)
{
rv = &(keymap->keys_shiftaltgr[index]);
}
else if (shift)
{
rv = &(keymap->keys_shift[index]);
}
else if (caps_lock && altgr)
{
rv = &(keymap->keys_capslockaltgr[index]);
}
else if (caps_lock)
{
rv = &(keymap->keys_capslock[index]);
}
else if (altgr)
{
rv = &(keymap->keys_altgr[index]);
}
else
{
rv = &(keymap->keys_noshift[index]);
// scancode_to_index() guarantees to map numlock scancodes
// to the same index values.
if (num_lock &&
index >= XR_RDP_SCAN_MIN_NUMLOCK &&
index <= XR_RDP_SCAN_MAX_NUMLOCK)
{
rv = &(keymap->keys_numlock[index - XR_RDP_SCAN_MIN_NUMLOCK]);
}
else if (shift && caps_lock && altgr)
{
rv = &(keymap->keys_shiftcapslockaltgr[index]);
}
else if (shift && caps_lock)
{
rv = &(keymap->keys_shiftcapslock[index]);
}
else if (shift && altgr)
{
rv = &(keymap->keys_shiftaltgr[index]);
}
else if (shift)
{
rv = &(keymap->keys_shift[index]);
}
else if (caps_lock && altgr)
{
rv = &(keymap->keys_capslockaltgr[index]);
}
else if (caps_lock)
{
rv = &(keymap->keys_capslock[index]);
}
else if (altgr)
{
rv = &(keymap->keys_altgr[index]);
}
else
{
rv = &(keymap->keys_noshift[index]);
}
}
return rv;
@ -98,13 +104,13 @@ get_key_info_from_scan_code(int device_flags, int scan_code, int *keys,
/*****************************************************************************/
int
get_keysym_from_scan_code(int device_flags, int scan_code, int *keys,
get_keysym_from_kbd_event(int keyboard_flags, int key_code, int *keys,
int caps_lock, int num_lock, int scroll_lock,
struct xrdp_keymap *keymap)
{
struct xrdp_key_info *ki;
ki = get_key_info_from_scan_code(device_flags, scan_code, keys,
ki = get_key_info_from_kbd_event(keyboard_flags, key_code, keys,
caps_lock, num_lock, scroll_lock,
keymap);
@ -118,13 +124,13 @@ get_keysym_from_scan_code(int device_flags, int scan_code, int *keys,
/*****************************************************************************/
char32_t
get_char_from_scan_code(int device_flags, int scan_code, int *keys,
get_char_from_kbd_event(int keyboard_flags, int key_code, int *keys,
int caps_lock, int num_lock, int scroll_lock,
struct xrdp_keymap *keymap)
{
struct xrdp_key_info *ki;
ki = get_key_info_from_scan_code(device_flags, scan_code, keys,
ki = get_key_info_from_kbd_event(keyboard_flags, key_code, keys,
caps_lock, num_lock, scroll_lock,
keymap);
@ -138,28 +144,29 @@ get_char_from_scan_code(int device_flags, int scan_code, int *keys,
/*****************************************************************************/
/**
* Tests a table key to see if it's a valid scancode
* Converts a table key to a scancode index value
*
* @param key Table key
* @param[out] scancode scancode index value (0..255) if 1 is returned
* @return Boolean != 0 if the key is valid
* @return index >= 0, or < 0 for an invalid key
*/
static int
is_valid_scancode(const char *key, int *scancode)
key_to_scancode_index(const char *key)
{
int rv = 0;
int extended = 0;
if ((key[0] == 'E' || key[0] == 'e') && key[1] == '0' && key[2] == '_')
int rv = -1;
int keyboard_flags = 0;
if ((key[0] == 'E' || key[0] == 'e') && key[2] == '_')
{
extended = 1;
key += 3;
if (key[1] == '0')
{
keyboard_flags |= KBD_FLAG_EXT;
key += 3;
}
}
if (isxdigit(key[0]) && isxdigit(key[1]) && key[2] == '\0')
{
rv = 1;
*scancode = XDIGIT_TO_VAL(key[0]) * 16 + XDIGIT_TO_VAL(key[1]);
*scancode = INDEX_FROM_SCANCODE(*scancode, extended);
int code = XDIGIT_TO_VAL(key[0]) * 16 + XDIGIT_TO_VAL(key[1]);
rv = scancode_to_index(SCANCODE_FROM_KBD_EVENT(code, keyboard_flags));
}
return rv;
}
@ -248,13 +255,14 @@ km_read_section(toml_table_t *tfile, const char *section_name,
{
const char *key;
toml_datum_t val;
int index;
int scancode; // index value 0..255
int i;
char *p;
const char *unicode_str;
for (index = 0 ; (key = toml_key_in(section, index)) != NULL; ++index)
for (i = 0 ; (key = toml_key_in(section, i)) != NULL; ++i)
{
if (!is_valid_scancode(key, &scancode))
// Get a scancode index from the key if possible
int sindex = key_to_scancode_index(key);
if (sindex < 0)
{
LOG(LOG_LEVEL_WARNING,
"Can't parse value '%s' in [%s] in keymap file",
@ -283,7 +291,7 @@ km_read_section(toml_table_t *tfile, const char *section_name,
/* Parse both values and add them to the keymap, logging any
* errors */
if (!is_valid_keysym(val.u.s, &keymap[scancode].sym))
if (!is_valid_keysym(val.u.s, &keymap[sindex].sym))
{
LOG(LOG_LEVEL_WARNING,
"Can't read KeySym for [%s]:%s in keymap file",
@ -291,7 +299,7 @@ km_read_section(toml_table_t *tfile, const char *section_name,
}
if (unicode_str != NULL &&
!is_valid_unicode_char(unicode_str, &keymap[scancode].chr))
!is_valid_unicode_char(unicode_str, &keymap[sindex].chr))
{
LOG(LOG_LEVEL_WARNING,
"Can't read unicode character for [%s]:%s in keymap file",
@ -385,7 +393,7 @@ km_load_file(const char *filename, struct xrdp_keymap *keymap)
/* The numlock map is much smaller and offset by
* XR_RDP_SCAN_MAX_NUMLOCK. Read the section into a temporary
* area and copy it over */
struct xrdp_key_info keys_numlock[256];
struct xrdp_key_info keys_numlock[SCANCODE_MAX_INDEX + 1];
int i;
for (i = XR_RDP_SCAN_MIN_NUMLOCK; i <= XR_RDP_SCAN_MAX_NUMLOCK; ++i)
{

View File

@ -147,8 +147,14 @@ int
xrdp_wm_mouse_touch(struct xrdp_wm *self, int gesture, int param);
int
xrdp_wm_mouse_click(struct xrdp_wm *self, int x, int y, int but, int down);
/**
* Handle a TS_KEYBOARD_EVENT ([MS-RDPBCGR] 2.2.8.1.1.3.1.1.1)
*
* @param device_flags keyboardFlags value from PDU
* @param key_code keyCode value from PDU
*/
int
xrdp_wm_key(struct xrdp_wm *self, int device_flags, int scan_code);
xrdp_wm_key(struct xrdp_wm *self, int keyboard_flags, int key_code);
int
xrdp_wm_key_sync(struct xrdp_wm *self, int device_flags, int key_flags);
int
@ -424,15 +430,15 @@ set_string(char **in_str, const char *in);
/* in lang.c */
struct xrdp_key_info *
get_key_info_from_scan_code(int device_flags, int scan_code, int *keys,
get_key_info_from_kbd_event(int keyboard_flags, int key_code, int *keys,
int caps_lock, int num_lock, int scroll_lock,
struct xrdp_keymap *keymap);
int
get_keysym_from_scan_code(int device_flags, int scan_code, int *keys,
get_keysym_from_kbd_event(int keyboard_flags, int key_code, int *keys,
int caps_lock, int num_lock, int scroll_lock,
struct xrdp_keymap *keymap);
char32_t
get_char_from_scan_code(int device_flags, int scan_code, int *keys,
get_char_from_kbd_event(int keyboard_flags, int key_code, int *keys,
int caps_lock, int num_lock, int scroll_lock,
struct xrdp_keymap *keymap);
int

View File

@ -1226,7 +1226,7 @@ xrdp_bitmap_def_proc(struct xrdp_bitmap *self, int msg,
}
else
{
char32_t c = get_char_from_scan_code
char32_t c = get_char_from_kbd_event
(param2, scan_code, self->wm->keys, self->wm->caps_lock,
self->wm->num_lock, self->wm->scroll_lock,
&(self->wm->keymap));

View File

@ -28,6 +28,7 @@
#include "xrdp_constants.h"
#include "fifo.h"
#include "guid.h"
#include "scancode.h"
#include "xrdp_client_info.h"
#define MAX_NR_CHANNELS 16
@ -452,25 +453,17 @@ struct xrdp_key_info
char32_t chr;
};
/**
* Keyboard description
*
* Each section maps an RDP scancode to a KeySym and a Unicode
* character.
*/
#define INDEX_FROM_SCANCODE(scancode,extended) \
(((scancode) & 0x7f) | ((extended) ? 0x80 : 0))
struct xrdp_keymap
{
struct xrdp_key_info keys_noshift[256];
struct xrdp_key_info keys_shift[256];
struct xrdp_key_info keys_altgr[256];
struct xrdp_key_info keys_shiftaltgr[256];
struct xrdp_key_info keys_capslock[256];
struct xrdp_key_info keys_capslockaltgr[256];
struct xrdp_key_info keys_shiftcapslock[256];
struct xrdp_key_info keys_shiftcapslockaltgr[256];
// These arrays are indexed by a return from scancode_to_index()
struct xrdp_key_info keys_noshift[SCANCODE_MAX_INDEX + 1];
struct xrdp_key_info keys_shift[SCANCODE_MAX_INDEX + 1];
struct xrdp_key_info keys_altgr[SCANCODE_MAX_INDEX + 1];
struct xrdp_key_info keys_shiftaltgr[SCANCODE_MAX_INDEX + 1];
struct xrdp_key_info keys_capslock[SCANCODE_MAX_INDEX + 1];
struct xrdp_key_info keys_capslockaltgr[SCANCODE_MAX_INDEX + 1];
struct xrdp_key_info keys_shiftcapslock[SCANCODE_MAX_INDEX + 1];
struct xrdp_key_info keys_shiftcapslockaltgr[SCANCODE_MAX_INDEX + 1];
// NumLock is restricted to a much smaller set of keys
struct xrdp_key_info keys_numlock[XR_RDP_SCAN_MAX_NUMLOCK -
XR_RDP_SCAN_MIN_NUMLOCK + 1];
@ -554,11 +547,12 @@ struct xrdp_wm
int current_pointer;
int mouse_x;
int mouse_y;
/* keyboard info */
int keys[256]; /* key states 0 up 1 down*/
/* keyboard info (indexed by a return from scancode_to_index()) */
int keys[SCANCODE_MAX_INDEX + 1]; /* key states 0 up 1 down*/
int caps_lock;
int scroll_lock;
int num_lock;
/* Unicode input */
int last_high_surrogate_key_up;
int last_high_surrogate_key_down;

View File

@ -1569,15 +1569,26 @@ xrdp_wm_mouse_click(struct xrdp_wm *self, int x, int y, int but, int down)
/*****************************************************************************/
int
xrdp_wm_key(struct xrdp_wm *self, int device_flags, int scan_code)
xrdp_wm_key(struct xrdp_wm *self, int keyboard_flags, int key_code)
{
int msg;
struct xrdp_key_info *ki;
LOG_DEVEL(LOG_LEVEL_DEBUG,
"xrdp_wm_key: RDP scancode:0x%04x, flags: 0x%04x",
scan_code, device_flags);
scan_code = scan_code % 128;
"xrdp_wm_key: RDP key_code:0x%04x, keyboard_flags: 0x%04x",
key_code, keyboard_flags);
int scancode = SCANCODE_FROM_KBD_EVENT(key_code, keyboard_flags);
int keyup = ((keyboard_flags & KBD_FLAG_UP) != 0);
int sindex = scancode_to_index(scancode);
if (sindex < 0)
{
// The scancode doesn't map to an index, so we can't handle it here.
// Log this so we can investigate
LOG(LOG_LEVEL_WARNING, "Ignoring unusable scancode %x (%s)",
scancode, (keyup ? "up" : "down"));
return 0;
}
if (self->popup_wnd != 0)
{
@ -1585,24 +1596,17 @@ xrdp_wm_key(struct xrdp_wm *self, int device_flags, int scan_code)
return 0;
}
// workaround odd shift behavior
// see https://github.com/neutrinolabs/xrdp/issues/397
if (scan_code == 42 && device_flags == (KBD_FLAG_UP | KBD_FLAG_EXT))
if (keyup)
{
return 0;
}
if (device_flags & KBD_FLAG_UP) /* 0x8000 */
{
self->keys[scan_code] = 0;
self->keys[sindex] = 0;
msg = WM_KEYUP;
}
else /* key down */
{
self->keys[scan_code] = 1 | device_flags;
self->keys[sindex] = 1;
msg = WM_KEYDOWN;
switch (scan_code)
switch (key_code)
{
case 58:
self->caps_lock = !self->caps_lock;
@ -1618,24 +1622,28 @@ xrdp_wm_key(struct xrdp_wm *self, int device_flags, int scan_code)
if (self->mm->mod != 0)
{
// Backend module loaded...
if (self->mm->mod->mod_event != 0)
{
ki = get_key_info_from_scan_code
(device_flags, scan_code, self->keys, self->caps_lock,
// ..and able to take events. Check the scancode maps to
// a real key in the currently loaded keymap
ki = get_key_info_from_kbd_event
(keyboard_flags, key_code, self->keys, self->caps_lock,
self->num_lock, self->scroll_lock,
&(self->keymap));
if (ki != 0)
{
self->mm->mod->mod_event(self->mm->mod, msg, ki->chr, ki->sym,
scan_code, device_flags);
key_code, keyboard_flags);
}
}
}
else if (self->focused_window != 0)
{
// Pass keypress on to a widget in the login window
xrdp_bitmap_def_proc(self->focused_window,
msg, scan_code, device_flags);
msg, key_code, keyboard_flags);
}
return 0;
@ -1720,6 +1728,29 @@ get_unicode_character(struct xrdp_wm *self, int device_flags, char16_t c16)
return c32;
}
/*****************************************************************************/
/**
* Takes a scancode index and fakes a keyboard event to represent it
* @param self module pointer
* @param device_flags default flags to pass in for the keyboard event.
* @param scancode index
*
* Some of the device_flags are overridden by the scancode derived from the
* scancode index
*/
static void
fake_kbd_event_from_scancode_index(struct xrdp_wm *self, int device_flags,
int index)
{
int scancode = scancode_from_index(index);
int key_code = SCANCODE_TO_KBD_EVENT_KEY_CODE(scancode);
device_flags &= ~(KBD_FLAG_EXT | KBD_FLAG_EXT1);
device_flags |= SCANCODE_TO_KBD_EVENT_KBD_FLAGS(scancode);
xrdp_wm_key(self, device_flags, key_code);
}
/*****************************************************************************/
static int
xrdp_wm_key_unicode(struct xrdp_wm *self, int device_flags, char32_t c16)
@ -1734,40 +1765,40 @@ xrdp_wm_key_unicode(struct xrdp_wm *self, int device_flags, char32_t c16)
// See if we can find the character in the existing keymap,
// and if so, generate normal key event(s) for it
for (index = XR_MIN_KEY_CODE; index < XR_MAX_KEY_CODE; index++)
for (index = 0; index <= SCANCODE_MAX_INDEX; ++index)
{
if (c32 == self->keymap.keys_noshift[index].chr)
{
xrdp_wm_key(self, device_flags, index - XR_MIN_KEY_CODE);
fake_kbd_event_from_scancode_index(self, device_flags, index);
return 0;
}
}
for (index = XR_MIN_KEY_CODE; index < XR_MAX_KEY_CODE; index++)
for (index = 0; index <= SCANCODE_MAX_INDEX; ++index)
{
if (c32 == self->keymap.keys_shift[index].chr)
{
if (device_flags & KBD_FLAG_UP)
{
xrdp_wm_key(self, device_flags, index - XR_MIN_KEY_CODE);
fake_kbd_event_from_scancode_index(self, device_flags, index);
xrdp_wm_key(self, KBD_FLAG_UP, XR_RDP_SCAN_LSHIFT);
}
else
{
xrdp_wm_key(self, KBD_FLAG_DOWN, XR_RDP_SCAN_LSHIFT);
xrdp_wm_key(self, device_flags, index - XR_MIN_KEY_CODE);
fake_kbd_event_from_scancode_index(self, device_flags, index);
}
return 0;
}
}
for (index = XR_MIN_KEY_CODE; index < XR_MAX_KEY_CODE; index++)
for (index = 0; index <= SCANCODE_MAX_INDEX; ++index)
{
if (c32 == self->keymap.keys_altgr[index].chr)
{
if (device_flags & KBD_FLAG_UP)
{
xrdp_wm_key(self, device_flags, index - XR_MIN_KEY_CODE);
fake_kbd_event_from_scancode_index(self, device_flags, index);
xrdp_wm_key(self, KBD_FLAG_UP | KBD_FLAG_EXT,
XR_RDP_SCAN_ALT);
}
@ -1775,19 +1806,19 @@ xrdp_wm_key_unicode(struct xrdp_wm *self, int device_flags, char32_t c16)
{
xrdp_wm_key(self, KBD_FLAG_DOWN | KBD_FLAG_EXT,
XR_RDP_SCAN_ALT);
xrdp_wm_key(self, device_flags, index - XR_MIN_KEY_CODE);
fake_kbd_event_from_scancode_index(self, device_flags, index);
}
return 0;
}
}
for (index = XR_MIN_KEY_CODE; index < XR_MAX_KEY_CODE; index++)
for (index = 0; index <= SCANCODE_MAX_INDEX; ++index)
{
if (c32 == self->keymap.keys_shiftaltgr[index].chr)
{
if (device_flags & KBD_FLAG_UP)
{
xrdp_wm_key(self, device_flags, index - XR_MIN_KEY_CODE);
fake_kbd_event_from_scancode_index(self, device_flags, index);
xrdp_wm_key(self, KBD_FLAG_UP | KBD_FLAG_EXT, XR_RDP_SCAN_ALT);
xrdp_wm_key(self, KBD_FLAG_UP, XR_RDP_SCAN_LSHIFT);
}
@ -1796,7 +1827,7 @@ xrdp_wm_key_unicode(struct xrdp_wm *self, int device_flags, char32_t c16)
xrdp_wm_key(self, KBD_FLAG_DOWN, XR_RDP_SCAN_LSHIFT);
xrdp_wm_key(self, KBD_FLAG_DOWN | KBD_FLAG_EXT,
XR_RDP_SCAN_ALT);
xrdp_wm_key(self, device_flags, index - XR_MIN_KEY_CODE);
fake_kbd_event_from_scancode_index(self, device_flags, index);
}
return 0;
}

View File

@ -266,6 +266,7 @@ lib_mod_event(struct mod *mod, int msg, tbus param1, tbus param2,
int len;
int key;
int rv;
int scancode;
LOG_DEVEL(LOG_LEVEL_TRACE, "in lib_mod_event");
make_stream(s);
@ -311,15 +312,8 @@ lib_mod_event(struct mod *mod, int msg, tbus param1, tbus param2,
/* xup doesn't need the Unicode character mapping in param1. Send
* the X11 scancode instead, so xorgxrdp doesn't have to do this
* work again */
if ((param4 & KBD_FLAG_EXT) != 0)
{
// Extended key - set bit 9 of the scancode for the lookup
param1 = scancode_to_keycode(param3 | 0x100);
}
else
{
param1 = scancode_to_keycode(param3);
}
scancode = SCANCODE_FROM_KBD_EVENT(param3, param4);
param1 = scancode_to_x11_keycode(scancode);
}
init_stream(s, 8192);