Skip to content

Commit

Permalink
Check-in for weekend - needs more testing
Browse files Browse the repository at this point in the history
  • Loading branch information
matt335672 committed Jun 22, 2024
1 parent 478f4f6 commit 2949c20
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 72 deletions.
10 changes: 9 additions & 1 deletion module/rdp.h
Original file line number Diff line number Diff line change
Expand Up @@ -130,11 +130,19 @@ typedef struct _rdpPointer rdpPointer;

struct _rdpKeyboard
{
int pause_spe;
/* TODO : Check if these are needed */
int ctrl_down;
int alt_down;
int shift_down;

int tab_down;

int skip_numlock;

int x11_keycode_caps_lock;
int x11_keycode_num_lock;
int x11_keycode_scroll_lock;

/* this is toggled every time num lock key is released, not like the
above *_down vars */
int scroll_lock_down;
Expand Down
151 changes: 80 additions & 71 deletions xrdpkeyb/rdpKeyboard.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ xrdp keyboard module
#include "rdpDraw.h"
#include "rdpMisc.h"

#include "xrdp_scancode_defs.h"

/******************************************************************************/
#define LOG_LEVEL 1
#define LLOGLN(_level, _args) \
Expand All @@ -79,9 +81,6 @@ xrdp keyboard module
/* num lock */
#define NUM_LOCK_KEY_CODE 77

// From /usr/share/X11/xkb/keycodes/evdev
#define EVDEV_PAUS_KEY_CODE 127

#define N_PREDEFINED_KEYS \
(sizeof(g_kbdMap) / (sizeof(KeySym) * GLYPHS_PER_KEY))

Expand Down Expand Up @@ -249,6 +248,7 @@ sendDownUpKeyEvent(DeviceIntPtr device, int type, int x_scancode)
static void
check_keysa(rdpKeyboard *keyboard)
{
/* TODO : Check if these are needed */
if (keyboard->ctrl_down != 0)
{
rdpEnqueueKey(keyboard->device, KeyRelease, keyboard->ctrl_down);
Expand All @@ -266,49 +266,71 @@ check_keysa(rdpKeyboard *keyboard)
rdpEnqueueKey(keyboard->device, KeyRelease, keyboard->shift_down);
keyboard->shift_down = 0;
}

// Terminate any pause sequence in progress
keyboard->skip_numlock = 0;
}

/**
* @param down - true for KeyDown events, false otherwise
* @param param1 - X11 keycode of pressed key
* @param param2 -
* @param param3 - scancode of pressed key
* @param param4 - device flags
* @param param3 - keyCode from TS_KEYBOARD_EVENT
* @param param4 - keyboardFlags from TS_KEYBOARD_EVENT
******************************************************************************/
static void
KbdAddEvent(rdpKeyboard *keyboard, int down, int param1, int param2,
int param3, int param4)
{
int x_keycode = param1;
int rdp_scancode = param3;
int is_spe = param4 & 512; /* 0x200 */
int rdp_scancode = SCANCODE_FROM_KBD_EVENT(param3, param4);
int type = down ? KeyPress : KeyRelease;

// Create an extended scancode where if the extended bit is set,
// the scancode is >= 0x100
int ext_rdp_scancode = (param4 & 0x100) | rdp_scancode;
LLOGLN(0, ("KbdAddEvent: down=%d scancode=%09x keycode=%d flags%08x", down, ext_rdp_scancode, x_keycode, param4));
switch (ext_rdp_scancode)
LLOGLN(0, ("KbdAddEvent: down=%d RDP scancode=%03x "
"PDU keyCode=%04x PDU keyboardFlags=%04x X11 keycode=%04x",
down, rdp_scancode,
param3, param4, x_keycode));

if (keyboard->skip_numlock)
{
keyboard->skip_numlock = 0;
if (rdp_scancode == SCANCODE_NUMLOCK_KEY)
{
return;
}
}
switch (rdp_scancode)
{
/* Non-repeating keys (except ctrl - see below) */
case 0x02a: /* left shift */
case 0x036: /* right shift */
case 0x03a: /* caps lock */
case 0x038: /* left alt */
case 0x046: /* scroll lock */
case 0x059: /* left meta */
case 0x05a: /* right meta */
case 0x138: /* right alt */
case 0x15b: /* left win key */
case 0x15c: /* right win key */
case 0x15d: /* menu key */
/* Non-repeating keys */
case SCANCODE_LSHIFT_KEY:
case SCANCODE_RSHIFT_KEY:
case SCANCODE_LCTRL_KEY:
case SCANCODE_RCTRL_KEY:
case SCANCODE_LALT_KEY:
case SCANCODE_RALT_KEY:
case SCANCODE_CAPS_KEY:
case SCANCODE_NUMLOCK_KEY:
case SCANCODE_LWIN_KEY:
case SCANCODE_RWIN_KEY:
case SCANCODE_MENU_KEY:
rdpEnqueueKey(keyboard->device, type, x_keycode);
break;

case 0x00f: /* tab */
case SCANCODE_SCROLL_KEY:
// Scroll lock is also non-repeating, but we need to keep
// track of the key state to handle a TS_SYNC_EVENT from
// the client.
if (type == KeyPress)
{
keyboard->scroll_lock_down = !keyboard->scroll_lock_down;
}
rdpEnqueueKey(keyboard->device, type, x_keycode);
break;

case SCANCODE_TAB_KEY:
if (!down && !keyboard->tab_down)
{
/* leave x_keycode 0 here, we don't want the tab key up */
/* Don't generate an event for this */
check_keysa(keyboard);
}
else
Expand All @@ -319,42 +341,12 @@ KbdAddEvent(rdpKeyboard *keyboard, int down, int param1, int param2,
keyboard->tab_down = down;
break;

case 0x01d: /* left ctrl */
case 0x11d: /* right ctrl */

case SCANCODE_PAUSE_KEY:
/* The pause key (0xE1 0x1D from the keyboard controller)
* is mapped to a combination of ctrl and numlock events -
* see [MS-RDPBCGR] 2.2.8.1.1.3.1.1.1 for details */
if (is_spe)
{
if (down)
{
keyboard->pause_spe = 1;
/* leave x_keycode 0 here, we don't want the control key down */
}
}
else
{
keyboard->ctrl_down = down ? x_keycode : 0;
rdpEnqueueKey(keyboard->device, type, x_keycode);
}

break;


case 0x045: /* Pause or Num Lock */

if (keyboard->pause_spe)
{
x_keycode = EVDEV_PAUS_KEY_CODE;

if (!down)
{
keyboard->pause_spe = 0;
}
}

sendDownUpKeyEvent(keyboard->device, type, x_keycode);
rdpEnqueueKey(keyboard->device, type, x_keycode);
keyboard->skip_numlock = 1;
break;

default:
Expand All @@ -368,35 +360,44 @@ KbdAddEvent(rdpKeyboard *keyboard, int down, int param1, int param2,
}

/******************************************************************************/
/* notes -
scroll lock doesn't seem to be a modifier in X
*/
static void
KbdSync(rdpKeyboard *keyboard, int param1)
{
int xkb_state;

xkb_state = XkbStateFieldFromRec(&(keyboard->device->key->xkbInfo->state));

if ((!(xkb_state & 0x02)) != (!(param1 & 4))) /* caps lock */
// Caps_Lock is a specific modifier */
if ((!(xkb_state & LockMask)) != (!(param1 & TS_SYNC_CAPS_LOCK)))
{
LLOGLN(0, ("KbdSync: toggling caps lock"));
KbdAddEvent(keyboard, 1, 58, 0, 58, 0);
KbdAddEvent(keyboard, 0, 58, 49152, 58, 49152);
rdpEnqueueKey(keyboard->device, KeyPress,
keyboard->x11_keycode_caps_lock);
rdpEnqueueKey(keyboard->device, KeyRelease,
keyboard->x11_keycode_caps_lock);
}

if ((!(xkb_state & 0x10)) != (!(param1 & 2))) /* num lock */
// Num_Lock is normally mapped to mod2 (see 'xmodmap -pm')
if ((!(xkb_state & Mod2Mask)) != (!(param1 & TS_SYNC_NUM_LOCK)))
{
LLOGLN(0, ("KbdSync: toggling num lock"));
KbdAddEvent(keyboard, 1, 69, 0, 69, 0);
KbdAddEvent(keyboard, 0, 69, 49152, 69, 49152);
rdpEnqueueKey(keyboard->device, KeyPress,
keyboard->x11_keycode_num_lock);
rdpEnqueueKey(keyboard->device, KeyRelease,
keyboard->x11_keycode_num_lock);
}

if ((!(keyboard->scroll_lock_down)) != (!(param1 & 1))) /* scroll lock */
// Scroll lock doesn't have its own modifier, so we need to track
// it ourselves
if ((!(keyboard->scroll_lock_down)) != (!(param1 & TS_SYNC_SCROLL_LOCK)))
{
LLOGLN(0, ("KbdSync: toggling scroll lock"));
KbdAddEvent(keyboard, 1, 70, 0, 70, 0);
KbdAddEvent(keyboard, 0, 70, 49152, 70, 49152);
rdpEnqueueKey(keyboard->device, KeyPress,
keyboard->x11_keycode_scroll_lock);
rdpEnqueueKey(keyboard->device, KeyRelease,
keyboard->x11_keycode_scroll_lock);

keyboard->scroll_lock_down = !keyboard->scroll_lock_down;
}
}

Expand Down Expand Up @@ -780,10 +781,18 @@ rdpLoadLayout(rdpKeyboard *keyboard, struct xrdp_client_info *client_info)
{
set.options = client_info->options;
}
if (strlen(client_info->xkb_rules) > 0)
{
set.rules = client_info->xkb_rules;
}

reload_xkb(keyboard->device, &set);
reload_xkb(inputInfo.keyboard, &set);

/* Copy X11 keycodes needed to sync the keyboard */
keyboard->x11_keycode_caps_lock = client_info->x11_keycode_caps_lock;
keyboard->x11_keycode_num_lock = client_info->x11_keycode_num_lock;
keyboard->x11_keycode_scroll_lock = client_info->x11_keycode_scroll_lock;
return 0;
}

Expand Down

0 comments on commit 2949c20

Please sign in to comment.