From 200e815a8a93be423584dd4ef5d64e78453194e7 Mon Sep 17 00:00:00 2001 From: Ludovico de Nittis <ludovico.denittis@collabora.com> Date: Tue, 31 Mar 2020 12:24:53 +0200 Subject: [PATCH] Create a new SrtSteam object Having an SrtSteam object will be easier in the future, if needed, to expand. Signed-off-by: Ludovico de Nittis <ludovico.denittis@collabora.com> --- steam-runtime-tools/steam-internal.h | 32 +++- steam-runtime-tools/steam.c | 267 ++++++++++++++++++++++++--- steam-runtime-tools/steam.h | 19 ++ steam-runtime-tools/system-info.c | 34 +--- 4 files changed, 294 insertions(+), 58 deletions(-) diff --git a/steam-runtime-tools/steam-internal.h b/steam-runtime-tools/steam-internal.h index a0d07465d..1845f2268 100644 --- a/steam-runtime-tools/steam-internal.h +++ b/steam-runtime-tools/steam-internal.h @@ -1,6 +1,6 @@ /*<private_header>*/ /* - * Copyright © 2019 Collabora Ltd. + * Copyright © 2019-2020 Collabora Ltd. * * SPDX-License-Identifier: MIT * @@ -31,8 +31,32 @@ #include <glib.h> #include <glib-object.h> +/* + * _srt_library_new: + * + * Returns: (transfer full): A new #SrtSteam + */ +static inline SrtSteam *_srt_steam_new (SrtSteamIssues issues, + const char *install_path, + const char *data_path, + const char *bin32_path); + +#ifndef __GTK_DOC_IGNORE__ +static inline SrtSteam * +_srt_steam_new (SrtSteamIssues issues, + const char *install_path, + const char *data_path, + const char *bin32_path) +{ + return g_object_new (SRT_TYPE_STEAM, + "issues", issues, + "install-path", install_path, + "data-path", data_path, + "bin32-path", bin32_path, + NULL); +} +#endif + G_GNUC_INTERNAL SrtSteamIssues _srt_steam_check (const GStrv env, - gchar **install_path_out, - gchar **data_path_out, - gchar **bin32_out); + SrtSteam **more_details_out); diff --git a/steam-runtime-tools/steam.c b/steam-runtime-tools/steam.c index 5ed75376b..de86addf8 100644 --- a/steam-runtime-tools/steam.c +++ b/steam-runtime-tools/steam.c @@ -1,5 +1,5 @@ /* - * Copyright © 2019 Collabora Ltd. + * Copyright © 2019-2020 Collabora Ltd. * * SPDX-License-Identifier: MIT * @@ -33,6 +33,7 @@ #include <glib.h> +#include "steam-runtime-tools/enums.h" #include "steam-runtime-tools/glib-compat.h" #include "steam-runtime-tools/utils.h" @@ -46,23 +47,237 @@ * installation. */ -/* +struct _SrtSteam +{ + /*< private >*/ + GObject parent; + SrtSteamIssues issues; + gchar *install_path; + gchar *data_path; + gchar *bin32_path; +}; + +struct _SrtSteamClass +{ + /*< private >*/ + GObjectClass parent_class; +}; + +enum { + PROP_0, + PROP_ISSUES, + PROP_INSTALL_PATH, + PROP_DATA_PATH, + PROP_BIN32_PATH, + N_PROPERTIES +}; + +G_DEFINE_TYPE (SrtSteam, srt_steam, G_TYPE_OBJECT) + +static void +srt_steam_init (SrtSteam *self) +{ +} + +static void +srt_steam_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + SrtSteam *self = SRT_STEAM (object); + + switch (prop_id) + { + case PROP_ISSUES: + g_value_set_flags (value, self->issues); + break; + + case PROP_INSTALL_PATH: + g_value_set_string (value, self->install_path); + break; + + case PROP_DATA_PATH: + g_value_set_string (value, self->data_path); + break; + + case PROP_BIN32_PATH: + g_value_set_string (value, self->bin32_path); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +srt_steam_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + SrtSteam *self = SRT_STEAM (object); + + switch (prop_id) + { + case PROP_ISSUES: + /* Construct-only */ + g_return_if_fail (self->issues == 0); + self->issues = g_value_get_flags (value); + break; + + case PROP_INSTALL_PATH: + /* Construct only */ + g_return_if_fail (self->install_path == NULL); + self->install_path = g_value_dup_string (value); + break; + + case PROP_DATA_PATH: + /* Construct only */ + g_return_if_fail (self->data_path == NULL); + self->data_path = g_value_dup_string (value); + break; + + case PROP_BIN32_PATH: + /* Construct only */ + g_return_if_fail (self->bin32_path == NULL); + self->bin32_path = g_value_dup_string (value); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +srt_steam_finalize (GObject *object) +{ + SrtSteam *self = SRT_STEAM (object); + + g_free (self->install_path); + g_free (self->data_path); + g_free (self->bin32_path); + + G_OBJECT_CLASS (srt_steam_parent_class)->finalize (object); +} + +static GParamSpec *properties[N_PROPERTIES] = { NULL }; + +static void +srt_steam_class_init (SrtSteamClass *cls) +{ + GObjectClass *object_class = G_OBJECT_CLASS (cls); + + object_class->get_property = srt_steam_get_property; + object_class->set_property = srt_steam_set_property; + object_class->finalize = srt_steam_finalize; + + properties[PROP_ISSUES] = + g_param_spec_flags ("issues", "Issues", "Problems with the steam installation", + SRT_TYPE_STEAM_ISSUES, SRT_STEAM_ISSUES_NONE, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS); + + properties[PROP_INSTALL_PATH] = + g_param_spec_string ("install-path", "Install path", + "Absolute path to the Steam installation", + NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS); + + properties[PROP_DATA_PATH] = + g_param_spec_string ("data-path", "Data path", + "Absolute path to the Steam data directory, which is usually " + "the same as install-path, but may be different while " + "testing a new Steam release", + NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS); + + properties[PROP_BIN32_PATH] = + g_param_spec_string ("bin32-path", "Bin32 path", + "Absolute path to `ubuntu12_32`", + NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties (object_class, N_PROPERTIES, properties); +} + +/** + * srt_steam_get_issues: + * @self: The #SrtSteam object + * + * Return the problems found in @self. + * + * Returns: A bitfield containing problems, or %SRT_STEAM_ISSUES_NONE + * if no problems were found + */ +SrtSteamIssues +srt_steam_get_issues (SrtSteam *self) +{ + g_return_val_if_fail (SRT_IS_STEAM (self), SRT_STEAM_ISSUES_INTERNAL_ERROR); + return self->issues; +} +/** + * srt_steam_get_install_path: + * @self: The #SrtSteam object + * + * Returns: (nullable) (type filename): The absolute path to the Steam + * installation, which is valid as long as @self is not destroyed. + */ +const char * +srt_steam_get_install_path (SrtSteam *self) +{ + g_return_val_if_fail (SRT_IS_STEAM (self), NULL); + return self->install_path; +} + +/** + * srt_steam_get_data_path: + * @self: The #SrtSteam object + * + * Used to return the absolute path to the Steam data directory, which + * is usually the same as `srt_steam_get_install_path`, but may be different + * while testing a new Steam release. + * + * Returns: (nullable) (type filename): The absolute path to the Steam data + * directory, which is valid as long as @self is not destroyed. + */ +const char * +srt_steam_get_data_path (SrtSteam *self) +{ + g_return_val_if_fail (SRT_IS_STEAM (self), NULL); + return self->data_path; +} + +/** + * srt_steam_get_bin32_path: + * @self: The #SrtSteam object + * + * Returns: (nullable) (type filename): The absolute path to `ubuntu12_32`, + * which is valid as long as @self is not destroyed. + */ +const char * +srt_steam_get_bin32_path (SrtSteam *self) +{ + g_return_val_if_fail (SRT_IS_STEAM (self), NULL); + return self->bin32_path; +} + +/** * _srt_steam_check: - * @environ: (nullable): The list of environment variables to use. - * @install_path_out: (out) (optional) (nullable) (type filename): - * Used to return the absolute path to the Steam installation - * @data_path_out: (out) (optional) (nullable) (type filename): - * Used to return the absolute path to the Steam data directory, - * which is usually the same as @install_path_out, but may be different - * while testing a new Steam release - * @bin32_out: (out) (optional) (nullable) (type filename): - * Used to return the absolute path to `ubuntu12_32` + * @my_environ: (nullable): The list of environment variables to use. + * @more_details_out: (out) (optional) (transfer full): Used to return an + * #SrtSteam object representing information about the current Steam + * installation. Free with `g_object_unref()`. + * + * Returns: A bitfield containing problems, or %SRT_STEAM_ISSUES_NONE + * if no problems were found */ SrtSteamIssues -_srt_steam_check (const GStrv environ, - gchar **install_path_out, - gchar **data_path_out, - gchar **bin32_out) +_srt_steam_check (const GStrv my_environ, + SrtSteam **more_details_out) { SrtSteamIssues issues = SRT_STEAM_ISSUES_NONE; gchar *dot_steam_bin32 = NULL; @@ -78,14 +293,10 @@ _srt_steam_check (const GStrv environ, g_return_val_if_fail (_srt_check_not_setuid (), SRT_STEAM_ISSUES_INTERNAL_ERROR); - g_return_val_if_fail (install_path_out == NULL || *install_path_out == NULL, - SRT_STEAM_ISSUES_INTERNAL_ERROR); - g_return_val_if_fail (data_path_out == NULL || *data_path_out == NULL, - SRT_STEAM_ISSUES_INTERNAL_ERROR); - g_return_val_if_fail (bin32_out == NULL || *bin32_out == NULL, + g_return_val_if_fail (more_details_out == NULL || *more_details_out == NULL, SRT_STEAM_ISSUES_INTERNAL_ERROR); - env = (environ == NULL) ? g_get_environ () : g_strdupv (environ); + env = (my_environ == NULL) ? g_get_environ () : g_strdupv (my_environ); home = g_environ_getenv (env, "HOME"); user_data = g_environ_getenv (env, "XDG_DATA_HOME"); @@ -256,17 +467,13 @@ _srt_steam_check (const GStrv environ, g_debug ("Found Steam data at %s", data_path); } - /* We can't just transfer ownership here, because in the older GLib - * that we're targeting, g_free() and free() are not guaranteed to be - * associated with the same memory pool. */ - if (install_path_out != NULL) - *install_path_out = g_strdup (install_path); - if (data_path_out != NULL) - *data_path_out = g_strdup (data_path); - if (bin32_out != NULL) - *bin32_out = g_strdup (bin32); + if (more_details_out != NULL) + *more_details_out = _srt_steam_new (issues, + install_path, + data_path, + bin32); free (install_path); free (data_path); diff --git a/steam-runtime-tools/steam.h b/steam-runtime-tools/steam.h index b19b1197e..a0597ce01 100644 --- a/steam-runtime-tools/steam.h +++ b/steam-runtime-tools/steam.h @@ -29,6 +29,20 @@ #error "Do not include directly, use <steam-runtime-tools/steam-runtime-tools.h>" #endif +#include <glib.h> +#include <glib-object.h> + +typedef struct _SrtSteam SrtSteam; +typedef struct _SrtSteamClass SrtSteamClass; + +#define SRT_TYPE_STEAM srt_steam_get_type () +#define SRT_STEAM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SRT_TYPE_STEAM, SrtSteam)) +#define SRT_STEAM_CLASS(cls) (G_TYPE_CHECK_CLASS_CAST ((cls), SRT_TYPE_STEAM, SrtSteamClass)) +#define SRT_IS_STEAM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SRT_TYPE_STEAM)) +#define SRT_IS_STEAM_CLASS(cls) (G_TYPE_CHECK_CLASS_TYPE ((cls), SRT_TYPE_STEAM)) +#define SRT_STEAM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), SRT_TYPE_STEAM, SrtSteamClass) +GType srt_steam_get_type (void); + /** * SrtSteamIssues: * @SRT_STEAM_ISSUES_NONE: There are no problems @@ -74,3 +88,8 @@ typedef enum SRT_STEAM_ISSUES_DOT_STEAM_ROOT_NOT_DIRECTORY = (1 << 6), SRT_STEAM_ISSUES_NONE = 0 } SrtSteamIssues; + +SrtSteamIssues srt_steam_get_issues (SrtSteam *self); +const char *srt_steam_get_install_path (SrtSteam *self); +const char *srt_steam_get_data_path (SrtSteam *self); +const char *srt_steam_get_bin32_path (SrtSteam *self); diff --git a/steam-runtime-tools/system-info.c b/steam-runtime-tools/system-info.c index 625838230..180f44831 100644 --- a/steam-runtime-tools/system-info.c +++ b/steam-runtime-tools/system-info.c @@ -104,6 +104,7 @@ struct _SrtSystemInfo * shouldn't matter, or %NULL to use the compiled-in default */ GQuark primary_multiarch_tuple; GHashTable *cached_hidden_deps; + SrtSteam *steam_data; struct { /* GQuark => MaybeLocale */ @@ -112,15 +113,6 @@ struct _SrtSystemInfo gboolean have_issues; } locales; struct - { - /* install_path != NULL or issues != NONE indicates we have already - * checked the Steam installation */ - gchar *install_path; - gchar *data_path; - gchar *bin32; - SrtSteamIssues issues; - } steam; - struct { /* path != NULL or issues != NONE indicates we have already checked * the Steam Runtime */ @@ -401,10 +393,9 @@ static void forget_steam (SrtSystemInfo *self) { forget_runtime (self); - self->steam.issues = SRT_STEAM_ISSUES_NONE; - g_clear_pointer (&self->steam.install_path, g_free); - g_clear_pointer (&self->steam.data_path, g_free); - g_clear_pointer (&self->steam.bin32, g_free); + if (self->steam_data != NULL) + g_object_unref (self->steam_data); + self->steam_data = NULL; } /* @@ -1626,13 +1617,8 @@ srt_system_info_set_sysroot (SrtSystemInfo *self, static void ensure_steam_cached (SrtSystemInfo *self) { - if (self->steam.issues == SRT_STEAM_ISSUES_NONE && - self->steam.install_path == NULL && - self->steam.data_path == NULL) - self->steam.issues = _srt_steam_check (self->env, - &self->steam.install_path, - &self->steam.data_path, - &self->steam.bin32); + if (self->steam_data == NULL) + _srt_steam_check (self->env, &self->steam_data); } /** @@ -1651,7 +1637,7 @@ srt_system_info_get_steam_issues (SrtSystemInfo *self) SRT_STEAM_ISSUES_INTERNAL_ERROR); ensure_steam_cached (self); - return self->steam.issues; + return srt_steam_get_issues (self->steam_data); } /** @@ -1693,7 +1679,7 @@ srt_system_info_dup_steam_installation_path (SrtSystemInfo *self) g_return_val_if_fail (SRT_IS_SYSTEM_INFO (self), NULL); ensure_steam_cached (self); - return g_strdup (self->steam.install_path); + return g_strdup (srt_steam_get_install_path (self->steam_data)); } /** @@ -1735,7 +1721,7 @@ srt_system_info_dup_steam_data_path (SrtSystemInfo *self) g_return_val_if_fail (SRT_IS_SYSTEM_INFO (self), NULL); ensure_steam_cached (self); - return g_strdup (self->steam.data_path); + return g_strdup (srt_steam_get_data_path (self->steam_data)); } static void @@ -2083,7 +2069,7 @@ ensure_runtime_cached (SrtSystemInfo *self) } else { - self->runtime.issues = _srt_runtime_check (self->steam.bin32, + self->runtime.issues = _srt_runtime_check (srt_steam_get_bin32_path (self->steam_data), self->runtime.expected_version, self->env, &self->runtime.version, -- GitLab