mirror of
https://github.com/OpenRCT2/OpenRCT2
synced 2026-01-15 11:03:00 +01:00
Honor preferred user language on macOS
This commit is contained in:
@@ -22,7 +22,10 @@
|
||||
#include <dlfcn.h>
|
||||
#include <errno.h>
|
||||
#include <fontconfig/fontconfig.h>
|
||||
#include <fnmatch.h>
|
||||
#include <locale.h>
|
||||
|
||||
#include "../config.h"
|
||||
#include "../localisation/language.h"
|
||||
#include "../localisation/string_ids.h"
|
||||
#include "../util/util.h"
|
||||
@@ -148,6 +151,66 @@ void platform_posix_sub_resolve_openrct_data_path(utf8 *out) {
|
||||
}
|
||||
}
|
||||
|
||||
uint16 platform_get_locale_language(){
|
||||
const char *langString = setlocale(LC_MESSAGES, "");
|
||||
if(langString != NULL){
|
||||
// The locale has the following form:
|
||||
// language[_territory[.codeset]][@modifier]
|
||||
// (see https://www.gnu.org/software/libc/manual/html_node/Locale-Names.html)
|
||||
// longest on my system is 29 with codeset and modifier, so 32 for the pattern should be more than enough
|
||||
char pattern[32];
|
||||
//strip the codeset and modifier part
|
||||
int length = strlen(langString);
|
||||
{
|
||||
for(int i = 0; i < length; ++i){
|
||||
if(langString[i] == '.' || langString[i] == '@'){
|
||||
length = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} //end strip
|
||||
strncpy(pattern,langString, length); //copy all until first '.' or '@'
|
||||
pattern[length] = '\0';
|
||||
//find _ if present
|
||||
const char *strip = strchr(pattern, '_');
|
||||
if(strip != NULL){
|
||||
// could also use '-', but '?' is more flexible. Maybe LanguagesDescriptors will change.
|
||||
// pattern is now "language?territory"
|
||||
pattern[strip - pattern] = '?';
|
||||
}
|
||||
|
||||
// Iterate through all available languages
|
||||
for(int i = 1; i < LANGUAGE_COUNT; ++i){
|
||||
if(!fnmatch(pattern, LanguagesDescriptors[i].locale, 0)){
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
//special cases :(
|
||||
if(!fnmatch(pattern, "en_CA", 0)){
|
||||
return LANGUAGE_ENGLISH_US;
|
||||
}
|
||||
else if (!fnmatch(pattern, "zh_CN", 0)){
|
||||
return LANGUAGE_CHINESE_SIMPLIFIED;
|
||||
}
|
||||
else if (!fnmatch(pattern, "zh_TW", 0)){
|
||||
return LANGUAGE_CHINESE_TRADITIONAL;
|
||||
}
|
||||
|
||||
//no exact match found trying only language part
|
||||
if(strip != NULL){
|
||||
pattern[strip - pattern] = '*';
|
||||
pattern[strip - pattern +1] = '\0'; // pattern is now "language*"
|
||||
for(int i = 1; i < LANGUAGE_COUNT; ++i){
|
||||
if(!fnmatch(pattern, LanguagesDescriptors[i].locale, 0)){
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return LANGUAGE_ENGLISH_UK;
|
||||
}
|
||||
|
||||
uint8 platform_get_locale_currency(){
|
||||
char *langstring = setlocale(LC_MONETARY, "");
|
||||
|
||||
|
||||
@@ -21,7 +21,8 @@
|
||||
#include <mach-o/dyld.h>
|
||||
#include "platform.h"
|
||||
#include "../util/util.h"
|
||||
#include "config.h"
|
||||
#include "../localisation/language.h"
|
||||
#include "../config.h"
|
||||
|
||||
bool platform_check_steam_overlay_attached() {
|
||||
STUB();
|
||||
@@ -192,6 +193,65 @@ bool platform_get_font_path(TTFFontDescriptor *font, utf8 *buffer)
|
||||
}
|
||||
}
|
||||
|
||||
bool platform_has_matching_language(NSString *preferredLocale, uint16* languageIdentifier)
|
||||
{
|
||||
@autoreleasepool
|
||||
{
|
||||
if ([preferredLocale isEqualToString:@"en"] || [preferredLocale isEqualToString:@"en-CA"]) {
|
||||
*languageIdentifier = LANGUAGE_ENGLISH_US;
|
||||
return YES;
|
||||
}
|
||||
|
||||
if ([preferredLocale isEqualToString:@"zh-CN"]) {
|
||||
*languageIdentifier = LANGUAGE_CHINESE_SIMPLIFIED;
|
||||
return YES;
|
||||
}
|
||||
|
||||
if ([preferredLocale isEqualToString:@"zh-TW"]) {
|
||||
*languageIdentifier = LANGUAGE_CHINESE_TRADITIONAL;
|
||||
return YES;
|
||||
}
|
||||
|
||||
// Find an exact match (language and region)
|
||||
for (int i = 1; i < LANGUAGE_COUNT; i++) {
|
||||
if([preferredLocale isEqualToString:[NSString stringWithUTF8String:LanguagesDescriptors[i].locale]]) {
|
||||
*languageIdentifier = i;
|
||||
return YES;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Only check for a matching language
|
||||
NSString *languageCode = [[preferredLocale componentsSeparatedByString:@"-"] firstObject];
|
||||
for (int i = 1; i < LANGUAGE_COUNT; i++) {
|
||||
NSString *optionLanguageCode = [[[NSString stringWithUTF8String:LanguagesDescriptors[i].locale] componentsSeparatedByString:@"-"] firstObject];
|
||||
if([languageCode isEqualToString:optionLanguageCode]) {
|
||||
*languageIdentifier = i;
|
||||
return YES;
|
||||
}
|
||||
}
|
||||
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
|
||||
uint16 platform_get_locale_language()
|
||||
{
|
||||
@autoreleasepool
|
||||
{
|
||||
NSArray<NSString*> *preferredLanguages = [NSLocale preferredLanguages];
|
||||
for (NSString *preferredLanguage in preferredLanguages) {
|
||||
uint16 languageIdentifier;
|
||||
if (platform_has_matching_language(preferredLanguage, &languageIdentifier)) {
|
||||
return languageIdentifier;
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback
|
||||
return LANGUAGE_ENGLISH_UK;
|
||||
}
|
||||
}
|
||||
|
||||
uint8 platform_get_locale_currency()
|
||||
{
|
||||
@autoreleasepool
|
||||
|
||||
@@ -33,8 +33,6 @@
|
||||
#include "../util/util.h"
|
||||
#include "platform.h"
|
||||
#include <dirent.h>
|
||||
#include <fnmatch.h>
|
||||
#include <locale.h>
|
||||
#include <sys/time.h>
|
||||
#include <time.h>
|
||||
#include <fts.h>
|
||||
@@ -795,66 +793,6 @@ void platform_get_user_directory(utf8 *outPath, const utf8 *subDirectory)
|
||||
log_verbose("outPath + subDirectory = '%s'", buffer);
|
||||
}
|
||||
|
||||
uint16 platform_get_locale_language(){
|
||||
const char *langString = setlocale(LC_MESSAGES, "");
|
||||
if(langString != NULL){
|
||||
// The locale has the following form:
|
||||
// language[_territory[.codeset]][@modifier]
|
||||
// (see https://www.gnu.org/software/libc/manual/html_node/Locale-Names.html)
|
||||
// longest on my system is 29 with codeset and modifier, so 32 for the pattern should be more than enough
|
||||
char pattern[32];
|
||||
//strip the codeset and modifier part
|
||||
int length = strlen(langString);
|
||||
{
|
||||
for(int i = 0; i < length; ++i){
|
||||
if(langString[i] == '.' || langString[i] == '@'){
|
||||
length = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} //end strip
|
||||
strncpy(pattern,langString, length); //copy all until first '.' or '@'
|
||||
pattern[length] = '\0';
|
||||
//find _ if present
|
||||
const char *strip = strchr(pattern, '_');
|
||||
if(strip != NULL){
|
||||
// could also use '-', but '?' is more flexible. Maybe LanguagesDescriptors will change.
|
||||
// pattern is now "language?territory"
|
||||
pattern[strip - pattern] = '?';
|
||||
}
|
||||
|
||||
// Iterate through all available languages
|
||||
for(int i = 1; i < LANGUAGE_COUNT; ++i){
|
||||
if(!fnmatch(pattern, LanguagesDescriptors[i].locale, 0)){
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
//special cases :(
|
||||
if(!fnmatch(pattern, "en_CA", 0)){
|
||||
return LANGUAGE_ENGLISH_US;
|
||||
}
|
||||
else if (!fnmatch(pattern, "zh_CN", 0)){
|
||||
return LANGUAGE_CHINESE_SIMPLIFIED;
|
||||
}
|
||||
else if (!fnmatch(pattern, "zh_TW", 0)){
|
||||
return LANGUAGE_CHINESE_TRADITIONAL;
|
||||
}
|
||||
|
||||
//no exact match found trying only language part
|
||||
if(strip != NULL){
|
||||
pattern[strip - pattern] = '*';
|
||||
pattern[strip - pattern +1] = '\0'; // pattern is now "language*"
|
||||
for(int i = 1; i < LANGUAGE_COUNT; ++i){
|
||||
if(!fnmatch(pattern, LanguagesDescriptors[i].locale, 0)){
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return LANGUAGE_ENGLISH_UK;
|
||||
}
|
||||
|
||||
time_t platform_file_get_modified_time(const utf8* path){
|
||||
struct stat buf;
|
||||
if (stat(path, &buf) == 0) {
|
||||
|
||||
Reference in New Issue
Block a user