Jelajahi Sumber

Add platform specific locale priority enumeration

These functions match the known obs locales with the system supplied
locales and return a vector of possible locales with the highest
priority locale first
Palana 11 tahun lalu
induk
melakukan
e3d7d90115
4 mengubah file dengan 139 tambahan dan 0 penghapusan
  1. 38 0
      obs/platform-osx.mm
  2. 74 0
      obs/platform-windows.cpp
  3. 25 0
      obs/platform-x11.cpp
  4. 2 0
      obs/platform.hpp

+ 38 - 0
obs/platform-osx.mm

@@ -18,6 +18,7 @@
 #include <sstream>
 #include <util/base.h>
 #include "platform.hpp"
+#include "obs-app.hpp"
 
 #include <unistd.h>
 
@@ -91,3 +92,40 @@ string GetDefaultVideoSavePath()
 
 	return url.path.fileSystemRepresentation;
 }
+
+vector<string> GetPreferredLocales()
+{
+	NSArray *preferred = [NSLocale preferredLanguages];
+
+	auto locales = GetLocaleNames();
+	auto lang_to_locale = [&locales](string lang) -> string {
+		string lang_match = "";
+
+		for (const auto &locale : locales) {
+			if (locale.first == lang.substr(0, locale.first.size()))
+				return locale.first;
+
+			if (!lang_match.size() &&
+				locale.first.substr(0, 2) == lang.substr(0, 2))
+				lang_match = locale.first;
+		}
+
+		return lang_match;
+	};
+
+	vector<string> result;
+	result.reserve(preferred.count);
+
+	for (NSString *lang in preferred) {
+		string locale = lang_to_locale(lang.UTF8String);
+		if (!locale.size())
+			continue;
+
+		if (find(begin(result), end(result), locale) != end(result))
+			continue;
+
+		result.emplace_back(locale);
+	}
+
+	return result;
+}

+ 74 - 0
obs/platform-windows.cpp

@@ -15,7 +15,9 @@
     along with this program.  If not, see <http://www.gnu.org/licenses/>.
 ******************************************************************************/
 
+#include <algorithm>
 #include <sstream>
+#include "obs-app.hpp"
 #include "platform.hpp"
 using namespace std;
 
@@ -84,3 +86,75 @@ string GetDefaultVideoSavePath()
 	os_wcs_to_utf8(path_utf16, wcslen(path_utf16), path_utf8, MAX_PATH);
 	return string(path_utf8);
 }
+
+static vector<string> GetUserPreferredLocales()
+{
+	vector<string> result;
+
+	ULONG num, length = 0;
+	if (!GetUserPreferredUILanguages(MUI_LANGUAGE_NAME, &num,
+				nullptr, &length))
+		return result;
+
+	vector<wchar_t> buffer(length);
+	if (!GetUserPreferredUILanguages(MUI_LANGUAGE_NAME, &num,
+				&buffer.front(), &length))
+		return result;
+
+	result.reserve(num);
+	auto start = begin(buffer);
+	auto end_  = end(buffer);
+	decltype(start) separator;
+	while ((separator = find(start, end_, 0)) != end_) {
+		if (result.size() == num)
+			break;
+
+		char conv[MAX_PATH] = {};
+		os_wcs_to_utf8(&*start, separator - start, conv, MAX_PATH);
+
+		result.emplace_back(conv);
+
+		start = separator + 1;
+	}
+
+	return result;
+}
+
+vector<string> GetPreferredLocales()
+{
+	vector<string> windows_locales = GetUserPreferredLocales();
+	auto obs_locales = GetLocaleNames();
+	auto windows_to_obs = [&obs_locales](string windows) {
+		string lang_match;
+
+		for (auto &locale_pair : obs_locales) {
+			auto &locale = locale_pair.first;
+			if (locale == windows.substr(0, locale.size()))
+				return locale;
+
+			if (lang_match.size())
+				continue;
+
+			if (locale.substr(0, 2) == windows.substr(0, 2))
+				lang_match = locale;
+		}
+
+		return lang_match;
+	};
+
+	vector<string> result;
+	result.reserve(obs_locales.size());
+
+	for (const string &locale : windows_locales) {
+		string match = windows_to_obs(locale);
+		if (!match.size())
+			continue;
+
+		if (find(begin(result), end(result), match) != end(result))
+			continue;
+
+		result.emplace_back(match);
+	}
+
+	return result;
+}

+ 25 - 0
obs/platform-x11.cpp

@@ -20,10 +20,13 @@
  * Even if there are not multiple monitors, this should still work.
  */
 
+#include "obs-app.hpp"
+
 #include <X11/Xlib.h>
 #include <X11/extensions/Xinerama.h>
 #include <unistd.h>
 #include <sstream>
+#include <locale.h>
 
 #include "platform.hpp"
 using namespace std;
@@ -106,3 +109,25 @@ string GetDefaultVideoSavePath()
 {
 	return string(getenv("HOME"));
 }
+
+vector<string> GetPreferredLocales()
+{
+	setlocale(LC_ALL, "");
+	string messages = setlocale(LC_MESSAGES, NULL);
+	if (!messages.size() || messages == "C" || messages == "POSIX")
+		return {};
+
+	if (messages.size() > 2)
+		messages[2] = '-';
+
+	for (auto &locale_pair : GetLocaleNames()) {
+		auto &locale = locale_pair.first;
+		if (locale == messages.substr(0, locale.size()))
+			return {locale};
+
+		if (locale.substr(0, 2) == messages.substr(0, 2))
+			return {locale};
+	}
+
+	return {};
+}

+ 2 - 0
obs/platform.hpp

@@ -40,3 +40,5 @@ void GetMonitors(std::vector<MonitorInfo> &monitors);
 bool InitApplicationBundle();
 
 std::string GetDefaultVideoSavePath();
+
+std::vector<std::string> GetPreferredLocales();