From: Chun-wei Fan Date: Mon, 10 Jan 2022 06:49:42 +0000 (+0800) Subject: language-names: Use Windows APIs to acquire language names X-Git-Tag: archive/raspbian/4.6.5+ds-1+rpi1~1^2~19^2~4^2~90^2~3 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=b666a767e4545e8a3c35193d5593b88c93f4f881;p=gtk4.git language-names: Use Windows APIs to acquire language names Instead of relying on the iso-codes package, use the native Windows NLS APIs to acquire the localized (translated) language names so that we do not need to incur an extra runtime dependency on Windows. It's not coverering 100% of the languages that we would like to support through this, but should cover much of the things that are required. --- diff --git a/gtk/language-names.c b/gtk/language-names.c index 16deef3bea..6dd2f22ec4 100644 --- a/gtk/language-names.c +++ b/gtk/language-names.c @@ -19,15 +19,80 @@ #include "language-names.h" +#ifdef G_OS_WIN32 +#define WIN32_LEAN_AND_MEAN +#include +#else #ifndef ISO_CODES_PREFIX #define ISO_CODES_PREFIX "/usr" #endif #define ISO_CODES_DATADIR ISO_CODES_PREFIX "/share/xml/iso-codes" #define ISO_CODES_LOCALESDIR ISO_CODES_PREFIX "/share/locale" +#endif static GHashTable *language_map; +#ifdef G_OS_WIN32 +/* if we are using native Windows use native Windows API for language names */ +static BOOL CALLBACK +get_win32_all_locales_scripts (LPWSTR locale_w, DWORD flags, LPARAM param) +{ + wchar_t *langname_w = NULL; + wchar_t locale_abbrev_w[9]; + gchar *langname, *locale_abbrev, *locale, *p; + gint i; + const LCTYPE iso639_lctypes[] = { LOCALE_SISO639LANGNAME, LOCALE_SISO639LANGNAME2 }; + GHashTable *ht_scripts_langs = (GHashTable *) param; + PangoLanguage *lang; + + gint langname_size, locale_abbrev_size; + langname_size = GetLocaleInfoEx (locale_w, LOCALE_SLOCALIZEDDISPLAYNAME, langname_w, 0); + if (langname_size == 0) + return FALSE; + + langname_w = g_new0 (wchar_t, langname_size); + + if (langname_size == 0) + return FALSE; + + GetLocaleInfoEx (locale_w, LOCALE_SLOCALIZEDDISPLAYNAME, langname_w, langname_size); + langname = g_utf16_to_utf8 (langname_w, -1, NULL, NULL, NULL); + locale = g_utf16_to_utf8 (locale_w, -1, NULL, NULL, NULL); + p = strchr (locale, '-'); + lang = pango_language_from_string (locale); + if (g_hash_table_lookup (ht_scripts_langs, lang) == NULL) + g_hash_table_insert (ht_scripts_langs, lang, langname); + + /* + * Track 3+-letter ISO639-2/3 language codes as well (these have a max length of 9 including terminating NUL) + * ISO639-2: iso639_lctypes[0] = LOCALE_SISO639LANGNAME + * ISO639-3: iso639_lctypes[1] = LOCALE_SISO639LANGNAME2 + */ + for (i = 0; i < 2; i++) + { + locale_abbrev_size = GetLocaleInfoEx (locale_w, iso639_lctypes[i], locale_abbrev_w, 0); + if (locale_abbrev_size > 0) + { + GetLocaleInfoEx (locale_w, iso639_lctypes[i], locale_abbrev_w, locale_abbrev_size); + + locale_abbrev = g_utf16_to_utf8 (locale_abbrev_w, -1, NULL, NULL, NULL); + lang = pango_language_from_string (locale_abbrev); + if (g_hash_table_lookup (ht_scripts_langs, lang) == NULL) + g_hash_table_insert (ht_scripts_langs, lang, langname); + + g_free (locale_abbrev); + } + } + + g_free (locale); + g_free (langname_w); + + return TRUE; +} + +#else /* non-Windows */ + static char * get_first_item_in_semicolon_list (const char *list) { @@ -232,6 +297,8 @@ languages_variant_init (const char *variant) g_free (buf); } +#endif + static void languages_init (void) { @@ -239,8 +306,13 @@ languages_init (void) return; language_map = g_hash_table_new_full (NULL, NULL, NULL, g_free); + +#ifdef G_OS_WIN32 + g_return_if_fail (EnumSystemLocalesEx (&get_win32_all_locales_scripts, LOCALE_ALL, (LPARAM) language_map, NULL)); +#else languages_variant_init ("iso_639"); languages_variant_init ("iso_639_3"); +#endif } const char *