libfreerdp-locale: refactoring of XKB-based detection

This commit is contained in:
Marc-André Moreau 2012-02-19 20:24:06 -05:00
parent 46e3343232
commit e85bfb4fd4
17 changed files with 311 additions and 545 deletions

View File

@ -202,7 +202,7 @@ void df_send_keyboard_event(rdpInput* input, boolean down, uint8 keycode, uint8
else else
return; return;
scancode = freerdp_keyboard_get_scancode_from_vkcode(vkcode, &extended); scancode = freerdp_keyboard_get_rdp_scancode_from_virtual_key_code(vkcode, &extended);
flags = (extended) ? KBD_FLAGS_EXTENDED : 0; flags = (extended) ? KBD_FLAGS_EXTENDED : 0;
flags |= (down) ? KBD_FLAGS_DOWN : KBD_FLAGS_RELEASE; flags |= (down) ? KBD_FLAGS_DOWN : KBD_FLAGS_RELEASE;

View File

@ -64,7 +64,7 @@ void xf_kbd_send_key(xfInfo* xfi, boolean down, uint8 keycode)
rdpInput* input; rdpInput* input;
input = xfi->instance->input; input = xfi->instance->input;
scancode = freerdp_keyboard_get_scancode_from_keycode(keycode, &extended); scancode = freerdp_keyboard_get_rdp_scancode_from_x11_keycode(keycode, &extended);
if (scancode == 0) if (scancode == 0)
{ {

View File

@ -1,8 +1,8 @@
/** /**
* FreeRDP: A Remote Desktop Protocol Client * FreeRDP: A Remote Desktop Protocol Implementation
* XKB-based keyboard mapping * Keyboard Mapping
* *
* Copyright 2009 Marc-Andre Moreau <marcandre.moreau@gmail.com> * Copyright 2009-2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -48,15 +48,6 @@ struct _VIRTUAL_KEY_CODE
}; };
typedef struct _VIRTUAL_KEY_CODE VIRTUAL_KEY_CODE; typedef struct _VIRTUAL_KEY_CODE VIRTUAL_KEY_CODE;
struct _VIRTUAL_KEY
{
uint32 scancode; /* Windows "scan code" */
boolean extended; /* extended key flag */
const char* name; /* Windows virtual key name */
const char* x_keyname; /* XKB keyname */
};
typedef struct _VIRTUAL_KEY VIRTUAL_KEY;
/* Mouse buttons */ /* Mouse buttons */
#define VK_LBUTTON 0x01 /* Left mouse button */ #define VK_LBUTTON 0x01 /* Left mouse button */
@ -488,11 +479,12 @@ typedef struct _VIRTUAL_KEY VIRTUAL_KEY;
#define KBD_CHINESE_TRADITIONAL_MICROSOFT_PINYIN_IME_3 0xE00E0804 #define KBD_CHINESE_TRADITIONAL_MICROSOFT_PINYIN_IME_3 0xE00E0804
#define KBD_CHINESE_TRADITIONAL_ALPHANUMERIC 0xE00F0404 #define KBD_CHINESE_TRADITIONAL_ALPHANUMERIC 0xE00F0404
FREERDP_API uint32 freerdp_keyboard_init(uint32 keyboard_layout_id); FREERDP_API uint32 freerdp_keyboard_init(uint32 keyboardLayoutId);
FREERDP_API RDP_KEYBOARD_LAYOUT* freerdp_keyboard_get_layouts(uint32 types); FREERDP_API RDP_KEYBOARD_LAYOUT* freerdp_keyboard_get_layouts(uint32 types);
FREERDP_API const char* freerdp_keyboard_get_layout_name_from_id(uint32 keyboardLayoutID); FREERDP_API const char* freerdp_keyboard_get_layout_name_from_id(uint32 keyboardLayoutId);
FREERDP_API uint32 freerdp_keyboard_get_scancode_from_keycode(uint32 keycode, boolean* extended); FREERDP_API uint32 freerdp_keyboard_get_rdp_scancode_from_x11_keycode(uint32 keycode, boolean* extended);
FREERDP_API uint32 freerdp_keyboard_get_keycode_from_scancode(uint32 scancode, boolean extended); FREERDP_API uint32 freerdp_keyboard_get_x11_keycode_from_rdp_scancode(uint32 scancode, boolean extended);
FREERDP_API uint32 freerdp_keyboard_get_scancode_from_vkcode(uint32 vkcode, boolean* extended); FREERDP_API uint32 freerdp_keyboard_get_rdp_scancode_from_virtual_key_code(uint32 vkcode, boolean* extended);
FREERDP_API char* freerdp_keyboard_get_virtual_key_code_name(uint32 vkcode);
#endif /* __FREERDP_LOCALE_KEYBOARD_H */ #endif /* __FREERDP_LOCALE_KEYBOARD_H */

View File

@ -1,8 +1,8 @@
/** /**
* FreeRDP: A Remote Desktop Protocol Client * FreeRDP: A Remote Desktop Protocol Implementation
* XKB-based Keyboard Mapping to Microsoft Keyboard System * Microsoft Locales
* *
* Copyright 2009 Marc-Andre Moreau <marcandre.moreau@gmail.com> * Copyright 2009-2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -20,7 +20,6 @@
set(FREERDP_LOCALE_SRCS set(FREERDP_LOCALE_SRCS
keyboard_layout.c keyboard_layout.c
keyboard.c keyboard.c
keyboard.h
locale.c locale.c
liblocale.h) liblocale.h)

View File

@ -1,8 +1,8 @@
/** /**
* FreeRDP: A Remote Desktop Protocol Client * FreeRDP: A Remote Desktop Protocol Implementation
* Localization Services * Keyboard Localization
* *
* Copyright 2009 Marc-Andre Moreau <marcandre.moreau@gmail.com> * Copyright 2009-2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -43,36 +43,29 @@
#include <freerdp/locale/locale.h> #include <freerdp/locale/locale.h>
#include <freerdp/locale/keyboard.h> #include <freerdp/locale/keyboard.h>
#include "keyboard.h" uint32 RDP_SCANCODE_TO_X11_KEYCODE[256][2];
RDP_SCANCODE X11_KEYCODE_TO_RDP_SCANCODE[256];
extern const VIRTUAL_KEY virtualKeyboard[258]; extern const VIRTUAL_KEY_CODE VIRTUAL_KEY_CODE_TABLE[256];
extern const RDP_SCANCODE VIRTUAL_KEY_CODE_TO_RDP_SCANCODE_TABLE[256];
/* static int freerdp_keyboard_load_map(uint32 keycode_to_vkcode[256], char* name)
* The actual mapping from X keycodes to RDP keycodes, initialized from xkb keycodes or similar.
* Used directly by freerdp_kbd_get_scancode_by_keycode. The mapping is a global variable,
* but it only depends on which keycodes the X servers keyboard driver uses and is thus very static.
*/
RDP_KEYCODE x11_keycode_to_rdp_scancode[256];
uint32 rdp_scancode_to_x11_keycode[256][2];
static int freerdp_keyboard_load_map(KeycodeToVkcode map, char* name)
{ {
FILE* fp; FILE* fp;
char* pch; char* pch;
char* beg; char* beg;
char* end; char* end;
int i = 0; int i = 0;
int kbdFound = 0; int kbd_found = 0;
char* keymap_path; char* keymap_path;
uint32 keycode = 0; uint32 keycode = 0;
char buffer[1024] = ""; char buffer[1024] = "";
char keymap_name[256] = ""; char keymap_name[256] = "";
char keymap_include[256] = ""; char keymap_include[256] = "";
char keymap_filename[256] = ""; char keymap_filename[256] = "";
char keycodeString[32] = ""; char keycode_string[32] = "";
char vkcodeName[128] = ""; char vkcode_name[128] = "";
VIRTUAL_KEY_CODE* vkcode;
beg = name; beg = name;
@ -111,7 +104,7 @@ static int freerdp_keyboard_load_map(KeycodeToVkcode map, char* name)
continue; /* Skip comments */ continue; /* Skip comments */
} }
if (kbdFound) if (kbd_found)
{ {
/* Closing curly bracket and semicolon */ /* Closing curly bracket and semicolon */
if ((pch = strstr(buffer, "};")) != NULL) if ((pch = strstr(buffer, "};")) != NULL)
@ -125,8 +118,8 @@ static int freerdp_keyboard_load_map(KeycodeToVkcode map, char* name)
/* We copy the virtual key code name in a string */ /* We copy the virtual key code name in a string */
beg = pch; beg = pch;
strncpy(vkcodeName, beg, end - beg); strncpy(vkcode_name, beg, end - beg);
vkcodeName[end - beg] = '\0'; vkcode_name[end - beg] = '\0';
/* Now we want to extract the virtual key code itself which is in between '<' and '>' */ /* Now we want to extract the virtual key code itself which is in between '<' and '>' */
if ((beg = strchr(pch + 3, '<')) == NULL) if ((beg = strchr(pch + 3, '<')) == NULL)
@ -138,24 +131,30 @@ static int freerdp_keyboard_load_map(KeycodeToVkcode map, char* name)
break; break;
/* We copy the string representing the number in a string */ /* We copy the string representing the number in a string */
strncpy(keycodeString, beg, end - beg); strncpy(keycode_string, beg, end - beg);
keycodeString[end - beg] = '\0'; keycode_string[end - beg] = '\0';
/* Convert the string representing the code to an integer */ /* Convert the string representing the code to an integer */
keycode = atoi(keycodeString); keycode = atoi(keycode_string);
/* Make sure it is a valid keycode */ /* Make sure it is a valid keycode */
if (keycode < 0 || keycode > 255) if (keycode < 0 || keycode > 255)
break; break;
/* Load this key mapping in the keyboard mapping */ /* Load this key mapping in the keyboard mapping */
for(i = 0; i < sizeof(virtualKeyboard) / sizeof(VIRTUAL_KEY); i++)
i = 0;
do
{ {
if (strcmp(vkcodeName, virtualKeyboard[i].name) == 0) vkcode = (VIRTUAL_KEY_CODE*) &VIRTUAL_KEY_CODE_TABLE[i];
{
map[keycode] = i; if (strcmp(vkcode_name, vkcode->name) == 0)
} keycode_to_vkcode[keycode] = vkcode->code;
i++;
} }
while (vkcode->code != 0);
} }
else if ((pch = strstr(buffer, ": extends")) != NULL) else if ((pch = strstr(buffer, ": extends")) != NULL)
{ {
@ -174,7 +173,7 @@ static int freerdp_keyboard_load_map(KeycodeToVkcode map, char* name)
strncpy(keymap_include, beg, end - beg); strncpy(keymap_include, beg, end - beg);
keymap_include[end - beg] = '\0'; keymap_include[end - beg] = '\0';
freerdp_keyboard_load_map(map, keymap_include); /* Load included keymap */ freerdp_keyboard_load_map(keycode_to_vkcode, keymap_include); /* Load included keymap */
} }
} }
else if ((pch = strstr(buffer, "keyboard")) != NULL) else if ((pch = strstr(buffer, "keyboard")) != NULL)
@ -192,7 +191,7 @@ static int freerdp_keyboard_load_map(KeycodeToVkcode map, char* name)
/* Does it match our keymap name? */ /* Does it match our keymap name? */
if (strncmp(keymap_name, pch, strlen(keymap_name)) == 0) if (strncmp(keymap_name, pch, strlen(keymap_name)) == 0)
kbdFound = 1; kbd_found = 1;
} }
} }
@ -201,37 +200,36 @@ static int freerdp_keyboard_load_map(KeycodeToVkcode map, char* name)
return 1; return 1;
} }
void freerdp_keyboard_load_maps(KeycodeToVkcode keycodeToVkcode, char* names) void freerdp_keyboard_load_maps(uint32 keycode_to_vkcode[256], char* names)
{ {
char* kbd; char* kbd;
char* namesEnd; char* names_end;
int keymapLoaded = 0; int keymap_loaded = 0;
memset(keycodeToVkcode, 0, sizeof(keycodeToVkcode)); memset(keycode_to_vkcode, 0, sizeof(keycode_to_vkcode));
kbd = names; kbd = names;
namesEnd = names + strlen(names); names_end = names + strlen(names);
do do
{ {
/* Multiple maps are separated by '+' */ /* multiple maps are separated by '+' */
int kbdlen = strcspn(kbd + 1, "+") + 1; int kbd_length = strcspn(kbd + 1, "+") + 1;
kbd[kbdlen] = '\0'; kbd[kbd_length] = '\0';
/* Load keyboard map */ /* Load keyboard map */
keymapLoaded += freerdp_keyboard_load_map(keycodeToVkcode, kbd); keymap_loaded += freerdp_keyboard_load_map(keycode_to_vkcode, kbd);
kbd += kbdlen + 1; kbd += kbd_length + 1;
} }
while (kbd < namesEnd); while (kbd < names_end);
DEBUG_KBD("loaded %d keymaps", keymapLoaded); DEBUG_KBD("loaded %d keymaps", keymap_loaded);
if (keymapLoaded <= 0) if (keymap_loaded <= 0)
printf("error: no keyboard mapping available!\n"); printf("error: no keyboard mapping available!\n");
} }
uint32 freerdp_detect_keyboard(uint32 keyboardLayoutID) uint32 freerdp_detect_keyboard(uint32 keyboardLayoutID)
{ {
if (keyboardLayoutID != 0) if (keyboardLayoutID != 0)
@ -252,82 +250,6 @@ uint32 freerdp_detect_keyboard(uint32 keyboardLayoutID)
return keyboardLayoutID; return keyboardLayoutID;
} }
#ifdef WITH_XKB
uint32 freerdp_keyboard_init_xkb(uint32 keyboardLayoutId)
{
void* display;
memset(x11_keycode_to_rdp_scancode, 0, sizeof(x11_keycode_to_rdp_scancode));
memset(rdp_scancode_to_x11_keycode, '\0', sizeof(rdp_scancode_to_x11_keycode));
display = freerdp_keyboard_xkb_init();
if (!display)
{
DEBUG_KBD("Error initializing xkb");
return 0;
}
if (keyboardLayoutId == 0)
{
keyboardLayoutId = detect_keyboard_layout_from_xkb(display);
DEBUG_KBD("detect_keyboard_layout_from_xkb: %X", keyboardLayoutId);
}
freerdp_keyboard_load_map_from_xkb(display, x11_keycode_to_rdp_scancode, rdp_scancode_to_x11_keycode);
return keyboardLayoutId;
}
#endif
#ifdef WITH_X11
uint32 freerdp_keyboard_init_x11(uint32 keyboardLayoutId)
{
uint32 vkcode;
uint32 keycode;
KeycodeToVkcode keycodeToVkcode;
memset(x11_keycode_to_rdp_scancode, 0, sizeof(x11_keycode_to_rdp_scancode));
memset(rdp_scancode_to_x11_keycode, '\0', sizeof(rdp_scancode_to_x11_keycode));
if (keyboardLayoutId == 0)
{
keyboardLayoutId = freerdp_detect_keyboard_layout_from_locale();
DEBUG_KBD("using keyboard layout: %X", keyboardLayoutID);
}
if (keyboardLayoutId == 0)
{
keyboardLayoutId = 0x0409;
DEBUG_KBD("using default keyboard layout: %X", keyboardLayoutID);
}
#ifdef __APPLE__
/* Apple X11 breaks XKB detection */
freerdp_keyboard_load_map(keycodeToVkcode, "macosx(macosx)");
#endif
for (keycode = 0; keycode < 256; keycode++)
{
vkcode = keycodeToVkcode[keycode];
DEBUG_KBD("X keycode %3d VK %3d %-19s-> RDP scancode %d/%d",
keycode, vkcode, virtualKeyboard[vkcode].name,
virtualKeyboard[vkcode].extended, virtualKeyboard[vkcode].scancode);
x11_keycode_to_rdp_scancode[keycode].keycode = virtualKeyboard[vkcode].scancode;
x11_keycode_to_rdp_scancode[keycode].extended = virtualKeyboard[vkcode].extended;
x11_keycode_to_rdp_scancode[keycode].keyname = virtualKeyboard[vkcode].name;
if (x11_keycode_to_rdp_scancode[keycode].extended)
rdp_scancode_to_x11_keycode[virtualKeyboard[vkcode].scancode][1] = keycode;
else
rdp_scancode_to_x11_keycode[virtualKeyboard[vkcode].scancode][0] = keycode;
}
return keyboardLayoutId;
}
#endif
uint32 freerdp_keyboard_init(uint32 keyboardLayoutId) uint32 freerdp_keyboard_init(uint32 keyboardLayoutId)
{ {
#ifdef WITH_XKB #ifdef WITH_XKB
@ -345,26 +267,27 @@ uint32 freerdp_keyboard_init(uint32 keyboardLayoutId)
return keyboardLayoutId; return keyboardLayoutId;
} }
uint32 freerdp_keyboard_get_scancode_from_keycode(uint32 keycode, boolean* extended) uint32 freerdp_keyboard_get_rdp_scancode_from_x11_keycode(uint32 keycode, boolean* extended)
{ {
DEBUG_KBD("%2x %4s -> %d/%d", keycode, x11_keycode_to_rdp_scancode[keycode].keyname, *extended = X11_KEYCODE_TO_RDP_SCANCODE[keycode].extended;
x11_keycode_to_rdp_scancode[keycode].extended, x11_keycode_to_rdp_scancode[keycode].keycode); return X11_KEYCODE_TO_RDP_SCANCODE[keycode].code;
*extended = x11_keycode_to_rdp_scancode[keycode].extended;
return x11_keycode_to_rdp_scancode[keycode].keycode;
} }
uint32 freerdp_keyboard_get_keycode_from_scancode(uint32 scancode, boolean extended) uint32 freerdp_keyboard_get_x11_keycode_from_rdp_scancode(uint32 scancode, boolean extended)
{ {
if (extended) if (extended)
return rdp_scancode_to_x11_keycode[scancode][1]; return RDP_SCANCODE_TO_X11_KEYCODE[scancode][1];
else else
return rdp_scancode_to_x11_keycode[scancode][0]; return RDP_SCANCODE_TO_X11_KEYCODE[scancode][0];
} }
uint32 freerdp_keyboard_get_scancode_from_vkcode(uint32 vkcode, boolean* extended) uint32 freerdp_keyboard_get_rdp_scancode_from_virtual_key_code(uint32 vkcode, boolean* extended)
{ {
*extended = virtualKeyboard[vkcode].extended; *extended = VIRTUAL_KEY_CODE_TO_RDP_SCANCODE_TABLE[vkcode].extended;
return virtualKeyboard[vkcode].scancode; return VIRTUAL_KEY_CODE_TO_RDP_SCANCODE_TABLE[vkcode].code;
}
char* freerdp_keyboard_get_virtual_key_code_name(uint32 vkcode)
{
return (char*) VIRTUAL_KEY_CODE_TABLE[vkcode].name;
} }

View File

@ -1,37 +0,0 @@
/**
* FreeRDP: A Remote Desktop Protocol Client
* XKB-based Keyboard Mapping to Microsoft Keyboard System
*
* Copyright 2009 Marc-Andre Moreau <marcandre.moreau@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __KEYBOARD_H
#define __KEYBOARD_H
#include <freerdp/types.h>
typedef uint32 KeycodeToVkcode[256];
struct _RDP_KEYCODE
{
uint32 extended;
uint32 keycode;
const char* keyname;
};
typedef struct _RDP_KEYCODE RDP_KEYCODE;
void freerdp_keyboard_load_maps(KeycodeToVkcode keycodeToVkcode, char* names);
#endif /* __KEYBOARD_H */

View File

@ -1,8 +1,8 @@
/** /**
* FreeRDP: A Remote Desktop Protocol Client * FreeRDP: A Remote Desktop Protocol Implementation
* XKB-based Keyboard Mapping to Microsoft Keyboard System * Keyboard Layouts
* *
* Copyright 2009 Marc-Andre Moreau <marcandre.moreau@gmail.com> * Copyright 2009-2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -207,30 +207,35 @@ static const RDP_KEYBOARD_IME RDP_KEYBOARD_IME_TABLE[] =
{ KBD_CHINESE_TRADITIONAL_ALPHANUMERIC, "romanime.ime", "Chinese (Traditional) - Alphanumeric" } { KBD_CHINESE_TRADITIONAL_ALPHANUMERIC, "romanime.ime", "Chinese (Traditional) - Alphanumeric" }
}; };
const VIRTUAL_KEY_CODE VIRTUAL_KEY_CODES[] = const VIRTUAL_KEY_CODE VIRTUAL_KEY_CODE_TABLE[256] =
{ {
{ 0, "" },
{ VK_LBUTTON, "VK_LBUTTON" }, { VK_LBUTTON, "VK_LBUTTON" },
{ VK_RBUTTON, "VK_RBUTTON" }, { VK_RBUTTON, "VK_RBUTTON" },
{ VK_CANCEL, "VK_CANCEL" }, { VK_CANCEL, "VK_CANCEL" },
{ VK_MBUTTON, "VK_MBUTTON" }, { VK_MBUTTON, "VK_MBUTTON" },
{ VK_XBUTTON1, "VK_XBUTTON1" }, { VK_XBUTTON1, "VK_XBUTTON1" },
{ VK_XBUTTON2, "VK_XBUTTON2" }, { VK_XBUTTON2, "VK_XBUTTON2" },
{ 0, "" },
{ VK_BACK, "VK_BACK" }, { VK_BACK, "VK_BACK" },
{ VK_TAB, "VK_TAB" }, { VK_TAB, "VK_TAB" },
{ 0, "" },
{ 0, "" },
{ VK_CLEAR, "VK_CLEAR" }, { VK_CLEAR, "VK_CLEAR" },
{ VK_RETURN, "VK_RETURN" }, { VK_RETURN, "VK_RETURN" },
{ 0, "" },
{ 0, "" },
{ VK_SHIFT, "VK_SHIFT" }, { VK_SHIFT, "VK_SHIFT" },
{ VK_CONTROL, "VK_CONTROL" }, { VK_CONTROL, "VK_CONTROL" },
{ VK_MENU, "VK_MENU" }, { VK_MENU, "VK_MENU" },
{ VK_PAUSE, "VK_PAUSE" }, { VK_PAUSE, "VK_PAUSE" },
{ VK_CAPITAL, "VK_CAPITAL" }, { VK_CAPITAL, "VK_CAPITAL" },
{ VK_KANA, "VK_KANA" }, { VK_KANA, "VK_KANA" }, /* also VK_HANGUL */
{ VK_HANGUEL, "VK_HANGUEL" }, { 0, "" },
{ VK_HANGUL, "VK_HANGUL" },
{ VK_JUNJA, "VK_JUNJA" }, { VK_JUNJA, "VK_JUNJA" },
{ VK_FINAL, "VK_FINAL" }, { VK_FINAL, "VK_FINAL" },
{ VK_HANJA, "VK_HANJA" }, { VK_KANJI, "VK_KANJI" }, /* also VK_HANJA */
{ VK_KANJI, "VK_KANJI" }, { 0, "" },
{ VK_ESCAPE, "VK_ESCAPE" }, { VK_ESCAPE, "VK_ESCAPE" },
{ VK_CONVERT, "VK_CONVERT" }, { VK_CONVERT, "VK_CONVERT" },
{ VK_NONCONVERT, "VK_NONCONVERT" }, { VK_NONCONVERT, "VK_NONCONVERT" },
@ -262,6 +267,13 @@ const VIRTUAL_KEY_CODE VIRTUAL_KEY_CODES[] =
{ VK_KEY_7, "VK_KEY_7" }, { VK_KEY_7, "VK_KEY_7" },
{ VK_KEY_8, "VK_KEY_8" }, { VK_KEY_8, "VK_KEY_8" },
{ VK_KEY_9, "VK_KEY_9" }, { VK_KEY_9, "VK_KEY_9" },
{ 0, "" },
{ 0, "" },
{ 0, "" },
{ 0, "" },
{ 0, "" },
{ 0, "" },
{ 0, "" },
{ VK_KEY_A, "VK_KEY_A" }, { VK_KEY_A, "VK_KEY_A" },
{ VK_KEY_B, "VK_KEY_B" }, { VK_KEY_B, "VK_KEY_B" },
{ VK_KEY_C, "VK_KEY_C" }, { VK_KEY_C, "VK_KEY_C" },
@ -291,6 +303,7 @@ const VIRTUAL_KEY_CODE VIRTUAL_KEY_CODES[] =
{ VK_LWIN, "VK_LWIN" }, { VK_LWIN, "VK_LWIN" },
{ VK_RWIN, "VK_RWIN" }, { VK_RWIN, "VK_RWIN" },
{ VK_APPS, "VK_APPS" }, { VK_APPS, "VK_APPS" },
{ 0, "" },
{ VK_SLEEP, "VK_SLEEP" }, { VK_SLEEP, "VK_SLEEP" },
{ VK_NUMPAD0, "VK_NUMPAD0" }, { VK_NUMPAD0, "VK_NUMPAD0" },
{ VK_NUMPAD1, "VK_NUMPAD1" }, { VK_NUMPAD1, "VK_NUMPAD1" },
@ -332,8 +345,30 @@ const VIRTUAL_KEY_CODE VIRTUAL_KEY_CODES[] =
{ VK_F22, "VK_F22" }, { VK_F22, "VK_F22" },
{ VK_F23, "VK_F23" }, { VK_F23, "VK_F23" },
{ VK_F24, "VK_F24" }, { VK_F24, "VK_F24" },
{ 0, "" },
{ 0, "" },
{ 0, "" },
{ 0, "" },
{ 0, "" },
{ 0, "" },
{ 0, "" },
{ 0, "" },
{ VK_NUMLOCK, "VK_NUMLOCK" }, { VK_NUMLOCK, "VK_NUMLOCK" },
{ VK_SCROLL, "VK_SCROLL" }, { VK_SCROLL, "VK_SCROLL" },
{ 0, "" },
{ 0, "" },
{ 0, "" },
{ 0, "" },
{ 0, "" },
{ 0, "" },
{ 0, "" },
{ 0, "" },
{ 0, "" },
{ 0, "" },
{ 0, "" },
{ 0, "" },
{ 0, "" },
{ 0, "" },
{ VK_LSHIFT, "VK_LSHIFT" }, { VK_LSHIFT, "VK_LSHIFT" },
{ VK_RSHIFT, "VK_RSHIFT" }, { VK_RSHIFT, "VK_RSHIFT" },
{ VK_LCONTROL, "VK_LCONTROL" }, { VK_LCONTROL, "VK_LCONTROL" },
@ -358,6 +393,8 @@ const VIRTUAL_KEY_CODE VIRTUAL_KEY_CODES[] =
{ VK_MEDIA_SELECT, "VK_MEDIA_SELECT" }, { VK_MEDIA_SELECT, "VK_MEDIA_SELECT" },
{ VK_LAUNCH_APP1, "VK_LAUNCH_APP1" }, { VK_LAUNCH_APP1, "VK_LAUNCH_APP1" },
{ VK_LAUNCH_APP2, "VK_LAUNCH_APP2" }, { VK_LAUNCH_APP2, "VK_LAUNCH_APP2" },
{ 0, "" },
{ 0, "" },
{ VK_OEM_1, "VK_OEM_1" }, { VK_OEM_1, "VK_OEM_1" },
{ VK_OEM_PLUS, "VK_OEM_PLUS" }, { VK_OEM_PLUS, "VK_OEM_PLUS" },
{ VK_OEM_COMMA, "VK_OEM_COMMA" }, { VK_OEM_COMMA, "VK_OEM_COMMA" },
@ -367,14 +404,57 @@ const VIRTUAL_KEY_CODE VIRTUAL_KEY_CODES[] =
{ VK_OEM_3, "VK_OEM_3" }, { VK_OEM_3, "VK_OEM_3" },
{ VK_ABNT_C1, "VK_ABNT_C1" }, { VK_ABNT_C1, "VK_ABNT_C1" },
{ VK_ABNT_C2, "VK_ABNT_C2" }, { VK_ABNT_C2, "VK_ABNT_C2" },
{ 0, "" },
{ 0, "" },
{ 0, "" },
{ 0, "" },
{ 0, "" },
{ 0, "" },
{ 0, "" },
{ 0, "" },
{ 0, "" },
{ 0, "" },
{ 0, "" },
{ 0, "" },
{ 0, "" },
{ 0, "" },
{ 0, "" },
{ 0, "" },
{ 0, "" },
{ 0, "" },
{ 0, "" },
{ 0, "" },
{ 0, "" },
{ 0, "" },
{ 0, "" },
{ 0, "" },
{ VK_OEM_4, "VK_OEM_4" }, { VK_OEM_4, "VK_OEM_4" },
{ VK_OEM_5, "VK_OEM_5" }, { VK_OEM_5, "VK_OEM_5" },
{ VK_OEM_6, "VK_OEM_6" }, { VK_OEM_6, "VK_OEM_6" },
{ VK_OEM_7, "VK_OEM_7" }, { VK_OEM_7, "VK_OEM_7" },
{ VK_OEM_8, "VK_OEM_8" }, { VK_OEM_8, "VK_OEM_8" },
{ 0, "" },
{ 0, "" },
{ VK_OEM_102, "VK_OEM_102" }, { VK_OEM_102, "VK_OEM_102" },
{ 0, "" },
{ 0, "" },
{ VK_PROCESSKEY, "VK_PROCESSKEY" }, { VK_PROCESSKEY, "VK_PROCESSKEY" },
{ 0, "" },
{ VK_PACKET, "VK_PACKET" }, { VK_PACKET, "VK_PACKET" },
{ 0, "" },
{ 0, "" },
{ 0, "" },
{ 0, "" },
{ 0, "" },
{ 0, "" },
{ 0, "" },
{ 0, "" },
{ 0, "" },
{ 0, "" },
{ 0, "" },
{ 0, "" },
{ 0, "" },
{ 0, "" },
{ VK_ATTN, "VK_ATTN" }, { VK_ATTN, "VK_ATTN" },
{ VK_CRSEL, "VK_CRSEL" }, { VK_CRSEL, "VK_CRSEL" },
{ VK_EXSEL, "VK_EXSEL" }, { VK_EXSEL, "VK_EXSEL" },
@ -383,12 +463,13 @@ const VIRTUAL_KEY_CODE VIRTUAL_KEY_CODES[] =
{ VK_ZOOM, "VK_ZOOM" }, { VK_ZOOM, "VK_ZOOM" },
{ VK_NONAME, "VK_NONAME" }, { VK_NONAME, "VK_NONAME" },
{ VK_PA1, "VK_PA1" }, { VK_PA1, "VK_PA1" },
{ VK_OEM_CLEAR, "VK_OEM_CLEAR" } { VK_OEM_CLEAR, "VK_OEM_CLEAR" },
{ 0, "" }
}; };
/* the index in this table is the virtual key code */ /* the index in this table is the virtual key code */
const RDP_SCANCODE VIRTUAL_KEY_CODE_TO_RDP_SCANCODE_TABLE[] = const RDP_SCANCODE VIRTUAL_KEY_CODE_TO_RDP_SCANCODE_TABLE[256] =
{ {
{ 0x00, 0 }, { 0x00, 0 },
{ 0x00, 0 }, /* VK_LBUTTON */ { 0x00, 0 }, /* VK_LBUTTON */
@ -648,269 +729,6 @@ const RDP_SCANCODE VIRTUAL_KEY_CODE_TO_RDP_SCANCODE_TABLE[] =
{ 0x00, 0 } { 0x00, 0 }
}; };
const VIRTUAL_KEY virtualKeyboard[] =
{
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "VK_LBUTTON" , NULL },
{ 0x00, 0, "VK_RBUTTON" , NULL },
{ 0x00, 0, "VK_CANCEL" , NULL },
{ 0x00, 0, "VK_MBUTTON" , NULL },
{ 0x00, 0, "VK_XBUTTON1" , NULL },
{ 0x00, 0, "VK_XBUTTON2" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x0E, 0, "VK_BACK" , "BKSP" },
{ 0x0F, 0, "VK_TAB" , "TAB" },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "VK_CLEAR" , NULL },
{ 0x1C, 0, "VK_RETURN" , "RTRN" },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x2A, 0, "VK_SHIFT" , "LFSH" },
{ 0x00, 0, "VK_CONTROL" , NULL },
{ 0x38, 0, "VK_MENU" , "LALT" },
{ 0x46, 1, "VK_PAUSE" , "PAUS" },
{ 0x3A, 0, "VK_CAPITAL" , "CAPS" },
{ 0x72, 0, "VK_KANA / VK_HANGUL" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "VK_JUNJA" , NULL },
{ 0x00, 0, "VK_FINAL" , NULL },
{ 0x71, 0, "VK_HANJA / VK_KANJI" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x01, 0, "VK_ESCAPE" , "ESC" },
{ 0x00, 0, "VK_CONVERT" , NULL },
{ 0x00, 0, "VK_NONCONVERT" , NULL },
{ 0x00, 0, "VK_ACCEPT" , NULL },
{ 0x00, 0, "VK_MODECHANGE" , NULL },
{ 0x39, 0, "VK_SPACE" , "SPCE" },
{ 0x49, 1, "VK_PRIOR" , "PGUP" },
{ 0x51, 1, "VK_NEXT" , "PGDN" },
{ 0x4F, 1, "VK_END" , "END" },
{ 0x47, 1, "VK_HOME" , "HOME" },
{ 0x4B, 1, "VK_LEFT" , "LEFT" },
{ 0x48, 1, "VK_UP" , "UP" },
{ 0x4D, 1, "VK_RIGHT" , "RGHT" },
{ 0x50, 1, "VK_DOWN" , "DOWN" },
{ 0x00, 0, "VK_SELECT" , NULL },
{ 0x37, 1, "VK_PRINT" , "PRSC" },
{ 0x37, 1, "VK_EXECUTE" , NULL },
{ 0x37, 1, "VK_SNAPSHOT" , NULL },
{ 0x52, 1, "VK_INSERT" , "INS" },
{ 0x53, 1, "VK_DELETE" , "DELE" },
{ 0x63, 0, "VK_HELP" , NULL },
{ 0x0B, 0, "VK_KEY_0" , "AE10" },
{ 0x02, 0, "VK_KEY_1" , "AE01" },
{ 0x03, 0, "VK_KEY_2" , "AE02" },
{ 0x04, 0, "VK_KEY_3" , "AE03" },
{ 0x05, 0, "VK_KEY_4" , "AE04" },
{ 0x06, 0, "VK_KEY_5" , "AE05" },
{ 0x07, 0, "VK_KEY_6" , "AE06" },
{ 0x08, 0, "VK_KEY_7" , "AE07" },
{ 0x09, 0, "VK_KEY_8" , "AE08" },
{ 0x0A, 0, "VK_KEY_9" , "AE09" },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x1E, 0, "VK_KEY_A" , "AC01" },
{ 0x30, 0, "VK_KEY_B" , "AB05" },
{ 0x2E, 0, "VK_KEY_C" , "AB03" },
{ 0x20, 0, "VK_KEY_D" , "AC03" },
{ 0x12, 0, "VK_KEY_E" , "AD03" },
{ 0x21, 0, "VK_KEY_F" , "AC04" },
{ 0x22, 0, "VK_KEY_G" , "AC05" },
{ 0x23, 0, "VK_KEY_H" , "AC06" },
{ 0x17, 0, "VK_KEY_I" , "AD08" },
{ 0x24, 0, "VK_KEY_J" , "AC07" },
{ 0x25, 0, "VK_KEY_K" , "AC08" },
{ 0x26, 0, "VK_KEY_L" , "AC09" },
{ 0x32, 0, "VK_KEY_M" , "AB07" },
{ 0x31, 0, "VK_KEY_N" , "AB06" },
{ 0x18, 0, "VK_KEY_O" , "AD09" },
{ 0x19, 0, "VK_KEY_P" , "AD10" },
{ 0x10, 0, "VK_KEY_Q" , "AD01" },
{ 0x13, 0, "VK_KEY_R" , "AD04" },
{ 0x1F, 0, "VK_KEY_S" , "AC02" },
{ 0x14, 0, "VK_KEY_T" , "AD05" },
{ 0x16, 0, "VK_KEY_U" , "AD07" },
{ 0x2F, 0, "VK_KEY_V" , "AB04" },
{ 0x11, 0, "VK_KEY_W" , "AD02" },
{ 0x2D, 0, "VK_KEY_X" , "AB02" },
{ 0x15, 0, "VK_KEY_Y" , "AD06" },
{ 0x2C, 0, "VK_KEY_Z" , "AB01" },
{ 0x5B, 1, "VK_LWIN" , "LWIN" },
{ 0x5C, 1, "VK_RWIN" , "RWIN" },
{ 0x5D, 1, "VK_APPS" , "COMP" },
{ 0x00, 0, "" , NULL },
{ 0x5F, 0, "VK_SLEEP" , NULL },
{ 0x52, 0, "VK_NUMPAD0" , "KP0" },
{ 0x4F, 0, "VK_NUMPAD1" , "KP1" },
{ 0x50, 0, "VK_NUMPAD2" , "KP2" },
{ 0x51, 0, "VK_NUMPAD3" , "KP3" },
{ 0x4B, 0, "VK_NUMPAD4" , "KP4" },
{ 0x4C, 0, "VK_NUMPAD5" , "KP5" },
{ 0x4D, 0, "VK_NUMPAD6" , "KP6" },
{ 0x47, 0, "VK_NUMPAD7" , "KP7" },
{ 0x48, 0, "VK_NUMPAD8" , "KP8" },
{ 0x49, 0, "VK_NUMPAD9" , "KP9" },
{ 0x37, 0, "VK_MULTIPLY" , "KPMU" },
{ 0x4E, 0, "VK_ADD" , "KPAD" },
{ 0x00, 0, "VK_SEPARATOR" , NULL },
{ 0x4A, 0, "VK_SUBTRACT" , "KPSU" },
{ 0x53, 0, "VK_DECIMAL" , "KPDL" },
{ 0x35, 0, "VK_DIVIDE" , "KPDV" },
{ 0x3B, 0, "VK_F1" , "FK01" },
{ 0x3C, 0, "VK_F2" , "FK02" },
{ 0x3D, 0, "VK_F3" , "FK03" },
{ 0x3E, 0, "VK_F4" , "FK04" },
{ 0x3F, 0, "VK_F5" , "FK05" },
{ 0x40, 0, "VK_F6" , "FK06" },
{ 0x41, 0, "VK_F7" , "FK07" },
{ 0x42, 0, "VK_F8" , "FK08" },
{ 0x43, 0, "VK_F9" , "FK09" },
{ 0x44, 0, "VK_F10" , "FK10" },
{ 0x57, 0, "VK_F11" , "FK11" },
{ 0x58, 0, "VK_F12" , "FK12" },
{ 0x64, 0, "VK_F13" , NULL },
{ 0x65, 0, "VK_F14" , NULL },
{ 0x66, 0, "VK_F15" , NULL },
{ 0x67, 0, "VK_F16" , NULL },
{ 0x68, 0, "VK_F17" , NULL },
{ 0x69, 0, "VK_F18" , NULL },
{ 0x6A, 0, "VK_F19" , NULL },
{ 0x6B, 0, "VK_F20" , NULL },
{ 0x6C, 0, "VK_F21" , NULL },
{ 0x6D, 0, "VK_F22" , NULL },
{ 0x6E, 0, "VK_F23" , NULL },
{ 0x6F, 0, "VK_F24" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x45, 0, "VK_NUMLOCK" , "NMLK" },
{ 0x46, 0, "VK_SCROLL" , "SCLK" },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x2A, 0, "VK_LSHIFT" , NULL },
{ 0x36, 0, "VK_RSHIFT" , "RTSH" },
{ 0x1D, 0, "VK_LCONTROL" , "LCTL" },
{ 0x1D, 1, "VK_RCONTROL" , "RCTL" },
{ 0x38, 0, "VK_LMENU" , NULL },
{ 0x38, 1, "VK_RMENU" , "RALT" },
{ 0x00, 0, "VK_BROWSER_BACK" , NULL },
{ 0x00, 0, "VK_BROWSER_FORWARD" , NULL },
{ 0x00, 0, "VK_BROWSER_REFRESH" , NULL },
{ 0x00, 0, "VK_BROWSER_STOP" , NULL },
{ 0x00, 0, "VK_BROWSER_SEARCH" , NULL },
{ 0x00, 0, "VK_BROWSER_FAVORITES", NULL },
{ 0x00, 0, "VK_BROWSER_HOME" , NULL },
{ 0x00, 0, "VK_VOLUME_MUTE" , NULL },
{ 0x00, 0, "VK_VOLUME_DOWN" , NULL },
{ 0x00, 0, "VK_VOLUME_UP" , NULL },
{ 0x00, 0, "VK_MEDIA_NEXT_TRACK" , NULL },
{ 0x00, 0, "VK_MEDIA_PREV_TRACK" , NULL },
{ 0x00, 0, "VK_MEDIA_STOP" , NULL },
{ 0x00, 0, "VK_MEDIA_PLAY_PAUSE" , NULL },
{ 0x00, 0, "VK_LAUNCH_MAIL" , NULL },
{ 0x00, 0, "VK_MEDIA_SELECT" , NULL },
{ 0x00, 0, "VK_LAUNCH_APP1" , NULL },
{ 0x00, 0, "VK_LAUNCH_APP2" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x27, 0, "VK_OEM_1" , "AC10" },
{ 0x0D, 0, "VK_OEM_PLUS" , "AE12" },
{ 0x33, 0, "VK_OEM_COMMA" , "AB08" },
{ 0x0C, 0, "VK_OEM_MINUS" , "AE11" },
{ 0x34, 0, "VK_OEM_PERIOD" , "AB09" },
{ 0x35, 0, "VK_OEM_2" , "AB10" },
{ 0x29, 0, "VK_OEM_3" , "TLDE" },
{ 0x73, 0, "VK_ABNT_C1" , "AB11" },
{ 0x7E, 0, "VK_ABNT_C2" , "I129" },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x1A, 0, "VK_OEM_4" , "AD11" },
{ 0x2B, 0, "VK_OEM_5" , "BKSL" },
{ 0x1B, 0, "VK_OEM_6" , "AD12" },
{ 0x28, 0, "VK_OEM_7" , "AC11" },
{ 0x1D, 0, "VK_OEM_8" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x56, 0, "VK_OEM_102" , "LSGT" },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "VK_PROCESSKEY" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "VK_PACKET" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "VK_ATTN" , NULL },
{ 0x00, 0, "VK_CRSEL" , NULL },
{ 0x00, 0, "VK_EXSEL" , NULL },
{ 0x00, 0, "VK_EREOF" , NULL },
{ 0x00, 0, "VK_PLAY" , NULL },
{ 0x62, 0, "VK_ZOOM" , NULL },
{ 0x00, 0, "VK_NONAME" , NULL },
{ 0x00, 0, "VK_PA1" , NULL },
{ 0x00, 0, "VK_OEM_CLEAR" , NULL },
{ 0x00, 0, "" , NULL },
/* end of 256 VK entries */
{ 0x54, 0, "" , "LVL3" },
{ 0x1C, 1, "" , "KPEN" }
};
RDP_KEYBOARD_LAYOUT* freerdp_keyboard_get_layouts(uint32 types) RDP_KEYBOARD_LAYOUT* freerdp_keyboard_get_layouts(uint32 types)
{ {
int num, length, i; int num, length, i;

View File

@ -1,8 +1,8 @@
/** /**
* FreeRDP: A Remote Desktop Protocol Client * FreeRDP: A Remote Desktop Protocol Implementation
* XKB-based Keyboard Mapping to Microsoft Keyboard System * Solaris Keyboard Mapping
* *
* Copyright 2009 Marc-Andre Moreau <marcandre.moreau@gmail.com> * Copyright 2009-2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -22,7 +22,7 @@
#include <string.h> #include <string.h>
#include "liblocale.h" #include "liblocale.h"
#include <freerdp/locale/layouts.h> #include <freerdp/locale/keyboard.h>
#include "keyboard_x11.h" #include "keyboard_x11.h"
@ -47,16 +47,16 @@
* keyboard layout indicated by the index given (in this case, 33, or US-English). * keyboard layout indicated by the index given (in this case, 33, or US-English).
*/ */
struct _SunOSKeyboard struct _SOLARIS_KEYBOARD
{ {
int type; /* Sun keyboard type */ uint32 type; /* Solaris keyboard type */
int layout; /* Layout */ uint32 layout; /* Layout */
char* xkbType; /* XKB keyboard */ char* xkbType; /* XKB keyboard */
uint32 keyboardLayoutID; /* XKB keyboard layout */ uint32 keyboardLayoutId; /* XKB keyboard layout */
}; };
typedef struct _SunOSKeyboard SunOSKeyboard; typedef struct _SOLARIS_KEYBOARD SOLARIS_KEYBOARD;
static const SunOSKeyboard SunOSKeyboards[] = static const SOLARIS_KEYBOARD SOLARIS_KEYBOARD_TABLE[] =
{ {
{ 4, 0, "sun(type4)", KBD_US }, /* US4 */ { 4, 0, "sun(type4)", KBD_US }, /* US4 */
{ 4, 1, "sun(type4)", KBD_US }, /* US4 */ { 4, 1, "sun(type4)", KBD_US }, /* US4 */
@ -197,7 +197,7 @@ static const SunOSKeyboard SunOSKeyboards[] =
{ 6, 272, "sun(type6)", KBD_PORTUGUESE_BRAZILIAN_ABNT } /* Brazil6_usb */ { 6, 272, "sun(type6)", KBD_PORTUGUESE_BRAZILIAN_ABNT } /* Brazil6_usb */
}; };
uint32 detect_keyboard_type_and_layout_sunos(char* xkbfile, int length) uint32 freerdp_detect_keyboard_type_and_layout_solaris(char* xkbfile, int length)
{ {
FILE* kbd; FILE* kbd;
@ -245,18 +245,17 @@ uint32 detect_keyboard_type_and_layout_sunos(char* xkbfile, int length)
} }
pclose(kbd); pclose(kbd);
for (i = 0; i < sizeof(SunOSKeyboards) / sizeof(SunOSKeyboard); i++) for (i = 0; i < sizeof(SOLARIS_KEYBOARD_TABLE) / sizeof(SOLARIS_KEYBOARD); i++)
{ {
if (SunOSKeyboards[i].type == type) if (SOLARIS_KEYBOARD_TABLE[i].type == type)
{ {
if (SunOSKeyboards[i].layout == layout) if (SOLARIS_KEYBOARD_TABLE[i].layout == layout)
{ {
strncpy(xkbfile, SunOSKeyboards[i].xkbType, length); strncpy(xkbfile, SOLARIS_KEYBOARD_TABLE[i].xkbType, length);
return SunOSKeyboards[i].keyboardLayoutID; return SOLARIS_KEYBOARD_TABLE[i].keyboardLayoutId;
} }
} }
} }
return 0; return 0;
} }

View File

@ -1,8 +1,8 @@
/** /**
* FreeRDP: A Remote Desktop Protocol Client * FreeRDP: A Remote Desktop Protocol Implementation
* XKB-based Keyboard Mapping to Microsoft Keyboard System * Solaris Keyboard Mapping
* *
* Copyright 2009 Marc-Andre Moreau <marcandre.moreau@gmail.com> * Copyright 2009-2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -17,11 +17,11 @@
* limitations under the License. * limitations under the License.
*/ */
#ifndef __KEYBOARD_SUN_H #ifndef __LOCALE_KEYBOARD_SUN_H
#define __KEYBOARD_SUN_H #define __LOCALE_KEYBOARD_SUN_H
#include "keyboard_x11.h" #include "keyboard_x11.h"
uint32 detect_keyboard_type_and_layout_sunos(char* xkbfile, int length); uint32 freerdp_detect_keyboard_type_and_layout_solaris(char* xkbfile, int length);
#endif #endif /* __LOCALE_KEYBOARD_SUN_H */

View File

@ -1,8 +1,8 @@
/** /**
* FreeRDP: A Remote Desktop Protocol Client * FreeRDP: A Remote Desktop Protocol Implementation
* XKB-based Keyboard Mapping to Microsoft Keyboard System * X11 Keyboard Mapping
* *
* Copyright 2009 Marc-Andre Moreau <marcandre.moreau@gmail.com> * Copyright 2009-2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -22,10 +22,15 @@
#include <string.h> #include <string.h>
#include "liblocale.h" #include "liblocale.h"
#include <freerdp/locale/locale.h>
#include <freerdp/locale/keyboard.h> #include <freerdp/locale/keyboard.h>
#include "keyboard_x11.h" #include "keyboard_x11.h"
extern uint32 RDP_SCANCODE_TO_X11_KEYCODE[256][2];
extern RDP_SCANCODE X11_KEYCODE_TO_RDP_SCANCODE[256];
extern const RDP_SCANCODE VIRTUAL_KEY_CODE_TO_RDP_SCANCODE_TABLE[];
struct _XKB_VARIANT struct _XKB_VARIANT
{ {
const char* variant; /* XKB Keyboard layout variant */ const char* variant; /* XKB Keyboard layout variant */
@ -891,6 +896,48 @@ static const XKB_LAYOUT xkbLayouts[] =
{ "tm", KBD_TURKISH_Q, tm_variants }, /* Turkmenistan */ { "tm", KBD_TURKISH_Q, tm_variants }, /* Turkmenistan */
}; };
uint32 freerdp_keyboard_init_x11(uint32 keyboardLayoutId)
{
uint32 vkcode;
uint32 keycode;
uint32 keycode_to_vkcode[256];
memset(X11_KEYCODE_TO_RDP_SCANCODE, 0, sizeof(X11_KEYCODE_TO_RDP_SCANCODE));
memset(RDP_SCANCODE_TO_X11_KEYCODE, 0, sizeof(RDP_SCANCODE_TO_X11_KEYCODE));
if (keyboardLayoutId == 0)
{
keyboardLayoutId = freerdp_detect_keyboard_layout_from_locale();
DEBUG_KBD("using keyboard layout: %X", keyboardLayoutID);
}
if (keyboardLayoutId == 0)
{
keyboardLayoutId = 0x0409;
DEBUG_KBD("using default keyboard layout: %X", keyboardLayoutID);
}
#ifdef __APPLE__
/* Apple X11 breaks XKB detection */
freerdp_keyboard_load_map(keycode_to_vkcode, "macosx(macosx)");
#endif
for (keycode = 0; keycode < 256; keycode++)
{
vkcode = keycode_to_vkcode[keycode];
X11_KEYCODE_TO_RDP_SCANCODE[keycode].code = VIRTUAL_KEY_CODE_TO_RDP_SCANCODE_TABLE[vkcode].code;
X11_KEYCODE_TO_RDP_SCANCODE[keycode].extended = VIRTUAL_KEY_CODE_TO_RDP_SCANCODE_TABLE[vkcode].extended;
if (X11_KEYCODE_TO_RDP_SCANCODE[keycode].extended)
RDP_SCANCODE_TO_X11_KEYCODE[VIRTUAL_KEY_CODE_TO_RDP_SCANCODE_TABLE[vkcode].code][1] = keycode;
else
RDP_SCANCODE_TO_X11_KEYCODE[VIRTUAL_KEY_CODE_TO_RDP_SCANCODE_TABLE[vkcode].code][0] = keycode;
}
return keyboardLayoutId;
}
uint32 find_keyboard_layout_in_xorg_rules(char* layout, char* variant) uint32 find_keyboard_layout_in_xorg_rules(char* layout, char* variant)
{ {
int i, j; int i, j;

View File

@ -1,8 +1,8 @@
/** /**
* FreeRDP: A Remote Desktop Protocol Client * FreeRDP: A Remote Desktop Protocol Implementation
* XKB-based Keyboard Mapping to Microsoft Keyboard System * X11 Keyboard Mapping
* *
* Copyright 2009 Marc-Andre Moreau <marcandre.moreau@gmail.com> * Copyright 2009-2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -17,15 +17,10 @@
* limitations under the License. * limitations under the License.
*/ */
/* Hardcoded mapping from xkb layout names and variants to RDP layout ids */ #ifndef __LOCALE_KEYBOARD_X11_H
#define __LOCALE_KEYBOARD_X11_H
#ifndef __LAYOUTS_X_H
#define __LAYOUTS_X_H
uint32 freerdp_keyboard_init_x11(uint32 keyboardLayoutId);
uint32 find_keyboard_layout_in_xorg_rules(char* layout, char* variant); uint32 find_keyboard_layout_in_xorg_rules(char* layout, char* variant);
#ifdef sun #endif /* __LOCALE_KEYBOARD_X11_H */
uint32 detect_keyboard_type_and_layout_sunos(char* xkbfile, int length);
#endif
#endif

View File

@ -1,6 +1,6 @@
/** /**
* FreeRDP: A Remote Desktop Protocol Client * FreeRDP: A Remote Desktop Protocol Implementation
* XKB-based Keyboard Mapping to Microsoft Keyboard System * XKB Keyboard Mapping
* *
* Copyright 2009-2012 Marc-Andre Moreau <marcandre.moreau@gmail.com> * Copyright 2009-2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
* *
@ -23,6 +23,8 @@
#include "keyboard_x11.h" #include "keyboard_x11.h"
#include <freerdp/locale/keyboard.h> #include <freerdp/locale/keyboard.h>
extern uint32 RDP_SCANCODE_TO_X11_KEYCODE[256][2];
extern RDP_SCANCODE X11_KEYCODE_TO_RDP_SCANCODE[256];
extern const RDP_SCANCODE VIRTUAL_KEY_CODE_TO_RDP_SCANCODE_TABLE[]; extern const RDP_SCANCODE VIRTUAL_KEY_CODE_TO_RDP_SCANCODE_TABLE[];
#include <X11/Xlib.h> #include <X11/Xlib.h>
@ -314,6 +316,31 @@ void* freerdp_keyboard_xkb_init()
return (void*) display; return (void*) display;
} }
uint32 freerdp_keyboard_init_xkb(uint32 keyboardLayoutId)
{
void* display;
memset(X11_KEYCODE_TO_RDP_SCANCODE, 0, sizeof(X11_KEYCODE_TO_RDP_SCANCODE));
memset(RDP_SCANCODE_TO_X11_KEYCODE, 0, sizeof(RDP_SCANCODE_TO_X11_KEYCODE));
display = freerdp_keyboard_xkb_init();
if (!display)
{
DEBUG_KBD("Error initializing xkb");
return 0;
}
if (keyboardLayoutId == 0)
{
keyboardLayoutId = detect_keyboard_layout_from_xkb(display);
DEBUG_KBD("detect_keyboard_layout_from_xkb: %X", keyboardLayoutId);
}
freerdp_keyboard_load_map_from_xkb(display);
return keyboardLayoutId;
}
/* return substring starting after nth comma, ending at following comma */ /* return substring starting after nth comma, ending at following comma */
static char* comma_substring(char* s, int n) static char* comma_substring(char* s, int n)
{ {
@ -377,7 +404,7 @@ uint32 detect_keyboard_layout_from_xkb(void* display)
return keyboard_layout; return keyboard_layout;
} }
int freerdp_keyboard_load_map_from_xkb(void* display, RDP_KEYCODE x_keycode_to_rdp_scancode[256], uint32 rdp_scancode_to_x_keycode[256][2]) int freerdp_keyboard_load_map_from_xkb(void* display)
{ {
int i, j; int i, j;
boolean found; boolean found;
@ -411,14 +438,13 @@ int freerdp_keyboard_load_map_from_xkb(void* display, RDP_KEYCODE x_keycode_to_r
{ {
uint32 vkcode = VIRTUAL_KEY_CODE_TO_XKB_KEY_NAME_TABLE[j].vkcode; uint32 vkcode = VIRTUAL_KEY_CODE_TO_XKB_KEY_NAME_TABLE[j].vkcode;
x_keycode_to_rdp_scancode[i].keycode = VIRTUAL_KEY_CODE_TO_RDP_SCANCODE_TABLE[vkcode].code; X11_KEYCODE_TO_RDP_SCANCODE[i].code = VIRTUAL_KEY_CODE_TO_RDP_SCANCODE_TABLE[vkcode].code;
x_keycode_to_rdp_scancode[i].extended = VIRTUAL_KEY_CODE_TO_RDP_SCANCODE_TABLE[vkcode].extended; X11_KEYCODE_TO_RDP_SCANCODE[i].extended = VIRTUAL_KEY_CODE_TO_RDP_SCANCODE_TABLE[vkcode].extended;
x_keycode_to_rdp_scancode[i].keyname = VIRTUAL_KEY_CODE_TO_XKB_KEY_NAME_TABLE[j].xkb_keyname;
if (x_keycode_to_rdp_scancode[i].extended) if (X11_KEYCODE_TO_RDP_SCANCODE[i].extended)
rdp_scancode_to_x_keycode[VIRTUAL_KEY_CODE_TO_RDP_SCANCODE_TABLE[vkcode].code][1] = i; RDP_SCANCODE_TO_X11_KEYCODE[VIRTUAL_KEY_CODE_TO_RDP_SCANCODE_TABLE[vkcode].code][1] = i;
else else
rdp_scancode_to_x_keycode[VIRTUAL_KEY_CODE_TO_RDP_SCANCODE_TABLE[vkcode].code][0] = i; RDP_SCANCODE_TO_X11_KEYCODE[VIRTUAL_KEY_CODE_TO_RDP_SCANCODE_TABLE[vkcode].code][0] = i;
} }
} }

View File

@ -1,6 +1,6 @@
/** /**
* FreeRDP: A Remote Desktop Protocol Client * FreeRDP: A Remote Desktop Protocol Implementation
* XKB-based Keyboard Mapping to Microsoft Keyboard System * XKB Keyboard Mapping
* *
* Copyright 2009-2012 Marc-Andre Moreau <marcandre.moreau@gmail.com> * Copyright 2009-2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
* *
@ -17,9 +17,11 @@
* limitations under the License. * limitations under the License.
*/ */
#include <freerdp/types.h> #ifndef __LOCALE_KEYBOARD_XKB_H
#define __LOCALE_KEYBOARD_XKB_H
#include "keyboard.h" #include <freerdp/types.h>
#include <freerdp/locale/keyboard.h>
struct _VIRTUAL_KEY_CODE_TO_XKB_KEY_NAME struct _VIRTUAL_KEY_CODE_TO_XKB_KEY_NAME
{ {
@ -28,6 +30,8 @@ struct _VIRTUAL_KEY_CODE_TO_XKB_KEY_NAME
}; };
typedef struct _VIRTUAL_KEY_CODE_TO_XKB_KEY_NAME VIRTUAL_KEY_CODE_TO_XKB_KEY_NAME; typedef struct _VIRTUAL_KEY_CODE_TO_XKB_KEY_NAME VIRTUAL_KEY_CODE_TO_XKB_KEY_NAME;
void* freerdp_keyboard_xkb_init(); uint32 freerdp_keyboard_init_xkb(uint32 keyboardLayoutId);
uint32 detect_keyboard_layout_from_xkb(void* display); uint32 detect_keyboard_layout_from_xkb(void* display);
int freerdp_keyboard_load_map_from_xkb(void* display, RDP_KEYCODE x11_keycode_to_rdp_scancode[256], uint32 rdp_scancode_to_x11_keycode[256][2]); int freerdp_keyboard_load_map_from_xkb(void* display);
#endif /* __LOCALE_KEYBOARD_XKB_H */

View File

@ -1,8 +1,8 @@
/** /**
* FreeRDP: A Remote Desktop Protocol Client * FreeRDP: A Remote Desktop Protocol Implementation
* XKB-based Keyboard Mapping to Microsoft Keyboard System * RDP Localization
* *
* Copyright 2009 Marc-Andre Moreau <marcandre.moreau@gmail.com> * Copyright 2009-2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -17,8 +17,8 @@
* limitations under the License. * limitations under the License.
*/ */
#ifndef __LIBKBD_H #ifndef __LIBLOCALE_H
#define __LIBKBD_H #define __LIBLOCALE_H
#include <freerdp/utils/debug.h> #include <freerdp/utils/debug.h>
@ -28,4 +28,4 @@
#define DEBUG_KBD(fmt, ...) DEBUG_NULL(fmt, ## __VA_ARGS__) #define DEBUG_KBD(fmt, ...) DEBUG_NULL(fmt, ## __VA_ARGS__)
#endif #endif
#endif /* __LIBKBD_H */ #endif /* __LIBLOCALE_H */

View File

@ -1,8 +1,8 @@
/** /**
* FreeRDP: A Remote Desktop Protocol Client * FreeRDP: A Remote Desktop Protocol Implementation
* XKB-based Keyboard Mapping to Microsoft Keyboard System * Microsoft Locales
* *
* Copyright 2009 Marc-Andre Moreau <marcandre.moreau@gmail.com> * Copyright 2009-2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -37,7 +37,7 @@ typedef struct _SYSTEM_LOCALE SYSTEM_LOCALE;
* http://msdn.microsoft.com/en-us/library/ms776260.aspx * http://msdn.microsoft.com/en-us/library/ms776260.aspx
*/ */
static const SYSTEM_LOCALE SystemLocaleTable[] = static const SYSTEM_LOCALE SYSTEM_LOCALE_TABLE[] =
{ {
{ "af", "ZA", AFRIKAANS }, /* Afrikaans (South Africa) */ { "af", "ZA", AFRIKAANS }, /* Afrikaans (South Africa) */
{ "sq", "AL", ALBANIAN }, /* Albanian (Albania) */ { "sq", "AL", ALBANIAN }, /* Albanian (Albania) */
@ -241,17 +241,17 @@ static const SYSTEM_LOCALE SystemLocaleTable[] =
}; };
struct _localeAndKeyboardLayout struct _LOCALE_KEYBOARD_LAYOUTS
{ {
uint32 locale; /* Locale ID */ uint32 locale; /* Locale ID */
uint32 keyboardLayouts[5]; /* array of associated keyboard layouts */ uint32 keyboardLayouts[5]; /* array of associated keyboard layouts */
}; };
typedef struct _localeAndKeyboardLayout localeAndKeyboardLayout; typedef struct _LOCALE_KEYBOARD_LAYOUTS LOCALE_KEYBOARD_LAYOUTS;
/* TODO: Use KBD_* defines instead of hardcoded values */ /* TODO: Use KBD_* defines instead of hardcoded values */
static const localeAndKeyboardLayout defaultKeyboardLayouts[] = static const LOCALE_KEYBOARD_LAYOUTS LOCALE_KEYBOARD_LAYOUTS_TABLE[] =
{ {
{ AFRIKAANS, { 0x00000409, 0x00000409, 0x0, 0x0, 0x0 } }, { AFRIKAANS, { 0x00000409, 0x00000409, 0x0, 0x0, 0x0 } },
{ ALBANIAN, { 0x0000041c, 0x00000409, 0x0, 0x0, 0x0 } }, { ALBANIAN, { 0x0000041c, 0x00000409, 0x0, 0x0, 0x0 } },
@ -464,11 +464,11 @@ SYSTEM_LOCALE* freerdp_detect_system_locale()
freerdp_get_system_language_and_country_codes(language, country); freerdp_get_system_language_and_country_codes(language, country);
for (i = 0; i < sizeof(SystemLocaleTable) / sizeof(SYSTEM_LOCALE); i++) for (i = 0; i < sizeof(SYSTEM_LOCALE_TABLE) / sizeof(SYSTEM_LOCALE); i++)
{ {
if ((strcmp(language, SystemLocaleTable[i].language) == 0) && (strcmp(country, SystemLocaleTable[i].country) == 0)) if ((strcmp(language, SYSTEM_LOCALE_TABLE[i].language) == 0) && (strcmp(country, SYSTEM_LOCALE_TABLE[i].country) == 0))
{ {
locale = (SYSTEM_LOCALE*) &SystemLocaleTable[i]; locale = (SYSTEM_LOCALE*) &SYSTEM_LOCALE_TABLE[i];
break; break;
} }
} }
@ -495,24 +495,24 @@ uint32 freerdp_detect_keyboard_layout_from_locale()
DEBUG_KBD("Found locale : %s_%s", locale.language, locale.country); DEBUG_KBD("Found locale : %s_%s", locale.language, locale.country);
for (i = 0; i < sizeof(defaultKeyboardLayouts) / sizeof(localeAndKeyboardLayout); i++) for (i = 0; i < sizeof(LOCALE_KEYBOARD_LAYOUTS_TABLE) / sizeof(LOCALE_KEYBOARD_LAYOUTS); i++)
{ {
if (defaultKeyboardLayouts[i].locale == locale->code) if (LOCALE_KEYBOARD_LAYOUTS_TABLE[i].locale == locale->code)
{ {
/* Locale found in list of default keyboard layouts */ /* Locale found in list of default keyboard layouts */
for (j = 0; j < 5; j++) for (j = 0; j < 5; j++)
{ {
if (defaultKeyboardLayouts[i].keyboardLayouts[j] == ENGLISH_UNITED_STATES) if (LOCALE_KEYBOARD_LAYOUTS_TABLE[i].keyboardLayouts[j] == ENGLISH_UNITED_STATES)
{ {
continue; /* Skip, try to get a more localized keyboard layout */ continue; /* Skip, try to get a more localized keyboard layout */
} }
else if (defaultKeyboardLayouts[i].keyboardLayouts[j] == 0) else if (LOCALE_KEYBOARD_LAYOUTS_TABLE[i].keyboardLayouts[j] == 0)
{ {
break; /* No more keyboard layouts */ break; /* No more keyboard layouts */
} }
else else
{ {
return defaultKeyboardLayouts[i].keyboardLayouts[j]; return LOCALE_KEYBOARD_LAYOUTS_TABLE[i].keyboardLayouts[j];
} }
} }

View File

@ -37,7 +37,7 @@ void xf_input_keyboard_event(rdpInput* input, uint16 flags, uint16 code)
if (flags & KBD_FLAGS_EXTENDED) if (flags & KBD_FLAGS_EXTENDED)
extended = true; extended = true;
keycode = freerdp_keyboard_get_keycode_from_scancode(code, extended); keycode = freerdp_keyboard_get_x11_keycode_from_rdp_scancode(code, extended);
if (keycode != 0) if (keycode != 0)
{ {