22#include <freerdp/config.h> 
   25#include <CoreFoundation/CFString.h> 
   26#include <CoreFoundation/CFLocale.h> 
   34#include <winpr/assert.h> 
   35#include <winpr/environment.h> 
   39#include <freerdp/locale/locale.h> 
   47  { 
"af", 
"ZA", AFRIKAANS },           
 
   48  { 
"sq", 
"AL", ALBANIAN },            
 
   49  { 
"gsw", 
"FR", ALSATIAN },           
 
   50  { 
"am", 
"ET", AMHARIC },             
 
   51  { 
"ar", 
"DZ", ARABIC_ALGERIA },      
 
   52  { 
"ar", 
"BH", ARABIC_BAHRAIN },      
 
   53  { 
"ar", 
"EG", ARABIC_EGYPT },        
 
   54  { 
"ar", 
"IQ", ARABIC_IRAQ },         
 
   55  { 
"ar", 
"JO", ARABIC_JORDAN },       
 
   56  { 
"ar", 
"KW", ARABIC_KUWAIT },       
 
   57  { 
"ar", 
"LB", ARABIC_LEBANON },      
 
   58  { 
"ar", 
"LY", ARABIC_LIBYA },        
 
   59  { 
"ar", 
"MA", ARABIC_MOROCCO },      
 
   60  { 
"ar", 
"OM", ARABIC_OMAN },         
 
   61  { 
"ar", 
"QA", ARABIC_QATAR },        
 
   62  { 
"ar", 
"SA", ARABIC_SAUDI_ARABIA }, 
 
   63  { 
"ar", 
"SY", ARABIC_SYRIA },        
 
   64  { 
"ar", 
"TN", ARABIC_TUNISIA },      
 
   65  { 
"ar", 
"AE", ARABIC_UAE },          
 
   66  { 
"ar", 
"YE", ARABIC_YEMEN },        
 
   67  { 
"az", 
"AZ", AZERI_LATIN },         
 
   68  { 
"az", 
"Cyrl_AZ", AZERI_CYRILLIC }, 
 
   69  { 
"hy", 
"AM", ARMENIAN },            
 
   70  { 
"as", 
"IN", ASSAMESE },            
 
   71  { 
"ba", 
"RU", BASHKIR },             
 
   72  { 
"eu", 
"ES", BASQUE },              
 
   73  { 
"be", 
"BY", BELARUSIAN },          
 
   74  { 
"bn", 
"IN", BENGALI_INDIA },       
 
   75  { 
"br", 
"FR", BRETON },              
 
   76  { 
"bs", 
"BA", BOSNIAN_LATIN },       
 
   77  { 
"bg", 
"BG", BULGARIAN },           
 
   78  { 
"ca", 
"ES", CATALAN },             
 
   79  { 
"zh", 
"HK", CHINESE_HONG_KONG },   
 
   80  { 
"zh", 
"MO", CHINESE_MACAU }, 
 
   81  { 
"zh", 
"CN", CHINESE_PRC },   
 
   82  { 
"zh", 
"SG", CHINESE_SINGAPORE },           
 
   83  { 
"zh", 
"TW", CHINESE_TAIWAN },              
 
   84  { 
"hr", 
"BA", CROATIAN_BOSNIA_HERZEGOVINA }, 
 
   86  { 
"hr", 
"HR", CROATIAN },                    
 
   87  { 
"cs", 
"CZ", CZECH },                       
 
   88  { 
"da", 
"DK", DANISH },                      
 
   89  { 
"prs", 
"AF", DARI },                       
 
   90  { 
"dv", 
"MV", DIVEHI },                      
 
   91  { 
"nl", 
"BE", DUTCH_BELGIAN },               
 
   92  { 
"nl", 
"NL", DUTCH_STANDARD },              
 
   93  { 
"en", 
"AU", ENGLISH_AUSTRALIAN },          
 
   94  { 
"en", 
"BZ", ENGLISH_BELIZE },              
 
   95  { 
"en", 
"CA", ENGLISH_CANADIAN },            
 
   96  { 
"en", 
"CB", ENGLISH_CARIBBEAN },           
 
   97  { 
"en", 
"IN", ENGLISH_INDIA },               
 
   98  { 
"en", 
"IE", ENGLISH_IRELAND },             
 
   99  { 
"en", 
"JM", ENGLISH_JAMAICA },             
 
  100  { 
"en", 
"MY", ENGLISH_MALAYSIA },            
 
  101  { 
"en", 
"NZ", ENGLISH_NEW_ZEALAND },         
 
  103    ENGLISH_PHILIPPINES }, 
 
  104  { 
"en", 
"SG", ENGLISH_SINGAPORE },      
 
  105  { 
"en", 
"ZA", ENGLISH_SOUTH_AFRICA },   
 
  106  { 
"en", 
"TT", ENGLISH_TRINIDAD },       
 
  107  { 
"en", 
"GB", ENGLISH_UNITED_KINGDOM }, 
 
  108  { 
"en", 
"US", ENGLISH_UNITED_STATES },  
 
  111  { 
"et", 
"EE", ESTONIAN },  
 
  112  { 
"fo", 
"FO", FAEROESE },  
 
  113  { 
"fil", 
"PH", FILIPINO }, 
 
  115  { 
"fi", 
"FI", FINNISH },   
 
  116  { 
"fr", 
"BE", FRENCH_BELGIAN },    
 
  117  { 
"fr", 
"CA", FRENCH_CANADIAN },   
 
  118  { 
"fr", 
"FR", FRENCH_STANDARD },   
 
  119  { 
"fr", 
"LU", FRENCH_LUXEMBOURG }, 
 
  120  { 
"fr", 
"MC", FRENCH_MONACO },     
 
  121  { 
"fr", 
"CH", FRENCH_SWISS },      
 
  122  { 
"fy", 
"NL", FRISIAN },  
 
  124  { 
"gl", 
"ES", GALICIAN }, 
 
  125  { 
"ka", 
"GE", GEORGIAN }, 
 
  126  { 
"de", 
"AT", GERMAN_AUSTRIAN },      
 
  127  { 
"de", 
"DE", GERMAN_STANDARD },      
 
  128  { 
"de", 
"LI", GERMAN_LIECHTENSTEIN }, 
 
  129  { 
"de", 
"LU", GERMAN_LUXEMBOURG },    
 
  130  { 
"de", 
"CH", GERMAN_SWISS },         
 
  131  { 
"el", 
"GR", GREEK },                
 
  132  { 
"kl", 
"GL", GREENLANDIC },          
 
  133  { 
"gu", 
"IN", GUJARATI },             
 
  134  { 
"he", 
"IL", HEBREW },               
 
  135  { 
"hi", 
"IN", HINDI },                
 
  136  { 
"hu", 
"HU", HUNGARIAN },            
 
  137  { 
"is", 
"IS", ICELANDIC },            
 
  138  { 
"ig", 
"NG", IGBO },                 
 
  139  { 
"id", 
"ID", INDONESIAN },           
 
  140  { 
"ga", 
"IE", IRISH }, 
 
  142  { 
"it", 
"IT", ITALIAN_STANDARD }, 
 
  143  { 
"it", 
"CH", ITALIAN_SWISS },    
 
  144  { 
"ja", 
"JP", JAPANESE },         
 
  145  { 
"kn", 
"IN", KANNADA },          
 
  146  { 
"kk", 
"KZ", KAZAKH },           
 
  147  { 
"kh", 
"KH", KHMER },            
 
  148  { 
"qut", 
"GT", KICHE },           
 
  149  { 
"rw", 
"RW", KINYARWANDA },      
 
  150  { 
"kok", 
"IN", KONKANI },         
 
  151  { 
"ko", 
"KR", KOREAN },           
 
  152  { 
"ky", 
"KG", KYRGYZ },           
 
  154  { 
"lv", 
"LV", LATVIAN },          
 
  155  { 
"lt", 
"LT", LITHUANIAN },       
 
  156  { 
"dsb", 
"DE", LOWER_SORBIAN },   
 
  157  { 
"lb", 
"LU", LUXEMBOURGISH },    
 
  159  { 
"mk", 
"MK", MACEDONIAN },       
 
  160  { 
"ms", 
"BN", MALAY_BRUNEI_DARUSSALAM }, 
 
  161  { 
"ms", 
"MY", MALAY_MALAYSIA },          
 
  162  { 
"ml", 
"IN", MALAYALAM },               
 
  163  { 
"mt", 
"MT", MALTESE },                 
 
  164  { 
"mi", 
"NZ", MAORI },                   
 
  165  { 
"arn", 
"CL", MAPUDUNGUN }, 
 
  167  { 
"mr", 
"IN", MARATHI },     
 
  168  { 
"moh", 
"CA", MOHAWK },   
 
  170  { 
"mn", 
"MN", MONGOLIAN }, 
 
  171  { 
"ne", 
"NP", NEPALI },    
 
  173  { 
"nb", 
"NO", NORWEGIAN_BOKMAL },  
 
  174  { 
"nn", 
"NO", NORWEGIAN_NYNORSK }, 
 
  175  { 
"oc", 
"FR", OCCITAN },           
 
  176  { 
"or", 
"IN", ORIYA },             
 
  177  { 
"ps", 
"AF", PASHTO }, 
 
  179  { 
"fa", 
"IR", FARSI },  
 
  180  { 
"pl", 
"PL", POLISH }, 
 
  181  { 
"pt", 
"BR", PORTUGUESE_BRAZILIAN }, 
 
  182  { 
"pt", 
"PT", PORTUGUESE_STANDARD },  
 
  183  { 
"pa", 
"IN", PUNJABI },              
 
  184  { 
"quz", 
"BO", QUECHUA_BOLIVIA },     
 
  185  { 
"quz", 
"EC", QUECHUA_ECUADOR },     
 
  186  { 
"quz", 
"PE", QUECHUA_PERU },        
 
  187  { 
"ro", 
"RO", ROMANIAN },             
 
  188  { 
"rm", 
"CH", ROMANSH }, 
 
  190  { 
"ru", 
"RU", RUSSIAN }, 
 
  191  { 
"smn", 
"FI", SAMI_INARI },           
 
  192  { 
"smj", 
"NO", SAMI_LULE_NORWAY },     
 
  193  { 
"smj", 
"SE", SAMI_LULE_SWEDEN },     
 
  194  { 
"se", 
"FI", SAMI_NORTHERN_FINLAND }, 
 
  195  { 
"se", 
"NO", SAMI_NORTHERN_NORWAY },  
 
  196  { 
"se", 
"SE", SAMI_NORTHERN_SWEDEN },  
 
  197  { 
"sms", 
"FI", SAMI_SKOLT },           
 
  198  { 
"sma", 
"NO", SAMI_SOUTHERN_NORWAY }, 
 
  199  { 
"sma", 
"SE", SAMI_SOUTHERN_SWEDEN }, 
 
  200  { 
"sa", 
"IN", SANSKRIT },              
 
  201  { 
"sr", 
"SP", SERBIAN_LATIN },         
 
  203    SERBIAN_LATIN_BOSNIA_HERZEGOVINA },  
 
  204  { 
"sr", 
"Cyrl_SP", SERBIAN_CYRILLIC }, 
 
  206    SERBIAN_CYRILLIC_BOSNIA_HERZEGOVINA }, 
 
  207  { 
"ns", 
"ZA", SESOTHO_SA_LEBOA }, 
 
  209  { 
"tn", 
"ZA", TSWANA },           
 
  210  { 
"si", 
"LK", SINHALA },          
 
  211  { 
"sk", 
"SK", SLOVAK },           
 
  212  { 
"sl", 
"SI", SLOVENIAN },        
 
  213  { 
"es", 
"AR", SPANISH_ARGENTINA },          
 
  214  { 
"es", 
"BO", SPANISH_BOLIVIA },            
 
  215  { 
"es", 
"CL", SPANISH_CHILE },              
 
  216  { 
"es", 
"CO", SPANISH_COLOMBIA },           
 
  217  { 
"es", 
"CR", SPANISH_COSTA_RICA },         
 
  218  { 
"es", 
"DO", SPANISH_DOMINICAN_REPUBLIC }, 
 
  219  { 
"es", 
"EC", SPANISH_ECUADOR },            
 
  220  { 
"es", 
"SV", SPANISH_EL_SALVADOR },        
 
  221  { 
"es", 
"GT", SPANISH_GUATEMALA },          
 
  222  { 
"es", 
"HN", SPANISH_HONDURAS },           
 
  223  { 
"es", 
"MX", SPANISH_MEXICAN },            
 
  224  { 
"es", 
"NI", SPANISH_NICARAGUA },          
 
  225  { 
"es", 
"PA", SPANISH_PANAMA },             
 
  226  { 
"es", 
"PY", SPANISH_PARAGUAY },           
 
  227  { 
"es", 
"PE", SPANISH_PERU },               
 
  228  { 
"es", 
"PR", SPANISH_PUERTO_RICO },        
 
  229  { 
"es", 
"ES", SPANISH_MODERN_SORT },        
 
  230  { 
"es", 
"ES", SPANISH_TRADITIONAL_SORT },   
 
  231  { 
"es", 
"US", SPANISH_UNITED_STATES }, 
 
  232  { 
"es", 
"UY", SPANISH_URUGUAY },       
 
  233  { 
"es", 
"VE", SPANISH_VENEZUELA },     
 
  234  { 
"sw", 
"KE", SWAHILI },               
 
  235  { 
"sv", 
"FI", SWEDISH_FINLAND },       
 
  236  { 
"sv", 
"SE", SWEDISH },               
 
  237  { 
"syr", 
"SY", SYRIAC },               
 
  238  { 
"ta", 
"IN", TAMIL },                 
 
  239  { 
"tt", 
"RU", TATAR },                 
 
  240  { 
"te", 
"IN", TELUGU },                
 
  241  { 
"th", 
"TH", THAI },                  
 
  242  { 
"bo", 
"BT", TIBETAN_BHUTAN },        
 
  243  { 
"bo", 
"CN", TIBETAN_PRC },           
 
  244  { 
"tr", 
"TR", TURKISH },               
 
  245  { 
"tk", 
"TM", TURKMEN },               
 
  246  { 
"ug", 
"CN", UIGHUR },                
 
  247  { 
"uk", 
"UA", UKRAINIAN },             
 
  248  { 
"wen", 
"DE", UPPER_SORBIAN },        
 
  249  { 
"tr", 
"IN", URDU_INDIA },            
 
  250  { 
"ur", 
"PK", URDU },        
 
  251  { 
"uz", 
"UZ", UZBEK_LATIN }, 
 
  252  { 
"uz", 
"Cyrl_UZ", UZBEK_CYRILLIC }, 
 
  253  { 
"vi", 
"VN", VIETNAMESE }, 
 
  254  { 
"cy", 
"GB", WELSH },      
 
  255  { 
"wo", 
"SN", WOLOF },      
 
  256  { 
"xh", 
"ZA", XHOSA },      
 
  257  { 
"sah", 
"RU", YAKUT },     
 
  259  { 
"yo", 
"NG", YORUBA },     
 
  269static const LOCALE_NAME LOCALE_NAME_TABLE[] = {
 
  270  { AFRIKAANS, 
"AFRIKAANS" },
 
  271  { ALBANIAN, 
"ALBANIAN" },
 
  272  { ALSATIAN, 
"ALSATIAN" },
 
  273  { AMHARIC, 
"AMHARIC" },
 
  274  { ARABIC_SAUDI_ARABIA, 
"ARABIC_SAUDI_ARABIA" },
 
  275  { ARABIC_IRAQ, 
"ARABIC_IRAQ" },
 
  276  { ARABIC_EGYPT, 
"ARABIC_EGYPT" },
 
  277  { ARABIC_LIBYA, 
"ARABIC_LIBYA" },
 
  278  { ARABIC_ALGERIA, 
"ARABIC_ALGERIA" },
 
  279  { ARABIC_MOROCCO, 
"ARABIC_MOROCCO" },
 
  280  { ARABIC_TUNISIA, 
"ARABIC_TUNISIA" },
 
  281  { ARABIC_OMAN, 
"ARABIC_OMAN" },
 
  282  { ARABIC_YEMEN, 
"ARABIC_YEMEN" },
 
  283  { ARABIC_SYRIA, 
"ARABIC_SYRIA" },
 
  284  { ARABIC_JORDAN, 
"ARABIC_JORDAN" },
 
  285  { ARABIC_LEBANON, 
"ARABIC_LEBANON" },
 
  286  { ARABIC_KUWAIT, 
"ARABIC_KUWAIT" },
 
  287  { ARABIC_UAE, 
"ARABIC_UAE" },
 
  288  { ARABIC_BAHRAIN, 
"ARABIC_BAHRAIN" },
 
  289  { ARABIC_QATAR, 
"ARABIC_QATAR" },
 
  290  { ARMENIAN, 
"ARMENIAN" },
 
  291  { ASSAMESE, 
"ASSAMESE" },
 
  292  { AZERI_LATIN, 
"AZERI_LATIN" },
 
  293  { AZERI_CYRILLIC, 
"AZERI_CYRILLIC" },
 
  294  { BASHKIR, 
"BASHKIR" },
 
  295  { BASQUE, 
"BASQUE" },
 
  296  { BELARUSIAN, 
"BELARUSIAN" },
 
  297  { BENGALI_INDIA, 
"BENGALI_INDIA" },
 
  298  { BOSNIAN_LATIN, 
"BOSNIAN_LATIN" },
 
  299  { BRETON, 
"BRETON" },
 
  300  { BULGARIAN, 
"BULGARIAN" },
 
  301  { CATALAN, 
"CATALAN" },
 
  302  { CHINESE_TAIWAN, 
"CHINESE_TAIWAN" },
 
  303  { CHINESE_PRC, 
"CHINESE_PRC" },
 
  304  { CHINESE_HONG_KONG, 
"CHINESE_HONG_KONG" },
 
  305  { CHINESE_SINGAPORE, 
"CHINESE_SINGAPORE" },
 
  306  { CHINESE_MACAU, 
"CHINESE_MACAU" },
 
  307  { CROATIAN, 
"CROATIAN" },
 
  308  { CROATIAN_BOSNIA_HERZEGOVINA, 
"CROATIAN_BOSNIA_HERZEGOVINA" },
 
  310  { DANISH, 
"DANISH" },
 
  312  { DIVEHI, 
"DIVEHI" },
 
  313  { DUTCH_STANDARD, 
"DUTCH_STANDARD" },
 
  314  { DUTCH_BELGIAN, 
"DUTCH_BELGIAN" },
 
  315  { ENGLISH_UNITED_STATES, 
"ENGLISH_UNITED_STATES" },
 
  316  { ENGLISH_UNITED_KINGDOM, 
"ENGLISH_UNITED_KINGDOM" },
 
  317  { ENGLISH_AUSTRALIAN, 
"ENGLISH_AUSTRALIAN" },
 
  318  { ENGLISH_CANADIAN, 
"ENGLISH_CANADIAN" },
 
  319  { ENGLISH_NEW_ZEALAND, 
"ENGLISH_NEW_ZEALAND" },
 
  320  { ENGLISH_INDIA, 
"ENGLISH_INDIA" },
 
  321  { ENGLISH_IRELAND, 
"ENGLISH_IRELAND" },
 
  322  { ENGLISH_MALAYSIA, 
"ENGLISH_MALAYSIA" },
 
  323  { ENGLISH_SOUTH_AFRICA, 
"ENGLISH_SOUTH_AFRICA" },
 
  324  { ENGLISH_JAMAICA, 
"ENGLISH_JAMAICA" },
 
  325  { ENGLISH_CARIBBEAN, 
"ENGLISH_CARIBBEAN" },
 
  326  { ENGLISH_BELIZE, 
"ENGLISH_BELIZE" },
 
  327  { ENGLISH_TRINIDAD, 
"ENGLISH_TRINIDAD" },
 
  328  { ENGLISH_ZIMBABWE, 
"ENGLISH_ZIMBABWE" },
 
  329  { ENGLISH_PHILIPPINES, 
"ENGLISH_PHILIPPINES" },
 
  330  { ENGLISH_SINGAPORE, 
"ENGLISH_SINGAPORE" },
 
  331  { ESTONIAN, 
"ESTONIAN" },
 
  332  { FAEROESE, 
"FAEROESE" },
 
  334  { FILIPINO, 
"FILIPINO" },
 
  335  { FINNISH, 
"FINNISH" },
 
  336  { FRENCH_STANDARD, 
"FRENCH_STANDARD" },
 
  337  { FRENCH_BELGIAN, 
"FRENCH_BELGIAN" },
 
  338  { FRENCH_CANADIAN, 
"FRENCH_CANADIAN" },
 
  339  { FRENCH_SWISS, 
"FRENCH_SWISS" },
 
  340  { FRENCH_LUXEMBOURG, 
"FRENCH_LUXEMBOURG" },
 
  341  { FRENCH_MONACO, 
"FRENCH_MONACO" },
 
  342  { FRISIAN, 
"FRISIAN" },
 
  343  { GEORGIAN, 
"GEORGIAN" },
 
  344  { GALICIAN, 
"GALICIAN" },
 
  345  { GERMAN_STANDARD, 
"GERMAN_STANDARD" },
 
  346  { GERMAN_SWISS, 
"GERMAN_SWISS" },
 
  347  { GERMAN_AUSTRIAN, 
"GERMAN_AUSTRIAN" },
 
  348  { GERMAN_LUXEMBOURG, 
"GERMAN_LUXEMBOURG" },
 
  349  { GERMAN_LIECHTENSTEIN, 
"GERMAN_LIECHTENSTEIN" },
 
  351  { GREENLANDIC, 
"GREENLANDIC" },
 
  352  { GUJARATI, 
"GUJARATI" },
 
  353  { HEBREW, 
"HEBREW" },
 
  355  { HUNGARIAN, 
"HUNGARIAN" },
 
  356  { ICELANDIC, 
"ICELANDIC" },
 
  358  { INDONESIAN, 
"INDONESIAN" },
 
  360  { ITALIAN_STANDARD, 
"ITALIAN_STANDARD" },
 
  361  { ITALIAN_SWISS, 
"ITALIAN_SWISS" },
 
  362  { JAPANESE, 
"JAPANESE" },
 
  363  { KANNADA, 
"KANNADA" },
 
  364  { KAZAKH, 
"KAZAKH" },
 
  367  { KINYARWANDA, 
"KINYARWANDA" },
 
  368  { KONKANI, 
"KONKANI" },
 
  369  { KOREAN, 
"KOREAN" },
 
  370  { KYRGYZ, 
"KYRGYZ" },
 
  372  { LATVIAN, 
"LATVIAN" },
 
  373  { LITHUANIAN, 
"LITHUANIAN" },
 
  374  { LOWER_SORBIAN, 
"LOWER_SORBIAN" },
 
  375  { LUXEMBOURGISH, 
"LUXEMBOURGISH" },
 
  376  { MACEDONIAN, 
"MACEDONIAN" },
 
  377  { MALAY_MALAYSIA, 
"MALAY_MALAYSIA" },
 
  378  { MALAY_BRUNEI_DARUSSALAM, 
"MALAY_BRUNEI_DARUSSALAM" },
 
  379  { MALAYALAM, 
"MALAYALAM" },
 
  380  { MALTESE, 
"MALTESE" },
 
  381  { MAPUDUNGUN, 
"MAPUDUNGUN" },
 
  383  { MARATHI, 
"MARATHI" },
 
  384  { MOHAWK, 
"MOHAWK" },
 
  385  { MONGOLIAN, 
"MONGOLIAN" },
 
  386  { NEPALI, 
"NEPALI" },
 
  387  { NORWEGIAN_BOKMAL, 
"NORWEGIAN_BOKMAL" },
 
  388  { NORWEGIAN_NYNORSK, 
"NORWEGIAN_NYNORSK" },
 
  389  { OCCITAN, 
"OCCITAN" },
 
  391  { PASHTO, 
"PASHTO" },
 
  392  { POLISH, 
"POLISH" },
 
  393  { PORTUGUESE_BRAZILIAN, 
"PORTUGUESE_BRAZILIAN" },
 
  394  { PORTUGUESE_STANDARD, 
"PORTUGUESE_STANDARD" },
 
  395  { PUNJABI, 
"PUNJABI" },
 
  396  { QUECHUA_BOLIVIA, 
"QUECHUA_BOLIVIA" },
 
  397  { QUECHUA_ECUADOR, 
"QUECHUA_ECUADOR" },
 
  398  { QUECHUA_PERU, 
"QUECHUA_PERU" },
 
  399  { ROMANIAN, 
"ROMANIAN" },
 
  400  { ROMANSH, 
"ROMANSH" },
 
  401  { RUSSIAN, 
"RUSSIAN" },
 
  402  { SAMI_INARI, 
"SAMI_INARI" },
 
  403  { SAMI_LULE_NORWAY, 
"SAMI_LULE_NORWAY" },
 
  404  { SAMI_LULE_SWEDEN, 
"SAMI_LULE_SWEDEN" },
 
  405  { SAMI_NORTHERN_FINLAND, 
"SAMI_NORTHERN_FINLAND" },
 
  406  { SAMI_NORTHERN_NORWAY, 
"SAMI_NORTHERN_NORWAY" },
 
  407  { SAMI_NORTHERN_SWEDEN, 
"SAMI_NORTHERN_SWEDEN" },
 
  408  { SAMI_SKOLT, 
"SAMI_SKOLT" },
 
  409  { SAMI_SOUTHERN_NORWAY, 
"SAMI_SOUTHERN_NORWAY" },
 
  410  { SAMI_SOUTHERN_SWEDEN, 
"SAMI_SOUTHERN_SWEDEN" },
 
  411  { SANSKRIT, 
"SANSKRIT" },
 
  412  { SERBIAN_LATIN, 
"SERBIAN_LATIN" },
 
  413  { SERBIAN_LATIN_BOSNIA_HERZEGOVINA, 
"SERBIAN_LATIN_BOSNIA_HERZEGOVINA" },
 
  414  { SERBIAN_CYRILLIC, 
"SERBIAN_CYRILLIC" },
 
  415  { SERBIAN_CYRILLIC_BOSNIA_HERZEGOVINA, 
"SERBIAN_CYRILLIC_BOSNIA_HERZEGOVINA" },
 
  416  { SESOTHO_SA_LEBOA, 
"SESOTHO_SA_LEBOA" },
 
  417  { SINHALA, 
"SINHALA" },
 
  418  { SLOVAK, 
"SLOVAK" },
 
  419  { SLOVENIAN, 
"SLOVENIAN" },
 
  420  { SPANISH_TRADITIONAL_SORT, 
"SPANISH_TRADITIONAL_SORT" },
 
  421  { SPANISH_MEXICAN, 
"SPANISH_MEXICAN" },
 
  422  { SPANISH_MODERN_SORT, 
"SPANISH_MODERN_SORT" },
 
  423  { SPANISH_GUATEMALA, 
"SPANISH_GUATEMALA" },
 
  424  { SPANISH_COSTA_RICA, 
"SPANISH_COSTA_RICA" },
 
  425  { SPANISH_PANAMA, 
"SPANISH_PANAMA" },
 
  426  { SPANISH_DOMINICAN_REPUBLIC, 
"SPANISH_DOMINICAN_REPUBLIC" },
 
  427  { SPANISH_VENEZUELA, 
"SPANISH_VENEZUELA" },
 
  428  { SPANISH_COLOMBIA, 
"SPANISH_COLOMBIA" },
 
  429  { SPANISH_PERU, 
"SPANISH_PERU" },
 
  430  { SPANISH_ARGENTINA, 
"SPANISH_ARGENTINA" },
 
  431  { SPANISH_ECUADOR, 
"SPANISH_ECUADOR" },
 
  432  { SPANISH_CHILE, 
"SPANISH_CHILE" },
 
  433  { SPANISH_UNITED_STATES, 
"SPANISH_UNITED_STATES" },
 
  434  { SPANISH_URUGUAY, 
"SPANISH_URUGUAY" },
 
  435  { SPANISH_PARAGUAY, 
"SPANISH_PARAGUAY" },
 
  436  { SPANISH_BOLIVIA, 
"SPANISH_BOLIVIA" },
 
  437  { SPANISH_EL_SALVADOR, 
"SPANISH_EL_SALVADOR" },
 
  438  { SPANISH_HONDURAS, 
"SPANISH_HONDURAS" },
 
  439  { SPANISH_NICARAGUA, 
"SPANISH_NICARAGUA" },
 
  440  { SPANISH_PUERTO_RICO, 
"SPANISH_PUERTO_RICO" },
 
  441  { SWAHILI, 
"SWAHILI" },
 
  442  { SWEDISH, 
"SWEDISH" },
 
  443  { SWEDISH_FINLAND, 
"SWEDISH_FINLAND" },
 
  444  { SYRIAC, 
"SYRIAC" },
 
  447  { TELUGU, 
"TELUGU" },
 
  449  { TIBETAN_BHUTAN, 
"TIBETAN_BHUTAN" },
 
  450  { TIBETAN_PRC, 
"TIBETAN_PRC" },
 
  451  { TSWANA, 
"TSWANA" },
 
  452  { UKRAINIAN, 
"UKRAINIAN" },
 
  453  { TURKISH, 
"TURKISH" },
 
  454  { TURKMEN, 
"TURKMEN" },
 
  455  { UIGHUR, 
"UIGHUR" },
 
  456  { UPPER_SORBIAN, 
"UPPER_SORBIAN" },
 
  458  { URDU_INDIA, 
"URDU_INDIA" },
 
  459  { UZBEK_LATIN, 
"UZBEK_LATIN" },
 
  460  { UZBEK_CYRILLIC, 
"UZBEK_CYRILLIC" },
 
  461  { VIETNAMESE, 
"VIETNAMESE" },
 
  467  { YORUBA, 
"YORUBA" },
 
  474  DWORD keyboardLayouts[5]; 
 
  475} LOCALE_KEYBOARD_LAYOUTS;
 
  479static const LOCALE_KEYBOARD_LAYOUTS LOCALE_KEYBOARD_LAYOUTS_TABLE[] = {
 
  480  { AFRIKAANS, { 0x00000409, 0x00000409, 0x0, 0x0, 0x0 } },
 
  481  { ALBANIAN, { 0x0000041c, 0x00000409, 0x0, 0x0, 0x0 } },
 
  482  { ARABIC_SAUDI_ARABIA, { 0x00000409, 0x00000401, 0x0, 0x0, 0x0 } },
 
  483  { ARABIC_IRAQ, { 0x00000409, 0x00000401, 0x0, 0x0, 0x0 } },
 
  484  { ARABIC_EGYPT, { 0x00000409, 0x00000401, 0x0, 0x0, 0x0 } },
 
  485  { ARABIC_LIBYA, { 0x0000040c, 0x00020401, 0x0, 0x0, 0x0 } },
 
  486  { ARABIC_ALGERIA, { 0x0000040c, 0x00020401, 0x0, 0x0, 0x0 } },
 
  487  { ARABIC_MOROCCO, { 0x0000040c, 0x00020401, 0x0, 0x0, 0x0 } },
 
  488  { ARABIC_TUNISIA, { 0x0000040c, 0x00020401, 0x0, 0x0, 0x0 } },
 
  489  { ARABIC_OMAN, { 0x00000409, 0x00000401, 0x0, 0x0, 0x0 } },
 
  490  { ARABIC_YEMEN, { 0x00000409, 0x00000401, 0x0, 0x0, 0x0 } },
 
  491  { ARABIC_SYRIA, { 0x00000409, 0x00000401, 0x0, 0x0, 0x0 } },
 
  492  { ARABIC_JORDAN, { 0x00000409, 0x00000401, 0x0, 0x0, 0x0 } },
 
  493  { ARABIC_LEBANON, { 0x00000409, 0x00000401, 0x0, 0x0, 0x0 } },
 
  494  { ARABIC_KUWAIT, { 0x00000409, 0x00000401, 0x0, 0x0, 0x0 } },
 
  495  { ARABIC_UAE, { 0x00000409, 0x00000401, 0x0, 0x0, 0x0 } },
 
  496  { ARABIC_BAHRAIN, { 0x00000409, 0x00000401, 0x0, 0x0, 0x0 } },
 
  497  { ARABIC_QATAR, { 0x00000409, 0x00000401, 0x0, 0x0, 0x0 } },
 
  498  { ARMENIAN, { 0x0000042b, 0x00000409, 0x00000419, 0x0, 0x0 } },
 
  499  { AZERI_LATIN, { 0x0000042c, 0x0000082c, 0x00000419, 0x0, 0x0 } },
 
  500  { AZERI_CYRILLIC, { 0x0000082c, 0x0000042c, 0x00000419, 0x0, 0x0 } },
 
  501  { BASQUE, { 0x0000040a, 0x00000409, 0x0, 0x0, 0x0 } },
 
  502  { BELARUSIAN, { 0x00000423, 0x00000409, 0x00000419, 0x0, 0x0 } },
 
  503  { BENGALI_INDIA, { 0x00000445, 0x00000409, 0x0, 0x0, 0x0 } },
 
  504  { BOSNIAN_LATIN, { 0x0000141A, 0x00000409, 0x0, 0x0, 0x0 } },
 
  505  { BULGARIAN, { 0x00000402, 0x00000409, 0x0, 0x0, 0x0 } },
 
  506  { CATALAN, { 0x0000040a, 0x00000409, 0x0, 0x0, 0x0 } },
 
  507  { CHINESE_TAIWAN, { 0x00000404, 0xe0080404, 0xE0010404, 0x0, 0x0 } },
 
  508  { CHINESE_PRC, { 0x00000804, 0xe00e0804, 0xe0010804, 0xe0030804, 0xe0040804 } },
 
  509  { CHINESE_HONG_KONG, { 0x00000409, 0xe0080404, 0x0, 0x0, 0x0 } },
 
  510  { CHINESE_SINGAPORE, { 0x00000409, 0xe00e0804, 0xe0010804, 0xe0030804, 0xe0040804 } },
 
  511  { CHINESE_MACAU, { 0x00000409, 0xe00e0804, 0xe0020404, 0xe0080404 } },
 
  512  { CROATIAN, { 0x0000041a, 0x00000409, 0x0, 0x0, 0x0 } },
 
  513  { CROATIAN_BOSNIA_HERZEGOVINA, { 0x0000041a, 0x00000409, 0x0, 0x0, 0x0 } },
 
  514  { CZECH, { 0x00000405, 0x00000409, 0x0, 0x0, 0x0 } },
 
  515  { DANISH, { 0x00000406, 0x00000409, 0x0, 0x0, 0x0 } },
 
  516  { DIVEHI, { 0x00000409, 0x00000465, 0x0, 0x0, 0x0 } },
 
  517  { DUTCH_STANDARD, { 0x00020409, 0x00000413, 0x00000409, 0x0, 0x0 } },
 
  518  { DUTCH_BELGIAN, { 0x00000813, 0x00000409, 0x0, 0x0, 0x0 } },
 
  519  { ENGLISH_UNITED_STATES, { 0x00000409, 0x0, 0x0, 0x0, 0x0 } },
 
  520  { ENGLISH_UNITED_KINGDOM, { 0x00000809, 0x0, 0x0, 0x0, 0x0 } },
 
  521  { ENGLISH_AUSTRALIAN, { 0x00000409, 0x0, 0x0, 0x0, 0x0 } },
 
  522  { ENGLISH_CANADIAN, { 0x00000409, 0x00011009, 0x00001009, 0x0, 0x0 } },
 
  523  { ENGLISH_NEW_ZEALAND, { 0x00000409, 0x0, 0x0, 0x0, 0x0 } },
 
  524  { ENGLISH_IRELAND, { 0x00001809, 0x00011809, 0x0, 0x0, 0x0 } },
 
  525  { ENGLISH_SOUTH_AFRICA, { 0x00000409, 0x0, 0x0, 0x0, 0x0 } },
 
  526  { ENGLISH_JAMAICA, { 0x00000409, 0x0, 0x0, 0x0, 0x0 } },
 
  527  { ENGLISH_CARIBBEAN, { 0x00000409, 0x0, 0x0, 0x0, 0x0 } },
 
  528  { ENGLISH_BELIZE, { 0x00000409, 0x0, 0x0, 0x0, 0x0 } },
 
  529  { ENGLISH_TRINIDAD, { 0x00000409, 0x0, 0x0, 0x0, 0x0 } },
 
  530  { ENGLISH_ZIMBABWE, { 0x00000409, 0x0, 0x0, 0x0, 0x0 } },
 
  531  { ENGLISH_PHILIPPINES, { 0x00000409, 0x0, 0x0, 0x0, 0x0 } },
 
  532  { ESTONIAN, { 0x00000425, 0x0, 0x0, 0x0, 0x0 } },
 
  533  { FAEROESE, { 0x00000406, 0x00000409, 0x0, 0x0, 0x0 } },
 
  534  { FARSI, { 0x00000409, 0x00000429, 0x00000401, 0x0, 0x0 } },
 
  535  { FINNISH, { 0x0000040b, 0x00000409, 0x0, 0x0, 0x0 } },
 
  536  { FRENCH_STANDARD, { 0x0000040c, 0x00000409, 0x0, 0x0, 0x0 } },
 
  537  { FRENCH_BELGIAN, { 0x0000080c, 0x00000409, 0x0, 0x0, 0x0 } },
 
  538  { FRENCH_CANADIAN, { 0x00000C0C, 0x00011009, 0x00000409, 0x0, 0x0 } },
 
  539  { FRENCH_SWISS, { 0x0000100c, 0x00000409, 0x0, 0x0, 0x0 } },
 
  540  { FRENCH_LUXEMBOURG, { 0x0000040c, 0x00000409, 0x0, 0x0, 0x0 } },
 
  541  { FRENCH_MONACO, { 0x0000040c, 0x00000409, 0x0, 0x0, 0x0 } },
 
  542  { GEORGIAN, { 0x00000437, 0x00000409, 0x00000419, 0x0, 0x0 } },
 
  543  { GALICIAN, { 0x0000040a, 0x00000409, 0x0, 0x0, 0x0 } },
 
  544  { GERMAN_STANDARD, { 0x00000407, 0x00000409, 0x0, 0x0, 0x0 } },
 
  545  { GERMAN_SWISS, { 0x00000807, 0x00000409, 0x0, 0x0, 0x0 } },
 
  546  { GERMAN_AUSTRIAN, { 0x00000407, 0x00000409, 0x0, 0x0, 0x0 } },
 
  547  { GERMAN_LUXEMBOURG, { 0x00000407, 0x00000409, 0x0, 0x0, 0x0 } },
 
  548  { GERMAN_LIECHTENSTEIN, { 0x00000407, 0x00000409, 0x0, 0x0, 0x0 } },
 
  549  { GREEK, { 0x00000408, 0x00000409, 0x0, 0x0, 0x0 } },
 
  550  { GUJARATI, { 0x00000409, 0x00000447, 0x00010439, 0x0, 0x0 } },
 
  551  { HEBREW, { 0x00000409, 0x0000040d, 0x0, 0x0, 0x0 } },
 
  552  { HINDI, { 0x00000409, 0x00010439, 0x00000439, 0x0, 0x0 } },
 
  553  { HUNGARIAN, { 0x0000040e, 0x00000409, 0x0, 0x0, 0x0 } },
 
  554  { ICELANDIC, { 0x0000040f, 0x00000409, 0x0, 0x0, 0x0 } },
 
  555  { INDONESIAN, { 0x00000409, 0x00000409, 0x0, 0x0, 0x0 } },
 
  556  { ITALIAN_STANDARD, { 0x00000410, 0x00000409, 0x0, 0x0, 0x0 } },
 
  557  { ITALIAN_SWISS, { 0x00000410, 0x00000409, 0x0, 0x0, 0x0 } },
 
  558  { JAPANESE, { 0xe0010411, 0x0, 0x0, 0x0, 0x0 } },
 
  559  { KANNADA, { 0x00000409, 0x0000044b, 0x00010439, 0x0, 0x0 } },
 
  560  { KAZAKH, { 0x0000043f, 0x00000409, 0x00000419, 0x0, 0x0 } },
 
  561  { KONKANI, { 0x00000409, 0x00000439, 0x0, 0x0, 0x0 } },
 
  562  { KOREAN, { 0xE0010412, 0x0, 0x0, 0x0, 0x0 } },
 
  563  { KYRGYZ, { 0x00000440, 0x00000409, 0x0, 0x0, 0x0 } },
 
  564  { LATVIAN, { 0x00010426, 0x0, 0x0, 0x0, 0x0 } },
 
  565  { LITHUANIAN, { 0x00010427, 0x0, 0x0, 0x0, 0x0 } },
 
  566  { MACEDONIAN, { 0x0000042f, 0x00000409, 0x0, 0x0, 0x0 } },
 
  567  { MALAY_MALAYSIA, { 0x00000409, 0x0, 0x0, 0x0, 0x0 } },
 
  568  { MALAY_BRUNEI_DARUSSALAM, { 0x00000409, 0x0, 0x0, 0x0, 0x0 } },
 
  569  { MALAYALAM, { 0x00000409, 0x0000044c, 0x0, 0x0, 0x0 } },
 
  570  { MALTESE, { 0x00000409, 0x0000043a, 0x0, 0x0, 0x0 } },
 
  571  { MAORI, { 0x00000409, 0x00000481, 0x0, 0x0, 0x0 } },
 
  572  { MARATHI, { 0x00000409, 0x0000044e, 0x00000439, 0x0, 0x0 } },
 
  573  { MONGOLIAN, { 0x00000450, 0x00000409, 0x0, 0x0, 0x0 } },
 
  574  { NORWEGIAN_BOKMAL, { 0x00000414, 0x00000409, 0x0, 0x0, 0x0 } },
 
  575  { NORWEGIAN_NYNORSK, { 0x00000414, 0x00000409, 0x0, 0x0, 0x0 } },
 
  576  { POLISH, { 0x00010415, 0x00000415, 0x00000409, 0x0, 0x0 } },
 
  577  { PORTUGUESE_BRAZILIAN, { 0x00000416, 0x00000409, 0x0, 0x0, 0x0 } },
 
  578  { PORTUGUESE_STANDARD, { 0x00000816, 0x00000409, 0x0, 0x0, 0x0 } },
 
  579  { PUNJABI, { 0x00000409, 0x00000446, 0x00010439, 0x0, 0x0 } },
 
  580  { QUECHUA_BOLIVIA, { 0x00000409, 0x0000080A, 0x0, 0x0, 0x0 } },
 
  581  { QUECHUA_ECUADOR, { 0x00000409, 0x0000080A, 0x0, 0x0, 0x0 } },
 
  582  { QUECHUA_PERU, { 0x00000409, 0x0000080A, 0x0, 0x0, 0x0 } },
 
  583  { ROMANIAN, { 0x00000418, 0x00000409, 0x0, 0x0, 0x0 } },
 
  584  { RUSSIAN, { 0x00000419, 0x00000409, 0x0, 0x0, 0x0 } },
 
  585  { SAMI_INARI, { 0x0001083b, 0x00000409, 0x0, 0x0, 0x0 } },
 
  586  { SAMI_LULE_NORWAY, { 0x0000043b, 0x00000409, 0x0, 0x0, 0x0 } },
 
  587  { SAMI_LULE_SWEDEN, { 0x0000083b, 0x00000409, 0x0, 0x0, 0x0 } },
 
  588  { SAMI_NORTHERN_FINLAND, { 0x0001083b, 0x00000409, 0x0, 0x0, 0x0 } },
 
  589  { SAMI_NORTHERN_NORWAY, { 0x0000043b, 0x00000409, 0x0, 0x0, 0x0 } },
 
  590  { SAMI_NORTHERN_SWEDEN, { 0x0000083b, 0x00000409, 0x0, 0x0, 0x0 } },
 
  591  { SAMI_SKOLT, { 0x0001083b, 0x00000409, 0x0, 0x0, 0x0 } },
 
  592  { SAMI_SOUTHERN_NORWAY, { 0x0000043b, 0x00000409, 0x0, 0x0, 0x0 } },
 
  593  { SAMI_SOUTHERN_SWEDEN, { 0x0000083b, 0x00000409, 0x0, 0x0, 0x0 } },
 
  594  { SANSKRIT, { 0x00000409, 0x00000439, 0x0, 0x0, 0x0 } },
 
  595  { SERBIAN_LATIN, { 0x0000081a, 0x00000409, 0x0, 0x0, 0x0 } },
 
  596  { SERBIAN_LATIN_BOSNIA_HERZEGOVINA, { 0x0000081a, 0x00000409, 0x0, 0x0, 0x0 } },
 
  597  { SERBIAN_CYRILLIC, { 0x00000c1a, 0x00000409, 0x0, 0x0, 0x0 } },
 
  598  { SERBIAN_CYRILLIC_BOSNIA_HERZEGOVINA, { 0x00000c1a, 0x00000409, 0x0, 0x0, 0x0 } },
 
  599  { SLOVAK, { 0x0000041b, 0x00000409, 0x0, 0x0, 0x0 } },
 
  600  { SLOVENIAN, { 0x00000424, 0x00000409, 0x0, 0x0, 0x0 } },
 
  601  { SPANISH_TRADITIONAL_SORT, { 0x0000040a, 0x00000409, 0x0, 0x0, 0x0 } },
 
  602  { SPANISH_MEXICAN, { 0x0000080a, 0x00000409, 0x0, 0x0, 0x0 } },
 
  603  { SPANISH_MODERN_SORT, { 0x0000040a, 0x00000409, 0x0, 0x0, 0x0 } },
 
  604  { SPANISH_GUATEMALA, { 0x0000080a, 0x00000409, 0x0, 0x0, 0x0 } },
 
  605  { SPANISH_COSTA_RICA, { 0x0000080a, 0x00000409, 0x0, 0x0, 0x0 } },
 
  606  { SPANISH_PANAMA, { 0x0000080a, 0x00000409, 0x0, 0x0, 0x0 } },
 
  607  { SPANISH_DOMINICAN_REPUBLIC, { 0x0000080a, 0x00000409, 0x0, 0x0, 0x0 } },
 
  608  { SPANISH_VENEZUELA, { 0x0000080a, 0x00000409, 0x0, 0x0, 0x0 } },
 
  609  { SPANISH_COLOMBIA, { 0x0000080a, 0x00000409, 0x0, 0x0, 0x0 } },
 
  610  { SPANISH_PERU, { 0x0000080a, 0x00000409, 0x0, 0x0, 0x0 } },
 
  611  { SPANISH_ARGENTINA, { 0x0000080a, 0x00000409, 0x0, 0x0, 0x0 } },
 
  612  { SPANISH_ECUADOR, { 0x0000080a, 0x00000409, 0x0, 0x0, 0x0 } },
 
  613  { SPANISH_CHILE, { 0x0000080a, 0x00000409, 0x0, 0x0, 0x0 } },
 
  614  { SPANISH_URUGUAY, { 0x0000080a, 0x00000409, 0x0, 0x0, 0x0 } },
 
  615  { SPANISH_PARAGUAY, { 0x0000080a, 0x00000409, 0x0, 0x0, 0x0 } },
 
  616  { SPANISH_BOLIVIA, { 0x0000080a, 0x00000409, 0x0, 0x0, 0x0 } },
 
  617  { SPANISH_EL_SALVADOR, { 0x0000080a, 0x00000409, 0x0, 0x0, 0x0 } },
 
  618  { SPANISH_HONDURAS, { 0x0000080a, 0x00000409, 0x0, 0x0, 0x0 } },
 
  619  { SPANISH_NICARAGUA, { 0x0000080a, 0x00000409, 0x0, 0x0, 0x0 } },
 
  620  { SPANISH_PUERTO_RICO, { 0x0000080a, 0x00000409, 0x0, 0x0, 0x0 } },
 
  621  { SWAHILI, { 0x00000409, 0x0, 0x0, 0x0, 0x0 } },
 
  622  { SWEDISH, { 0x0000041d, 0x00000409, 0x0, 0x0, 0x0 } },
 
  623  { SWEDISH_FINLAND, { 0x0000041d, 0x00000409, 0x0, 0x0, 0x0 } },
 
  624  { SYRIAC, { 0x00000409, 0x0000045a, 0x0, 0x0, 0x0 } },
 
  625  { TAMIL, { 0x00000409, 0x00000449, 0x0, 0x0, 0x0 } },
 
  626  { TATAR, { 0x00000444, 0x00000409, 0x00000419, 0x0, 0x0 } },
 
  627  { TELUGU, { 0x00000409, 0x0000044a, 0x00010439, 0x0, 0x0 } },
 
  628  { THAI, { 0x00000409, 0x0000041e, 0x0, 0x0, 0x0 } },
 
  629  { TSWANA, { 0x00000409, 0x0000041f, 0x0, 0x0, 0x0 } },
 
  630  { UKRAINIAN, { 0x00000422, 0x00000409, 0x0, 0x0, 0x0 } },
 
  631  { TURKISH, { 0x0000041f, 0x0000041f, 0x0, 0x0, 0x0 } },
 
  632  { UKRAINIAN, { 0x00000422, 0x00000409, 0x0, 0x0, 0x0 } },
 
  633  { URDU, { 0x00000401, 0x00000409, 0x0, 0x0, 0x0 } },
 
  634  { UZBEK_LATIN, { 0x00000409, 0x00000843, 0x00000419, 0x0, 0x0 } },
 
  635  { UZBEK_CYRILLIC, { 0x00000843, 0x00000409, 0x00000419, 0x0, 0x0 } },
 
  636  { VIETNAMESE, { 0x00000409, 0x0000042a, 0x0, 0x0, 0x0 } },
 
  637  { WELSH, { 0x00000452, 0x00000809, 0x0, 0x0, 0x0 } },
 
  638  { XHOSA, { 0x00000409, 0x00000409, 0x0, 0x0, 0x0 } },
 
  641static BOOL freerdp_get_system_language_and_country_codes(
char* language, 
size_t languageLen,
 
  642                                                          char* country, 
size_t countryLen)
 
  644  WINPR_ASSERT(language);
 
  645  WINPR_ASSERT(languageLen > 0);
 
  646  WINPR_ASSERT(country);
 
  647  WINPR_ASSERT(countryLen);
 
  649#if defined(__APPLE__) 
  651    CFStringRef langRef, countryRef;
 
  652    CFLocaleRef localeRef = CFLocaleCopyCurrent();
 
  656    langRef = (CFStringRef)CFLocaleGetValue(localeRef, kCFLocaleLanguageCode);
 
  657    countryRef = (CFStringRef)CFLocaleGetValue(localeRef, kCFLocaleCountryCode);
 
  658    if (!langRef || !countryRef)
 
  660      CFRelease(localeRef);
 
  664    if (!CFStringGetCString(langRef, language, languageLen, kCFStringEncodingUTF8) ||
 
  665        !CFStringGetCString(countryRef, country, countryLen, kCFStringEncodingUTF8))
 
  667      CFRelease(localeRef);
 
  671    CFRelease(localeRef);
 
  678    size_t underscore = 0;
 
  679    char* env_lang = NULL;
 
  680    LPCSTR lang = 
"LANG";
 
  682    nSize = GetEnvironmentVariableA(lang, NULL, 0);
 
  687    env_lang = (
char*)malloc(nSize);
 
  692    if (GetEnvironmentVariableA(lang, env_lang, nSize) !=
 
  699    underscore = strcspn(env_lang, 
"_");
 
  709      size_t len = MIN(languageLen - 1u, underscore);
 
  710      strncpy(language, env_lang, len);
 
  711      language[len] = 
'\0';
 
  714    dot = strcspn(env_lang, 
".");
 
  717    if (dot > underscore)
 
  719      size_t len = MIN(countryLen - 1, dot - underscore - 1);
 
  720      strncpy(country, &env_lang[underscore + 1], len);
 
  735static const SYSTEM_LOCALE* freerdp_detect_system_locale(
void)
 
  737  char language[LOCALE_LANGUAGE_LEN] = { 0 };
 
  738  char country[LOCALE_COUNTRY_LEN] = { 0 };
 
  741  freerdp_get_system_language_and_country_codes(language, ARRAYSIZE(language), country,
 
  744  for (
size_t i = 0; i < ARRAYSIZE(SYSTEM_LOCALE_TABLE); i++)
 
  748    if ((strcmp(language, current->language) == 0) && (strcmp(country, current->country) == 0))
 
  758DWORD freerdp_get_system_locale_id(
void)
 
  761  locale = freerdp_detect_system_locale();
 
  769static const SYSTEM_LOCALE* get_locale_from_str(
const char* name)
 
  771  for (
size_t i = 0; i < ARRAYSIZE(SYSTEM_LOCALE_TABLE); i++)
 
  773    char buffer[LOCALE_LANGUAGE_LEN + LOCALE_COUNTRY_LEN + 2] = { 0 };
 
  776    (void)_snprintf(buffer, 
sizeof(buffer), 
"%s_%s", current->language, current->country);
 
  778    if ((strcmp(name, buffer) == 0))
 
  781    else if ((strcmp(name, current->language) == 0))
 
  787static INT64 get_layout_from_locale(
const SYSTEM_LOCALE* locale)
 
  789  for (
size_t i = 0; i < ARRAYSIZE(LOCALE_KEYBOARD_LAYOUTS_TABLE); i++)
 
  791    const LOCALE_KEYBOARD_LAYOUTS* current = &LOCALE_KEYBOARD_LAYOUTS_TABLE[i];
 
  792    WINPR_ASSERT(current);
 
  794    if (current->locale == locale->code)
 
  797      for (
size_t j = 0; j < 5; j++)
 
  799        if (current->keyboardLayouts[j] == ENGLISH_UNITED_STATES)
 
  803        else if (current->keyboardLayouts[j] == 0)
 
  811            return ENGLISH_UNITED_STATES;
 
  817          return current->keyboardLayouts[j];
 
  824const char* freerdp_get_system_locale_name_from_id(DWORD localeId)
 
  826  for (
size_t index = 0; index < ARRAYSIZE(LOCALE_NAME_TABLE); index++)
 
  828    const LOCALE_NAME* current = &LOCALE_NAME_TABLE[index];
 
  830    if (localeId == current->localeId)
 
  831      return current->name;
 
  837INT64 freerdp_get_locale_id_from_string(
const char* locale)
 
  845int freerdp_detect_keyboard_layout_from_system_locale(DWORD* keyboardLayoutId)
 
  847  char language[LOCALE_LANGUAGE_LEN] = { 0 };
 
  848  char country[LOCALE_COUNTRY_LEN] = { 0 };
 
  850  freerdp_get_system_language_and_country_codes(language, ARRAYSIZE(language), country,
 
  853  char locale[LOCALE_COUNTRY_LEN + LOCALE_LANGUAGE_LEN + 2] = { 0 };
 
  854  (void)_snprintf(locale, 
sizeof(locale), 
"%s_%s", language, country);
 
  855  const int64_t 
id = freerdp_detect_keyboard_layout_from_locale(locale);
 
  858  *keyboardLayoutId = WINPR_ASSERTING_INT_CAST(uint32_t, 
id);
 
  862int64_t freerdp_detect_keyboard_layout_from_locale(
const char* localestr)
 
  864  WINPR_ASSERT(localestr);
 
  866  if ((strcmp(localestr, 
"C") == 0) || (strcmp(localestr, 
"POSIX") == 0))
 
  867    return ENGLISH_UNITED_STATES; 
 
  869  const SYSTEM_LOCALE* locale = get_locale_from_str(localestr);
 
  874  DEBUG_KBD(
"Found locale : %s_%s", locale->language, locale->country);
 
  875  return get_layout_from_locale(locale);
 
  878const SYSTEM_LOCALE* freerdp_get_system_locale_list(
size_t* count)
 
  881  *count = ARRAYSIZE(SYSTEM_LOCALE_TABLE);
 
  882  return SYSTEM_LOCALE_TABLE;
 
  885DWORD freerdp_get_keyboard_default_layout_for_locale(DWORD locale)
 
  887  for (
size_t x = 0; x < ARRAYSIZE(LOCALE_KEYBOARD_LAYOUTS_TABLE); x++)
 
  889    const LOCALE_KEYBOARD_LAYOUTS* cur = &LOCALE_KEYBOARD_LAYOUTS_TABLE[x];
 
  890    if (cur->locale == locale)
 
  891      return cur->keyboardLayouts[0];
 
A SYSTEM_LOCALE holding details about a locale.