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:
parent
d82a172b55
commit
c91ef80ca9
@ -326,9 +326,48 @@ const struct map_settings global_settings[] =
|
|||||||
// Default mapping set is "evdev"
|
// Default mapping set is "evdev"
|
||||||
const struct map_settings *settings = &global_settings[SI_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
|
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 min = 0;
|
||||||
unsigned int max = settings->size;
|
unsigned int max = settings->size;
|
||||||
@ -419,3 +458,12 @@ scancode_get_keycode_set(void)
|
|||||||
{
|
{
|
||||||
return settings->name;
|
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;
|
||||||
|
}
|
||||||
|
@ -18,13 +18,32 @@
|
|||||||
* @file common/scancode.h
|
* @file common/scancode.h
|
||||||
* @brief Scancode handling
|
* @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
|
* The values received in TS_KEYBOARD_EVENT PDUs are largely the same as
|
||||||
* indirectly documented in the Microsoft "Keyboard Scan Code Specification",
|
* Windows scancodes. These are indirectly documented in the Microsoft
|
||||||
* Rev 1.3a (March 16th 2000) and are otherwise known as "Scan code set
|
* "Keyboard Scan Code Specification", Rev 1.3a (March 16th 2000) and
|
||||||
* 1" scancodes. This document no longer appears to be available directly from
|
* are otherwise known as "Scan code set 1" scancodes. This document no
|
||||||
* the Microsoft website.
|
* 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
|
* X11 keycodes are the X11 equivalent of RDP scancodes. In general, these
|
||||||
* are specific to an X server. In practice however, these are nowadays
|
* are specific to an X server. In practice however, these are nowadays
|
||||||
@ -39,15 +58,63 @@
|
|||||||
#if !defined(SCANCODE_H)
|
#if !defined(SCANCODE_H)
|
||||||
#define 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
|
* @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
|
* @return keycode, or 0 for no keycode
|
||||||
*/
|
*/
|
||||||
unsigned short
|
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
|
* 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 *
|
const char *
|
||||||
scancode_get_keycode_set(void);
|
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 */
|
#endif /* SCANCODE_H */
|
||||||
|
@ -63,9 +63,6 @@
|
|||||||
#define XRDP_MAX_BITMAP_CACHE_IDX 2000
|
#define XRDP_MAX_BITMAP_CACHE_IDX 2000
|
||||||
#define XRDP_BITMAP_CACHE_ENTRIES 2048
|
#define XRDP_BITMAP_CACHE_ENTRIES 2048
|
||||||
|
|
||||||
#define XR_MIN_KEY_CODE 8
|
|
||||||
#define XR_MAX_KEY_CODE 256
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Constants come from ITU-T Recommendations
|
* Constants come from ITU-T Recommendations
|
||||||
*/
|
*/
|
||||||
|
@ -279,7 +279,7 @@ output_file_section(FILE *outf,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
e.keycode = scancode_to_keycode(scancode);
|
e.keycode = scancode_to_x11_keycode(scancode);
|
||||||
nbytes = XLookupString(&e, text, 255, &ks, NULL);
|
nbytes = XLookupString(&e, text, 255, &ks, NULL);
|
||||||
if (ks == NoSymbol)
|
if (ks == NoSymbol)
|
||||||
{
|
{
|
||||||
|
@ -31,7 +31,7 @@ START_TEST(test_scancode__evdev_all_values_returned)
|
|||||||
iter = 0;
|
iter = 0;
|
||||||
while ((scancode = scancode_get_next(&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);
|
ck_assert_int_ne(keycode, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -57,7 +57,7 @@ START_TEST(test_scancode__evdev_bad_values_mapped_to_0)
|
|||||||
{
|
{
|
||||||
if (!valid[scancode])
|
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;
|
iter = 0;
|
||||||
while ((scancode = scancode_get_next(&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);
|
ck_assert_int_ne(keycode, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -100,7 +100,7 @@ START_TEST(test_scancode__base_bad_values_mapped_to_0)
|
|||||||
{
|
{
|
||||||
if (!valid[scancode])
|
if (!valid[scancode])
|
||||||
{
|
{
|
||||||
ck_assert_int_eq(scancode_to_keycode(scancode), 0);
|
ck_assert_int_eq(scancode_to_x11_keycode(scancode), 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
134
xrdp/lang.c
134
xrdp/lang.c
@ -39,58 +39,64 @@
|
|||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
struct xrdp_key_info *
|
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,
|
int caps_lock, int num_lock, int scroll_lock,
|
||||||
struct xrdp_keymap *keymap)
|
struct xrdp_keymap *keymap)
|
||||||
{
|
{
|
||||||
struct xrdp_key_info *rv;
|
struct xrdp_key_info *rv;
|
||||||
int shift;
|
int shift;
|
||||||
|
int altgr_scancode;
|
||||||
int altgr;
|
int altgr;
|
||||||
int ext;
|
|
||||||
int index;
|
int index;
|
||||||
|
|
||||||
ext = device_flags & KBD_FLAG_EXT; /* 0x0100 */
|
|
||||||
shift = keys[42] || keys[54];
|
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;
|
rv = 0;
|
||||||
index = INDEX_FROM_SCANCODE(scan_code, ext);
|
|
||||||
|
|
||||||
if (num_lock &&
|
index = scancode_to_index(SCANCODE_FROM_KBD_EVENT(key_code, keyboard_flags));
|
||||||
index >= XR_RDP_SCAN_MIN_NUMLOCK && index <= XR_RDP_SCAN_MAX_NUMLOCK)
|
if (index >= 0)
|
||||||
{
|
{
|
||||||
rv = &(keymap->keys_numlock[index - XR_RDP_SCAN_MIN_NUMLOCK]);
|
// scancode_to_index() guarantees to map numlock scancodes
|
||||||
}
|
// to the same index values.
|
||||||
else if (shift && caps_lock && altgr)
|
if (num_lock &&
|
||||||
{
|
index >= XR_RDP_SCAN_MIN_NUMLOCK &&
|
||||||
rv = &(keymap->keys_shiftcapslockaltgr[index]);
|
index <= XR_RDP_SCAN_MAX_NUMLOCK)
|
||||||
}
|
{
|
||||||
else if (shift && caps_lock)
|
rv = &(keymap->keys_numlock[index - XR_RDP_SCAN_MIN_NUMLOCK]);
|
||||||
{
|
}
|
||||||
rv = &(keymap->keys_shiftcapslock[index]);
|
else if (shift && caps_lock && altgr)
|
||||||
}
|
{
|
||||||
else if (shift && altgr)
|
rv = &(keymap->keys_shiftcapslockaltgr[index]);
|
||||||
{
|
}
|
||||||
rv = &(keymap->keys_shiftaltgr[index]);
|
else if (shift && caps_lock)
|
||||||
}
|
{
|
||||||
else if (shift)
|
rv = &(keymap->keys_shiftcapslock[index]);
|
||||||
{
|
}
|
||||||
rv = &(keymap->keys_shift[index]);
|
else if (shift && altgr)
|
||||||
}
|
{
|
||||||
else if (caps_lock && altgr)
|
rv = &(keymap->keys_shiftaltgr[index]);
|
||||||
{
|
}
|
||||||
rv = &(keymap->keys_capslockaltgr[index]);
|
else if (shift)
|
||||||
}
|
{
|
||||||
else if (caps_lock)
|
rv = &(keymap->keys_shift[index]);
|
||||||
{
|
}
|
||||||
rv = &(keymap->keys_capslock[index]);
|
else if (caps_lock && altgr)
|
||||||
}
|
{
|
||||||
else if (altgr)
|
rv = &(keymap->keys_capslockaltgr[index]);
|
||||||
{
|
}
|
||||||
rv = &(keymap->keys_altgr[index]);
|
else if (caps_lock)
|
||||||
}
|
{
|
||||||
else
|
rv = &(keymap->keys_capslock[index]);
|
||||||
{
|
}
|
||||||
rv = &(keymap->keys_noshift[index]);
|
else if (altgr)
|
||||||
|
{
|
||||||
|
rv = &(keymap->keys_altgr[index]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rv = &(keymap->keys_noshift[index]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return rv;
|
return rv;
|
||||||
@ -98,13 +104,13 @@ get_key_info_from_scan_code(int device_flags, int scan_code, int *keys,
|
|||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
int
|
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,
|
int caps_lock, int num_lock, int scroll_lock,
|
||||||
struct xrdp_keymap *keymap)
|
struct xrdp_keymap *keymap)
|
||||||
{
|
{
|
||||||
struct xrdp_key_info *ki;
|
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,
|
caps_lock, num_lock, scroll_lock,
|
||||||
keymap);
|
keymap);
|
||||||
|
|
||||||
@ -118,13 +124,13 @@ get_keysym_from_scan_code(int device_flags, int scan_code, int *keys,
|
|||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
char32_t
|
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,
|
int caps_lock, int num_lock, int scroll_lock,
|
||||||
struct xrdp_keymap *keymap)
|
struct xrdp_keymap *keymap)
|
||||||
{
|
{
|
||||||
struct xrdp_key_info *ki;
|
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,
|
caps_lock, num_lock, scroll_lock,
|
||||||
keymap);
|
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 key Table key
|
||||||
* @param[out] scancode scancode index value (0..255) if 1 is returned
|
* @return index >= 0, or < 0 for an invalid key
|
||||||
* @return Boolean != 0 if the key is valid
|
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
is_valid_scancode(const char *key, int *scancode)
|
key_to_scancode_index(const char *key)
|
||||||
{
|
{
|
||||||
int rv = 0;
|
int rv = -1;
|
||||||
int extended = 0;
|
int keyboard_flags = 0;
|
||||||
if ((key[0] == 'E' || key[0] == 'e') && key[1] == '0' && key[2] == '_')
|
if ((key[0] == 'E' || key[0] == 'e') && key[2] == '_')
|
||||||
{
|
{
|
||||||
extended = 1;
|
if (key[1] == '0')
|
||||||
key += 3;
|
{
|
||||||
|
keyboard_flags |= KBD_FLAG_EXT;
|
||||||
|
key += 3;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isxdigit(key[0]) && isxdigit(key[1]) && key[2] == '\0')
|
if (isxdigit(key[0]) && isxdigit(key[1]) && key[2] == '\0')
|
||||||
{
|
{
|
||||||
rv = 1;
|
int code = XDIGIT_TO_VAL(key[0]) * 16 + XDIGIT_TO_VAL(key[1]);
|
||||||
*scancode = XDIGIT_TO_VAL(key[0]) * 16 + XDIGIT_TO_VAL(key[1]);
|
rv = scancode_to_index(SCANCODE_FROM_KBD_EVENT(code, keyboard_flags));
|
||||||
*scancode = INDEX_FROM_SCANCODE(*scancode, extended);
|
|
||||||
}
|
}
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
@ -248,13 +255,14 @@ km_read_section(toml_table_t *tfile, const char *section_name,
|
|||||||
{
|
{
|
||||||
const char *key;
|
const char *key;
|
||||||
toml_datum_t val;
|
toml_datum_t val;
|
||||||
int index;
|
int i;
|
||||||
int scancode; // index value 0..255
|
|
||||||
char *p;
|
char *p;
|
||||||
const char *unicode_str;
|
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,
|
LOG(LOG_LEVEL_WARNING,
|
||||||
"Can't parse value '%s' in [%s] in keymap file",
|
"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
|
/* Parse both values and add them to the keymap, logging any
|
||||||
* errors */
|
* 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,
|
LOG(LOG_LEVEL_WARNING,
|
||||||
"Can't read KeySym for [%s]:%s in keymap file",
|
"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 &&
|
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,
|
LOG(LOG_LEVEL_WARNING,
|
||||||
"Can't read unicode character for [%s]:%s in keymap file",
|
"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
|
/* The numlock map is much smaller and offset by
|
||||||
* XR_RDP_SCAN_MAX_NUMLOCK. Read the section into a temporary
|
* XR_RDP_SCAN_MAX_NUMLOCK. Read the section into a temporary
|
||||||
* area and copy it over */
|
* area and copy it over */
|
||||||
struct xrdp_key_info keys_numlock[256];
|
struct xrdp_key_info keys_numlock[SCANCODE_MAX_INDEX + 1];
|
||||||
int i;
|
int i;
|
||||||
for (i = XR_RDP_SCAN_MIN_NUMLOCK; i <= XR_RDP_SCAN_MAX_NUMLOCK; ++i)
|
for (i = XR_RDP_SCAN_MIN_NUMLOCK; i <= XR_RDP_SCAN_MAX_NUMLOCK; ++i)
|
||||||
{
|
{
|
||||||
|
14
xrdp/xrdp.h
14
xrdp/xrdp.h
@ -147,8 +147,14 @@ int
|
|||||||
xrdp_wm_mouse_touch(struct xrdp_wm *self, int gesture, int param);
|
xrdp_wm_mouse_touch(struct xrdp_wm *self, int gesture, int param);
|
||||||
int
|
int
|
||||||
xrdp_wm_mouse_click(struct xrdp_wm *self, int x, int y, int but, int down);
|
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
|
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
|
int
|
||||||
xrdp_wm_key_sync(struct xrdp_wm *self, int device_flags, int key_flags);
|
xrdp_wm_key_sync(struct xrdp_wm *self, int device_flags, int key_flags);
|
||||||
int
|
int
|
||||||
@ -424,15 +430,15 @@ set_string(char **in_str, const char *in);
|
|||||||
|
|
||||||
/* in lang.c */
|
/* in lang.c */
|
||||||
struct xrdp_key_info *
|
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,
|
int caps_lock, int num_lock, int scroll_lock,
|
||||||
struct xrdp_keymap *keymap);
|
struct xrdp_keymap *keymap);
|
||||||
int
|
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,
|
int caps_lock, int num_lock, int scroll_lock,
|
||||||
struct xrdp_keymap *keymap);
|
struct xrdp_keymap *keymap);
|
||||||
char32_t
|
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,
|
int caps_lock, int num_lock, int scroll_lock,
|
||||||
struct xrdp_keymap *keymap);
|
struct xrdp_keymap *keymap);
|
||||||
int
|
int
|
||||||
|
@ -1226,7 +1226,7 @@ xrdp_bitmap_def_proc(struct xrdp_bitmap *self, int msg,
|
|||||||
}
|
}
|
||||||
else
|
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,
|
(param2, scan_code, self->wm->keys, self->wm->caps_lock,
|
||||||
self->wm->num_lock, self->wm->scroll_lock,
|
self->wm->num_lock, self->wm->scroll_lock,
|
||||||
&(self->wm->keymap));
|
&(self->wm->keymap));
|
||||||
|
@ -28,6 +28,7 @@
|
|||||||
#include "xrdp_constants.h"
|
#include "xrdp_constants.h"
|
||||||
#include "fifo.h"
|
#include "fifo.h"
|
||||||
#include "guid.h"
|
#include "guid.h"
|
||||||
|
#include "scancode.h"
|
||||||
#include "xrdp_client_info.h"
|
#include "xrdp_client_info.h"
|
||||||
|
|
||||||
#define MAX_NR_CHANNELS 16
|
#define MAX_NR_CHANNELS 16
|
||||||
@ -452,25 +453,17 @@ struct xrdp_key_info
|
|||||||
char32_t chr;
|
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_keymap
|
||||||
{
|
{
|
||||||
struct xrdp_key_info keys_noshift[256];
|
// These arrays are indexed by a return from scancode_to_index()
|
||||||
struct xrdp_key_info keys_shift[256];
|
struct xrdp_key_info keys_noshift[SCANCODE_MAX_INDEX + 1];
|
||||||
struct xrdp_key_info keys_altgr[256];
|
struct xrdp_key_info keys_shift[SCANCODE_MAX_INDEX + 1];
|
||||||
struct xrdp_key_info keys_shiftaltgr[256];
|
struct xrdp_key_info keys_altgr[SCANCODE_MAX_INDEX + 1];
|
||||||
struct xrdp_key_info keys_capslock[256];
|
struct xrdp_key_info keys_shiftaltgr[SCANCODE_MAX_INDEX + 1];
|
||||||
struct xrdp_key_info keys_capslockaltgr[256];
|
struct xrdp_key_info keys_capslock[SCANCODE_MAX_INDEX + 1];
|
||||||
struct xrdp_key_info keys_shiftcapslock[256];
|
struct xrdp_key_info keys_capslockaltgr[SCANCODE_MAX_INDEX + 1];
|
||||||
struct xrdp_key_info keys_shiftcapslockaltgr[256];
|
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
|
// NumLock is restricted to a much smaller set of keys
|
||||||
struct xrdp_key_info keys_numlock[XR_RDP_SCAN_MAX_NUMLOCK -
|
struct xrdp_key_info keys_numlock[XR_RDP_SCAN_MAX_NUMLOCK -
|
||||||
XR_RDP_SCAN_MIN_NUMLOCK + 1];
|
XR_RDP_SCAN_MIN_NUMLOCK + 1];
|
||||||
@ -554,11 +547,12 @@ struct xrdp_wm
|
|||||||
int current_pointer;
|
int current_pointer;
|
||||||
int mouse_x;
|
int mouse_x;
|
||||||
int mouse_y;
|
int mouse_y;
|
||||||
/* keyboard info */
|
/* keyboard info (indexed by a return from scancode_to_index()) */
|
||||||
int keys[256]; /* key states 0 up 1 down*/
|
int keys[SCANCODE_MAX_INDEX + 1]; /* key states 0 up 1 down*/
|
||||||
int caps_lock;
|
int caps_lock;
|
||||||
int scroll_lock;
|
int scroll_lock;
|
||||||
int num_lock;
|
int num_lock;
|
||||||
|
|
||||||
/* Unicode input */
|
/* Unicode input */
|
||||||
int last_high_surrogate_key_up;
|
int last_high_surrogate_key_up;
|
||||||
int last_high_surrogate_key_down;
|
int last_high_surrogate_key_down;
|
||||||
|
@ -1569,15 +1569,26 @@ xrdp_wm_mouse_click(struct xrdp_wm *self, int x, int y, int but, int down)
|
|||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
int
|
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;
|
int msg;
|
||||||
struct xrdp_key_info *ki;
|
struct xrdp_key_info *ki;
|
||||||
|
|
||||||
LOG_DEVEL(LOG_LEVEL_DEBUG,
|
LOG_DEVEL(LOG_LEVEL_DEBUG,
|
||||||
"xrdp_wm_key: RDP scancode:0x%04x, flags: 0x%04x",
|
"xrdp_wm_key: RDP key_code:0x%04x, keyboard_flags: 0x%04x",
|
||||||
scan_code, device_flags);
|
key_code, keyboard_flags);
|
||||||
scan_code = scan_code % 128;
|
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)
|
if (self->popup_wnd != 0)
|
||||||
{
|
{
|
||||||
@ -1585,24 +1596,17 @@ xrdp_wm_key(struct xrdp_wm *self, int device_flags, int scan_code)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// workaround odd shift behavior
|
if (keyup)
|
||||||
// see https://github.com/neutrinolabs/xrdp/issues/397
|
|
||||||
if (scan_code == 42 && device_flags == (KBD_FLAG_UP | KBD_FLAG_EXT))
|
|
||||||
{
|
{
|
||||||
return 0;
|
self->keys[sindex] = 0;
|
||||||
}
|
|
||||||
|
|
||||||
if (device_flags & KBD_FLAG_UP) /* 0x8000 */
|
|
||||||
{
|
|
||||||
self->keys[scan_code] = 0;
|
|
||||||
msg = WM_KEYUP;
|
msg = WM_KEYUP;
|
||||||
}
|
}
|
||||||
else /* key down */
|
else /* key down */
|
||||||
{
|
{
|
||||||
self->keys[scan_code] = 1 | device_flags;
|
self->keys[sindex] = 1;
|
||||||
msg = WM_KEYDOWN;
|
msg = WM_KEYDOWN;
|
||||||
|
|
||||||
switch (scan_code)
|
switch (key_code)
|
||||||
{
|
{
|
||||||
case 58:
|
case 58:
|
||||||
self->caps_lock = !self->caps_lock;
|
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)
|
if (self->mm->mod != 0)
|
||||||
{
|
{
|
||||||
|
// Backend module loaded...
|
||||||
if (self->mm->mod->mod_event != 0)
|
if (self->mm->mod->mod_event != 0)
|
||||||
{
|
{
|
||||||
ki = get_key_info_from_scan_code
|
// ..and able to take events. Check the scancode maps to
|
||||||
(device_flags, scan_code, self->keys, self->caps_lock,
|
// 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->num_lock, self->scroll_lock,
|
||||||
&(self->keymap));
|
&(self->keymap));
|
||||||
|
|
||||||
if (ki != 0)
|
if (ki != 0)
|
||||||
{
|
{
|
||||||
self->mm->mod->mod_event(self->mm->mod, msg, ki->chr, ki->sym,
|
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)
|
else if (self->focused_window != 0)
|
||||||
{
|
{
|
||||||
|
// Pass keypress on to a widget in the login window
|
||||||
xrdp_bitmap_def_proc(self->focused_window,
|
xrdp_bitmap_def_proc(self->focused_window,
|
||||||
msg, scan_code, device_flags);
|
msg, key_code, keyboard_flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -1720,6 +1728,29 @@ get_unicode_character(struct xrdp_wm *self, int device_flags, char16_t c16)
|
|||||||
return c32;
|
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
|
static int
|
||||||
xrdp_wm_key_unicode(struct xrdp_wm *self, int device_flags, char32_t c16)
|
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,
|
// See if we can find the character in the existing keymap,
|
||||||
// and if so, generate normal key event(s) for it
|
// 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)
|
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;
|
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 (c32 == self->keymap.keys_shift[index].chr)
|
||||||
{
|
{
|
||||||
if (device_flags & KBD_FLAG_UP)
|
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);
|
xrdp_wm_key(self, KBD_FLAG_UP, XR_RDP_SCAN_LSHIFT);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
xrdp_wm_key(self, KBD_FLAG_DOWN, XR_RDP_SCAN_LSHIFT);
|
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;
|
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 (c32 == self->keymap.keys_altgr[index].chr)
|
||||||
{
|
{
|
||||||
if (device_flags & KBD_FLAG_UP)
|
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,
|
xrdp_wm_key(self, KBD_FLAG_UP | KBD_FLAG_EXT,
|
||||||
XR_RDP_SCAN_ALT);
|
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,
|
xrdp_wm_key(self, KBD_FLAG_DOWN | KBD_FLAG_EXT,
|
||||||
XR_RDP_SCAN_ALT);
|
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;
|
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 (c32 == self->keymap.keys_shiftaltgr[index].chr)
|
||||||
{
|
{
|
||||||
if (device_flags & KBD_FLAG_UP)
|
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 | KBD_FLAG_EXT, XR_RDP_SCAN_ALT);
|
||||||
xrdp_wm_key(self, KBD_FLAG_UP, XR_RDP_SCAN_LSHIFT);
|
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, XR_RDP_SCAN_LSHIFT);
|
||||||
xrdp_wm_key(self, KBD_FLAG_DOWN | KBD_FLAG_EXT,
|
xrdp_wm_key(self, KBD_FLAG_DOWN | KBD_FLAG_EXT,
|
||||||
XR_RDP_SCAN_ALT);
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
12
xup/xup.c
12
xup/xup.c
@ -266,6 +266,7 @@ lib_mod_event(struct mod *mod, int msg, tbus param1, tbus param2,
|
|||||||
int len;
|
int len;
|
||||||
int key;
|
int key;
|
||||||
int rv;
|
int rv;
|
||||||
|
int scancode;
|
||||||
|
|
||||||
LOG_DEVEL(LOG_LEVEL_TRACE, "in lib_mod_event");
|
LOG_DEVEL(LOG_LEVEL_TRACE, "in lib_mod_event");
|
||||||
make_stream(s);
|
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
|
/* xup doesn't need the Unicode character mapping in param1. Send
|
||||||
* the X11 scancode instead, so xorgxrdp doesn't have to do this
|
* the X11 scancode instead, so xorgxrdp doesn't have to do this
|
||||||
* work again */
|
* work again */
|
||||||
if ((param4 & KBD_FLAG_EXT) != 0)
|
scancode = SCANCODE_FROM_KBD_EVENT(param3, param4);
|
||||||
{
|
param1 = scancode_to_x11_keycode(scancode);
|
||||||
// Extended key - set bit 9 of the scancode for the lookup
|
|
||||||
param1 = scancode_to_keycode(param3 | 0x100);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
param1 = scancode_to_keycode(param3);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
init_stream(s, 8192);
|
init_stream(s, 8192);
|
||||||
|
Loading…
Reference in New Issue
Block a user