Move pause key processing from xorgxrdp
This commit moves processing of the pause key from xorgxrdp back to xrdp itself, so that the key can be passed to the VNC backend.
This commit is contained in:
parent
5779edd23f
commit
7fe5b3ea34
@ -167,7 +167,8 @@ static const struct scancode_to_keycode
|
|||||||
{ 0x165, 225 }, // VK_BROWSER_SEARCH I225 (KEY_SEARCH)
|
{ 0x165, 225 }, // VK_BROWSER_SEARCH I225 (KEY_SEARCH)
|
||||||
{ 0x166, 164 }, // VK_BROWSER_FAVORITES I164 (KEY_BOOKMARKS)
|
{ 0x166, 164 }, // VK_BROWSER_FAVORITES I164 (KEY_BOOKMARKS)
|
||||||
{ 0x16b, 165 }, // VK_LAUNCH_APP1 I165 (KEY_COMPUTER)
|
{ 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:-
|
// Sources:-
|
||||||
@ -291,7 +292,8 @@ static const struct scancode_to_keycode
|
|||||||
{ 0x153, 107 }, // VK_DELETE DELE
|
{ 0x153, 107 }, // VK_DELETE DELE
|
||||||
{ 0x15b, 115 }, // VK_LWIN LWIN
|
{ 0x15b, 115 }, // VK_LWIN LWIN
|
||||||
{ 0x15c, 116 }, // VK_RWIN RWIN
|
{ 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
|
struct map_settings
|
||||||
@ -339,12 +341,23 @@ scancode_to_index(unsigned short scancode)
|
|||||||
// 0x80 - 0xff : Invalid code
|
// 0x80 - 0xff : Invalid code
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (scancode <= 0x17f)
|
if (scancode <= 0x177)
|
||||||
{
|
{
|
||||||
// 01x100 - 0x17f : Move bit 9 to bit 8
|
// 01x100 - 0x177 : Move bit 9 to bit 8
|
||||||
return (scancode & 0x7f) | 0x80;
|
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;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -354,7 +367,11 @@ scancode_from_index(int index)
|
|||||||
{
|
{
|
||||||
index &= 0xff;
|
index &= 0xff;
|
||||||
unsigned short result;
|
unsigned short result;
|
||||||
if (index < 0x80)
|
if (index == SCANCODE_INDEX_PAUSE_KEY)
|
||||||
|
{
|
||||||
|
result = SCANCODE_PAUSE_KEY;
|
||||||
|
}
|
||||||
|
else if (index < 0x80)
|
||||||
{
|
{
|
||||||
result = index;
|
result = index;
|
||||||
}
|
}
|
||||||
|
@ -75,6 +75,7 @@ enum
|
|||||||
SCANCODE_BACKSPACE_KEY = 0x0e,
|
SCANCODE_BACKSPACE_KEY = 0x0e,
|
||||||
SCANCODE_ENTER_KEY = 0x1c,
|
SCANCODE_ENTER_KEY = 0x1c,
|
||||||
SCANCODE_TAB_KEY = 0x0f,
|
SCANCODE_TAB_KEY = 0x0f,
|
||||||
|
SCANCODE_PAUSE_KEY = 0x21d,
|
||||||
|
|
||||||
SCANCODE_KP_ENTER_KEY = 0x11c,
|
SCANCODE_KP_ENTER_KEY = 0x11c,
|
||||||
SCANCODE_KP_DEL_KEY = 0x53,
|
SCANCODE_KP_DEL_KEY = 0x53,
|
||||||
@ -99,6 +100,8 @@ enum
|
|||||||
SCANCODE_INDEX_LSHIFT_KEY = SCANCODE_LSHIFT_KEY,
|
SCANCODE_INDEX_LSHIFT_KEY = SCANCODE_LSHIFT_KEY,
|
||||||
SCANCODE_INDEX_RSHIFT_KEY = SCANCODE_RSHIFT_KEY,
|
SCANCODE_INDEX_RSHIFT_KEY = SCANCODE_RSHIFT_KEY,
|
||||||
SCANCODE_INDEX_RALT_KEY = (SCANCODE_RALT_KEY & 0x7f) | 0x80,
|
SCANCODE_INDEX_RALT_KEY = (SCANCODE_RALT_KEY & 0x7f) | 0x80,
|
||||||
|
SCANCODE_INDEX_PAUSE_KEY = 0xf8,
|
||||||
|
// 0xf9 - 0xff reserved for future extended1 mappings
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Keys affected by numlock
|
* Keys affected by numlock
|
||||||
@ -116,7 +119,7 @@ enum
|
|||||||
// Convert key_code and flags values received from a TS_KEYBOARD_EVENT
|
// Convert key_code and flags values received from a TS_KEYBOARD_EVENT
|
||||||
// into a value suitable for use by this module
|
// into a value suitable for use by this module
|
||||||
#define SCANCODE_FROM_KBD_EVENT(key_code,keyboard_flags) \
|
#define SCANCODE_FROM_KBD_EVENT(key_code,keyboard_flags) \
|
||||||
(((key_code) & 0x7f) | ((keyboard_flags) & 0x100))
|
(((key_code) & 0x7f) | ((keyboard_flags) & 0x300))
|
||||||
|
|
||||||
// Convert a scancode used by this module back into a
|
// Convert a scancode used by this module back into a
|
||||||
// TS_KEYBOARD_EVENT keyCode value
|
// TS_KEYBOARD_EVENT keyCode value
|
||||||
@ -124,16 +127,18 @@ enum
|
|||||||
|
|
||||||
// Convert a scancode used by this module back into a
|
// Convert a scancode used by this module back into a
|
||||||
// TS_KEYBOARD_EVENT keyboardFlags value
|
// TS_KEYBOARD_EVENT keyboardFlags value
|
||||||
#define SCANCODE_TO_KBD_EVENT_KBD_FLAGS(scancode) ((scancode) & 0x100)
|
#define SCANCODE_TO_KBD_EVENT_KBD_FLAGS(scancode) ((scancode) & 0x300)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert a scancode to an index
|
* Convert a scancode to an index
|
||||||
* @param scancode scancode in the range 0x00 - 0x1ff
|
* @param scancode scancode in the range 0x00 - 0x2ff
|
||||||
* @return index in the range 0..SCANCODE_MAX_INDEX (inclusive) or -1
|
* @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,
|
* This function converts a 10-bit scancode into an 8-bit array index,
|
||||||
* independent of the currently loaded keymap
|
* 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
|
* For scancodes in the range 0x00 - 0x7f, the index is identical to the
|
||||||
* scancode. This includes scancodes for all the keys affected by
|
* scancode. This includes scancodes for all the keys affected by
|
||||||
* numlock.
|
* numlock.
|
||||||
@ -157,7 +162,8 @@ scancode_from_index(int index);
|
|||||||
* Looks up an RDP scancode and converts to an x11 keycode
|
* 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). Extended1 scancodes
|
||||||
|
* (currently just the pause key) are in the range 0x200-0x2ff
|
||||||
* @return keycode, or 0 for no keycode
|
* @return keycode, or 0 for no keycode
|
||||||
*/
|
*/
|
||||||
unsigned short
|
unsigned short
|
||||||
|
@ -299,7 +299,11 @@ output_file_section(FILE *outf,
|
|||||||
unicode = wtext[0];
|
unicode = wtext[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (scancode > 0xff)
|
if (scancode > 0x1ff)
|
||||||
|
{
|
||||||
|
fputs("E1_", outf);
|
||||||
|
}
|
||||||
|
else if (scancode > 0xff)
|
||||||
{
|
{
|
||||||
fputs("E0_", outf);
|
fputs("E0_", outf);
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
#include "test_common.h"
|
#include "test_common.h"
|
||||||
|
|
||||||
// Max supported scancode value
|
// Max supported scancode value
|
||||||
#define MAX_SUPPORTED_SCANCODE 0x1ff
|
#define MAX_SUPPORTED_SCANCODE 0x2ff
|
||||||
|
|
||||||
// Checks conversions to-and-from scancode indexes
|
// Checks conversions to-and-from scancode indexes
|
||||||
START_TEST(test_scancode__scancode_to_index)
|
START_TEST(test_scancode__scancode_to_index)
|
||||||
@ -27,18 +27,35 @@ START_TEST(test_scancode__scancode_to_index)
|
|||||||
ck_assert_int_eq(scancode_to_index(i), -1);
|
ck_assert_int_eq(scancode_to_index(i), -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 0x100 - 0x17f map to 0x80 - 0xff
|
// 0x100 - 0x177 map to 0x80 - 0xf7
|
||||||
for (i = 0x100; i <= 0x17f; ++i)
|
for (i = 0x100; i <= 0x177; ++i)
|
||||||
{
|
{
|
||||||
ck_assert_int_eq(scancode_to_index(i), i - 0x80);
|
ck_assert_int_eq(scancode_to_index(i), i - 0x80);
|
||||||
ck_assert_int_eq(scancode_from_index(i - 0x80), i);
|
ck_assert_int_eq(scancode_from_index(i - 0x80), i);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Scancodes from 0x180 - MAX_SUPPORTED_SCANCODE are not supported
|
// Scancodes from 0x178 - 0x1ff are not supported
|
||||||
for (i = 0x180; i <= MAX_SUPPORTED_SCANCODE; ++i)
|
for (i = 0x178; i <= 0x1ff; ++i)
|
||||||
{
|
{
|
||||||
ck_assert_int_eq(scancode_to_index(i), -1);
|
ck_assert_int_eq(scancode_to_index(i), -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// In the range 0x200 up, only SCANCODE_PAUSE_KEY is
|
||||||
|
// supported
|
||||||
|
ck_assert_int_ge(SCANCODE_PAUSE_KEY, 0x200);
|
||||||
|
ck_assert_int_le(SCANCODE_PAUSE_KEY, MAX_SUPPORTED_SCANCODE);
|
||||||
|
for (i = 0x200; i <= MAX_SUPPORTED_SCANCODE; ++i)
|
||||||
|
{
|
||||||
|
if (i == SCANCODE_PAUSE_KEY)
|
||||||
|
{
|
||||||
|
ck_assert_int_eq(scancode_to_index(i), SCANCODE_INDEX_PAUSE_KEY);
|
||||||
|
ck_assert_int_eq(scancode_from_index(SCANCODE_INDEX_PAUSE_KEY), i);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ck_assert_int_eq(scancode_to_index(i), -1);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Checks all returned evdev scancodes are mapped to a keycode
|
// Checks all returned evdev scancodes are mapped to a keycode
|
||||||
|
@ -5,6 +5,8 @@ AM_CPPFLAGS = \
|
|||||||
-DXRDP_PID_PATH=\"${localstatedir}/run\" \
|
-DXRDP_PID_PATH=\"${localstatedir}/run\" \
|
||||||
-I$(top_srcdir)/common
|
-I$(top_srcdir)/common
|
||||||
|
|
||||||
|
AM_CFLAGS = $(X_CFLAGS)
|
||||||
|
|
||||||
module_LTLIBRARIES = \
|
module_LTLIBRARIES = \
|
||||||
libvnc.la
|
libvnc.la
|
||||||
|
|
||||||
|
115
vnc/vnc.c
115
vnc/vnc.c
@ -30,6 +30,8 @@
|
|||||||
#include <config_ac.h>
|
#include <config_ac.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <X11/keysym.h>
|
||||||
|
|
||||||
#include "vnc.h"
|
#include "vnc.h"
|
||||||
#include "vnc_clip.h"
|
#include "vnc_clip.h"
|
||||||
#include "rfb.h"
|
#include "rfb.h"
|
||||||
@ -443,13 +445,90 @@ resize_server_to_client_layout(struct vnc *v)
|
|||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/**
|
||||||
|
* Process keysym messages
|
||||||
|
* @param v Module
|
||||||
|
* @param keysym Keysym of keypress
|
||||||
|
* @param keydown boolean - is key down?
|
||||||
|
* @return != 0 for error
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
process_keysym_msg(struct vnc *v, int keysym, int keydown)
|
||||||
|
{
|
||||||
|
struct stream *s = NULL;
|
||||||
|
int error = 0;
|
||||||
|
|
||||||
|
if (keysym > 0)
|
||||||
|
{
|
||||||
|
make_stream(s);
|
||||||
|
|
||||||
|
/* Break key processing [MS-RDPBCGR] 2.2.8.1.1.3.1.1.1 */
|
||||||
|
if (v->ignore_next_numlock)
|
||||||
|
{
|
||||||
|
v->ignore_next_numlock = 0;
|
||||||
|
if (keysym == XK_Num_Lock)
|
||||||
|
{
|
||||||
|
goto end_keysym_msg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (keysym == XK_ISO_Level3_Shift) /* altgr */
|
||||||
|
{
|
||||||
|
if (v->shift_state)
|
||||||
|
{
|
||||||
|
/* fix for mstsc sending left control down with altgr */
|
||||||
|
init_stream(s, 64);
|
||||||
|
out_uint8(s, RFB_C2S_KEY_EVENT);
|
||||||
|
out_uint8(s, 0); /* down flag */
|
||||||
|
out_uint8s(s, 2);
|
||||||
|
out_uint32_be(s, XK_Control_L); /* left control */
|
||||||
|
s_mark_end(s);
|
||||||
|
error = lib_send_copy(v, s);
|
||||||
|
if (error != 0)
|
||||||
|
{
|
||||||
|
goto end_keysym_msg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
init_stream(s, 64);
|
||||||
|
out_uint8(s, RFB_C2S_KEY_EVENT);
|
||||||
|
out_uint8(s, keydown ? 1 : 0);
|
||||||
|
out_uint8s(s, 2);
|
||||||
|
out_uint32_be(s, keysym);
|
||||||
|
s_mark_end(s);
|
||||||
|
error = lib_send_copy(v, s);
|
||||||
|
|
||||||
|
switch (keysym)
|
||||||
|
{
|
||||||
|
case XK_Control_L: /* left control */
|
||||||
|
v->shift_state = keydown;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case XK_Pause:
|
||||||
|
// [MS-RDPBCGR] 2.2.8.1.1.3.1.1.1 - A pause key scancode
|
||||||
|
// (up or down) is always immediately followed by a
|
||||||
|
// numlock key which we should ignore
|
||||||
|
v->ignore_next_numlock = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
end_keysym_msg:
|
||||||
|
free_stream(s);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
static int
|
static int
|
||||||
lib_mod_event(struct vnc *v, int msg, long param1, long param2,
|
lib_mod_event(struct vnc *v, int msg, long param1, long param2,
|
||||||
long param3, long param4)
|
long param3, long param4)
|
||||||
{
|
{
|
||||||
struct stream *s;
|
struct stream *s;
|
||||||
int key;
|
|
||||||
int error;
|
int error;
|
||||||
int x;
|
int x;
|
||||||
int y;
|
int y;
|
||||||
@ -492,38 +571,7 @@ lib_mod_event(struct vnc *v, int msg, long param1, long param2,
|
|||||||
}
|
}
|
||||||
else if ((msg >= 15) && (msg <= 16)) /* key events */
|
else if ((msg >= 15) && (msg <= 16)) /* key events */
|
||||||
{
|
{
|
||||||
key = param2;
|
error = process_keysym_msg(v, param2, (msg == 15));
|
||||||
|
|
||||||
if (key > 0)
|
|
||||||
{
|
|
||||||
if (key == 65027) /* altgr */
|
|
||||||
{
|
|
||||||
if (v->shift_state)
|
|
||||||
{
|
|
||||||
/* fix for mstsc sending left control down with altgr */
|
|
||||||
init_stream(s, 8192);
|
|
||||||
out_uint8(s, RFB_C2S_KEY_EVENT);
|
|
||||||
out_uint8(s, 0); /* down flag */
|
|
||||||
out_uint8s(s, 2);
|
|
||||||
out_uint32_be(s, 65507); /* left control */
|
|
||||||
s_mark_end(s);
|
|
||||||
lib_send_copy(v, s);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
init_stream(s, 8192);
|
|
||||||
out_uint8(s, RFB_C2S_KEY_EVENT);
|
|
||||||
out_uint8(s, msg == 15); /* down flag */
|
|
||||||
out_uint8s(s, 2);
|
|
||||||
out_uint32_be(s, key);
|
|
||||||
s_mark_end(s);
|
|
||||||
error = lib_send_copy(v, s);
|
|
||||||
|
|
||||||
if (key == 65507) /* left control */
|
|
||||||
{
|
|
||||||
v->shift_state = msg == 15;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
/* mouse events
|
/* mouse events
|
||||||
*
|
*
|
||||||
@ -613,7 +661,6 @@ lib_mod_event(struct vnc *v, int msg, long param1, long param2,
|
|||||||
error = lib_send_copy(v, s);
|
error = lib_send_copy(v, s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
free_stream(s);
|
free_stream(s);
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
@ -170,6 +170,7 @@ struct vnc
|
|||||||
char port[256];
|
char port[256];
|
||||||
int sck_closed;
|
int sck_closed;
|
||||||
int shift_state; /* 0 up, 1 down */
|
int shift_state; /* 0 up, 1 down */
|
||||||
|
int ignore_next_numlock; /* Used in pause key processing */
|
||||||
int keylayout;
|
int keylayout;
|
||||||
int clip_chanid;
|
int clip_chanid;
|
||||||
struct vnc_clipboard_data *vc;
|
struct vnc_clipboard_data *vc;
|
||||||
|
@ -159,6 +159,11 @@ key_to_scancode_index(const char *key)
|
|||||||
keyboard_flags |= KBDFLAGS_EXTENDED;
|
keyboard_flags |= KBDFLAGS_EXTENDED;
|
||||||
key += 3;
|
key += 3;
|
||||||
}
|
}
|
||||||
|
else if (key[1] == '1')
|
||||||
|
{
|
||||||
|
keyboard_flags |= KBDFLAGS_EXTENDED1;
|
||||||
|
key += 3;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isxdigit(key[0]) && isxdigit(key[1]) && key[2] == '\0')
|
if (isxdigit(key[0]) && isxdigit(key[1]) && key[2] == '\0')
|
||||||
|
Loading…
Reference in New Issue
Block a user