mirror of https://github.com/neutrinolabs/xrdp
Update xrdp to use new keymap file format
This commit is contained in:
parent
7301b505c9
commit
1cb2ce06cd
|
@ -42,11 +42,7 @@ test_xrdp_LDADD = \
|
||||||
$(top_builddir)/xrdp/xrdp_bitmap_load.o \
|
$(top_builddir)/xrdp/xrdp_bitmap_load.o \
|
||||||
$(top_builddir)/xrdp/xrdp_bitmap_common.o \
|
$(top_builddir)/xrdp/xrdp_bitmap_common.o \
|
||||||
$(top_builddir)/xrdp/funcs.o \
|
$(top_builddir)/xrdp/funcs.o \
|
||||||
$(top_builddir)/common/libcommon.la \
|
|
||||||
$(top_builddir)/libipm/libipm.la \
|
|
||||||
$(top_builddir)/libxrdp/libxrdp.la \
|
$(top_builddir)/libxrdp/libxrdp.la \
|
||||||
$(top_builddir)/libpainter/src/libpainter.la \
|
|
||||||
$(top_builddir)/librfxcodec/src/librfxencode.la \
|
|
||||||
$(top_builddir)/xrdp/lang.o \
|
$(top_builddir)/xrdp/lang.o \
|
||||||
$(top_builddir)/xrdp/xrdp_mm.o \
|
$(top_builddir)/xrdp/xrdp_mm.o \
|
||||||
$(top_builddir)/xrdp/xrdp_wm.o \
|
$(top_builddir)/xrdp/xrdp_wm.o \
|
||||||
|
@ -61,6 +57,11 @@ test_xrdp_LDADD = \
|
||||||
$(top_builddir)/xrdp/xrdp_process.o \
|
$(top_builddir)/xrdp/xrdp_process.o \
|
||||||
$(top_builddir)/xrdp/xrdp_login_wnd.o \
|
$(top_builddir)/xrdp/xrdp_login_wnd.o \
|
||||||
$(top_builddir)/xrdp/xrdp_main_utils.o \
|
$(top_builddir)/xrdp/xrdp_main_utils.o \
|
||||||
|
$(top_builddir)/libpainter/src/libpainter.la \
|
||||||
|
$(top_builddir)/librfxcodec/src/librfxencode.la \
|
||||||
|
$(top_builddir)/libipm/libipm.la \
|
||||||
|
$(top_builddir)/common/libcommon.la \
|
||||||
|
$(top_builddir)/third_party/tomlc99/libtoml.la \
|
||||||
$(PIXMAN_LIBS) \
|
$(PIXMAN_LIBS) \
|
||||||
$(IMLIB2_LIBS) \
|
$(IMLIB2_LIBS) \
|
||||||
@CHECK_LIBS@ \
|
@CHECK_LIBS@ \
|
||||||
|
|
380
xrdp/lang.c
380
xrdp/lang.c
|
@ -23,47 +23,19 @@
|
||||||
#include <config_ac.h>
|
#include <config_ac.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
#include "xrdp.h"
|
#include "xrdp.h"
|
||||||
#include "ms-rdpbcgr.h"
|
#include "ms-rdpbcgr.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "string_calls.h"
|
#include "string_calls.h"
|
||||||
|
#include "toml.h"
|
||||||
|
|
||||||
/* map for rdp to x11 scancodes
|
// Macro to return 0..15 for a valid isxdigit() character
|
||||||
code1 is regular scancode, code2 is extended scancode */
|
#define XDIGIT_TO_VAL(d) (\
|
||||||
struct codepair
|
isdigit(d) ? (d) - '0' : \
|
||||||
{
|
((d) >= 'a' && (d) <= 'f') ? (d) - 'a' + 10 : \
|
||||||
tui8 code1;
|
(d) - 'A' + 10)
|
||||||
tui8 code2;
|
|
||||||
};
|
|
||||||
static struct codepair g_map[] =
|
|
||||||
{
|
|
||||||
{ 0, 0 }, { 9, 0 }, { 10, 0 }, { 11, 0 }, { 12, 0 }, /* 0 - 4 */
|
|
||||||
{ 13, 0 }, { 14, 0 }, { 15, 0 }, { 16, 0 }, { 17, 0 }, /* 5 - 9 */
|
|
||||||
{ 18, 0 }, { 19, 0 }, { 20, 0 }, { 21, 0 }, { 22, 0 }, /* 10 - 14 */
|
|
||||||
{ 23, 0 }, { 24, 173 }, { 25, 0 }, { 26, 0 }, { 27, 0 }, /* 15 - 19 */
|
|
||||||
{ 28, 0 }, { 29, 0 }, { 30, 0 }, { 31, 0 }, { 32, 0 }, /* 20 - 24 */
|
|
||||||
{ 33, 171 }, { 34, 0 }, { 35, 0 }, { 36, 108 }, { 37, 109 }, /* 25 - 29 */
|
|
||||||
{ 38, 0 }, { 39, 0 }, { 40, 121 }, { 41, 0 }, { 42, 172 }, /* 30 - 34 */
|
|
||||||
{ 43, 0 }, { 44, 174 }, { 45, 0 }, { 46, 0 }, { 47, 0 }, /* 35 - 39 */
|
|
||||||
{ 48, 0 }, { 49, 0 }, { 50, 0 }, { 51, 0 }, { 52, 0 }, /* 40 - 44 */
|
|
||||||
{ 53, 0 }, { 54, 122 }, { 55, 0 }, { 56, 123 }, { 57, 0 }, /* 45 - 49 */
|
|
||||||
{ 58, 180 }, { 59, 0 }, { 60, 0 }, { 61, 112 }, { 62, 0 }, /* 50 - 54 */
|
|
||||||
{ 63, 111 }, { 64, 113 }, { 65, 0 }, { 66, 0 }, { 67, 0 }, /* 55 - 59 */
|
|
||||||
{ 68, 0 }, { 69, 0 }, { 70, 0 }, { 71, 0 }, { 72, 0 }, /* 60 - 64 */
|
|
||||||
{ 73, 0 }, { 74, 0 }, { 75, 0 }, { 76, 0 }, { 77, 0 }, /* 65 - 69 */
|
|
||||||
{ 78, 0 }, { 79, 97 }, { 80, 98 }, { 81, 99 }, { 82, 0 }, /* 70 - 74 */
|
|
||||||
{ 83, 100 }, { 84, 0 }, { 85, 102 }, { 86, 0 }, { 87, 103 }, /* 75 - 79 */
|
|
||||||
{ 88, 104 }, { 89, 105 }, { 90, 106 }, { 91, 107 }, { 92, 0 }, /* 80 - 84 */
|
|
||||||
{ 93, 0 }, { 94, 0 }, { 95, 0 }, { 96, 0 }, { 97, 0 }, /* 85 - 89 */
|
|
||||||
{ 98, 0 }, { 0, 115 }, { 0, 116 }, { 0, 117 }, { 102, 0 }, /* 90 - 94 */
|
|
||||||
{ 103, 0 }, { 104, 0 }, { 105, 0 }, { 106, 0 }, { 107, 0 }, /* 95 - 99 */
|
|
||||||
{ 108, 0 }, { 109, 225 }, { 110, 164 }, { 111, 181 }, { 112, 136 }, /* 100 - 104 */
|
|
||||||
{ 113, 167 }, { 114, 166 }, { 115, 0 }, { 116, 163 }, { 117, 234 }, /* 105 - 109 */
|
|
||||||
{ 118, 156 }, { 119, 157 }, { 120, 0 }, { 121, 0 }, { 122, 0 }, /* 110 - 114 */
|
|
||||||
{ 123, 0 }, { 124, 0 }, { 125, 0 }, { 126, 0 }, { 127, 0 }, /* 115 - 119 */
|
|
||||||
{ 128, 0 }, { 129, 0 }, { 130, 0 }, { 131, 0 }, { 132, 0 }, /* 120 - 124 */
|
|
||||||
{ 133, 0 }, { 134, 0 }, { 135, 0 } /* 125 - 127 */
|
|
||||||
};
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
struct xrdp_key_info *
|
struct xrdp_key_info *
|
||||||
|
@ -81,20 +53,12 @@ get_key_info_from_scan_code(int device_flags, int scan_code, int *keys,
|
||||||
shift = keys[42] || keys[54];
|
shift = keys[42] || keys[54];
|
||||||
altgr = keys[56] & KBD_FLAG_EXT; /* right alt */
|
altgr = keys[56] & KBD_FLAG_EXT; /* right alt */
|
||||||
rv = 0;
|
rv = 0;
|
||||||
scan_code = scan_code & 0x7f;
|
index = INDEX_FROM_SCANCODE(scan_code, ext);
|
||||||
index = ext ? g_map[scan_code].code2 : g_map[scan_code].code1;
|
|
||||||
|
|
||||||
/* keymap file is created with numlock off so we have to do this */
|
if (num_lock &&
|
||||||
if ((index >= 79) && (index <= 91))
|
index >= XR_RDP_SCAN_MIN_NUMLOCK && index <= XR_RDP_SCAN_MAX_NUMLOCK)
|
||||||
{
|
{
|
||||||
if (num_lock)
|
rv = &(keymap->keys_numlock[index - XR_RDP_SCAN_MIN_NUMLOCK]);
|
||||||
{
|
|
||||||
rv = &(keymap->keys_shift[index]);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
rv = &(keymap->keys_noshift[index]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (shift && caps_lock && altgr)
|
else if (shift && caps_lock && altgr)
|
||||||
{
|
{
|
||||||
|
@ -173,58 +137,169 @@ 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
|
||||||
|
*
|
||||||
|
* @param key Table key
|
||||||
|
* @param[out] scancode scancode index value (0..255) if 1 is returned
|
||||||
|
* @return Boolean != 0 if the key is valid
|
||||||
|
*/
|
||||||
static int
|
static int
|
||||||
km_read_section(int fd, const char *section_name, struct xrdp_key_info *keymap)
|
is_valid_scancode(const char *key, int *scancode)
|
||||||
{
|
{
|
||||||
struct list *names;
|
int rv = 0;
|
||||||
struct list *values;
|
int extended = 0;
|
||||||
int index;
|
if ((key[0] == 'E' || key[0] == 'e') && key[1] == '0' && key[2] == '_')
|
||||||
int code;
|
|
||||||
int pos1;
|
|
||||||
char *name;
|
|
||||||
char *value;
|
|
||||||
|
|
||||||
names = list_create();
|
|
||||||
names->auto_free = 1;
|
|
||||||
values = list_create();
|
|
||||||
values->auto_free = 1;
|
|
||||||
|
|
||||||
g_memset(keymap, '\0', sizeof(*keymap));
|
|
||||||
if (file_read_section(fd, section_name, names, values) == 0)
|
|
||||||
{
|
{
|
||||||
for (index = names->count - 1; index >= 0; index--)
|
extended = 1;
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/**
|
||||||
|
* Tests a value to see if it's a valid KeySym (decimal number)
|
||||||
|
*
|
||||||
|
* @param val
|
||||||
|
* @param[out] keysym. Keysym value if 1 is returned
|
||||||
|
* @return Boolean != 0 if the string is valid
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
is_valid_keysym(const char *val, int *sym)
|
||||||
|
{
|
||||||
|
int rv = 0;
|
||||||
|
int s = 0;
|
||||||
|
if (*val != '\0')
|
||||||
|
{
|
||||||
|
while (isdigit(*val))
|
||||||
{
|
{
|
||||||
name = (char *)list_get_item(names, index);
|
s = s * 10 + (*val++ - '0');
|
||||||
value = (char *)list_get_item(values, index);
|
}
|
||||||
|
if (*val == '\0')
|
||||||
if ((name != 0) && (value != 0))
|
{
|
||||||
{
|
*sym = s;
|
||||||
if (g_strncasecmp(name, "key", 3) == 0)
|
rv = 1;
|
||||||
{
|
}
|
||||||
code = g_atoi(name + 3);
|
}
|
||||||
}
|
|
||||||
else
|
return rv;
|
||||||
{
|
}
|
||||||
code = g_atoi(name);
|
|
||||||
}
|
/*****************************************************************************/
|
||||||
|
/**
|
||||||
if ((code >= 0) && (code < 256))
|
* Tests a value to see if it's a valid unicode character (U+xxxx)
|
||||||
{
|
*
|
||||||
pos1 = g_pos(value, ":");
|
* @param val
|
||||||
|
* @param[out] chr value if 1 is returned
|
||||||
if (pos1 >= 0)
|
* @return Boolean != 0 if the string is valid
|
||||||
{
|
*/
|
||||||
keymap[code].chr = g_atoi(value + pos1 + 1);
|
static int
|
||||||
}
|
is_valid_unicode_char(const char *val, char32_t *chr)
|
||||||
|
{
|
||||||
keymap[code].sym = g_atoi(value);
|
int rv = 0;
|
||||||
}
|
|
||||||
}
|
if ((val[0] == 'U' || val[0] == 'u') &&
|
||||||
|
val[1] == '+' && isxdigit(val[2]))
|
||||||
|
{
|
||||||
|
val += 2; // Skip 'U+'
|
||||||
|
const char *p = val;
|
||||||
|
char32_t c = 0;
|
||||||
|
|
||||||
|
while (isxdigit(*p))
|
||||||
|
{
|
||||||
|
c = c * 16 + XDIGIT_TO_VAL(*p);
|
||||||
|
++p;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*p == '\0' && (p - val) >= 4 && (p - val) <= 6)
|
||||||
|
{
|
||||||
|
rv = 1;
|
||||||
|
*chr = c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
static int
|
||||||
|
km_read_section(toml_table_t *tfile, const char *section_name,
|
||||||
|
struct xrdp_key_info *keymap)
|
||||||
|
{
|
||||||
|
toml_table_t *section = toml_table_in(tfile, section_name);
|
||||||
|
g_memset(keymap, '\0', sizeof(*keymap));
|
||||||
|
|
||||||
|
if (section == NULL)
|
||||||
|
{
|
||||||
|
LOG(LOG_LEVEL_WARNING, "Section [%s] not found in keymap file",
|
||||||
|
section_name);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const char *key;
|
||||||
|
toml_datum_t val;
|
||||||
|
int index;
|
||||||
|
int scancode; // index value 0..255
|
||||||
|
char *p;
|
||||||
|
const char *unicode_str;
|
||||||
|
for (index = 0 ; (key = toml_key_in(section, index)) != NULL; ++index)
|
||||||
|
{
|
||||||
|
if (!is_valid_scancode(key, &scancode))
|
||||||
|
{
|
||||||
|
LOG(LOG_LEVEL_WARNING,
|
||||||
|
"Can't parse value '%s' in [%s] in keymap file",
|
||||||
|
key, section_name);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
val = toml_string_in(section, key);
|
||||||
|
if (!val.ok)
|
||||||
|
{
|
||||||
|
LOG(LOG_LEVEL_WARNING,
|
||||||
|
"Can't read value for [%s]:%s in keymap file",
|
||||||
|
section_name, key);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Does the value contain a unicode character?
|
||||||
|
if ((p = strchr(val.u.s, ':')) != NULL)
|
||||||
|
{
|
||||||
|
unicode_str = (p + 1);
|
||||||
|
*p = '\0'; // val is a copy, writeable by us
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
unicode_str = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Parse both values and add them to the keymap, logging any
|
||||||
|
* errors */
|
||||||
|
if (!is_valid_keysym(val.u.s, &keymap[scancode].sym))
|
||||||
|
{
|
||||||
|
LOG(LOG_LEVEL_WARNING,
|
||||||
|
"Can't read KeySym for [%s]:%s in keymap file",
|
||||||
|
section_name, key);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (unicode_str != NULL &&
|
||||||
|
!is_valid_unicode_char(unicode_str, &keymap[scancode].chr))
|
||||||
|
{
|
||||||
|
LOG(LOG_LEVEL_WARNING,
|
||||||
|
"Can't read unicode character for [%s]:%s in keymap file",
|
||||||
|
section_name, key);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(val.u.s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
list_delete(names);
|
|
||||||
list_delete(values);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -233,83 +308,88 @@ int
|
||||||
get_keymaps(int keylayout, struct xrdp_keymap *keymap)
|
get_keymaps(int keylayout, struct xrdp_keymap *keymap)
|
||||||
{
|
{
|
||||||
int basic_key_layout = keylayout & 0x0000ffff;
|
int basic_key_layout = keylayout & 0x0000ffff;
|
||||||
char *filename;
|
char filename[256];
|
||||||
struct xrdp_keymap *lkeymap;
|
int layout_list[10];
|
||||||
|
int layout_count = 0;
|
||||||
|
int i;
|
||||||
|
|
||||||
filename = (char *)g_malloc(256, 0);
|
/* Work out a list of layouts to try to load */
|
||||||
|
layout_list[layout_count++] = keylayout; // Requested layout
|
||||||
/* check if there is a keymap file e.g. km-e00100411.ini */
|
if (basic_key_layout != keylayout)
|
||||||
g_snprintf(filename, 255, "%s/km-%08x.ini", XRDP_CFG_PATH, keylayout);
|
|
||||||
|
|
||||||
/* if the file does not exist, use only lower 16 bits instead */
|
|
||||||
if (!g_file_exist(filename))
|
|
||||||
{
|
{
|
||||||
LOG(LOG_LEVEL_WARNING, "Cannot find keymap file %s", filename);
|
layout_list[layout_count++] = basic_key_layout; // First fallback
|
||||||
/* e.g. km-00000411.ini */
|
|
||||||
g_snprintf(filename, 255, "%s/km-%08x.ini", XRDP_CFG_PATH, basic_key_layout);
|
|
||||||
}
|
}
|
||||||
|
layout_list[layout_count++] = 0x0409; // Last chance 'en-US'
|
||||||
|
|
||||||
/* finally, use 'en-us' */
|
/* search for a loadable layout in the list */
|
||||||
if (!g_file_exist(filename))
|
for (i = 0; i < layout_count; ++i)
|
||||||
{
|
{
|
||||||
LOG(LOG_LEVEL_WARNING, "Cannot find keymap file %s", filename);
|
// Convert key layout to a filename
|
||||||
g_snprintf(filename, 255, "%s/km-00000409.ini", XRDP_CFG_PATH);
|
g_snprintf(filename, sizeof(filename),
|
||||||
}
|
XRDP_CFG_PATH "/km-%08x.toml", layout_list[i]);
|
||||||
|
|
||||||
if (g_file_exist(filename))
|
if (km_load_file(filename, keymap) == 0)
|
||||||
{
|
|
||||||
|
|
||||||
lkeymap = (struct xrdp_keymap *)g_malloc(sizeof(struct xrdp_keymap), 0);
|
|
||||||
/* make a copy of the built-in keymap */
|
|
||||||
g_memcpy(lkeymap, keymap, sizeof(struct xrdp_keymap));
|
|
||||||
|
|
||||||
km_load_file(filename, keymap);
|
|
||||||
|
|
||||||
if (g_memcmp(lkeymap, keymap, sizeof(struct xrdp_keymap)) != 0)
|
|
||||||
{
|
{
|
||||||
LOG(LOG_LEVEL_WARNING,
|
return 0;
|
||||||
"local keymap file for 0x%08x found and doesn't match "
|
|
||||||
"built in keymap, using local keymap file", keylayout);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
g_free(lkeymap);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
LOG(LOG_LEVEL_WARNING, "File does not exist: %s", filename);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
g_free(filename);
|
/* No luck finding anything */
|
||||||
|
LOG(LOG_LEVEL_ERROR, "Cannot find a usable keymap file");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
int km_load_file(const char *filename, struct xrdp_keymap *keymap)
|
int
|
||||||
|
km_load_file(const char *filename, struct xrdp_keymap *keymap)
|
||||||
{
|
{
|
||||||
int fd;
|
FILE *fp;
|
||||||
|
toml_table_t *tfile;
|
||||||
|
char errbuf[200];
|
||||||
|
int rv = 0;
|
||||||
|
|
||||||
LOG(LOG_LEVEL_INFO, "Loading keymap file %s", filename);
|
if ((fp = fopen(filename, "r")) == NULL)
|
||||||
fd = g_file_open_ro(filename);
|
|
||||||
|
|
||||||
if (fd != -1)
|
|
||||||
{
|
{
|
||||||
/* read the keymaps */
|
LOG(LOG_LEVEL_ERROR, "Error loading keymap file %s (%s)",
|
||||||
km_read_section(fd, "noshift", keymap->keys_noshift);
|
filename, g_get_strerror());
|
||||||
km_read_section(fd, "shift", keymap->keys_shift);
|
rv = 1;
|
||||||
km_read_section(fd, "altgr", keymap->keys_altgr);
|
}
|
||||||
km_read_section(fd, "shiftaltgr", keymap->keys_shiftaltgr);
|
else if ((tfile = toml_parse_file(fp, errbuf, sizeof(errbuf))) == NULL)
|
||||||
km_read_section(fd, "capslock", keymap->keys_capslock);
|
{
|
||||||
km_read_section(fd, "capslockaltgr", keymap->keys_capslockaltgr);
|
LOG(LOG_LEVEL_ERROR, "Error in keymap file %s - %s", filename, errbuf);
|
||||||
km_read_section(fd, "shiftcapslock", keymap->keys_shiftcapslock);
|
fclose(fp);
|
||||||
km_read_section(fd, "shiftcapslockaltgr", keymap->keys_shiftcapslockaltgr);
|
rv = 1;
|
||||||
|
|
||||||
g_file_close(fd);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LOG(LOG_LEVEL_ERROR, "Error loading keymap file %s (%s)", filename, g_get_strerror());
|
fclose(fp);
|
||||||
return 1;
|
LOG(LOG_LEVEL_INFO, "Loading keymap file %s", filename);
|
||||||
|
|
||||||
|
/* read the keymaps */
|
||||||
|
km_read_section(tfile, "noshift", keymap->keys_noshift);
|
||||||
|
km_read_section(tfile, "shift", keymap->keys_shift);
|
||||||
|
km_read_section(tfile, "altgr", keymap->keys_altgr);
|
||||||
|
km_read_section(tfile, "shiftaltgr", keymap->keys_shiftaltgr);
|
||||||
|
km_read_section(tfile, "capslock", keymap->keys_capslock);
|
||||||
|
km_read_section(tfile, "capslockaltgr", keymap->keys_capslockaltgr);
|
||||||
|
km_read_section(tfile, "shiftcapslock", keymap->keys_shiftcapslock);
|
||||||
|
km_read_section(tfile, "shiftcapslockaltgr",
|
||||||
|
keymap->keys_shiftcapslockaltgr);
|
||||||
|
|
||||||
|
/* 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];
|
||||||
|
int i;
|
||||||
|
km_read_section(tfile, "numlock", keys_numlock);
|
||||||
|
for (i = XR_RDP_SCAN_MIN_NUMLOCK; i <= XR_RDP_SCAN_MAX_NUMLOCK; ++i)
|
||||||
|
{
|
||||||
|
keymap->keys_numlock[i - XR_RDP_SCAN_MIN_NUMLOCK] = keys_numlock[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
toml_free(tfile);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
|
@ -452,6 +452,15 @@ 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];
|
struct xrdp_key_info keys_noshift[256];
|
||||||
|
@ -462,6 +471,9 @@ struct xrdp_keymap
|
||||||
struct xrdp_key_info keys_capslockaltgr[256];
|
struct xrdp_key_info keys_capslockaltgr[256];
|
||||||
struct xrdp_key_info keys_shiftcapslock[256];
|
struct xrdp_key_info keys_shiftcapslock[256];
|
||||||
struct xrdp_key_info keys_shiftcapslockaltgr[256];
|
struct xrdp_key_info keys_shiftcapslockaltgr[256];
|
||||||
|
// 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];
|
||||||
};
|
};
|
||||||
|
|
||||||
/* the window manager */
|
/* the window manager */
|
||||||
|
|
Loading…
Reference in New Issue