|
45 | 45 | #include <shellapi.h> |
46 | 46 | #define WIN32_LEAN_AND_MEAN |
47 | 47 | #include <windows.h> |
| 48 | +#include <mbctype.h> |
48 | 49 | #else |
49 | 50 | #include <signal.h> |
50 | 51 | #endif |
@@ -77,6 +78,7 @@ bool opt_disable_missing_files_check = false; |
77 | 78 | string opt_starting_collection; |
78 | 79 | string opt_starting_profile; |
79 | 80 | string opt_starting_scene; |
| 81 | +bool using_utf8 = false; |
80 | 82 |
|
81 | 83 | bool restart = false; |
82 | 84 | bool restart_safe = false; |
@@ -416,6 +418,42 @@ static void create_log_file(fstream &logFile) |
416 | 418 | } |
417 | 419 | } |
418 | 420 |
|
| 421 | +static bool set_utf8_locale(void) |
| 422 | +{ |
| 423 | + // Use system locale with UTF-8 codepage (available from Windows 10 version 1803) |
| 424 | + bool usingUTF8 = !!setlocale(LC_ALL, ".UTF-8"); |
| 425 | + |
| 426 | + /* |
| 427 | + Fallback to minimal C locale |
| 428 | + Could use "" for system defaults, but the Windows default ANSI codepages (such as .125x or .9xx) |
| 429 | + mismatch with UTF-8 that is assumed by many parts of the codebase. "C" only covers ASCII, so no mismatches. |
| 430 | + */ |
| 431 | + usingUTF8 = usingUTF8 || !!setlocale(LC_ALL, "C.UTF-8"); |
| 432 | + |
| 433 | +#ifdef _WIN32 |
| 434 | + usingUTF8 = usingUTF8 && (_setmbcp(CP_UTF8) == 0); |
| 435 | +#endif |
| 436 | + if (!usingUTF8) { |
| 437 | + setlocale(LC_ALL, "C"); |
| 438 | + } |
| 439 | + |
| 440 | + // fix float handling |
| 441 | + setlocale(LC_NUMERIC, "C"); |
| 442 | + |
| 443 | + // Copy C runtime locale for C++ |
| 444 | + std::locale defaultLocale(setlocale(LC_ALL, nullptr)); |
| 445 | + std::locale::global(defaultLocale); |
| 446 | + |
| 447 | + /* |
| 448 | + system() is already the QLocale default, but just to be explicit about the intention. |
| 449 | + Unlike CRT and C++ locales above, QLocale doesn't support customization of locale categories and codepages. |
| 450 | + Ie. We can't enforce decimal point to be a dot and at the same time use user's preferred locale. |
| 451 | + */ |
| 452 | + QLocale::setDefault(QLocale::system()); |
| 453 | + |
| 454 | + return usingUTF8; |
| 455 | +} |
| 456 | + |
419 | 457 | static auto ProfilerNameStoreRelease = [](profiler_name_store_t *store) { |
420 | 458 | profiler_name_store_free(store); |
421 | 459 | }; |
@@ -533,6 +571,12 @@ static int run_program(fstream &logFile, int argc, char *argv[]) |
533 | 571 | qputenv("QT_NO_SUBTRACTOPAQUESIBLINGS", "1"); |
534 | 572 |
|
535 | 573 | OBSApp program(argc, argv, profilerNameStore.get()); |
| 574 | + |
| 575 | +#if defined(Q_OS_UNIX) |
| 576 | + // OBSApp (QApplication) constructor overwrote the locale for unix, so set it again |
| 577 | + set_utf8_locale(); |
| 578 | +#endif |
| 579 | + |
536 | 580 | try { |
537 | 581 | QAccessible::installFactory(accessibleFactory); |
538 | 582 | QFontDatabase::addApplicationFont(":/fonts/OpenSans-Regular.ttf"); |
@@ -683,6 +727,15 @@ static int run_program(fstream &logFile, int argc, char *argv[]) |
683 | 727 | blog(LOG_INFO, "Command Line Arguments: %s", stor.str().c_str()); |
684 | 728 | } |
685 | 729 |
|
| 730 | + if (!using_utf8) { |
| 731 | + blog(LOG_DEBUG, "UTF-8 locale is not available on this OS version. " |
| 732 | + "Skipping regional formatting and sorting."); |
| 733 | + } |
| 734 | + |
| 735 | + // Use collation (sorting rules) as indicator of regional settings |
| 736 | + blog(LOG_DEBUG, "Locale: %s", setlocale(LC_COLLATE, nullptr)); |
| 737 | + blog(LOG_DEBUG, "App language: %s", program.GetLocale()); |
| 738 | + |
686 | 739 | if (!program.OBSInit()) { |
687 | 740 | return 0; |
688 | 741 | } |
@@ -903,6 +956,7 @@ static void set_process_mitigation_policies() |
903 | 956 |
|
904 | 957 | int main(int argc, char *argv[]) |
905 | 958 | { |
| 959 | + using_utf8 = set_utf8_locale(); |
906 | 960 | #ifndef _WIN32 |
907 | 961 | using SignalHandlerCallback = decltype(OBSApp::sigIntSignalHandler); |
908 | 962 |
|
|
0 commit comments