From: grumbel Date: Wed, 18 Nov 2009 17:44:46 +0000 (+0000) Subject: Switched from tinygettext/tags/tinygetext-supertux/ to tinygettext/trunk/ X-Git-Url: https://git.verplant.org/?a=commitdiff_plain;h=30c9c0e5f4debd315fc3ffed2b845de7979e884f;p=supertux.git Switched from tinygettext/tags/tinygetext-supertux/ to tinygettext/trunk/ git-svn-id: http://supertux.lethargik.org/svn/supertux/trunk/supertux@6032 837edb03-e0f3-0310-88ca-d4d4e8b29345 --- diff --git a/CMakeLists.txt b/CMakeLists.txt index 0db533738..b2d1e08b1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -163,11 +163,12 @@ LINK_DIRECTORIES(external/squirrel) include_directories (${SUPERTUX_SOURCE_DIR}/src/) include_directories (${SUPERTUX_SOURCE_DIR}/external/squirrel/include/) include_directories (${SUPERTUX_SOURCE_DIR}/external/) +include_directories (${SUPERTUX_SOURCE_DIR}/external/findlocale/) include_directories (${SUPERTUX_SOURCE_DIR}/external/obstack/) ## Build list of sources for supertux binary -FILE(GLOB SUPERTUX_SOURCES RELATIVE ${SUPERTUX_SOURCE_DIR} src/*.cpp src/*/*.cpp src/video/sdl/*.cpp external/obstack/*.c external/tinygettext/*.cpp) +FILE(GLOB SUPERTUX_SOURCES RELATIVE ${SUPERTUX_SOURCE_DIR} src/*.cpp src/*/*.cpp src/video/sdl/*.cpp external/obstack/*.c external/tinygettext/*.cpp external/findlocale/findlocale.c) IF(HAVE_OPENGL) FILE(GLOB SUPERTUX_OPENGL_SOURCES RELATIVE ${SUPERTUX_SOURCE_DIR} src/video/gl/*.cpp) diff --git a/SConscript b/SConscript index 13b6d4d12..2f2e4ee71 100644 --- a/SConscript +++ b/SConscript @@ -19,6 +19,7 @@ class Project: self.build_squirrel() self.build_tinygettext() self.build_binreloc() + self.build_findlocale() self.build_supertux() self.build_tests() @@ -34,6 +35,10 @@ class Project: env = Environment(CPPPATH=["external/binreloc/", "."]) self.libbinreloc = env.StaticLibrary("binreloc", "external/binreloc/binreloc.c") + def build_findlocale(self): + env = Environment(CPPPATH=["external/findlocale/", "."]) + self.libfindlocale = env.StaticLibrary("findlocale", "external/findlocale/findlocale.c") + def build_squirrel(self): env = Environment(CPPPATH=["external/squirrel/include/"]) self.libsquirrel = env.StaticLibrary("squirrel", @@ -43,6 +48,7 @@ class Project: def build_supertux(self): self.env = Environment(CPPPATH=["external/squirrel/include/", + "external/findlocale/", "external/", "external/obstack", "src/", @@ -66,7 +72,7 @@ class Project: self.env.ParseConfig("sdl-config --libs --cflags") self.env.ParseConfig("pkg-config --libs --cflags openal") self.env.ParseConfig("pkg-config --libs --cflags vorbis vorbisfile ogg") - self.env.Append(LIBS=[self.libsquirrel, self.libbinreloc, self.libtinygettext]) + self.env.Append(LIBS=[self.libsquirrel, self.libbinreloc, self.libtinygettext, self.libfindlocale]) self.env.Append(LIBS=["SDL_image", "curl", "GL", "physfs"]) # Create config.h diff --git a/external/README b/external/README new file mode 100644 index 000000000..a83919326 --- /dev/null +++ b/external/README @@ -0,0 +1,4 @@ +findlocale/ + * findlocale-0.46.tar.gz from http://icculus.org/~aspirin/findlocale/ + +# EOF # diff --git a/external/findlocale/LICENSE b/external/findlocale/LICENSE new file mode 100644 index 000000000..526047327 --- /dev/null +++ b/external/findlocale/LICENSE @@ -0,0 +1,23 @@ +Copyright (C) 2004 Adam D. Moss (the "Author"). All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is fur- +nished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FIT- +NESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CON- +NECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of the Author of the +Software shall not be used in advertising or otherwise to promote the sale, +use or other dealings in this Software without prior written authorization +from the Author. diff --git a/external/findlocale/Makefile b/external/findlocale/Makefile new file mode 100644 index 000000000..12fff7524 --- /dev/null +++ b/external/findlocale/Makefile @@ -0,0 +1,16 @@ +CC = cc +CFLAGS = -Os -Wall + +all: example + +example: findlocale.o example.o + $(CC) example.o findlocale.o -o example + +findlocale.o: findlocale.c findlocale.h + $(CC) $(CFLAGS) -c findlocale.c + +example.o: example.c findlocale.h + $(CC) $(CFLAGS) -c example.c + +clean: + $(RM) findlocale.o example.o example diff --git a/external/findlocale/README.findlocale b/external/findlocale/README.findlocale new file mode 100644 index 000000000..c98d41368 --- /dev/null +++ b/external/findlocale/README.findlocale @@ -0,0 +1,19 @@ +FindLocale -- a cross-platform C module for detecting the user's language +Adam D. Moss / adam at steambird.com / adam at gimp.org + +This is an early release of a straightforward API which can be used to +detect the user's current preferred (language,country,variant) setting +in a uniform manner across multiple platforms. It is not intended +to provide localization functions, but rather it is a basis on which to +make localization decisions. + +Currently, win32 (win95+) and unix-alikes are supported. + +Please see example.c and findlocale.h for illumination of this API. + +Ports and patches are always welcome. + +License: Completely free; see the LICENSE file. + +--adam + diff --git a/external/findlocale/VERSION b/external/findlocale/VERSION new file mode 100644 index 000000000..98057b390 --- /dev/null +++ b/external/findlocale/VERSION @@ -0,0 +1,14 @@ +v0.46 -- 2005-04-06 + + * example.c crash-avoidance for C runtimes who hate printfing + NULL strings. + +v0.45 -- 2004-10-19 + + * considerably more comprehensive LCID/LANGID to + (language,country,variant) mapping on win32. + +v0.4 -- 2004-10-01 + + * initial release + diff --git a/external/findlocale/example.c b/external/findlocale/example.c new file mode 100644 index 000000000..5c1f31390 --- /dev/null +++ b/external/findlocale/example.c @@ -0,0 +1,19 @@ + +#include +#include + +#include "findlocale.h" + +int +main(int in_argc, char **in_argv) { + FL_Locale *locale; + FL_FindLocale(&locale, FL_MESSAGES); + printf("I think that your current settings are...\n" + "Language = '%s'\nCountry = '%s'\nVariant = '%s'\n", + locale->lang ? locale->lang : "(null)", + locale->country ? locale->country : "(null)", + locale->variant ? locale->variant : "(null)"); + FL_FreeLocale(&locale); + return 0; +} + diff --git a/external/findlocale/findlocale.c b/external/findlocale/findlocale.c new file mode 100644 index 000000000..4b5c816f2 --- /dev/null +++ b/external/findlocale/findlocale.c @@ -0,0 +1,491 @@ + +#include +#include +#include + +#ifdef WIN32 +#include +#include +#endif + +#include "findlocale.h" + +static int +is_lcchar(const int c) { + return isalnum(c); +} + +static void +lang_country_variant_from_envstring(const char *str, + char **lang, + char **country, + char **variant) { + int end = 0; + int start; + + /* get lang, if any */ + start = end; + while (is_lcchar(str[end])) { + ++end; + } + if (start != end) { + int i; + int len = end - start; + char *s = malloc(len + 1); + for (i=0; ilang = lang; + l->country = country; + l->variant = variant; + return 1; + } + } + free(lang); free(country); free(variant); + return 0; +} + + +static int +accumulate_env(const char *name, FL_Locale *l) { + char *env; + char *lang = NULL; + char *country = NULL; + char *variant = NULL; + env = getenv(name); + if (env) { + return accumulate_locstring(env, l); + } + free(lang); free(country); free(variant); + return 0; +} + + +static void +canonise_fl(FL_Locale *l) { + /* this function fixes some common locale-specifying mistakes */ + /* en_UK -> en_GB */ + if (l->lang && 0 == strcmp(l->lang, "en")) { + if (l->country && 0 == strcmp(l->country, "UK")) { + free((void*)l->country); + l->country = strdup("GB"); + } + } + /* ja_JA -> ja_JP */ + if (l->lang && 0 == strcmp(l->lang, "ja")) { + if (l->country && 0 == strcmp(l->country, "JA")) { + free((void*)l->country); + l->country = strdup("JP"); + } + } +} + + +#ifdef WIN32 +#include +#define ML(pn,sn) MAKELANGID(LANG_##pn, SUBLANG_##pn##_##sn) +#define MLN(pn) MAKELANGID(LANG_##pn, SUBLANG_DEFAULT) +#define RML(pn,sn) MAKELANGID(LANG_##pn, SUBLANG_##sn) +typedef struct { + LANGID id; + char* code; +} IDToCode; +static const IDToCode both_to_code[] = { + {ML(ENGLISH,US), "en_US.ISO_8859-1"}, + {ML(ENGLISH,CAN), "en_CA"}, /* english / canadian */ + {ML(ENGLISH,UK), "en_GB"}, + {ML(ENGLISH,EIRE), "en_IE"}, + {ML(ENGLISH,AUS), "en_AU"}, + {MLN(GERMAN), "de_DE"}, + {MLN(SPANISH), "es_ES"}, + {ML(SPANISH,MEXICAN), "es_MX"}, + {MLN(FRENCH), "fr_FR"}, + {ML(FRENCH,CANADIAN), "fr_CA"}, + {ML(FRENCH,BELGIAN), "fr_BE"}, /* ? */ + {ML(DUTCH,BELGIAN), "nl_BE"}, /* ? */ + {ML(PORTUGUESE,BRAZILIAN), "pt_BR"}, + {MLN(PORTUGUESE), "pt_PT"}, + {MLN(SWEDISH), "sv_SE"}, + {ML(CHINESE,HONGKONG), "zh_HK"}, + /* these are machine-generated and not yet verified */ + {RML(AFRIKAANS,DEFAULT), "af_ZA"}, + {RML(ALBANIAN,DEFAULT), "sq_AL"}, + {RML(ARABIC,ARABIC_ALGERIA), "ar_DZ"}, + {RML(ARABIC,ARABIC_BAHRAIN), "ar_BH"}, + {RML(ARABIC,ARABIC_EGYPT), "ar_EG"}, + {RML(ARABIC,ARABIC_IRAQ), "ar_IQ"}, + {RML(ARABIC,ARABIC_JORDAN), "ar_JO"}, + {RML(ARABIC,ARABIC_KUWAIT), "ar_KW"}, + {RML(ARABIC,ARABIC_LEBANON), "ar_LB"}, + {RML(ARABIC,ARABIC_LIBYA), "ar_LY"}, + {RML(ARABIC,ARABIC_MOROCCO), "ar_MA"}, + {RML(ARABIC,ARABIC_OMAN), "ar_OM"}, + {RML(ARABIC,ARABIC_QATAR), "ar_QA"}, + {RML(ARABIC,ARABIC_SAUDI_ARABIA), "ar_SA"}, + {RML(ARABIC,ARABIC_SYRIA), "ar_SY"}, + {RML(ARABIC,ARABIC_TUNISIA), "ar_TN"}, + {RML(ARABIC,ARABIC_UAE), "ar_AE"}, + {RML(ARABIC,ARABIC_YEMEN), "ar_YE"}, + {RML(ARMENIAN,DEFAULT), "hy_AM"}, + {RML(AZERI,AZERI_CYRILLIC), "az_AZ"}, + {RML(AZERI,AZERI_LATIN), "az_AZ"}, + {RML(BASQUE,DEFAULT), "eu_ES"}, + {RML(BELARUSIAN,DEFAULT), "be_BY"}, +/*{RML(BRETON,DEFAULT), "br_FR"},*/ + {RML(BULGARIAN,DEFAULT), "bg_BG"}, + {RML(CATALAN,DEFAULT), "ca_ES"}, + {RML(CHINESE,CHINESE_HONGKONG), "zh_HK"}, + {RML(CHINESE,CHINESE_MACAU), "zh_MO"}, + {RML(CHINESE,CHINESE_SIMPLIFIED), "zh_CN"}, + {RML(CHINESE,CHINESE_SINGAPORE), "zh_SG"}, + {RML(CHINESE,CHINESE_TRADITIONAL), "zh_TW"}, +/*{RML(CORNISH,DEFAULT), "kw_GB"},*/ + {RML(CZECH,DEFAULT), "cs_CZ"}, + {RML(DANISH,DEFAULT), "da_DK"}, + {RML(DUTCH,DUTCH), "nl_NL"}, + {RML(DUTCH,DUTCH_BELGIAN), "nl_BE"}, +/*{RML(DUTCH,DUTCH_SURINAM), "nl_SR"},*/ + {RML(ENGLISH,ENGLISH_AUS), "en_AU"}, + {RML(ENGLISH,ENGLISH_BELIZE), "en_BZ"}, + {RML(ENGLISH,ENGLISH_CAN), "en_CA"}, + {RML(ENGLISH,ENGLISH_CARIBBEAN), "en_CB"}, + {RML(ENGLISH,ENGLISH_EIRE), "en_IE"}, + {RML(ENGLISH,ENGLISH_JAMAICA), "en_JM"}, + {RML(ENGLISH,ENGLISH_NZ), "en_NZ"}, + {RML(ENGLISH,ENGLISH_PHILIPPINES), "en_PH"}, + {RML(ENGLISH,ENGLISH_SOUTH_AFRICA), "en_ZA"}, + {RML(ENGLISH,ENGLISH_TRINIDAD), "en_TT"}, + {RML(ENGLISH,ENGLISH_UK), "en_GB"}, + {RML(ENGLISH,ENGLISH_US), "en_US"}, + {RML(ENGLISH,ENGLISH_ZIMBABWE), "en_ZW"}, +/*{RML(ESPERANTO,DEFAULT), "eo_"},*/ + {RML(ESTONIAN,DEFAULT), "et_EE"}, + {RML(FAEROESE,DEFAULT), "fo_FO"}, + {RML(FARSI,DEFAULT), "fa_IR"}, + {RML(FINNISH,DEFAULT), "fi_FI"}, + {RML(FRENCH,FRENCH), "fr_FR"}, + {RML(FRENCH,FRENCH_BELGIAN), "fr_BE"}, + {RML(FRENCH,FRENCH_CANADIAN), "fr_CA"}, + {RML(FRENCH,FRENCH_LUXEMBOURG), "fr_LU"}, + {RML(FRENCH,FRENCH_MONACO), "fr_MC"}, + {RML(FRENCH,FRENCH_SWISS), "fr_CH"}, +/*{RML(GAELIC,GAELIC), "ga_IE"},*/ +/*{RML(GAELIC,GAELIC_MANX), "gv_GB"},*/ +/*{RML(GAELIC,GAELIC_SCOTTISH), "gd_GB"},*/ +/*{RML(GALICIAN,DEFAULT), "gl_ES"},*/ + {RML(GEORGIAN,DEFAULT), "ka_GE"}, + {RML(GERMAN,GERMAN), "de_DE"}, + {RML(GERMAN,GERMAN_AUSTRIAN), "de_AT"}, + {RML(GERMAN,GERMAN_LIECHTENSTEIN), "de_LI"}, + {RML(GERMAN,GERMAN_LUXEMBOURG), "de_LU"}, + {RML(GERMAN,GERMAN_SWISS), "de_CH"}, + {RML(GREEK,DEFAULT), "el_GR"}, + {RML(GUJARATI,DEFAULT), "gu_IN"}, + {RML(HEBREW,DEFAULT), "he_IL"}, + {RML(HINDI,DEFAULT), "hi_IN"}, + {RML(HUNGARIAN,DEFAULT), "hu_HU"}, + {RML(ICELANDIC,DEFAULT), "is_IS"}, + {RML(INDONESIAN,DEFAULT), "id_ID"}, + {RML(ITALIAN,ITALIAN), "it_IT"}, + {RML(ITALIAN,ITALIAN_SWISS), "it_CH"}, + {RML(JAPANESE,DEFAULT), "ja_JP"}, + {RML(KANNADA,DEFAULT), "kn_IN"}, + {RML(KAZAK,DEFAULT), "kk_KZ"}, + {RML(KONKANI,DEFAULT), "kok_IN"}, + {RML(KOREAN,KOREAN), "ko_KR"}, +/*{RML(KYRGYZ,DEFAULT), "ky_KG"},*/ + {RML(LATVIAN,DEFAULT), "lv_LV"}, + {RML(LITHUANIAN,LITHUANIAN), "lt_LT"}, + {RML(MACEDONIAN,DEFAULT), "mk_MK"}, + {RML(MALAY,MALAY_BRUNEI_DARUSSALAM), "ms_BN"}, + {RML(MALAY,MALAY_MALAYSIA), "ms_MY"}, + {RML(MARATHI,DEFAULT), "mr_IN"}, +/*{RML(MONGOLIAN,DEFAULT), "mn_MN"},*/ + {RML(NORWEGIAN,NORWEGIAN_BOKMAL), "nb_NO"}, + {RML(NORWEGIAN,NORWEGIAN_NYNORSK), "nn_NO"}, + {RML(POLISH,DEFAULT), "pl_PL"}, + {RML(PORTUGUESE,PORTUGUESE), "pt_PT"}, + {RML(PORTUGUESE,PORTUGUESE_BRAZILIAN), "pt_BR"}, + {RML(PUNJABI,DEFAULT), "pa_IN"}, + {RML(ROMANIAN,DEFAULT), "ro_RO"}, + {RML(RUSSIAN,DEFAULT), "ru_RU"}, + {RML(SANSKRIT,DEFAULT), "sa_IN"}, + {RML(SERBIAN,DEFAULT), "hr_HR"}, + {RML(SERBIAN,SERBIAN_CYRILLIC), "sr_SP"}, + {RML(SERBIAN,SERBIAN_LATIN), "sr_SP"}, + {RML(SLOVAK,DEFAULT), "sk_SK"}, + {RML(SLOVENIAN,DEFAULT), "sl_SI"}, + {RML(SPANISH,SPANISH), "es_ES"}, + {RML(SPANISH,SPANISH_ARGENTINA), "es_AR"}, + {RML(SPANISH,SPANISH_BOLIVIA), "es_BO"}, + {RML(SPANISH,SPANISH_CHILE), "es_CL"}, + {RML(SPANISH,SPANISH_COLOMBIA), "es_CO"}, + {RML(SPANISH,SPANISH_COSTA_RICA), "es_CR"}, + {RML(SPANISH,SPANISH_DOMINICAN_REPUBLIC), "es_DO"}, + {RML(SPANISH,SPANISH_ECUADOR), "es_EC"}, + {RML(SPANISH,SPANISH_EL_SALVADOR), "es_SV"}, + {RML(SPANISH,SPANISH_GUATEMALA), "es_GT"}, + {RML(SPANISH,SPANISH_HONDURAS), "es_HN"}, + {RML(SPANISH,SPANISH_MEXICAN), "es_MX"}, + {RML(SPANISH,SPANISH_MODERN), "es_ES"}, + {RML(SPANISH,SPANISH_NICARAGUA), "es_NI"}, + {RML(SPANISH,SPANISH_PANAMA), "es_PA"}, + {RML(SPANISH,SPANISH_PARAGUAY), "es_PY"}, + {RML(SPANISH,SPANISH_PERU), "es_PE"}, + {RML(SPANISH,SPANISH_PUERTO_RICO), "es_PR"}, + {RML(SPANISH,SPANISH_URUGUAY), "es_UY"}, + {RML(SPANISH,SPANISH_VENEZUELA), "es_VE"}, + {RML(SWAHILI,DEFAULT), "sw_KE"}, + {RML(SWEDISH,SWEDISH), "sv_SE"}, + {RML(SWEDISH,SWEDISH_FINLAND), "sv_FI"}, +/*{RML(SYRIAC,DEFAULT), "syr_SY"},*/ + {RML(TAMIL,DEFAULT), "ta_IN"}, + {RML(TATAR,DEFAULT), "tt_TA"}, + {RML(TELUGU,DEFAULT), "te_IN"}, + {RML(THAI,DEFAULT), "th_TH"}, + {RML(TURKISH,DEFAULT), "tr_TR"}, + {RML(UKRAINIAN,DEFAULT), "uk_UA"}, + {RML(URDU,URDU_PAKISTAN), "ur_PK"}, + {RML(UZBEK,UZBEK_CYRILLIC), "uz_UZ"}, + {RML(UZBEK,UZBEK_LATIN), "uz_UZ"}, + {RML(VIETNAMESE,DEFAULT), "vi_VN"}, +/*{RML(WALON,DEFAULT), "wa_BE"},*/ +/*{RML(WELSH,DEFAULT), "cy_GB"},*/ +}; +static const IDToCode primary_to_code[] = { + {LANG_AFRIKAANS, "af"}, + {LANG_ARABIC, "ar"}, + {LANG_AZERI, "az"}, + {LANG_BULGARIAN, "bg"}, +/*{LANG_BRETON, "br"},*/ + {LANG_BELARUSIAN, "by"}, + {LANG_CATALAN, "ca"}, + {LANG_CZECH, "cs"}, +/*{LANG_WELSH, "cy"},*/ + {LANG_DANISH, "da"}, + {LANG_GERMAN, "de"}, + {LANG_GREEK, "el"}, + {LANG_ENGLISH, "en"}, +/*{LANG_ESPERANTO, "eo"},*/ + {LANG_SPANISH, "es"}, + {LANG_ESTONIAN, "et"}, + {LANG_BASQUE, "eu"}, + {LANG_FARSI, "fa"}, + {LANG_FINNISH, "fi"}, + {LANG_FAEROESE, "fo"}, + {LANG_FRENCH, "fr"}, +/*{LANG_GAELIC, "ga"},*/ +/*{LANG_GALICIAN, "gl"},*/ + {LANG_GUJARATI, "gu"}, + {LANG_HEBREW, "he"}, + {LANG_HINDI, "hi"}, + {LANG_SERBIAN, "hr"}, + {LANG_HUNGARIAN, "hu"}, + {LANG_ARMENIAN, "hy"}, + {LANG_INDONESIAN, "id"}, + {LANG_ITALIAN, "it"}, + {LANG_JAPANESE, "ja"}, + {LANG_GEORGIAN, "ka"}, + {LANG_KAZAK, "kk"}, + {LANG_KANNADA, "kn"}, + {LANG_KOREAN, "ko"}, +/*{LANG_KYRGYZ, "ky"},*/ + {LANG_LITHUANIAN, "lt"}, + {LANG_LATVIAN, "lv"}, + {LANG_MACEDONIAN, "mk"}, +/*{LANG_MONGOLIAN, "mn"},*/ + {LANG_MARATHI, "mr"}, + {LANG_MALAY, "ms"}, + {LANG_NORWEGIAN, "nb"}, + {LANG_DUTCH, "nl"}, + {LANG_NORWEGIAN, "nn"}, + {LANG_NORWEGIAN, "no"},/* unofficial? */ + {LANG_PUNJABI, "pa"}, + {LANG_POLISH, "pl"}, + {LANG_PORTUGUESE, "pt"}, + {LANG_ROMANIAN, "ro"}, + {LANG_RUSSIAN, "ru"}, + {LANG_SLOVAK, "sk"}, + {LANG_SLOVENIAN, "sl"}, + {LANG_ALBANIAN, "sq"}, + {LANG_SERBIAN, "sr"}, + {LANG_SWEDISH, "sv"}, + {LANG_SWAHILI, "sw"}, + {LANG_TAMIL, "ta"}, + {LANG_THAI, "th"}, + {LANG_TURKISH, "tr"}, + {LANG_TATAR, "tt"}, + {LANG_UKRAINIAN, "uk"}, + {LANG_URDU, "ur"}, + {LANG_UZBEK, "uz"}, + {LANG_VIETNAMESE, "vi"}, +/*{LANG_WALON, "wa"},*/ + {LANG_CHINESE, "zh"}, +}; +static int num_primary_to_code = + sizeof(primary_to_code) / sizeof(*primary_to_code); +static int num_both_to_code = + sizeof(both_to_code) / sizeof(*both_to_code); + +static const int +lcid_to_fl(LCID lcid, + FL_Locale *rtn) { + LANGID langid = LANGIDFROMLCID(lcid); + LANGID primary_lang = PRIMARYLANGID(langid); + LANGID sub_lang = SUBLANGID(langid); + int i; + /* try to find an exact primary/sublanguage combo that we know about */ + for (i=0; ilang = NULL; + rtn->country = NULL; + rtn->variant = NULL; + +#ifdef WIN32 + /* win32 >= mswindows95 */ + { + LCID lcid = GetThreadLocale(); + if (lcid_to_fl(lcid, rtn)) { + success = FL_CONFIDENT; + } + if (success == FL_FAILED) { + /* assume US English on mswindows systems unless we know otherwise */ + if (accumulate_locstring("en_US.ISO_8859-1", rtn)) { + success = FL_DEFAULT_GUESS; + } + } + } +#else + /* assume unixoid */ + { + /* examples: */ + /* sv_SE.ISO_8859-1 */ + /* fr_FR.ISO8859-1 */ + /* no_NO_NB */ + /* no_NO_NY */ + /* no_NO */ + /* de_DE */ + /* try the various vars in decreasing order of authority */ + if (accumulate_env("LC_ALL", rtn) || + accumulate_env("LC_MESSAGES", rtn) || + accumulate_env("LANG", rtn) || + accumulate_env("LANGUAGE", rtn)) { + success = FL_CONFIDENT; + } + if (success == FL_FAILED) { + /* assume US English on unixoid systems unless we know otherwise */ + if (accumulate_locstring("en_US.ISO_8859-1", rtn)) { + success = FL_DEFAULT_GUESS; + } + } + } +#endif + + if (success != FL_FAILED) { + canonise_fl(rtn); + } + + *locale = rtn; + return success; +} + + +void +FL_FreeLocale(FL_Locale **locale) { + if (locale) { + FL_Locale *l = *locale; + if (l) { + if (l->lang) { + free((void*)l->lang); + } + if (l->country) { + free((void*)l->country); + } + if (l->variant) { + free((void*)l->variant); + } + free(l); + *locale = NULL; + } + } +} diff --git a/external/findlocale/findlocale.h b/external/findlocale/findlocale.h new file mode 100644 index 000000000..c388deee4 --- /dev/null +++ b/external/findlocale/findlocale.h @@ -0,0 +1,34 @@ +#ifndef __findlocale_h_ +#define __findlocale_h_ + +typedef const char* FL_Lang; +typedef const char* FL_Country; +typedef const char* FL_Variant; + +typedef struct { + FL_Lang lang; + FL_Country country; + FL_Variant variant; +} FL_Locale; + +typedef enum { + /* for some reason we failed to even guess: this should never happen */ + FL_FAILED = 0, + /* couldn't query locale -- returning a guess (almost always English) */ + FL_DEFAULT_GUESS = 1, + /* the returned locale type was found by successfully asking the system */ + FL_CONFIDENT = 2 +} FL_Success; + +typedef enum { + FL_MESSAGES = 0 +} FL_Domain; + +/* This allocates/fills in a FL_Locale structure with pointers to + strings (which should be treated as static), or NULL for inappropriate / + undetected fields. */ +FL_Success FL_FindLocale(FL_Locale **locale, FL_Domain domain); +/* This should be used to free the struct written by FL_FindLocale */ +void FL_FreeLocale(FL_Locale **locale); + +#endif /*__findlocale_h_*/ diff --git a/src/lisp/parser.cpp b/src/lisp/parser.cpp index b921003bf..c78255102 100644 --- a/src/lisp/parser.cpp +++ b/src/lisp/parser.cpp @@ -37,10 +37,10 @@ Parser::Parser(bool translate) : obst() { if(translate) { - dictionary_manager = new TinyGetText::DictionaryManager(); + dictionary_manager = new tinygettext::DictionaryManager(); dictionary_manager->set_charset("UTF-8"); if (g_config && (g_config->locale != "")) - dictionary_manager->set_language(g_config->locale); + dictionary_manager->set_language(tinygettext::Language::from_name(g_config->locale)); } obstack_init(&obst); diff --git a/src/lisp/parser.hpp b/src/lisp/parser.hpp index cbc89afd5..8d3927b39 100644 --- a/src/lisp/parser.hpp +++ b/src/lisp/parser.hpp @@ -20,7 +20,7 @@ #include "lisp/lexer.hpp" #include "obstack/obstack.h" -namespace TinyGetText { +namespace tinygettext { class Dictionary; class DictionaryManager; } @@ -56,8 +56,8 @@ private: private: Lexer* lexer; std::string filename; - TinyGetText::DictionaryManager* dictionary_manager; - TinyGetText::Dictionary* dictionary; + tinygettext::DictionaryManager* dictionary_manager; + tinygettext::Dictionary* dictionary; Lexer::TokenType token; struct obstack obst; diff --git a/src/supertux/globals.cpp b/src/supertux/globals.cpp index 1089c1388..22a731175 100644 --- a/src/supertux/globals.cpp +++ b/src/supertux/globals.cpp @@ -19,7 +19,7 @@ SDL_Surface* g_screen; JoystickKeyboardController* g_main_controller = 0; -TinyGetText::DictionaryManager dictionary_manager; +tinygettext::DictionaryManager dictionary_manager; int SCREEN_WIDTH; int SCREEN_HEIGHT; diff --git a/src/supertux/language_menu.cpp b/src/supertux/language_menu.cpp index d7a0fb174..ed13ada79 100644 --- a/src/supertux/language_menu.cpp +++ b/src/supertux/language_menu.cpp @@ -17,27 +17,31 @@ #include "supertux/language_menu.hpp" +extern "C" { +#include "findlocale.h" +} #include "gui/menu_item.hpp" #include "supertux/gameconfig.hpp" +enum { + MNID_LANGUAGE_AUTO_DETECT = 0, + MNID_LANGUAGE_ENGLISH = 1, + MNID_LANGUAGE_NEXT = 10 +}; + LanguageMenu::LanguageMenu() { add_label(_("Language")); add_hl(); - add_entry(0, std::string("<")+_("auto-detect")+">"); - add_entry(1, "English"); + add_entry(MNID_LANGUAGE_AUTO_DETECT, _("")); + add_entry(MNID_LANGUAGE_ENGLISH, "English"); - int mnid = 10; - std::set languages = dictionary_manager.get_languages(); - for (std::set::iterator i = languages.begin(); i != languages.end(); i++) { - std::string locale_name = *i; - TinyGetText::LanguageDef ldef = TinyGetText::get_language_def(locale_name); - std::string locale_fullname = locale_name; - if (std::string(ldef.code) == locale_name) { - locale_fullname = ldef.name; - } - add_entry(mnid++, locale_fullname); - } + int mnid = MNID_LANGUAGE_NEXT; + std::set languages = dictionary_manager.get_languages(); + for (std::set::iterator i = languages.begin(); i != languages.end(); i++) + { + add_entry(mnid++, i->get_name()); + } add_hl(); add_back(_("Back")); @@ -46,27 +50,40 @@ LanguageMenu::LanguageMenu() void LanguageMenu::menu_action(MenuItem* item) { - if (item->id == 0) { - g_config->locale = ""; - dictionary_manager.set_language(g_config->locale); - g_config->save(); - Menu::pop_current(); + if (item->id == MNID_LANGUAGE_AUTO_DETECT) // auto detect + { + FL_Locale *locale; + FL_FindLocale(&locale, FL_MESSAGES); + tinygettext::Language language = tinygettext::Language::from_spec(locale->lang, locale->country, locale->variant); + FL_FreeLocale(&locale); + + dictionary_manager.set_language(language); + g_config->locale = language.str(); + g_config->save(); + Menu::pop_current(); } - else if (item->id == 1) { + else if (item->id == MNID_LANGUAGE_ENGLISH) // english + { g_config->locale = "en"; - dictionary_manager.set_language(g_config->locale); + dictionary_manager.set_language(tinygettext::Language::from_name(g_config->locale)); g_config->save(); Menu::pop_current(); } - int mnid = 10; - std::set languages = dictionary_manager.get_languages(); - for (std::set::iterator i = languages.begin(); i != languages.end(); i++) { - std::string locale_name = *i; - if (item->id == mnid++) { - g_config->locale = locale_name; - dictionary_manager.set_language(g_config->locale); - g_config->save(); - Menu::pop_current(); + else + { + int mnid = MNID_LANGUAGE_NEXT; + std::set languages = dictionary_manager.get_languages(); + + for (std::set::iterator i = languages.begin(); i != languages.end(); i++) + { + if (item->id == mnid++) + { + g_config->locale = i->str(); + dictionary_manager.set_language(*i); + g_config->save(); + Menu::pop_current(); + break; + } } } } diff --git a/src/supertux/main.cpp b/src/supertux/main.cpp index 91943bd3d..b7219f538 100644 --- a/src/supertux/main.cpp +++ b/src/supertux/main.cpp @@ -23,7 +23,8 @@ #ifdef MACOSX namespace supertux_apple { -} +# include +} // namespace supertux_apple #endif #include "addon/addon_manager.hpp" @@ -31,17 +32,17 @@ namespace supertux_apple { #include "binreloc/binreloc.h" #include "control/joystickkeyboardcontroller.hpp" #include "math/random_generator.hpp" +#include "physfs/ifile_stream.hpp" #include "physfs/physfs_sdl.hpp" #include "scripting/squirrel_util.hpp" #include "supertux/gameconfig.hpp" +#include "supertux/globals.hpp" #include "supertux/mainloop.hpp" #include "supertux/resources.hpp" -#include "supertux/globals.hpp" #include "supertux/title_screen.hpp" #include "util/file_system.hpp" #include "util/gettext.hpp" #include "video/drawing_context.hpp" -#include "supertux/globals.hpp" #include "worldmap/worldmap.hpp" namespace { DrawingContext *context_pointer; } @@ -63,7 +64,7 @@ static void init_tinygettext() // Config setting "locale" overrides language detection if (g_config->locale != "") { - dictionary_manager.set_language( g_config->locale ); + dictionary_manager.set_language(tinygettext::Language::from_name(g_config->locale)); } } @@ -514,6 +515,16 @@ static inline void timelog(const char* ) } #endif +std::istream* physfs_open_file(const char* name) +{ + return new IFileStream(name); +} + +void physfs_free_list(char** name) +{ + PHYSFS_freeList(name); +} + int supertux_main(int argc, char** argv) { int result = 0; @@ -527,6 +538,15 @@ int supertux_main(int argc, char** argv) init_physfs(argv[0]); init_sdl(); + { // Let tinygettext use PhysFS + tinygettext::DirOp dir_op; + dir_op.enumerate_files = &PHYSFS_enumerateFiles; + dir_op.free_list = &physfs_free_list; + dir_op.open_file = &physfs_open_file; + + dictionary_manager.set_dir_op(dir_op); + } + timelog("controller"); g_main_controller = new JoystickKeyboardController(); diff --git a/src/util/gettext.hpp b/src/util/gettext.hpp index ba16756e3..876ce03d2 100644 --- a/src/util/gettext.hpp +++ b/src/util/gettext.hpp @@ -19,7 +19,7 @@ #include "tinygettext/tinygettext.hpp" -extern TinyGetText::DictionaryManager dictionary_manager; +extern tinygettext::DictionaryManager dictionary_manager; static inline const char* _(const char* message) { @@ -31,11 +31,6 @@ static inline std::string _(const std::string& message) return dictionary_manager.get_dictionary().translate(message); } -static inline const char* N_(const char* id, const char* id2, int num) -{ - return dictionary_manager.get_dictionary().translate(id, id2, num).c_str(); -} - #endif /* _LIBGETTEXT_H */ /* EOF */