From 5e5d52ccf405d354a2913ca290c1a98bc7348b70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20=C3=85strand?= Date: Wed, 3 Aug 2005 09:56:17 +0000 Subject: [PATCH] Autoselecting keyboard map based on current locale. Re-implementation of patch #1068995. git-svn-id: svn://svn.code.sf.net/p/rdesktop/code/trunk/rdesktop@961 423420c4-83ab-492f-b58f-81f9feb106b5 --- doc/rdesktop.1 | 6 +++++- proto.h | 1 + rdesktop.c | 14 ++++++++---- xkeymap.c | 58 +++++++++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 73 insertions(+), 6 deletions(-) diff --git a/doc/rdesktop.1 b/doc/rdesktop.1 index afe657d..5a0b4b2 100644 --- a/doc/rdesktop.1 +++ b/doc/rdesktop.1 @@ -41,7 +41,11 @@ client. Keyboard layout to emulate. This requires a corresponding keymap file to be installed. The standard keymaps provided with rdesktop follow the RFC1766 naming scheme: a language code followed by a country code if necessary - e.g. -en-us, en-gb, de, fr, sv, etc. The default is en-us (a US keyboard). +en-us, en-gb, de, fr, sv, etc. + +The default keyboard map depends on the current locale (LC_* and LANG +environment variables). If no valid locale is specified, the default +keyboard map is en-us (a US keyboard). The keyboard maps are file names, which means that they are case sensitive. The standard keymaps are all in lowercase. diff --git a/proto.h b/proto.h index d3f4e2f..166afae 100644 --- a/proto.h +++ b/proto.h @@ -166,6 +166,7 @@ void ui_clip_request_data(uint32 format); void ui_clip_sync(void); void xclip_init(void); /* xkeymap.c */ +void xkeymap_from_locale(const char *locale); FILE *xkeymap_open(const char *filename); void xkeymap_init(void); BOOL handle_special_keys(uint32 keysym, unsigned int state, uint32 ev_time, BOOL pressed); diff --git a/rdesktop.c b/rdesktop.c index 3335feb..daccda0 100644 --- a/rdesktop.c +++ b/rdesktop.c @@ -30,10 +30,10 @@ #include #include "rdesktop.h" -#ifdef HAVE_ICONV #ifdef HAVE_LOCALE_H #include #endif +#ifdef HAVE_ICONV #ifdef HAVE_LANGINFO_H #include #endif @@ -50,7 +50,7 @@ char g_title[64] = ""; char g_username[64]; char g_hostname[16]; -char keymapname[PATH_MAX]; +char keymapname[PATH_MAX] = "en-us"; int g_keylayout = 0x409; /* Defaults to US keyboard layout */ int g_width = 800; /* width is special: If 0, the @@ -370,13 +370,19 @@ main(int argc, char *argv[]) uint32 flags, ext_disc_reason = 0; char *p; int c; - + char *locale; int username_option = 0; + /* Set locale according to environment */ + locale = setlocale(LC_ALL, ""); + if (locale) + { + xkeymap_from_locale(locale); + } + flags = RDP_LOGON_NORMAL; prompt_password = False; domain[0] = password[0] = shell[0] = directory[0] = 0; - strcpy(keymapname, "en-us"); g_embed_wnd = 0; g_num_devices = 0; diff --git a/xkeymap.c b/xkeymap.c index d7be993..66170aa 100644 --- a/xkeymap.c +++ b/xkeymap.c @@ -156,6 +156,63 @@ add_sequence(char *rest, char *mapname) DEBUG_KBD(("\n")); } +void +xkeymap_from_locale(const char *locale) +{ + char *str, *ptr; + FILE *fp; + + /* Create a working copy */ + str = strdup(locale); + if (str == NULL) + { + perror("strdup"); + exit(1); + } + + /* Truncate at dot and at */ + ptr = strrchr(str, '.'); + if (ptr) + *ptr = '\0'; + ptr = strrchr(str, '@'); + if (ptr) + *ptr = '\0'; + + /* Replace _ with - */ + ptr = strrchr(str, '_'); + if (ptr) + *ptr = '-'; + + /* Convert to lowercase */ + ptr = str; + while (*ptr) + { + *ptr = tolower((int) *ptr); + ptr++; + } + + /* Try to open this keymap (da-dk) */ + fp = xkeymap_open(str); + if (fp == NULL) + { + /* Truncate at dash */ + ptr = strrchr(str, '-'); + if (ptr) + *ptr = '\0'; + + /* Try the short name (da) */ + fp = xkeymap_open(str); + } + + if (fp) + { + fclose(fp); + STRNCPY(keymapname, str, sizeof(keymapname)); + fprintf(stderr, "Autoselected keyboard map %s.\n", keymapname); + } +} + + /* Joins two path components. The result should be freed with xfree(). */ static char * @@ -359,7 +416,6 @@ void xkeymap_init(void) { unsigned int max_keycode; - char *mapname_ptr; if (strcmp(keymapname, "none")) {