diff --git a/include/freerdp/locale/keyboard.h b/include/freerdp/locale/keyboard.h index 796b7a8d2..c06a4323b 100644 --- a/include/freerdp/locale/keyboard.h +++ b/include/freerdp/locale/keyboard.h @@ -34,14 +34,14 @@ struct rdp_keyboard_layout }; typedef struct rdp_keyboard_layout rdpKeyboardLayout; -struct _virtualKey +struct _VIRTUAL_KEY { uint32 scancode; /* Windows "scan code", aka keycode in RDP */ boolean extended; /* Windows "extended" flag, boolean */ const char* name; /* Windows virtual key name */ const char* x_keyname; /* XKB keyname */ }; -typedef struct _virtualKey virtualKey; +typedef struct _VIRTUAL_KEY VIRTUAL_KEY; /* Mouse buttons */ @@ -476,7 +476,7 @@ typedef struct _virtualKey virtualKey; FREERDP_API uint32 freerdp_keyboard_init(uint32 keyboard_layout_id); FREERDP_API rdpKeyboardLayout* freerdp_keyboard_get_layouts(uint32 types); -FREERDP_API const char* get_layout_name(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_keycode_from_scancode(uint32 scancode, boolean extended); FREERDP_API uint32 freerdp_keyboard_get_scancode_from_vkcode(uint32 vkcode, boolean* extended); diff --git a/include/freerdp/locale/locale.h b/include/freerdp/locale/locale.h index 36433542b..681a77e6d 100644 --- a/include/freerdp/locale/locale.h +++ b/include/freerdp/locale/locale.h @@ -230,6 +230,6 @@ #define YORUBA 0x046A #define ZULU 0x0435 -FREERDP_API uint32 detect_keyboard_layout_from_locale(); +FREERDP_API uint32 freerdp_detect_keyboard_layout_from_locale(); #endif /* __FREERDP_LOCALE_H */ diff --git a/libfreerdp-locale/keyboard.c b/libfreerdp-locale/keyboard.c index bf05926e5..90ab219c4 100644 --- a/libfreerdp-locale/keyboard.c +++ b/libfreerdp-locale/keyboard.c @@ -45,7 +45,7 @@ #include "keyboard.h" -extern const virtualKey virtualKeyboard[258]; +extern const VIRTUAL_KEY virtualKeyboard[258]; /* * The actual mapping from X keycodes to RDP keycodes, initialized from xkb keycodes or similar. @@ -64,7 +64,7 @@ uint32 freerdp_detect_keyboard(uint32 keyboardLayoutID) if (keyboardLayoutID == 0) { - keyboardLayoutID = detect_keyboard_layout_from_locale(); + keyboardLayoutID = freerdp_detect_keyboard_layout_from_locale(); DEBUG_KBD("detect_keyboard_layout_from_locale: %X", keyboardLayoutID); } @@ -113,7 +113,7 @@ uint32 freerdp_keyboard_init_x11(uint32 keyboardLayoutId) if (keyboardLayoutId == 0) { - keyboardLayoutId = detect_keyboard_layout_from_locale(); + keyboardLayoutId = freerdp_detect_keyboard_layout_from_locale(); DEBUG_KBD("using keyboard layout: %X", keyboardLayoutID); } @@ -258,7 +258,7 @@ static int freerdp_keyboard_load_map(KeycodeToVkcode map, char* name) break; /* Load this key mapping in the keyboard mapping */ - for(i = 0; i < sizeof(virtualKeyboard) / sizeof(virtualKey); i++) + for(i = 0; i < sizeof(virtualKeyboard) / sizeof(VIRTUAL_KEY); i++) { if (strcmp(vkcodeName, virtualKeyboard[i].name) == 0) { diff --git a/libfreerdp-locale/keyboard_layout.c b/libfreerdp-locale/keyboard_layout.c index b59a15260..3998ec925 100644 --- a/libfreerdp-locale/keyboard_layout.c +++ b/libfreerdp-locale/keyboard_layout.c @@ -215,7 +215,7 @@ static const keyboardIME keyboardIMEs[] = { KBD_CHINESE_TRADITIONAL_ALPHANUMERIC, "romanime.ime", "Chinese (Traditional) - Alphanumeric" } }; -const virtualKey virtualKeyboard[] = +const VIRTUAL_KEY virtualKeyboard[] = { { 0x00, 0, "" , NULL }, { 0x00, 0, "VK_LBUTTON" , NULL }, @@ -526,7 +526,7 @@ rdpKeyboardLayout* freerdp_keyboard_get_layouts(uint32 types) return layouts; } -const char* get_layout_name(uint32 keyboardLayoutID) +const char* freerdp_keyboard_get_layout_name_from_id(uint32 keyboardLayoutID) { int i; diff --git a/libfreerdp-locale/keyboard_xkb.c b/libfreerdp-locale/keyboard_xkb.c index ac4db24ff..f11f2faf3 100644 --- a/libfreerdp-locale/keyboard_xkb.c +++ b/libfreerdp-locale/keyboard_xkb.c @@ -23,7 +23,7 @@ #include "keyboard_x11.h" #include -extern const virtualKey virtualKeyboard[258]; +extern const VIRTUAL_KEY virtualKeyboard[258]; #include #include diff --git a/libfreerdp-locale/locale.c b/libfreerdp-locale/locale.c index 562880498..be2d5b4a4 100644 --- a/libfreerdp-locale/locale.c +++ b/libfreerdp-locale/locale.c @@ -24,20 +24,20 @@ #include -struct _locale +struct _SYSTEM_LOCALE { char language[4]; /* Two or three letter language code */ char country[10]; /* Two or three letter country code (Sometimes with Cyrl_ prefix) */ uint32 code; /* 32-bit unsigned integer corresponding to the locale */ }; -typedef struct _locale locale; +typedef struct _SYSTEM_LOCALE SYSTEM_LOCALE; /* * Refer to MSDN article "Locale Identifier Constants and Strings": * http://msdn.microsoft.com/en-us/library/ms776260.aspx */ -static const locale locales[] = +static const SYSTEM_LOCALE SystemLocaleTable[] = { { "af", "ZA", AFRIKAANS }, /* Afrikaans (South Africa) */ { "sq", "AL", ALBANIAN }, /* Albanian (Albania) */ @@ -241,15 +241,13 @@ static const locale locales[] = }; -typedef struct +struct _localeAndKeyboardLayout { - /* Locale ID */ - unsigned int locale; + uint32 locale; /* Locale ID */ + uint32 keyboardLayouts[5]; /* array of associated keyboard layouts */ - /* Array of associated keyboard layouts */ - unsigned int keyboardLayouts[5]; - -} localeAndKeyboardLayout; +}; +typedef struct _localeAndKeyboardLayout localeAndKeyboardLayout; /* TODO: Use KBD_* defines instead of hardcoded values */ @@ -416,76 +414,105 @@ static const localeAndKeyboardLayout defaultKeyboardLayouts[] = { XHOSA, { 0x00000409, 0x00000409, 0x0, 0x0, 0x0 } }, }; -uint32 detect_keyboard_layout_from_locale() +boolean freerdp_get_system_language_and_country_codes(char* language, char* country) { int dot; - int i, j, k; int underscore; - char language[4]; - char country[10]; + char* env_lang; /* LANG = _. */ - char* envLang = getenv("LANG"); /* Get locale from environment variable LANG */ + env_lang = getenv("LANG"); /* Get locale from environment variable LANG */ - if (envLang == NULL) - return 0; /* LANG environment variable was not set */ + if (env_lang == NULL) + return false; /* LANG environment variable was not set */ - underscore = strcspn(envLang, "_"); + underscore = strcspn(env_lang, "_"); if (underscore > 3) - return 0; /* The language name should not be more than 3 letters long */ + { + return false; /* The language name should not be more than 3 letters long */ + } else { /* Get language code */ - strncpy(language, envLang, underscore); + strncpy(language, env_lang, underscore); language[underscore] = '\0'; } - /* - * There is always the special case of "C" or "POSIX" as locale name - * In this case, use a U.S. keyboard and a U.S. keyboard layout - */ - - if ((strcmp(language, "C") == 0) || (strcmp(language, "POSIX") == 0)) - return ENGLISH_UNITED_STATES; /* U.S. Keyboard Layout */ - - dot = strcspn(envLang, "."); + dot = strcspn(env_lang, "."); /* Get country code */ if (dot > underscore) { - strncpy(country, &envLang[underscore + 1], dot - underscore - 1); + strncpy(country, &env_lang[underscore + 1], dot - underscore - 1); country[dot - underscore - 1] = '\0'; } else - return 0; /* Invalid locale */ - - for (i = 0; i < sizeof(locales) / sizeof(locale); i++) { - if ((strcmp(language, locales[i].language) == 0) && (strcmp(country, locales[i].country) == 0)) - break; + return false; /* Invalid locale */ } - DEBUG_KBD("Found locale : %s_%s", locales[i].language, locales[i].country); + return true; +} - for (j = 0; j < sizeof(defaultKeyboardLayouts) / sizeof(localeAndKeyboardLayout); j++) +SYSTEM_LOCALE* freerdp_detect_system_locale() +{ + int i; + char language[4]; + char country[10]; + SYSTEM_LOCALE* locale = NULL; + + freerdp_get_system_language_and_country_codes(language, country); + + for (i = 0; i < sizeof(SystemLocaleTable) / sizeof(SYSTEM_LOCALE); i++) { - if (defaultKeyboardLayouts[j].locale == locales[i].code) + if ((strcmp(language, SystemLocaleTable[i].language) == 0) && (strcmp(country, SystemLocaleTable[i].country) == 0)) + { + locale = (SYSTEM_LOCALE*) &SystemLocaleTable[i]; + break; + } + } + + return locale; +} + +uint32 freerdp_detect_keyboard_layout_from_locale() +{ + int i, j; + char language[4]; + char country[10]; + SYSTEM_LOCALE* locale; + + freerdp_get_system_language_and_country_codes(language, country); + + if ((strcmp(language, "C") == 0) || (strcmp(language, "POSIX") == 0)) + return ENGLISH_UNITED_STATES; /* U.S. Keyboard Layout */ + + locale = freerdp_detect_system_locale(); + + if (locale == NULL) + return 0; + + DEBUG_KBD("Found locale : %s_%s", locale.language, locale.country); + + for (i = 0; i < sizeof(defaultKeyboardLayouts) / sizeof(localeAndKeyboardLayout); i++) + { + if (defaultKeyboardLayouts[i].locale == locale->code) { /* Locale found in list of default keyboard layouts */ - for (k = 0; k < 5; k++) + for (j = 0; j < 5; j++) { - if (defaultKeyboardLayouts[j].keyboardLayouts[k] == ENGLISH_UNITED_STATES) + if (defaultKeyboardLayouts[i].keyboardLayouts[j] == ENGLISH_UNITED_STATES) { continue; /* Skip, try to get a more localized keyboard layout */ } - else if (defaultKeyboardLayouts[j].keyboardLayouts[k] == 0) + else if (defaultKeyboardLayouts[i].keyboardLayouts[j] == 0) { break; /* No more keyboard layouts */ } else { - return defaultKeyboardLayouts[j].keyboardLayouts[k]; + return defaultKeyboardLayouts[i].keyboardLayouts[j]; } } @@ -494,7 +521,7 @@ uint32 detect_keyboard_layout_from_locale() * other possible keyboard layout for the locale, we end up here with k > 1 */ - if (k >= 1) + if (j >= 1) return ENGLISH_UNITED_STATES; else return 0;