Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 1 addition & 18 deletions frontend/OBSApp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,7 @@ string CurrentDateTimeString()
struct tm tstruct;
char buf[80];
tstruct = *localtime(&now);
strftime(buf, sizeof(buf), "%Y-%m-%d, %X", &tstruct);
strftime(buf, sizeof(buf), "%Y-%m-%d, %H:%M:%S", &tstruct);
return buf;
}

Expand Down Expand Up @@ -724,11 +724,6 @@ bool OBSApp::InitLocale()

locale = lang;

// set basic default application locale
if (!locale.empty()) {
QLocale::setDefault(QLocale(QString::fromStdString(locale).replace('-', '_')));
}

string englishPath;
if (!GetDataFilePath("locale/" DEFAULT_LANG ".ini", englishPath)) {
OBSErrorBox(NULL, "Failed to find locale/" DEFAULT_LANG ".ini");
Expand Down Expand Up @@ -768,11 +763,6 @@ bool OBSApp::InitLocale()
blog(LOG_INFO, "Using preferred locale '%s'", locale_.c_str());
locale = locale_;

// set application default locale to the new chosen one
if (!locale.empty()) {
QLocale::setDefault(QLocale(QString::fromStdString(locale).replace('-', '_')));
}

return true;
}

Expand Down Expand Up @@ -914,13 +904,6 @@ OBSApp::OBSApp(int &argc, char **argv, profiler_name_store_t *store)
{
installNativeEventFilter(new OBS::NativeEventFilter);

/* fix float handling */
#if defined(Q_OS_UNIX)
if (!setlocale(LC_NUMERIC, "C")) {
blog(LOG_WARNING, "Failed to set LC_NUMERIC to C locale");
}
#endif

#ifndef _WIN32
// Add POSIX signal handlers:
// * SIGINT
Expand Down
6 changes: 3 additions & 3 deletions frontend/OBSApp_Themes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -384,7 +384,7 @@ static vector<OBSThemeVariable> ParseThemeVariables(const char *themeData)

/* Look for a suffix and mark variable as size if it exists */
while (ch < end) {
if (!isdigit(*ch) && !isspace(*ch) && *ch != '.') {
if (!isdigit((unsigned char)*ch) && !isspace((unsigned char)*ch) && *ch != '.') {
var.suffix = QString::fromUtf8(ch, end - ch);
var.type = OBSThemeVariable::Size;
break;
Expand Down Expand Up @@ -581,14 +581,14 @@ static OBSThemeVariable ParseMathVariable(const QHash<QString, OBSThemeVariable>
const QByteArray utf8 = value.toUtf8();
const char *data = utf8.constData();

if (isdigit(*data)) {
if (isdigit((unsigned char)*data)) {
double f = os_strtod(data);
var.type = OBSThemeVariable::Number;
var.value = f;

const char *dataEnd = data + utf8.size();
while (data < dataEnd) {
if (*data && !isdigit(*data) && *data != '.') {
if (*data && !isdigit((unsigned char)*data) && *data != '.') {
var.suffix = QString::fromUtf8(data, dataEnd - data);
var.type = OBSThemeVariable::Size;
break;
Expand Down
5 changes: 5 additions & 0 deletions frontend/cmake/windows/obs.manifest
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@
</requestedPrivileges>
</security>
</trustInfo>
<application>
<windowsSettings>
<activeCodePage xmlns="http://schemas.microsoft.com/SMI/2019/WindowsSettings">UTF-8</activeCodePage>
</windowsSettings>
</application>
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
<application>
<!-- Windows 10 and Windows 11 -->
Expand Down
54 changes: 54 additions & 0 deletions frontend/obs-main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
#include <shellapi.h>
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <mbctype.h>
#else
#include <signal.h>
#endif
Expand Down Expand Up @@ -77,6 +78,7 @@ bool opt_disable_missing_files_check = false;
string opt_starting_collection;
string opt_starting_profile;
string opt_starting_scene;
bool using_utf8 = false;

bool restart = false;
bool restart_safe = false;
Expand Down Expand Up @@ -416,6 +418,42 @@ static void create_log_file(fstream &logFile)
}
}

static bool set_utf8_locale(void)
{
// Use system locale with UTF-8 codepage (available from Windows 10 version 1803)
bool usingUTF8 = !!setlocale(LC_ALL, ".UTF-8");

/*
Fallback to minimal C locale
Could use "" for system defaults, but the Windows default ANSI codepages (such as .125x or .9xx)
mismatch with UTF-8 that is assumed by many parts of the codebase. "C" only covers ASCII, so no mismatches.
*/
usingUTF8 = usingUTF8 || !!setlocale(LC_ALL, "C.UTF-8");

#ifdef _WIN32
usingUTF8 = usingUTF8 && (_setmbcp(CP_UTF8) == 0);
#endif
if (!usingUTF8) {
setlocale(LC_ALL, "C");
}

// fix float handling
setlocale(LC_NUMERIC, "C");

// Copy C runtime locale for C++
std::locale defaultLocale(setlocale(LC_ALL, nullptr));
std::locale::global(defaultLocale);

/*
system() is already the QLocale default, but just to be explicit about the intention.
Unlike CRT and C++ locales above, QLocale doesn't support customization of locale categories and codepages.
Ie. We can't enforce decimal point to be a dot and at the same time use user's preferred locale.
*/
QLocale::setDefault(QLocale::system());

return usingUTF8;
}

static auto ProfilerNameStoreRelease = [](profiler_name_store_t *store) {
profiler_name_store_free(store);
};
Expand Down Expand Up @@ -533,6 +571,12 @@ static int run_program(fstream &logFile, int argc, char *argv[])
qputenv("QT_NO_SUBTRACTOPAQUESIBLINGS", "1");

OBSApp program(argc, argv, profilerNameStore.get());

#if defined(Q_OS_UNIX)
// OBSApp (QApplication) constructor overwrote the locale for unix, so set it again
set_utf8_locale();
#endif

try {
QAccessible::installFactory(accessibleFactory);
QFontDatabase::addApplicationFont(":/fonts/OpenSans-Regular.ttf");
Expand Down Expand Up @@ -683,6 +727,15 @@ static int run_program(fstream &logFile, int argc, char *argv[])
blog(LOG_INFO, "Command Line Arguments: %s", stor.str().c_str());
}

if (!using_utf8) {
blog(LOG_DEBUG, "UTF-8 locale is not available on this OS version. "
"Skipping regional formatting and sorting.");
}

// Use collation (sorting rules) as indicator of regional settings
blog(LOG_DEBUG, "Locale: %s", setlocale(LC_COLLATE, nullptr));
blog(LOG_DEBUG, "App language: %s", program.GetLocale());

if (!program.OBSInit()) {
return 0;
}
Expand Down Expand Up @@ -903,6 +956,7 @@ static void set_process_mitigation_policies()

int main(int argc, char *argv[])
{
using_utf8 = set_utf8_locale();
#ifndef _WIN32
using SignalHandlerCallback = decltype(OBSApp::sigIntSignalHandler);

Expand Down
2 changes: 1 addition & 1 deletion libobs/obs-win-crash-handler.c
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ static inline void write_header(struct exception_handler_data *data)
time_t now = time(0);
struct tm ts;
ts = *localtime(&now);
strftime(date_time, sizeof(date_time), "%Y-%m-%d, %X", &ts);
strftime(date_time, sizeof(date_time), "%Y-%m-%d, %H:%M:%S", &ts);

const char *obs_bitness;
if (sizeof(void *) == 8)
Expand Down
5 changes: 4 additions & 1 deletion libobs/obs.h
Original file line number Diff line number Diff line change
Expand Up @@ -382,8 +382,11 @@ EXPORT const char *obs_get_version_string(void);
* and safely copies argv/argc from main(). Subsequent calls do nothing.
*
* @param argc The count of command line arguments, from main()
* @param argv An array of command line arguments, copied from main() and ends
* @param argv An array of command line arguments in UTF-8, copied from main() and ends
* with NULL.
*
* On Windows this requires that active code page is UTF-8.
* For example as a declaration in obs.manifest.
*/
EXPORT void obs_set_cmdline_args(int argc, const char *const *argv);

Expand Down
2 changes: 1 addition & 1 deletion libobs/util/cf-lexer.c
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ static inline void cf_convert_from_escape_literal(char **p_dst, const char **p_s

/* oct */
default:
if (isdigit(*src)) {
if (isdigit((unsigned char)*src)) {
*(dst++) = (char)strtoul(src, NULL, 8);
src += 3;
}
Expand Down
12 changes: 6 additions & 6 deletions libobs/util/dstr.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ int astrcmpi(const char *str1, const char *str2)
str2 = astrblank;

do {
char ch1 = (char)toupper(*str1);
char ch2 = (char)toupper(*str2);
unsigned char ch1 = (unsigned char)toupper((unsigned char)*str1);
unsigned char ch2 = (unsigned char)toupper((unsigned char)*str2);

if (ch1 < ch2)
return -1;
Expand Down Expand Up @@ -85,8 +85,8 @@ int astrcmp_n(const char *str1, const char *str2, size_t n)
str2 = astrblank;

do {
char ch1 = *str1;
char ch2 = *str2;
unsigned char ch1 = (unsigned char)*str1;
unsigned char ch2 = (unsigned char)*str2;

if (ch1 < ch2)
return -1;
Expand Down Expand Up @@ -129,8 +129,8 @@ int astrcmpi_n(const char *str1, const char *str2, size_t n)
str2 = astrblank;

do {
char ch1 = (char)toupper(*str1);
char ch2 = (char)toupper(*str2);
unsigned char ch1 = (unsigned char)toupper((unsigned char)*str1);
unsigned char ch2 = (unsigned char)toupper((unsigned char)*str2);

if (ch1 < ch2)
return -1;
Expand Down
20 changes: 12 additions & 8 deletions libobs/util/lexer.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ int strref_cmp(const struct strref *str1, const char *str2)
str2 = astrblank;

do {
char ch1, ch2;
unsigned char ch1;
unsigned char ch2;

ch1 = (i < str1->len) ? str1->array[i] : 0;
ch2 = *str2;
Expand All @@ -53,10 +54,11 @@ int strref_cmpi(const struct strref *str1, const char *str2)
str2 = astrblank;

do {
char ch1, ch2;
unsigned char ch1;
unsigned char ch2;

ch1 = (i < str1->len) ? (char)toupper(str1->array[i]) : 0;
ch2 = (char)toupper(*str2);
ch1 = (i < str1->len) ? (unsigned char)toupper((unsigned char)str1->array[i]) : 0;
ch2 = (unsigned char)toupper((unsigned char)*str2);

if (ch1 < ch2)
return -1;
Expand All @@ -77,7 +79,8 @@ int strref_cmp_strref(const struct strref *str1, const struct strref *str2)
return -1;

do {
char ch1, ch2;
unsigned char ch1;
unsigned char ch2;

ch1 = (i < str1->len) ? str1->array[i] : 0;
ch2 = (i < str2->len) ? str2->array[i] : 0;
Expand All @@ -103,10 +106,11 @@ int strref_cmpi_strref(const struct strref *str1, const struct strref *str2)
return -1;

do {
char ch1, ch2;
unsigned char ch1;
unsigned char ch2;

ch1 = (i < str1->len) ? (char)toupper(str1->array[i]) : 0;
ch2 = (i < str2->len) ? (char)toupper(str2->array[i]) : 0;
ch1 = (i < str1->len) ? (unsigned char)toupper((unsigned char)str1->array[i]) : 0;
ch2 = (i < str2->len) ? (unsigned char)toupper((unsigned char)str2->array[i]) : 0;

if (ch1 < ch2)
return -1;
Expand Down
4 changes: 2 additions & 2 deletions plugins/text-freetype2/find-font.c
Original file line number Diff line number Diff line change
Expand Up @@ -333,8 +333,8 @@ static inline size_t get_rating(struct font_path_info *info, struct dstr *cmp)
size_t num = 0;

do {
char ch1 = (char)toupper(*src);
char ch2 = (char)toupper(*dst);
unsigned char ch1 = (unsigned char)toupper((unsigned char)*src);
unsigned char ch2 = (unsigned char)toupper((unsigned char)*dst);

if (ch1 != ch2)
break;
Expand Down