blob: 900af3f916d833e07ed39284400e638ee5d3f1f6 [file] [log] [blame] [edit]
/*
* BRLTTY - A background process providing access to the console screen (when in
* text mode) for a blind person using a refreshable braille display.
*
* Copyright (C) 1995-2023 by The BRLTTY Developers.
*
* BRLTTY comes with ABSOLUTELY NO WARRANTY.
*
* This is free software, placed under the terms of the
* GNU Lesser General Public License, as published by the Free Software
* Foundation; either version 2.1 of the License, or (at your option) any
* later version. Please see the file LICENSE-LGPL for details.
*
* Web Page: http://brltty.app/
*
* This software is maintained by Dave Mielke <dave@mielke.cc>.
*/
#include "prologue.h"
#include <fcntl.h>
#include <errno.h>
#include "log.h"
#include "system.h"
#include "system_windows.h"
#include "timing.h"
#include "messages.h"
/* ntdll.dll */
WIN_PROC_STUB(NtSetInformationProcess);
/* kernel32.dll: console */
WIN_PROC_STUB(AttachConsole);
WIN_PROC_STUB(GetLocaleInfoEx);
/* user32.dll */
WIN_PROC_STUB(GetAltTabInfoA);
WIN_PROC_STUB(SendInput);
#ifdef __MINGW32__
/* ws2_32.dll */
WIN_PROC_STUB(getaddrinfo);
WIN_PROC_STUB(freeaddrinfo);
#endif /* __MINGW32__ */
static void *
loadLibrary (const char *name) {
HMODULE module = LoadLibrary(name);
if (!module) logMessage(LOG_DEBUG, "%s: %s", gettext("cannot load library"), name);
return module;
}
static void *
getProcedure (HMODULE module, const char *name) {
void *address = module? GetProcAddress(module, name): NULL;
if (!address) logMessage(LOG_DEBUG, "%s: %s", gettext("cannot find procedure"), name);
return address;
}
static int
addWindowsCommandLineCharacter (char **buffer, int *size, int *length, char character) {
if (*length == *size) {
char *newBuffer = realloc(*buffer, (*size = *size? *size<<1: 0X80));
if (!newBuffer) {
logSystemError("realloc");
return 0;
}
*buffer = newBuffer;
}
(*buffer)[(*length)++] = character;
return 1;
}
char *
makeWindowsCommandLine (const char *const *arguments) {
const char backslash = '\\';
const char quote = '"';
char *buffer = NULL;
int size = 0;
int length = 0;
#define ADD(c) if (!addWindowsCommandLineCharacter(&buffer, &size, &length, (c))) goto error
while (*arguments) {
const char *character = *arguments;
int backslashCount = 0;
int needQuotes = 0;
int start = length;
while (*character) {
if (*character == backslash) {
++backslashCount;
} else {
if (*character == quote) {
needQuotes = 1;
backslashCount = (backslashCount * 2) + 1;
} else if ((*character == ' ') || (*character == '\t')) {
needQuotes = 1;
}
while (backslashCount > 0) {
ADD(backslash);
--backslashCount;
}
ADD(*character);
}
++character;
}
if (needQuotes) backslashCount *= 2;
while (backslashCount > 0) {
ADD(backslash);
--backslashCount;
}
if (needQuotes) {
ADD(quote);
ADD(quote);
memmove(&buffer[start+1], &buffer[start], length-start-1);
buffer[start] = quote;
}
ADD(' ');
++arguments;
}
#undef ADD
buffer[length-1] = 0;
{
char *line = realloc(buffer, length);
if (line) return line;
logSystemError("realloc");
}
error:
if (buffer) free(buffer);
return NULL;
}
static void
loadLibraries (void) {
HMODULE library;
#define LOAD_LIBRARY(name) (library = loadLibrary(name))
#define GET_PROC(name) (name##Proc = getProcedure(library, #name))
if (LOAD_LIBRARY("ntdll.dll")) {
GET_PROC(NtSetInformationProcess);
}
if (LOAD_LIBRARY("kernel32.dll")) {
GET_PROC(AttachConsole);
GET_PROC(GetLocaleInfoEx);
}
if (LOAD_LIBRARY("user32.dll")) {
GET_PROC(GetAltTabInfoA);
GET_PROC(SendInput);
}
#ifdef __MINGW32__
if (LOAD_LIBRARY("ws2_32.dll")) {
GET_PROC(getaddrinfo);
GET_PROC(freeaddrinfo);
}
#endif /* __MINGW32__ */
}
static void
setLocale (void) {
{
const char *locale = getenv("LANG");
if (locale && *locale) {
setMessagesLocale(locale);
return;
}
}
char *locale = getWindowsLocaleName();
setMessagesLocale(locale);
if (locale) free(locale);
}
void
initializeSystemObject (void) {
setLocale();
loadLibraries();
}
#ifdef __MINGW32__
#include "win_errno.h"
#ifndef SUBLANG_DUTCH_NETHERLANDS
#define SUBLANG_DUTCH_NETHERLANDS SUBLANG_DUTCH
#endif /* SUBLANG_DUTCH_NETHERLANDS */
#ifndef SUBLANG_ENGLISH_IRELAND
#define SUBLANG_ENGLISH_IRELAND SUBLANG_ENGLISH_EIRE
#endif /* SUBLANG_ENGLISH_IRELAND */
#ifndef SUBLANG_FRENCH_FRANCE
#define SUBLANG_FRENCH_FRANCE SUBLANG_FRENCH
#endif /* SUBLANG_FRENCH_FRANCE */
#ifndef SUBLANG_GERMAN_GERMANY
#define SUBLANG_GERMAN_GERMANY SUBLANG_GERMAN
#endif /* SUBLANG_GERMAN_GERMANY */
#ifndef SUBLANG_ITALIAN_ITALY
#define SUBLANG_ITALIAN_ITALY SUBLANG_ITALIAN
#endif /* SUBLANG_ITALIAN_ITALY */
#ifndef SUBLANG_KOREAN_KOREA
#define SUBLANG_KOREAN_KOREA SUBLANG_KOREAN
#endif /* SUBLANG_KOREAN_KOREA */
#ifndef SUBLANG_LITHUANIAN_LITHUANIA
#define SUBLANG_LITHUANIAN_LITHUANIA SUBLANG_LITHUANIAN
#endif /* SUBLANG_LITHUANIAN_LITHUANIA */
#ifndef SUBLANG_PORTUGUESE_PORTUGAL
#define SUBLANG_PORTUGUESE_PORTUGAL SUBLANG_PORTUGUESE
#endif /* SUBLANG_PORTUGUESE_PORTUGAL */
#ifndef SUBLANG_SPANISH_SPAIN
#define SUBLANG_SPANISH_SPAIN SUBLANG_SPANISH
#endif /* SUBLANG_SPANISH_SPAIN */
#ifndef SUBLANG_SWEDISH_SWEDEN
#define SUBLANG_SWEDISH_SWEDEN SUBLANG_SWEDISH
#endif /* SUBLANG_SWEDISH_SWEDEN */
#ifndef SUBLANG_SYRIAC_TURKEY
#define SUBLANG_SYRIAC_TURKEY SUBLANG_SYRIAC
#endif /* SUBLANG_SYRIAC_TURKEY */
char *
getWindowsLocaleName (void) {
if (GetLocaleInfoExProc) {
#define WIN_LOCALE_SIZE 85
WCHAR buffer[WIN_LOCALE_SIZE];
int result = GetLocaleInfoExProc(LOCALE_NAME_USER_DEFAULT, LOCALE_SNAME, buffer, WIN_LOCALE_SIZE);
if (result > 0) {
char locale[WIN_LOCALE_SIZE];
const WCHAR *source = buffer;
char *target = locale;
do {
WCHAR c = *source;
if (c == '-') c = '_';
*target++ = c;
} while (*source++);
{
char *name = strdup(locale);
if (name) {
return name;
} else {
logMallocError();
}
}
} else {
logWindowsSystemError("GetLocaleInfoEx");
}
}
{
DWORD langid;
int result = GetLocaleInfo(LOCALE_USER_DEFAULT,
LOCALE_ILANGUAGE | LOCALE_RETURN_NUMBER,
(char *)&langid, sizeof(langid)/sizeof(TCHAR));
if (result > 0) {
char *name;
switch (langid) {
#define DIALECT(primary,secondary,locale) case MAKELANGID(LANG_##primary, SUBLANG_##primary##_##secondary): name = (locale); break;
DIALECT(AFRIKAANS, SOUTH_AFRICA, "af_ZA");
DIALECT(ALBANIAN, ALBANIA, "sq_AL");
DIALECT(ALSATIAN, FRANCE, "gsw_FR");
DIALECT(AMHARIC, ETHIOPIA, "am_ET");
DIALECT(ARABIC, ALGERIA, "ar_DZ");
DIALECT(ARABIC, BAHRAIN, "ar_BH");
DIALECT(ARABIC, EGYPT, "ar_EG");
DIALECT(ARABIC, IRAQ, "ar_IQ");
DIALECT(ARABIC, JORDAN, "ar_JO");
DIALECT(ARABIC, KUWAIT, "ar_QW");
DIALECT(ARABIC, LEBANON, "ar_LB");
DIALECT(ARABIC, LIBYA, "ar_LY");
DIALECT(ARABIC, MOROCCO, "ar_MA");
DIALECT(ARABIC, OMAN, "ar_OM");
DIALECT(ARABIC, QATAR, "ar_QA");
DIALECT(ARABIC, SAUDI_ARABIA, "ar_SA");
DIALECT(ARABIC, SYRIA, "ar_SY");
DIALECT(ARABIC, TUNISIA, "ar_TN");
DIALECT(ARABIC, UAE, "ar_AE");
DIALECT(ARABIC, YEMEN, "ar_YE");
DIALECT(ARMENIAN, ARMENIA, "hy_AM");
DIALECT(ASSAMESE, INDIA, "as_IN");
DIALECT(AZERI, CYRILLIC, "az@cyrillic");
DIALECT(AZERI, LATIN, "az@latin");
DIALECT(BASHKIR, RUSSIA, "ba_RU");
DIALECT(BASQUE, BASQUE, "eu_XX");
DIALECT(BELARUSIAN, BELARUS, "be_BY");
DIALECT(BENGALI, BANGLADESH, "bn_HD");
DIALECT(BENGALI, INDIA, "bn_IN");
DIALECT(BOSNIAN, BOSNIA_HERZEGOVINA_CYRILLIC, "bs_BA@cyrillic");
DIALECT(BOSNIAN, BOSNIA_HERZEGOVINA_LATIN, "bs_BA@latin");
DIALECT(BRETON, FRANCE, "br_FR");
DIALECT(BULGARIAN, BULGARIA, "bg_BG");
DIALECT(CATALAN, CATALAN, "ca_XX");
DIALECT(CHINESE, HONGKONG, "zh_HK");
DIALECT(CHINESE, MACAU, "zh_MO");
DIALECT(CHINESE, SIMPLIFIED, "zh_CN");
DIALECT(CHINESE, SINGAPORE, "zh_SG");
DIALECT(CHINESE, TRADITIONAL, "zh_TW");
DIALECT(CORSICAN, FRANCE, "co_FR");
DIALECT(CROATIAN, BOSNIA_HERZEGOVINA_LATIN, "hr_BA@latin");
DIALECT(CROATIAN, CROATIA, "hr_HR");
DIALECT(CZECH, CZECH_REPUBLIC, "cs_CZ");
DIALECT(DANISH, DENMARK, "da_DK");
DIALECT(DIVEHI, MALDIVES, "dv_MV");
DIALECT(DUTCH, BELGIAN, "nl_BE");
DIALECT(DUTCH, NETHERLANDS, "nl_NL");
DIALECT(ENGLISH, AUS, "en_AU");
DIALECT(ENGLISH, BELIZE, "en_BZ");
DIALECT(ENGLISH, CAN, "en_CA");
DIALECT(ENGLISH, CARIBBEAN, "en_XX");
DIALECT(ENGLISH, INDIA, "en_IN");
DIALECT(ENGLISH, IRELAND, "en_IE");
DIALECT(ENGLISH, JAMAICA, "en_JM");
DIALECT(ENGLISH, MALAYSIA, "en_MY");
DIALECT(ENGLISH, NZ, "en_NZ");
DIALECT(ENGLISH, PHILIPPINES, "en_PH");
DIALECT(ENGLISH, SINGAPORE, "en_SG");
DIALECT(ENGLISH, SOUTH_AFRICA, "en_ZA");
DIALECT(ENGLISH, TRINIDAD, "en_TT");
DIALECT(ENGLISH, UK, "en_GB");
DIALECT(ENGLISH, US, "en_US");
DIALECT(ENGLISH, ZIMBABWE, "en_ZW");
DIALECT(ESTONIAN, ESTONIA, "et_EE");
DIALECT(FAEROESE, FAROE_ISLANDS, "fo_FO");
DIALECT(FILIPINO, PHILIPPINES, "fil_PH");
DIALECT(FINNISH, FINLAND, "fi_FI");
DIALECT(FRENCH, BELGIAN, "fr_BE");
DIALECT(FRENCH, CANADIAN, "fr_CA");
DIALECT(FRENCH, FRANCE, "fr_FR");
DIALECT(FRENCH, LUXEMBOURG, "fr_LU");
DIALECT(FRENCH, MONACO, "fr_MC");
DIALECT(FRENCH, SWISS, "fr_CH");
DIALECT(FRISIAN, NETHERLANDS, "fy_NL");
DIALECT(GALICIAN, GALICIAN, "gl_ES");
DIALECT(GEORGIAN, GEORGIA, "ka_GE");
DIALECT(GERMAN, AUSTRIAN, "de_AT");
DIALECT(GERMAN, GERMANY, "de_DE");
DIALECT(GERMAN, LIECHTENSTEIN, "de_LI");
DIALECT(GERMAN, LUXEMBOURG, "de_LU");
DIALECT(GERMAN, SWISS, "de_CH");
DIALECT(GREEK, GREECE, "el_GR");
DIALECT(GREENLANDIC, GREENLAND, "kl_GL");
DIALECT(GUJARATI, INDIA, "gu_IN");
DIALECT(HAUSA, NIGERIA, "ha_NG");
DIALECT(HEBREW, ISRAEL, "he_IL");
DIALECT(HINDI, INDIA, "hi_IN");
DIALECT(HUNGARIAN, HUNGARY, "hu_HU");
DIALECT(ICELANDIC, ICELAND, "is_IS");
DIALECT(IGBO, NIGERIA, "ig_NG");
DIALECT(INDONESIAN, INDONESIA, "id_ID");
DIALECT(INUKTITUT, CANADA, "iu_CA");
DIALECT(IRISH, IRELAND, "ga_IE");
DIALECT(ITALIAN, ITALY, "it_IT");
DIALECT(ITALIAN, SWISS, "it_CH");
DIALECT(JAPANESE, JAPAN, "ja_JP");
DIALECT(KASHMIRI, INDIA, "ks_IN");
DIALECT(KAZAK, KAZAKHSTAN, "kk_KZ");
DIALECT(KHMER, CAMBODIA, "km_KH");
DIALECT(KICHE, GUATEMALA, "quc_GT");
DIALECT(KINYARWANDA, RWANDA, "rw_RW");
DIALECT(KONKANI, INDIA, "kok_IN");
DIALECT(KOREAN, KOREA, "ko_KR");
DIALECT(KYRGYZ, KYRGYZSTAN, "ky_KG");
DIALECT(LAO, LAO_PDR, "lo_LA");
DIALECT(LATVIAN, LATVIA, "lv_LV");
DIALECT(LITHUANIAN, LITHUANIA, "lt_LT");
DIALECT(LOWER_SORBIAN, GERMANY, "dsb_DE");
DIALECT(LUXEMBOURGISH, LUXEMBOURG, "lb_LU");
DIALECT(MACEDONIAN, MACEDONIA, "mk_MK");
DIALECT(MALAY, BRUNEI_DARUSSALAM, "ms_BN");
DIALECT(MALAY, MALAYSIA, "ms_MY");
DIALECT(MALAYALAM, INDIA, "ml_IN");
DIALECT(MALTESE, MALTA, "mt_MT");
DIALECT(MAORI, NEW_ZEALAND, "mi_NZ");
DIALECT(MAPUDUNGUN, CHILE, "arn_CL");
DIALECT(MARATHI, INDIA, "mr_IN");
DIALECT(MOHAWK, MOHAWK, "moh");
DIALECT(MONGOLIAN, CYRILLIC_MONGOLIA, "mn_MN@cyrillic");
DIALECT(MONGOLIAN, PRC, "mn_CN");
DIALECT(NEPALI, INDIA, "ne_IN");
DIALECT(NEPALI, NEPAL, "ne_NP");
DIALECT(NORWEGIAN, BOKMAL, "nb_NO");
DIALECT(NORWEGIAN, NYNORSK, "nn_NO");
DIALECT(OCCITAN, FRANCE, "oc_FR");
DIALECT(ORIYA, INDIA, "or_IN");
DIALECT(PASHTO, AFGHANISTAN, "ps_AF");
DIALECT(PERSIAN, IRAN, "fa_IR");
DIALECT(POLISH, POLAND, "pl_PL");
DIALECT(PORTUGUESE, BRAZILIAN, "pt_BR");
DIALECT(PORTUGUESE, PORTUGAL, "pt_PT");
DIALECT(PUNJABI, INDIA, "pa_IN");
#ifdef SUBLANG_PUNJABI_PAKISTAN
DIALECT(PUNJABI, PAKISTAN, "pa_PK");
#endif /* SUBLANG_PUNJABI_PAKISTAN */
DIALECT(QUECHUA, BOLIVIA, "qu_BO");
DIALECT(QUECHUA, ECUADOR, "qu_EC");
DIALECT(QUECHUA, PERU, "qu_PE");
#ifdef SUBLANG_ROMANIAN_MOLDOVA
DIALECT(ROMANIAN, MOLDOVA, "ro_MD");
#endif /* SUBLANG_ROMANIAN_MOLDOVA */
DIALECT(ROMANIAN, ROMANIA, "ro_RO");
DIALECT(RUSSIAN, RUSSIA, "ru_RU");
DIALECT(SAMI, LULE_NORWAY, "smj_NO");
DIALECT(SAMI, LULE_SWEDEN, "smj_SE");
DIALECT(SAMI, NORTHERN_FINLAND, "sme_FI");
DIALECT(SAMI, NORTHERN_NORWAY, "sme_NO");
DIALECT(SAMI, NORTHERN_SWEDEN, "sme_SE");
DIALECT(SAMI, SOUTHERN_NORWAY, "sma_NO");
DIALECT(SAMI, SOUTHERN_SWEDEN, "sma_SE");
DIALECT(SANSKRIT, INDIA, "sa_IN");
DIALECT(SERBIAN, BOSNIA_HERZEGOVINA_CYRILLIC, "sr_BA@cyrillic");
DIALECT(SERBIAN, BOSNIA_HERZEGOVINA_LATIN, "sr_BA@latin");
DIALECT(SERBIAN, CYRILLIC, "sr@cyrillic");
DIALECT(SERBIAN, LATIN, "sr@latin");
DIALECT(SINDHI, AFGHANISTAN, "sd_AF");
DIALECT(SINHALESE, SRI_LANKA, "si_LK");
DIALECT(SLOVAK, SLOVAKIA, "sk_SK");
DIALECT(SLOVENIAN, SLOVENIA, "sl_SI");
DIALECT(SOTHO, NORTHERN_SOUTH_AFRICA, "st_XX");
DIALECT(SPANISH, ARGENTINA, "es_AR");
DIALECT(SPANISH, BOLIVIA, "es_BO");
DIALECT(SPANISH, CHILE, "es_CL");
DIALECT(SPANISH, COLOMBIA, "es_CO");
DIALECT(SPANISH, COSTA_RICA, "es_CR");
DIALECT(SPANISH, DOMINICAN_REPUBLIC, "es_DO");
DIALECT(SPANISH, ECUADOR, "es_EC");
DIALECT(SPANISH, EL_SALVADOR, "es_SV");
DIALECT(SPANISH, GUATEMALA, "es_GT");
DIALECT(SPANISH, HONDURAS, "es_HN");
DIALECT(SPANISH, MEXICAN, "es_MX");
DIALECT(SPANISH, MODERN, "es_XX");
DIALECT(SPANISH, NICARAGUA, "es_NI");
DIALECT(SPANISH, PANAMA, "es_PA");
DIALECT(SPANISH, PARAGUAY, "es_PY");
DIALECT(SPANISH, PERU, "es_PE");
DIALECT(SPANISH, PUERTO_RICO, "es_PR");
DIALECT(SPANISH, SPAIN, "es_ES");
DIALECT(SPANISH, URUGUAY, "es_UY");
DIALECT(SPANISH, US, "es_US");
DIALECT(SPANISH, VENEZUELA, "es_VE");
DIALECT(SWEDISH, FINLAND, "sv_FI");
DIALECT(SWEDISH, SWEDEN, "sv_SE");
DIALECT(SYRIAC, TURKEY, "syr_TR");
DIALECT(TAMAZIGHT, ALGERIA_LATIN, "ber_DZ@latin");
DIALECT(TAMIL, INDIA, "ta_IN");
DIALECT(TATAR, RUSSIA, "tt_RU");
DIALECT(TELUGU, INDIA, "te_IN");
DIALECT(THAI, THAILAND, "th_TH");
DIALECT(TIBETAN, BHUTAN, "bo_BT");
DIALECT(TIBETAN, PRC, "bo_CN");
DIALECT(TIGRIGNA, ERITREA, "ti_ER");
DIALECT(TSWANA, SOUTH_AFRICA, "tn_ZA");
DIALECT(TURKISH, TURKEY, "tr_TR");
DIALECT(UIGHUR, PRC, "ug_CN");
DIALECT(UKRAINIAN, UKRAINE, "uk_UA");
//DIALECT(UPPER_SORBIAN, GERMANY, "hsb_DE");
DIALECT(URDU, INDIA, "ur_IN");
DIALECT(URDU, PAKISTAN, "ur_PK");
DIALECT(UZBEK, CYRILLIC, "uz@cyrillic");
DIALECT(UZBEK, LATIN, "uz@latin");
DIALECT(VIETNAMESE, VIETNAM, "vi_VN");
DIALECT(WELSH, UNITED_KINGDOM, "cy_GB");
DIALECT(WOLOF, SENEGAL, "fy_SN");
DIALECT(XHOSA, SOUTH_AFRICA, "xh_ZA");
DIALECT(YAKUT, RUSSIA, "sah_RU");
DIALECT(YI, PRC, "ii_CN");
DIALECT(YORUBA, NIGERIA, "yo_NG");
DIALECT(ZULU, SOUTH_AFRICA, "zu_ZA");
#undef DIALECTo
default:
switch (PRIMARYLANGID(langid)) {
#define LANGUAGE(primary,locale) case LANG_##primary: name = (locale); break;
LANGUAGE(AFRIKAANS, "af");
LANGUAGE(ALBANIAN, "sq");
LANGUAGE(ALSATIAN, "gsw");
LANGUAGE(AMHARIC, "am");
LANGUAGE(ARABIC, "ar");
LANGUAGE(ARMENIAN, "hy");
LANGUAGE(ASSAMESE, "as");
LANGUAGE(AZERI, "az");
LANGUAGE(BASHKIR, "ba");
LANGUAGE(BASQUE, "eu");
LANGUAGE(BELARUSIAN, "be");
LANGUAGE(BENGALI, "bn");
LANGUAGE(BOSNIAN, "bs");
LANGUAGE(BOSNIAN_NEUTRAL, "bs");
LANGUAGE(BRETON, "br");
LANGUAGE(BULGARIAN, "bg");
LANGUAGE(CATALAN, "ca");
LANGUAGE(CHINESE, "zh");
LANGUAGE(CORSICAN, "co");
//LANGUAGE(CROATIAN, "hr");
LANGUAGE(CZECH, "cs");
LANGUAGE(DANISH, "da");
LANGUAGE(DARI, "gbz");
LANGUAGE(DIVEHI, "dv");
LANGUAGE(DUTCH, "nl");
LANGUAGE(ENGLISH, "en");
LANGUAGE(ESTONIAN, "et");
LANGUAGE(FAEROESE, "fo");
LANGUAGE(FILIPINO, "fil");
LANGUAGE(FINNISH, "fi");
LANGUAGE(FRENCH, "fr");
LANGUAGE(FRISIAN, "fy");
LANGUAGE(GALICIAN, "gl");
LANGUAGE(GEORGIAN, "ka");
LANGUAGE(GERMAN, "de");
LANGUAGE(GREEK, "el");
LANGUAGE(GREENLANDIC, "kl");
LANGUAGE(GUJARATI, "gu");
LANGUAGE(HAUSA, "ha");
LANGUAGE(HEBREW, "he");
LANGUAGE(HINDI, "hi");
LANGUAGE(HUNGARIAN, "hu");
LANGUAGE(ICELANDIC, "is");
LANGUAGE(IGBO, "ig");
LANGUAGE(INDONESIAN, "id");
LANGUAGE(INUKTITUT, "iu");
LANGUAGE(IRISH, "ga");
LANGUAGE(ITALIAN, "it");
LANGUAGE(JAPANESE, "ja");
LANGUAGE(KANNADA, "kn");
LANGUAGE(KASHMIRI, "ks");
LANGUAGE(KAZAK, "kk");
LANGUAGE(KHMER, "km");
LANGUAGE(KICHE, "quc");
LANGUAGE(KINYARWANDA, "rw");
LANGUAGE(KONKANI, "kok");
LANGUAGE(KOREAN, "ko");
LANGUAGE(KYRGYZ, "ky");
LANGUAGE(LAO, "lo");
LANGUAGE(LATVIAN, "lv");
LANGUAGE(LITHUANIAN, "lt");
LANGUAGE(LOWER_SORBIAN, "dsb");
LANGUAGE(LUXEMBOURGISH, "lb");
LANGUAGE(MACEDONIAN, "mk");
#ifndef __MINGW64_VERSION_MAJOR
LANGUAGE(MALAGASY, "mg");
#endif
LANGUAGE(MALAY, "ms");
LANGUAGE(MALAYALAM, "ml");
LANGUAGE(MALTESE, "mt");
LANGUAGE(MANIPURI, "mni");
LANGUAGE(MAORI, "mi");
LANGUAGE(MAPUDUNGUN, "arn");
LANGUAGE(MARATHI, "mr");
LANGUAGE(MOHAWK, "moh");
LANGUAGE(MONGOLIAN, "mn");
LANGUAGE(NEPALI, "ne");
LANGUAGE(NORWEGIAN, "no");
LANGUAGE(OCCITAN, "oc");
LANGUAGE(ORIYA, "or");
LANGUAGE(PASHTO, "ps");
LANGUAGE(PERSIAN, "fa");
LANGUAGE(POLISH, "pl");
LANGUAGE(PORTUGUESE, "pt");
LANGUAGE(PUNJABI, "pa");
LANGUAGE(QUECHUA, "qu");
LANGUAGE(ROMANIAN, "ro");
LANGUAGE(RUSSIAN, "ru");
LANGUAGE(SAMI, "se");
LANGUAGE(SANSKRIT, "sa");
//LANGUAGE(SERBIAN, "sr");
LANGUAGE(SERBIAN_NEUTRAL, "sr");
LANGUAGE(SINDHI, "sd");
LANGUAGE(SINHALESE, "si");
LANGUAGE(SLOVAK, "sk");
LANGUAGE(SLOVENIAN, "sl");
LANGUAGE(SOTHO, "st");
LANGUAGE(SPANISH, "es");
LANGUAGE(SWAHILI, "sw");
LANGUAGE(SWEDISH, "sv");
LANGUAGE(SYRIAC, "syr");
LANGUAGE(TAMAZIGHT, "ber");
LANGUAGE(TAMIL, "ta");
LANGUAGE(TATAR, "tt");
LANGUAGE(TELUGU, "te");
LANGUAGE(THAI, "th");
LANGUAGE(TIBETAN, "bo");
LANGUAGE(TIGRIGNA, "ti");
LANGUAGE(TSWANA, "tn");
LANGUAGE(TURKISH, "tr");
LANGUAGE(UIGHUR, "ug");
LANGUAGE(UKRAINIAN, "uk");
//LANGUAGE(UPPER_SORBIAN, "hsb");
LANGUAGE(URDU, "ur");
LANGUAGE(UZBEK, "uz");
LANGUAGE(VIETNAMESE, "vi");
LANGUAGE(WELSH, "cy");
LANGUAGE(WOLOF, "fy");
LANGUAGE(XHOSA, "xh");
LANGUAGE(YAKUT, "sah");
LANGUAGE(YI, "ii");
LANGUAGE(YORUBA, "yo");
LANGUAGE(ZULU, "zu");
#undef LANGUAGE
default:
name = NULL;
break;
}
break;
}
if (name) {
if ((name = strdup(name))) {
return name;
} else {
logMallocError();
}
}
} else {
logWindowsSystemError("GetLocaleInfo");
}
}
return NULL;
}
#if (__MINGW32_MAJOR_VERSION < 3) || ((__MINGW32_MAJOR_VERSION == 3) && (__MINGW32_MINOR_VERSION < 10))
int
gettimeofday (struct timeval *tvp, void *tzp) {
DWORD time = GetTickCount();
/* this is not 49.7 days-proof ! */
tvp->tv_sec = time / 1000;
tvp->tv_usec = (time % 1000) * 1000;
return 0;
}
#endif /* gettimeofday() */
#if !defined(__MINGW64_VERSION_MAJOR) && ((__MINGW32_MAJOR_VERSION < 3) || ((__MINGW32_MAJOR_VERSION == 3) && (__MINGW32_MINOR_VERSION < 15)))
void
usleep (int usec) {
if (usec > 0) {
approximateDelay((usec + (USECS_PER_MSEC - 1)) / USECS_PER_MSEC);
}
}
#endif /* usleep() */
#endif /* __MINGW32__ */