diff --git a/common/Makefile.am.inc b/common/Makefile.am.inc
index 7f9af9561..d08b8d12d 100644
--- a/common/Makefile.am.inc
+++ b/common/Makefile.am.inc
@@ -160,6 +160,8 @@ libflatpak_common_la_SOURCES = \
common/flatpak-json-oci.c \
common/flatpak-json-private.h \
common/flatpak-json.c \
+ common/flatpak-locale-utils-private.h \
+ common/flatpak-locale-utils.c \
common/flatpak-metadata-private.h \
common/flatpak-oci-registry-private.h \
common/flatpak-oci-registry.c \
diff --git a/common/flatpak-dir-private.h b/common/flatpak-dir-private.h
index 59ae500ac..2f7cf8971 100644
--- a/common/flatpak-dir-private.h
+++ b/common/flatpak-dir-private.h
@@ -1053,20 +1053,4 @@ char ** flatpak_dir_list_unused_refs (Fla
GCancellable *cancellable,
GError **error);
-const GPtrArray *flatpak_get_system_locales (void);
-const GPtrArray *flatpak_get_user_locales (void);
-
-/* Only for regression tests, should not be used directly */
-GDBusProxy *flatpak_locale_get_localed_dbus_proxy (void);
-void flatpak_get_locale_langs_from_localed_dbus (GDBusProxy *proxy,
- GPtrArray *langs);
-GDBusProxy *flatpak_locale_get_accounts_dbus_proxy (void);
-gboolean flatpak_get_all_langs_from_accounts_dbus (GDBusProxy *proxy,
- GPtrArray *langs);
-void flatpak_get_locale_langs_from_accounts_dbus (GDBusProxy *proxy,
- GPtrArray *langs);
-void flatpak_get_locale_langs_from_accounts_dbus_for_user (GDBusProxy *proxy,
- GPtrArray *langs,
- guint uid);
-
#endif /* __FLATPAK_DIR_H__ */
diff --git a/common/flatpak-dir.c b/common/flatpak-dir.c
index faa086da2..f6a2f872a 100644
--- a/common/flatpak-dir.c
+++ b/common/flatpak-dir.c
@@ -50,6 +50,7 @@
#include "flatpak-appdata-private.h"
#include "flatpak-dir-private.h"
#include "flatpak-error.h"
+#include "flatpak-locale-utils-private.h"
#include "flatpak-oci-registry-private.h"
#include "flatpak-ref.h"
#include "flatpak-run-private.h"
@@ -16096,243 +16097,6 @@ flatpak_dir_get_remote_auto_install_authenticator_ref (FlatpakDir *self,
return g_steal_pointer (&ref);
}
-
-GDBusProxy *
-flatpak_locale_get_localed_dbus_proxy (void)
-{
- const char *localed_bus_name = "org.freedesktop.locale1";
- const char *localed_object_path = "/org/freedesktop/locale1";
- const char *localed_interface_name = localed_bus_name;
-
- return g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
- G_DBUS_PROXY_FLAGS_NONE,
- NULL,
- localed_bus_name,
- localed_object_path,
- localed_interface_name,
- NULL,
- NULL);
-}
-
-void
-flatpak_get_locale_langs_from_localed_dbus (GDBusProxy *proxy, GPtrArray *langs)
-{
- g_autoptr(GVariant) locale_variant = NULL;
- g_autofree const gchar **strv = NULL;
- gsize i, j;
-
- locale_variant = g_dbus_proxy_get_cached_property (proxy, "Locale");
- if (locale_variant == NULL)
- return;
-
- strv = g_variant_get_strv (locale_variant, NULL);
-
- for (i = 0; strv[i]; i++)
- {
- const gchar *locale = NULL;
- g_autofree char *lang = NULL;
-
- const char * const *categories = flatpak_get_locale_categories ();
-
- for (j = 0; categories[j]; j++)
- {
- g_autofree char *prefix = g_strdup_printf ("%s=", categories[j]);
- if (g_str_has_prefix (strv[i], prefix))
- {
- locale = strv[i] + strlen (prefix);
- break;
- }
- }
-
- if (locale == NULL || strcmp (locale, "") == 0)
- continue;
-
- lang = flatpak_get_lang_from_locale (locale);
- if (lang != NULL && !flatpak_g_ptr_array_contains_string (langs, lang))
- g_ptr_array_add (langs, g_steal_pointer (&lang));
- }
-}
-
-GDBusProxy *
-flatpak_locale_get_accounts_dbus_proxy (void)
-{
- const char *accounts_bus_name = "org.freedesktop.Accounts";
- const char *accounts_object_path = "/org/freedesktop/Accounts";
- const char *accounts_interface_name = accounts_bus_name;
-
- return g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
- G_DBUS_PROXY_FLAGS_NONE,
- NULL,
- accounts_bus_name,
- accounts_object_path,
- accounts_interface_name,
- NULL,
- NULL);
-}
-
-gboolean
-flatpak_get_all_langs_from_accounts_dbus (GDBusProxy *proxy, GPtrArray *langs)
-{
- g_auto(GStrv) all_langs = NULL;
- int i;
- g_autoptr(GVariant) ret = NULL;
- g_autoptr(GError) error = NULL;
-
- ret = g_dbus_proxy_call_sync (G_DBUS_PROXY (proxy),
- "GetUsersLanguages",
- g_variant_new ("()"),
- G_DBUS_CALL_FLAGS_NONE,
- -1,
- NULL,
- &error);
- if (!ret)
- {
- g_debug ("Failed to get languages for all users: %s", error->message);
- return FALSE;
- }
-
- g_variant_get (ret,
- "(^as)",
- &all_langs);
-
- if (all_langs != NULL)
- {
- for (i = 0; all_langs[i] != NULL; i++)
- {
- g_autofree char *lang = NULL;
- lang = flatpak_get_lang_from_locale (all_langs[i]);
- if (lang != NULL && !flatpak_g_ptr_array_contains_string (langs, lang))
- g_ptr_array_add (langs, g_steal_pointer (&lang));
- }
- }
-
- return TRUE;
-}
-
-void
-flatpak_get_locale_langs_from_accounts_dbus (GDBusProxy *proxy, GPtrArray *langs)
-{
- const char *accounts_bus_name = "org.freedesktop.Accounts";
- const char *accounts_interface_name = "org.freedesktop.Accounts.User";
- g_auto(GStrv) object_paths = NULL;
- int i;
- g_autoptr(GVariant) ret = NULL;
-
- ret = g_dbus_proxy_call_sync (G_DBUS_PROXY (proxy),
- "ListCachedUsers",
- g_variant_new ("()"),
- G_DBUS_CALL_FLAGS_NONE,
- -1,
- NULL,
- NULL);
- if (ret != NULL)
- g_variant_get (ret,
- "(^ao)",
- &object_paths);
-
- if (object_paths != NULL)
- {
- for (i = 0; object_paths[i] != NULL; i++)
- {
- g_autoptr(GDBusProxy) accounts_proxy = NULL;
- g_autoptr(GVariant) value = NULL;
-
- accounts_proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
- G_DBUS_PROXY_FLAGS_NONE,
- NULL,
- accounts_bus_name,
- object_paths[i],
- accounts_interface_name,
- NULL,
- NULL);
-
- if (accounts_proxy)
- {
- value = g_dbus_proxy_get_cached_property (accounts_proxy, "Language");
- if (value != NULL)
- {
- const char *locale = g_variant_get_string (value, NULL);
- g_autofree char *lang = NULL;
-
- if (strcmp (locale, "") == 0)
- continue; /* This user wants the system default locale */
-
- lang = flatpak_get_lang_from_locale (locale);
- if (lang != NULL && !flatpak_g_ptr_array_contains_string (langs, lang))
- g_ptr_array_add (langs, g_steal_pointer (&lang));
- }
- }
- }
- }
-}
-
-void
-flatpak_get_locale_langs_from_accounts_dbus_for_user (GDBusProxy *proxy, GPtrArray *langs, guint uid)
-{
- const char *accounts_bus_name = "org.freedesktop.Accounts";
- const char *accounts_interface_name = "org.freedesktop.Accounts.User";
- g_autofree char *object_path = NULL;
- g_autoptr(GVariant) ret = NULL;
-
- ret = g_dbus_proxy_call_sync (G_DBUS_PROXY (proxy),
- "FindUserById",
- g_variant_new ("(x)", uid),
- G_DBUS_CALL_FLAGS_NONE,
- -1,
- NULL,
- NULL);
- if (ret != NULL)
- g_variant_get (ret, "(o)", &object_path);
-
- if (object_path != NULL)
- {
- g_autoptr(GDBusProxy) accounts_proxy = NULL;
- g_autoptr(GVariant) value = NULL;
-
- accounts_proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
- G_DBUS_PROXY_FLAGS_NONE,
- NULL,
- accounts_bus_name,
- object_path,
- accounts_interface_name,
- NULL,
- NULL);
- if (!accounts_proxy)
- return;
-
- value = g_dbus_proxy_get_cached_property (accounts_proxy, "Languages");
- if (value != NULL)
- {
- const char **locales = g_variant_get_strv (value, NULL);
- guint i;
-
- for (i = 0; locales != NULL && locales[i] != NULL; i++)
- {
- g_autofree char *lang = NULL;
- lang = flatpak_get_lang_from_locale (locales[i]);
- if (lang != NULL && !flatpak_g_ptr_array_contains_string (langs, lang))
- g_ptr_array_add (langs, g_steal_pointer (&lang));
- }
- }
- else
- {
- value = g_dbus_proxy_get_cached_property (accounts_proxy, "Language");
- if (value != NULL)
- {
- const char *locale = g_variant_get_string (value, NULL);
- g_autofree char *lang = NULL;
-
- if (strcmp (locale, "") != 0)
- {
- lang = flatpak_get_lang_from_locale (locale);
- if (lang != NULL && !flatpak_g_ptr_array_contains_string (langs, lang))
- g_ptr_array_add (langs, g_steal_pointer (&lang));
- }
- }
- }
- }
-}
-
static int
cmpstringp (const void *p1, const void *p2)
{
@@ -16363,65 +16127,6 @@ flatpak_dir_get_config_strv (FlatpakDir *self, char *key)
return NULL;
}
-const GPtrArray *
-flatpak_get_system_locales (void)
-{
- static GPtrArray *cached = NULL;
-
- if (g_once_init_enter (&cached))
- {
- GPtrArray *langs = g_ptr_array_new_with_free_func (g_free);
- g_autoptr(GDBusProxy) accounts_proxy = NULL;
-
- accounts_proxy = flatpak_locale_get_accounts_dbus_proxy ();
-
- if (accounts_proxy == NULL
- || !flatpak_get_all_langs_from_accounts_dbus (accounts_proxy, langs))
- {
- g_autoptr(GDBusProxy) localed_proxy = NULL;
-
- /* Get the system default locales */
- localed_proxy = flatpak_locale_get_localed_dbus_proxy ();
- if (localed_proxy != NULL)
- flatpak_get_locale_langs_from_localed_dbus (localed_proxy, langs);
-
- /* Now add the user account locales from AccountsService. If accounts_proxy is
- * not NULL, it means that AccountsService exists */
- if (accounts_proxy != NULL)
- flatpak_get_locale_langs_from_accounts_dbus (accounts_proxy, langs);
- }
-
- g_ptr_array_add (langs, NULL);
-
- g_once_init_leave (&cached, langs);
- }
-
- return (const GPtrArray *)cached;
-}
-
-const GPtrArray *
-flatpak_get_user_locales (void)
-{
- static GPtrArray *cached = NULL;
-
- if (g_once_init_enter (&cached))
- {
- GPtrArray *langs = g_ptr_array_new_with_free_func (g_free);
- g_autoptr(GDBusProxy) accounts_proxy = NULL;
-
- accounts_proxy = flatpak_locale_get_accounts_dbus_proxy ();
-
- if (accounts_proxy != NULL)
- flatpak_get_locale_langs_from_accounts_dbus_for_user (accounts_proxy, langs, getuid ());
-
- g_ptr_array_add (langs, NULL);
-
- g_once_init_leave (&cached, langs);
- }
-
- return (const GPtrArray *)cached;
-}
-
char **
flatpak_dir_get_default_locales (FlatpakDir *self)
{
diff --git a/common/flatpak-locale-utils-private.h b/common/flatpak-locale-utils-private.h
new file mode 100644
index 000000000..0519d209c
--- /dev/null
+++ b/common/flatpak-locale-utils-private.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright © 2014 Red Hat, Inc
+ * Copyright © 2023 Collabora Ltd.
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see .
+ *
+ * Authors:
+ * Alexander Larsson
+ */
+
+#pragma once
+
+#include
+
+const char * const *flatpak_get_locale_categories (void);
+char *flatpak_get_lang_from_locale (const char *locale);
+char **flatpak_get_current_locale_langs (void);
+const GPtrArray *flatpak_get_system_locales (void);
+const GPtrArray *flatpak_get_user_locales (void);
+
+/* Only for regression tests, should not be used directly */
+GDBusProxy *flatpak_locale_get_localed_dbus_proxy (void);
+void flatpak_get_locale_langs_from_localed_dbus (GDBusProxy *proxy,
+ GPtrArray *langs);
+GDBusProxy *flatpak_locale_get_accounts_dbus_proxy (void);
+gboolean flatpak_get_all_langs_from_accounts_dbus (GDBusProxy *proxy,
+ GPtrArray *langs);
+void flatpak_get_locale_langs_from_accounts_dbus (GDBusProxy *proxy,
+ GPtrArray *langs);
+void flatpak_get_locale_langs_from_accounts_dbus_for_user (GDBusProxy *proxy,
+ GPtrArray *langs,
+ guint uid);
diff --git a/common/flatpak-locale-utils.c b/common/flatpak-locale-utils.c
new file mode 100644
index 000000000..859721bc2
--- /dev/null
+++ b/common/flatpak-locale-utils.c
@@ -0,0 +1,388 @@
+/* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
+ * Copyright © 2014-2019 Red Hat, Inc
+ * Copyright © 2017 Endless Mobile, Inc.
+ * Copyright © 2023 Collabora Ltd.
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see .
+ *
+ * Authors:
+ * Alexander Larsson
+ * Philip Withnall
+ * Matthew Leeds
+ */
+
+#include "config.h"
+#include "flatpak-locale-utils-private.h"
+
+#include
+#include "libglnx.h"
+
+#include "flatpak-utils-private.h"
+
+const char * const *
+flatpak_get_locale_categories (void)
+{
+ /* See locale(7) for these categories */
+ static const char * const categories[] = {
+ "LANG", "LC_ALL", "LC_MESSAGES", "LC_ADDRESS", "LC_COLLATE", "LC_CTYPE",
+ "LC_IDENTIFICATION", "LC_MONETARY", "LC_MEASUREMENT", "LC_NAME", "LC_NUMERIC",
+ "LC_PAPER", "LC_TELEPHONE", "LC_TIME",
+ NULL
+ };
+
+ return categories;
+}
+
+char *
+flatpak_get_lang_from_locale (const char *locale)
+{
+ g_autofree char *lang = g_strdup (locale);
+ char *c;
+
+ c = strchr (lang, '@');
+ if (c != NULL)
+ *c = 0;
+ c = strchr (lang, '_');
+ if (c != NULL)
+ *c = 0;
+ c = strchr (lang, '.');
+ if (c != NULL)
+ *c = 0;
+
+ if (strcmp (lang, "C") == 0)
+ return NULL;
+
+ return g_steal_pointer (&lang);
+}
+
+char **
+flatpak_get_current_locale_langs (void)
+{
+ const char * const *categories = flatpak_get_locale_categories ();
+ GPtrArray *langs = g_ptr_array_new ();
+ int i;
+
+ for (; categories != NULL && *categories != NULL; categories++)
+ {
+ const gchar * const *locales = g_get_language_names_with_category (*categories);
+
+ for (i = 0; locales[i] != NULL; i++)
+ {
+ g_autofree char *lang = flatpak_get_lang_from_locale (locales[i]);
+ if (lang != NULL && !flatpak_g_ptr_array_contains_string (langs, lang))
+ g_ptr_array_add (langs, g_steal_pointer (&lang));
+ }
+ }
+
+ g_ptr_array_sort (langs, flatpak_strcmp0_ptr);
+ g_ptr_array_add (langs, NULL);
+
+ return (char **) g_ptr_array_free (langs, FALSE);
+}
+
+GDBusProxy *
+flatpak_locale_get_localed_dbus_proxy (void)
+{
+ const char *localed_bus_name = "org.freedesktop.locale1";
+ const char *localed_object_path = "/org/freedesktop/locale1";
+ const char *localed_interface_name = localed_bus_name;
+
+ return g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
+ G_DBUS_PROXY_FLAGS_NONE,
+ NULL,
+ localed_bus_name,
+ localed_object_path,
+ localed_interface_name,
+ NULL,
+ NULL);
+}
+
+void
+flatpak_get_locale_langs_from_localed_dbus (GDBusProxy *proxy, GPtrArray *langs)
+{
+ g_autoptr(GVariant) locale_variant = NULL;
+ g_autofree const gchar **strv = NULL;
+ gsize i, j;
+
+ locale_variant = g_dbus_proxy_get_cached_property (proxy, "Locale");
+ if (locale_variant == NULL)
+ return;
+
+ strv = g_variant_get_strv (locale_variant, NULL);
+
+ for (i = 0; strv[i]; i++)
+ {
+ const gchar *locale = NULL;
+ g_autofree char *lang = NULL;
+
+ const char * const *categories = flatpak_get_locale_categories ();
+
+ for (j = 0; categories[j]; j++)
+ {
+ g_autofree char *prefix = g_strdup_printf ("%s=", categories[j]);
+ if (g_str_has_prefix (strv[i], prefix))
+ {
+ locale = strv[i] + strlen (prefix);
+ break;
+ }
+ }
+
+ if (locale == NULL || strcmp (locale, "") == 0)
+ continue;
+
+ lang = flatpak_get_lang_from_locale (locale);
+ if (lang != NULL && !flatpak_g_ptr_array_contains_string (langs, lang))
+ g_ptr_array_add (langs, g_steal_pointer (&lang));
+ }
+}
+
+GDBusProxy *
+flatpak_locale_get_accounts_dbus_proxy (void)
+{
+ const char *accounts_bus_name = "org.freedesktop.Accounts";
+ const char *accounts_object_path = "/org/freedesktop/Accounts";
+ const char *accounts_interface_name = accounts_bus_name;
+
+ return g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
+ G_DBUS_PROXY_FLAGS_NONE,
+ NULL,
+ accounts_bus_name,
+ accounts_object_path,
+ accounts_interface_name,
+ NULL,
+ NULL);
+}
+
+gboolean
+flatpak_get_all_langs_from_accounts_dbus (GDBusProxy *proxy, GPtrArray *langs)
+{
+ g_auto(GStrv) all_langs = NULL;
+ int i;
+ g_autoptr(GVariant) ret = NULL;
+ g_autoptr(GError) error = NULL;
+
+ ret = g_dbus_proxy_call_sync (G_DBUS_PROXY (proxy),
+ "GetUsersLanguages",
+ g_variant_new ("()"),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL,
+ &error);
+ if (!ret)
+ {
+ g_debug ("Failed to get languages for all users: %s", error->message);
+ return FALSE;
+ }
+
+ g_variant_get (ret,
+ "(^as)",
+ &all_langs);
+
+ if (all_langs != NULL)
+ {
+ for (i = 0; all_langs[i] != NULL; i++)
+ {
+ g_autofree char *lang = NULL;
+ lang = flatpak_get_lang_from_locale (all_langs[i]);
+ if (lang != NULL && !flatpak_g_ptr_array_contains_string (langs, lang))
+ g_ptr_array_add (langs, g_steal_pointer (&lang));
+ }
+ }
+
+ return TRUE;
+}
+
+void
+flatpak_get_locale_langs_from_accounts_dbus (GDBusProxy *proxy, GPtrArray *langs)
+{
+ const char *accounts_bus_name = "org.freedesktop.Accounts";
+ const char *accounts_interface_name = "org.freedesktop.Accounts.User";
+ g_auto(GStrv) object_paths = NULL;
+ int i;
+ g_autoptr(GVariant) ret = NULL;
+
+ ret = g_dbus_proxy_call_sync (G_DBUS_PROXY (proxy),
+ "ListCachedUsers",
+ g_variant_new ("()"),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL,
+ NULL);
+ if (ret != NULL)
+ g_variant_get (ret,
+ "(^ao)",
+ &object_paths);
+
+ if (object_paths != NULL)
+ {
+ for (i = 0; object_paths[i] != NULL; i++)
+ {
+ g_autoptr(GDBusProxy) accounts_proxy = NULL;
+ g_autoptr(GVariant) value = NULL;
+
+ accounts_proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
+ G_DBUS_PROXY_FLAGS_NONE,
+ NULL,
+ accounts_bus_name,
+ object_paths[i],
+ accounts_interface_name,
+ NULL,
+ NULL);
+
+ if (accounts_proxy)
+ {
+ value = g_dbus_proxy_get_cached_property (accounts_proxy, "Language");
+ if (value != NULL)
+ {
+ const char *locale = g_variant_get_string (value, NULL);
+ g_autofree char *lang = NULL;
+
+ if (strcmp (locale, "") == 0)
+ continue; /* This user wants the system default locale */
+
+ lang = flatpak_get_lang_from_locale (locale);
+ if (lang != NULL && !flatpak_g_ptr_array_contains_string (langs, lang))
+ g_ptr_array_add (langs, g_steal_pointer (&lang));
+ }
+ }
+ }
+ }
+}
+
+void
+flatpak_get_locale_langs_from_accounts_dbus_for_user (GDBusProxy *proxy, GPtrArray *langs, guint uid)
+{
+ const char *accounts_bus_name = "org.freedesktop.Accounts";
+ const char *accounts_interface_name = "org.freedesktop.Accounts.User";
+ g_autofree char *object_path = NULL;
+ g_autoptr(GVariant) ret = NULL;
+
+ ret = g_dbus_proxy_call_sync (G_DBUS_PROXY (proxy),
+ "FindUserById",
+ g_variant_new ("(x)", uid),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL,
+ NULL);
+ if (ret != NULL)
+ g_variant_get (ret, "(o)", &object_path);
+
+ if (object_path != NULL)
+ {
+ g_autoptr(GDBusProxy) accounts_proxy = NULL;
+ g_autoptr(GVariant) value = NULL;
+
+ accounts_proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
+ G_DBUS_PROXY_FLAGS_NONE,
+ NULL,
+ accounts_bus_name,
+ object_path,
+ accounts_interface_name,
+ NULL,
+ NULL);
+ if (!accounts_proxy)
+ return;
+
+ value = g_dbus_proxy_get_cached_property (accounts_proxy, "Languages");
+ if (value != NULL)
+ {
+ const char **locales = g_variant_get_strv (value, NULL);
+ guint i;
+
+ for (i = 0; locales != NULL && locales[i] != NULL; i++)
+ {
+ g_autofree char *lang = NULL;
+ lang = flatpak_get_lang_from_locale (locales[i]);
+ if (lang != NULL && !flatpak_g_ptr_array_contains_string (langs, lang))
+ g_ptr_array_add (langs, g_steal_pointer (&lang));
+ }
+ }
+ else
+ {
+ value = g_dbus_proxy_get_cached_property (accounts_proxy, "Language");
+ if (value != NULL)
+ {
+ const char *locale = g_variant_get_string (value, NULL);
+ g_autofree char *lang = NULL;
+
+ if (strcmp (locale, "") != 0)
+ {
+ lang = flatpak_get_lang_from_locale (locale);
+ if (lang != NULL && !flatpak_g_ptr_array_contains_string (langs, lang))
+ g_ptr_array_add (langs, g_steal_pointer (&lang));
+ }
+ }
+ }
+ }
+}
+
+const GPtrArray *
+flatpak_get_system_locales (void)
+{
+ static GPtrArray *cached = NULL;
+
+ if (g_once_init_enter (&cached))
+ {
+ GPtrArray *langs = g_ptr_array_new_with_free_func (g_free);
+ g_autoptr(GDBusProxy) accounts_proxy = NULL;
+
+ accounts_proxy = flatpak_locale_get_accounts_dbus_proxy ();
+
+ if (accounts_proxy == NULL
+ || !flatpak_get_all_langs_from_accounts_dbus (accounts_proxy, langs))
+ {
+ g_autoptr(GDBusProxy) localed_proxy = NULL;
+
+ /* Get the system default locales */
+ localed_proxy = flatpak_locale_get_localed_dbus_proxy ();
+ if (localed_proxy != NULL)
+ flatpak_get_locale_langs_from_localed_dbus (localed_proxy, langs);
+
+ /* Now add the user account locales from AccountsService. If accounts_proxy is
+ * not NULL, it means that AccountsService exists */
+ if (accounts_proxy != NULL)
+ flatpak_get_locale_langs_from_accounts_dbus (accounts_proxy, langs);
+ }
+
+ g_ptr_array_add (langs, NULL);
+
+ g_once_init_leave (&cached, langs);
+ }
+
+ return (const GPtrArray *)cached;
+}
+
+const GPtrArray *
+flatpak_get_user_locales (void)
+{
+ static GPtrArray *cached = NULL;
+
+ if (g_once_init_enter (&cached))
+ {
+ GPtrArray *langs = g_ptr_array_new_with_free_func (g_free);
+ g_autoptr(GDBusProxy) accounts_proxy = NULL;
+
+ accounts_proxy = flatpak_locale_get_accounts_dbus_proxy ();
+
+ if (accounts_proxy != NULL)
+ flatpak_get_locale_langs_from_accounts_dbus_for_user (accounts_proxy, langs, getuid ());
+
+ g_ptr_array_add (langs, NULL);
+
+ g_once_init_leave (&cached, langs);
+ }
+
+ return (const GPtrArray *)cached;
+}
diff --git a/common/flatpak-utils-private.h b/common/flatpak-utils-private.h
index 6187c48a0..b9a68cdae 100644
--- a/common/flatpak-utils-private.h
+++ b/common/flatpak-utils-private.h
@@ -107,10 +107,6 @@ char **flatpak_strv_merge (char **strv1,
char **flatpak_subpaths_merge (char **subpaths1,
char **subpaths2);
-const char * const *flatpak_get_locale_categories (void);
-char *flatpak_get_lang_from_locale (const char *locale);
-char **flatpak_get_current_locale_langs (void);
-
GBytes * flatpak_read_stream (GInputStream * in,
gboolean null_terminate,
GError **error);
diff --git a/common/flatpak-utils.c b/common/flatpak-utils.c
index 7c2c60f2c..be9f1d462 100644
--- a/common/flatpak-utils.c
+++ b/common/flatpak-utils.c
@@ -7401,42 +7401,6 @@ flatpak_subpaths_merge (char **subpaths1,
return res;
}
-const char * const *
-flatpak_get_locale_categories (void)
-{
- /* See locale(7) for these categories */
- static const char * const categories[] = {
- "LANG", "LC_ALL", "LC_MESSAGES", "LC_ADDRESS", "LC_COLLATE", "LC_CTYPE",
- "LC_IDENTIFICATION", "LC_MONETARY", "LC_MEASUREMENT", "LC_NAME", "LC_NUMERIC",
- "LC_PAPER", "LC_TELEPHONE", "LC_TIME",
- NULL
- };
-
- return categories;
-}
-
-char *
-flatpak_get_lang_from_locale (const char *locale)
-{
- g_autofree char *lang = g_strdup (locale);
- char *c;
-
- c = strchr (lang, '@');
- if (c != NULL)
- *c = 0;
- c = strchr (lang, '_');
- if (c != NULL)
- *c = 0;
- c = strchr (lang, '.');
- if (c != NULL)
- *c = 0;
-
- if (strcmp (lang, "C") == 0)
- return NULL;
-
- return g_steal_pointer (&lang);
-}
-
gboolean
flatpak_g_ptr_array_contains_string (GPtrArray *array, const char *str)
{
@@ -7450,31 +7414,6 @@ flatpak_g_ptr_array_contains_string (GPtrArray *array, const char *str)
return FALSE;
}
-char **
-flatpak_get_current_locale_langs (void)
-{
- const char * const *categories = flatpak_get_locale_categories ();
- GPtrArray *langs = g_ptr_array_new ();
- int i;
-
- for (; categories != NULL && *categories != NULL; categories++)
- {
- const gchar * const *locales = g_get_language_names_with_category (*categories);
-
- for (i = 0; locales[i] != NULL; i++)
- {
- g_autofree char *lang = flatpak_get_lang_from_locale (locales[i]);
- if (lang != NULL && !flatpak_g_ptr_array_contains_string (langs, lang))
- g_ptr_array_add (langs, g_steal_pointer (&lang));
- }
- }
-
- g_ptr_array_sort (langs, flatpak_strcmp0_ptr);
- g_ptr_array_add (langs, NULL);
-
- return (char **) g_ptr_array_free (langs, FALSE);
-}
-
void
flatpak_log_dir_access (FlatpakDir *dir)
{
diff --git a/common/meson.build b/common/meson.build
index 18f0249a6..0dc07d288 100644
--- a/common/meson.build
+++ b/common/meson.build
@@ -176,6 +176,7 @@ sources = [
'flatpak-instance.c',
'flatpak-json-oci.c',
'flatpak-json.c',
+ 'flatpak-locale-utils.c',
'flatpak-oci-registry.c',
'flatpak-portal-error.c',
'flatpak-progress.c',
diff --git a/tests/test-locale-utils.c b/tests/test-locale-utils.c
index 8fe92fd70..38e708794 100644
--- a/tests/test-locale-utils.c
+++ b/tests/test-locale-utils.c
@@ -9,7 +9,7 @@
#include "libglnx.h"
#include "flatpak.h"
-#include "flatpak-utils-private.h"
+#include "flatpak-locale-utils-private.h"
#include "tests/testlib.h"