Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update scancode processing #3138

Merged
merged 11 commits into from
Aug 6, 2024
1 change: 1 addition & 0 deletions common/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ include_HEADERS = \
xrdp_client_info.h \
xrdp_constants.h \
xrdp_rail.h \
xrdp_scancode_defs.h \
xrdp_sockets.h

AM_CPPFLAGS = \
Expand Down
18 changes: 7 additions & 11 deletions common/ms-rdpbcgr.h
Original file line number Diff line number Diff line change
Expand Up @@ -480,13 +480,10 @@
#define RDP_INPUT_MOUSEX 0x8002

/* Keyboard Event: keyboardFlags (2.2.8.1.1.3.1.1.1) */
/* TODO: to be renamed */
#define KBD_FLAG_RIGHT 0x0001
#define KBD_FLAG_EXT 0x0100 /* KBDFLAGS_EXTENDED */
#define KBD_FLAG_EXT1 0x0200 /* KBDFLAGS_EXTENDED1 */
#define KBD_FLAG_QUIET 0x1000
#define KBD_FLAG_DOWN 0x4000
#define KBD_FLAG_UP 0x8000
#define KBDFLAGS_EXTENDED 0x0100
#define KBDFLAGS_EXTENDED1 0x0200
#define KBDFLAGS_DOWN 0x4000
#define KBDFLAGS_RELEASE 0x8000

/* Mouse Event: pointerFlags (2.2.8.1.1.3.1.1.3) */
#define PTRFLAGS_HWHEEL 0x0400
Expand All @@ -505,10 +502,9 @@
#define PTRXFLAGS_BUTTON2 0x0002

/* Synchronize Event: toggleFlags (2.2.8.1.1.3.1.1.5) */
/* TODO: to be renamed */
#define KBD_FLAG_SCROLL 0x0001 /* TS_SYNC_SCROLL_LOCK */
#define KBD_FLAG_NUMLOCK 0x0002
#define KBD_FLAG_CAPITAL 0x0004
#define TS_SYNC_SCROLL_LOCK 0x0001
#define TS_SYNC_NUM_LOCK 0x0002
#define TS_SYNC_CAPS_LOCK 0x0004
#define TS_SYNC_KANA_LOCK 0x0008

/* Client Fast-Path Input Event PDU 2.2.8.1.2 */
Expand Down
73 changes: 70 additions & 3 deletions common/scancode.c
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ static const struct scancode_to_keycode
{ 0x079, 100 }, // - HENK
{ 0x07b, 102 }, // VK_OEM_PA1 MUHE
{ 0x07d, 132 }, // - AE13
{ 0x07e, 129 }, // VK_ABNT_C2 KPPT (Brazil ABNT2)
{ 0x110, 173 }, // VK_MEDIA_PREV_TRACK I173 (KEY_PREVIOUSSONG)
{ 0x119, 171 }, // VK_MEDIA_NEXT_TRACK I171 (KEY_NEXTSONG)
{ 0x11c, 104 }, // VK_RETURN KPEN
Expand Down Expand Up @@ -167,7 +168,8 @@ static const struct scancode_to_keycode
{ 0x165, 225 }, // VK_BROWSER_SEARCH I225 (KEY_SEARCH)
{ 0x166, 164 }, // VK_BROWSER_FAVORITES I164 (KEY_BOOKMARKS)
{ 0x16b, 165 }, // VK_LAUNCH_APP1 I165 (KEY_COMPUTER)
{ 0x16c, 163 } // VK_LAUNCH_MAIL I163 (KEY_MAIL)
{ 0x16c, 163 }, // VK_LAUNCH_MAIL I163 (KEY_MAIL)
{ 0x21d, 127 } // VK_PAUSE PAUS (KEY_PAUSE)
};

// Sources:-
Expand Down Expand Up @@ -271,6 +273,7 @@ static const struct scancode_to_keycode
{ 0x079, 129 }, // - XFER
{ 0x07b, 131 }, // VK_OEM_PA1 NFER
{ 0x07d, 133 }, // - AE13
{ 0x07e, 134 }, // VK_ABNT_C2 KPPT (Brazil ABNT2)
{ 0x11c, 108 }, // VK_RETURN KPEN
{ 0x11d, 109 }, // VK_RCONTROL RCTL
{ 0x120, 141 }, // VK_VOLUME_MUTE MUTE
Expand All @@ -291,7 +294,8 @@ static const struct scancode_to_keycode
{ 0x153, 107 }, // VK_DELETE DELE
{ 0x15b, 115 }, // VK_LWIN LWIN
{ 0x15c, 116 }, // VK_RWIN RWIN
{ 0x15d, 117 } // VK_APPS COMP
{ 0x15d, 117 }, // VK_APPS COMP
{ 0x21d, 110 } // VK_PAUSE PAUS (KEY_PAUSE)
};

struct map_settings
Expand Down Expand Up @@ -326,9 +330,63 @@ 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 <= 0x177)
{
// 01x100 - 0x177 : Move bit 9 to bit 8
return (scancode & 0x7f) | 0x80;
}

if (scancode == SCANCODE_PAUSE_KEY)
{
return SCANCODE_INDEX_PAUSE_KEY;
}

// This leaves the following which are all rejected
// 0x178 - 0x17f (currently unused). These would map to indexes 0xf8
// to 0xff which we are reserving for extended1 keys.
// 0x180 - 0x1ff Illegal format
// >0x200 Anything not mentioned explicitly above (e.g.
// SCANCODE_PAUSE_KEY)
return -1;
}

/*****************************************************************************/
unsigned short
scancode_to_keycode(unsigned short scancode)
scancode_from_index(int index)
{
index &= 0xff;
unsigned short result;
if (index == SCANCODE_INDEX_PAUSE_KEY)
{
result = SCANCODE_PAUSE_KEY;
}
else 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;
Expand Down Expand Up @@ -419,3 +477,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;
}
100 changes: 91 additions & 9 deletions common/scancode.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -39,15 +58,69 @@
#if !defined(SCANCODE_H)
#define SCANCODE_H

#include "xrdp_scancode_defs.h"

enum
{
/**
* Scancodes for keys used in the code are defined in the global
* file xrdp_scancode_defs.h
*/

/**
* Scancode indexes for some of the keys in xrdp_scancode_defs.h
*/
SCANCODE_INDEX_LSHIFT_KEY = SCANCODE_LSHIFT_KEY,
SCANCODE_INDEX_RSHIFT_KEY = SCANCODE_RSHIFT_KEY,
SCANCODE_INDEX_RALT_KEY = (SCANCODE_RALT_KEY & 0x7f) | 0x80,
SCANCODE_INDEX_PAUSE_KEY = 0xf8,
// 0xf9 - 0xff reserved for future extended1 mappings

/**
* Maximum value returned by scancode_to_index()
*/
SCANCODE_MAX_INDEX = 255
};

/**
* Convert a scancode to an index
* @param scancode scancode in the range 0x00 - 0x2ff
* @return index in the range 0..SCANCODE_MAX_INDEX (inclusive) or -1
*
* This function converts a 10-bit scancode into an 8-bit array index,
* independent of the currently loaded keymap
*
* This is possible as the scancodes from 0x80 - 0x2ff are sparsely allocated.
*
* 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
* 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). Extended1 scancodes
* (currently just the pause key) are in the range 0x200-0x2ff
* @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
Expand Down Expand Up @@ -84,4 +157,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 */
7 changes: 6 additions & 1 deletion common/xrdp_client_info.h
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,11 @@ struct xrdp_client_info
char layout[16];
char variant[16];
char options[256];
char xkb_rules[32];
// A few x11 keycodes are needed by the xup module
int x11_keycode_caps_lock;
int x11_keycode_num_lock;
int x11_keycode_scroll_lock;

/* ==================================================================== */
/* Private to xrdp below this line */
Expand Down Expand Up @@ -269,6 +274,6 @@ enum xrdp_encoder_flags

/* yyyymmdd of last incompatible change to xrdp_client_info */
/* also used for changes to all the xrdp installed headers */
#define CLIENT_INFO_CURRENT_VERSION 20240514
#define CLIENT_INFO_CURRENT_VERSION 20240805

#endif
9 changes: 0 additions & 9 deletions common/xrdp_constants.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
*/
Expand Down Expand Up @@ -288,12 +285,6 @@

#define FASTPATH_MAX_PACKET_SIZE 0x3fff

#define XR_RDP_SCAN_LSHIFT 42
#define XR_RDP_SCAN_ALT 56
// scancodes affected by numlock
#define XR_RDP_SCAN_MIN_NUMLOCK 71 // KP7
#define XR_RDP_SCAN_MAX_NUMLOCK 83 // KPDL

// Since we're not guaranteed to have pixman, copy these directives.
#define XRDP_PIXMAN_TYPE_ARGB 2
#define XRDP_PIXMAN_TYPE_ABGR 3
Expand Down
Loading