From 260865b1acbe8d7b22a47bcc1e23982b07c20d15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= Date: Tue, 20 Feb 2024 14:50:15 +0000 Subject: [PATCH] nm-setting: implement direct_enum as GObject property of type int --- src/libnm-client-impl/libnm.ver | 1 + ...gen-metadata-nm-settings-libnm-core.xml.in | 2 +- src/libnm-core-impl/nm-setting-connection.c | 22 +-- src/libnm-core-impl/nm-setting-ip-config.c | 6 +- src/libnm-core-impl/nm-setting-ip6-config.c | 22 +-- src/libnm-core-impl/nm-setting-private.h | 96 +++++++++-- src/libnm-core-impl/nm-setting-wireguard.c | 3 +- src/libnm-core-impl/nm-setting.c | 153 +++++++++++++++--- src/libnm-core-impl/tests/test-setting.c | 37 +++-- src/libnm-core-intern/nm-core-internal.h | 8 +- src/libnm-core-public/nm-setting.h | 3 + src/libnmc-setting/nm-meta-setting-desc.c | 63 +++----- 12 files changed, 301 insertions(+), 115 deletions(-) diff --git a/src/libnm-client-impl/libnm.ver b/src/libnm-client-impl/libnm.ver index f4c924012..052e70185 100644 --- a/src/libnm-client-impl/libnm.ver +++ b/src/libnm-client-impl/libnm.ver @@ -1966,4 +1966,5 @@ global: nm_setting_hsr_get_type; nm_setting_hsr_new; nm_setting_ip_config_get_dhcp_dscp; + nm_setting_get_enum_property_type; } libnm_1_44_0; diff --git a/src/libnm-core-impl/gen-metadata-nm-settings-libnm-core.xml.in b/src/libnm-core-impl/gen-metadata-nm-settings-libnm-core.xml.in index 84220043e..033639e06 100644 --- a/src/libnm-core-impl/gen-metadata-nm-settings-libnm-core.xml.in +++ b/src/libnm-core-impl/gen-metadata-nm-settings-libnm-core.xml.in @@ -769,7 +769,7 @@ /> property_type->direct_type; \ + GType direct_gtype = _property_info->direct_data.enum_gtype; \ + GParamSpec *spec = _property_info->param_spec; \ + GType spec_gtype = spec ? spec->value_type : G_TYPE_INVALID; \ + \ + direct_nmtype == NM_VALUE_TYPE_ENUM &&direct_gtype &&G_TYPE_IS_ENUM(direct_gtype) \ + && NM_IN_SET(spec_gtype, G_TYPE_INT, direct_gtype); \ + }) + +/*****************************************************************************/ + #define _nm_setting_property_define_direct_ternary_enum(properties_override, \ obj_properties, \ prop_name, \ @@ -954,17 +1028,17 @@ _nm_properties_override(GArray *properties_override, const NMSettInfoProperty *p private_struct_type, \ private_struct_field, \ ...) \ - _nm_setting_property_define_direct_enum((properties_override), \ - (obj_properties), \ - prop_name, \ - (prop_id), \ - NM_TYPE_TERNARY, \ - NM_TERNARY_DEFAULT, \ - (param_flags), \ - NULL, \ - private_struct_type, \ - private_struct_field, \ - __VA_ARGS__) + _nm_setting_property_define_direct_real_enum((properties_override), \ + (obj_properties), \ + prop_name, \ + (prop_id), \ + NM_TYPE_TERNARY, \ + NM_TERNARY_DEFAULT, \ + (param_flags), \ + NULL, \ + private_struct_type, \ + private_struct_field, \ + __VA_ARGS__) /*****************************************************************************/ diff --git a/src/libnm-core-impl/nm-setting-wireguard.c b/src/libnm-core-impl/nm-setting-wireguard.c index c313d22c2..4f96f7421 100644 --- a/src/libnm-core-impl/nm-setting-wireguard.c +++ b/src/libnm-core-impl/nm-setting-wireguard.c @@ -2361,8 +2361,7 @@ nm_setting_wireguard_class_init(NMSettingWireGuardClass *klass) NM_SETTING_PARAM_SECRET, NMSettingWireGuard, _priv.private_key, - .direct_set_fcn.set_string = - _set_string_fcn_public_key, + .direct_data.set_string = _set_string_fcn_public_key, .direct_string_allow_empty = TRUE); /** diff --git a/src/libnm-core-impl/nm-setting.c b/src/libnm-core-impl/nm-setting.c index 182971dfd..ebd2070ea 100644 --- a/src/libnm-core-impl/nm-setting.c +++ b/src/libnm-core-impl/nm-setting.c @@ -684,10 +684,10 @@ _property_direct_set_string(const NMSettInfoSetting *sett_info, + (!!property_info->direct_string_is_refstr) + (property_info->direct_set_string_mac_address_len > 0) + (property_info->direct_set_string_ip_address_addr_family != 0)) - <= (property_info->direct_set_fcn.set_string ? 0 : 1)); + <= (property_info->direct_data.set_string ? 0 : 1)); - if (property_info->direct_set_fcn.set_string) { - return property_info->direct_set_fcn.set_string(sett_info, property_info, setting, src); + if (property_info->direct_data.set_string) { + return property_info->direct_data.set_string(sett_info, property_info, setting, src); } dst = _nm_setting_get_private_field(setting, sett_info, property_info); @@ -826,7 +826,13 @@ _nm_setting_property_get_property_direct(GObject *object, { const int *p_val = _nm_setting_get_private_field(setting, sett_info, property_info); - g_value_set_enum(value, *p_val); + nm_assert(_nm_setting_property_is_valid_direct_enum(property_info)); + + if (G_TYPE_IS_ENUM(pspec->value_type)) + g_value_set_enum(value, *p_val); + else + g_value_set_int(value, *p_val); + return; } case NM_VALUE_TYPE_FLAGS: @@ -961,7 +967,13 @@ _nm_setting_property_set_property_direct(GObject *object, int *p_val = _nm_setting_get_private_field(setting, sett_info, property_info); int v; - v = g_value_get_enum(value); + nm_assert(_nm_setting_property_is_valid_direct_enum(property_info)); + + if (G_TYPE_IS_ENUM(pspec->value_type)) + v = g_value_get_enum(value); + else + v = g_value_get_int(value); + if (*p_val == v) return; *p_val = v; @@ -1097,7 +1109,13 @@ _init_direct(NMSetting *setting) int *p_val = _nm_setting_get_private_field(setting, sett_info, property_info); int def_val; - def_val = NM_G_PARAM_SPEC_GET_DEFAULT_ENUM(property_info->param_spec); + nm_assert(_nm_setting_property_is_valid_direct_enum(property_info)); + + if (G_TYPE_IS_ENUM(property_info->param_spec->value_type)) + def_val = NM_G_PARAM_SPEC_GET_DEFAULT_ENUM(property_info->param_spec); + else + def_val = NM_G_PARAM_SPEC_GET_DEFAULT_INT(property_info->param_spec); + nm_assert(NM_IN_SET(*p_val, 0, property_info->direct_is_aliased_field ? def_val : 0)); *p_val = def_val; break; @@ -1255,10 +1273,22 @@ _nm_setting_property_to_dbus_fcn_direct(_NM_SETT_INFO_PROP_TO_DBUS_FCN_ARGS _nm_ { int val; + nm_assert(_nm_setting_property_is_valid_direct_enum(property_info)); + val = *((int *) _nm_setting_get_private_field(setting, sett_info, property_info)); - if (!property_info->to_dbus_including_default - && val == NM_G_PARAM_SPEC_GET_DEFAULT_ENUM(property_info->param_spec)) - return NULL; + + if (!property_info->to_dbus_including_default) { + int default_value; + + if (G_TYPE_IS_ENUM(property_info->param_spec->value_type)) + default_value = NM_G_PARAM_SPEC_GET_DEFAULT_ENUM(property_info->param_spec); + else + default_value = NM_G_PARAM_SPEC_GET_DEFAULT_INT(property_info->param_spec); + + if (val == default_value) + return NULL; + } + return nm_g_variant_maybe_singleton_i(val); } case NM_VALUE_TYPE_FLAGS: @@ -1434,7 +1464,10 @@ _nm_setting_property_from_dbus_fcn_direct(_NM_SETT_INFO_PROP_FROM_DBUS_FCN_ARGS GVariant *_value = (value); \ gboolean _success = FALSE; \ \ - nm_assert(_property_info->param_spec->value_type == _gtype); \ + nm_assert(_property_info->param_spec->value_type == _gtype \ + || (_property_info->property_type->direct_type == NM_VALUE_TYPE_ENUM \ + && _property_info->direct_data.enum_gtype == _gtype)); \ + \ if (_property_info->property_type->from_dbus_direct_allow_transform) { \ nm_auto_unset_gvalue GValue _gvalue = G_VALUE_INIT; \ \ @@ -1585,21 +1618,20 @@ _nm_setting_property_from_dbus_fcn_direct(_NM_SETT_INFO_PROP_FROM_DBUS_FCN_ARGS } case NM_VALUE_TYPE_ENUM: { - const GParamSpecEnum *param_spec; - int *p_val; - int v; + int *p_val; + int v; - param_spec = NM_G_PARAM_SPEC_CAST_ENUM(property_info->param_spec); + nm_assert(_nm_setting_property_is_valid_direct_enum(property_info)); if (g_variant_is_of_type(value, G_VARIANT_TYPE_INT32)) { G_STATIC_ASSERT(sizeof(int) >= sizeof(gint32)); v = g_variant_get_int32(value); } else { - if (!_variant_get_value_transform(property_info, - value, - G_TYPE_FROM_CLASS(param_spec->enum_class), - g_value_get_flags, - &v)) + GType gtype = G_TYPE_IS_ENUM(property_info->param_spec->value_type) + ? property_info->param_spec->value_type + : G_TYPE_INT; + + if (!_variant_get_value_transform(property_info, value, gtype, g_value_get_flags, &v)) goto out_error_wrong_dbus_type; } @@ -1607,8 +1639,18 @@ _nm_setting_property_from_dbus_fcn_direct(_NM_SETT_INFO_PROP_FROM_DBUS_FCN_ARGS if (*p_val == v) goto out_unchanged; - if (!g_enum_get_value(param_spec->enum_class, v)) - goto out_error_param_spec_validation; + /* To avoid that clients with old libnm fails setting a newer value received + * from the daemon, do not validate here if the value is within range or not. + * Instead, do it in 'verify' that the client can ignore. + * However, some properties are implemented as real enums, mostly those that + * were originally implemented as such. Maintain the old behaviour on them. */ + if (G_TYPE_IS_ENUM(property_info->param_spec->value_type)) { + const GParamSpecEnum *enum_spec = NM_G_PARAM_SPEC_CAST_ENUM(property_info->param_spec); + + if (!g_enum_get_value(enum_spec->enum_class, v)) + goto out_error_param_spec_validation; + } + *p_val = v; goto out_notify; } @@ -2443,7 +2485,6 @@ _verify_properties(NMSetting *setting, GError **error) case NM_VALUE_TYPE_BOOL: case NM_VALUE_TYPE_BYTES: case NM_VALUE_TYPE_STRV: - case NM_VALUE_TYPE_ENUM: case NM_VALUE_TYPE_FLAGS: case NM_VALUE_TYPE_INT32: case NM_VALUE_TYPE_INT64: @@ -2451,6 +2492,37 @@ _verify_properties(NMSetting *setting, GError **error) case NM_VALUE_TYPE_UINT32: case NM_VALUE_TYPE_UINT64: break; + case NM_VALUE_TYPE_ENUM: + { + nm_auto_unref_gtypeclass GEnumClass *enum_class = NULL; + int *val; + + nm_assert(_nm_setting_property_is_valid_direct_enum(property_info)); + + enum_class = g_type_class_ref(property_info->direct_data.enum_gtype); + val = _nm_setting_get_private_field(setting, sett_info, property_info); + + /* We validate here that the value is within the range of the enum, and not + * in the GObject property and/or DBus setters. This way, clients using an + * old libnm can accept new values added later to the enum, because clients + * are not required to 'verify' */ + if (!g_enum_get_value(enum_class, *val)) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("invalid value %d, expected %d-%d"), + *val, + enum_class->minimum, + enum_class->maximum); + g_prefix_error(error, + "%s.%s: ", + klass->setting_info->setting_name, + property_info->name); + return FALSE; + } + + return TRUE; + } case NM_VALUE_TYPE_STRING: { const char *val; @@ -4465,6 +4537,43 @@ nm_range_from_str(const char *str, GError **error) return nm_range_new(start, end); } +/** + * nm_setting_get_enum_property_type: + * @setting_type: the GType of the NMSetting instance + * @property_name: the name of the property + * + * Get the type of the enum that defines the values that the property accepts. It is only + * useful for properties configured to accept values from certain enum type, otherwise + * it will return %G_TYPE_INVALID. Note that flags (children of G_TYPE_FLAGS) are also + * considered enums. + * + * Note that the GObject property might be implemented as an integer, actually, and not + * as enum. Find out what underlying type is used, checking the #GParamSpec, before + * setting the GObject property. + * + * Returns: the enum's GType, or %G_TYPE_INVALID if the property is not of enum type + * + * Since: 1.46 + */ +GType +nm_setting_get_enum_property_type(GType setting_type, const char *property_name) +{ + nm_auto_unref_gtypeclass NMSettingClass *setting_class = g_type_class_ref(setting_type); + const NMSettInfoProperty *property_info; + GParamSpec *spec; + + g_return_val_if_fail(NM_IS_SETTING_CLASS(setting_class), G_TYPE_INVALID); + + property_info = _nm_setting_class_get_property_info(setting_class, property_name); + spec = property_info->param_spec; + + if (spec && (G_TYPE_IS_ENUM(spec->value_type) || G_TYPE_IS_FLAGS(spec->value_type))) + return property_info->param_spec->value_type; + if (property_info->property_type->direct_type == NM_VALUE_TYPE_ENUM) + return property_info->direct_data.enum_gtype; + return G_TYPE_INVALID; +} + /*****************************************************************************/ static void diff --git a/src/libnm-core-impl/tests/test-setting.c b/src/libnm-core-impl/tests/test-setting.c index 72b855a59..4b5a0b6f5 100644 --- a/src/libnm-core-impl/tests/test-setting.c +++ b/src/libnm-core-impl/tests/test-setting.c @@ -4565,7 +4565,7 @@ test_setting_metadata(void) GArray *property_types_data; guint prop_idx_val; gboolean can_set_including_default = FALSE; - gboolean can_have_direct_set_fcn = FALSE; + gboolean can_have_direct_data = FALSE; int n_special_options; g_assert(sip->name); @@ -4662,18 +4662,35 @@ test_setting_metadata(void) can_set_including_default = TRUE; } else if (sip->property_type->direct_type == NM_VALUE_TYPE_ENUM) { - const GParamSpecEnum *pspec; + nm_auto_unref_gtypeclass GEnumClass *enum_class = NULL; + int default_value; + g_assert(_nm_setting_property_is_valid_direct_enum(sip)); + g_assert(G_TYPE_IS_ENUM(sip->direct_data.enum_gtype)); g_assert(g_variant_type_equal(sip->property_type->dbus_type, "i")); g_assert(sip->param_spec); - g_assert(g_type_is_a(sip->param_spec->value_type, G_TYPE_ENUM)); - g_assert(sip->param_spec->value_type != G_TYPE_ENUM); - pspec = NM_G_PARAM_SPEC_CAST_ENUM(sip->param_spec); - g_assert(G_TYPE_FROM_CLASS(pspec->enum_class) == sip->param_spec->value_type); - g_assert(g_enum_get_value(pspec->enum_class, pspec->default_value)); + if (G_TYPE_IS_ENUM(sip->param_spec->value_type)) { + const GParamSpecEnum *pspec = NM_G_PARAM_SPEC_CAST_ENUM(sip->param_spec); + + g_assert(sip->param_spec->value_type != G_TYPE_ENUM); + g_assert(G_TYPE_FROM_CLASS(pspec->enum_class) == sip->param_spec->value_type); + g_assert(sip->param_spec->value_type == sip->direct_data.enum_gtype); + + default_value = pspec->default_value; + } else if (sip->param_spec->value_type == G_TYPE_INT) { + const GParamSpecInt *pspec = NM_G_PARAM_SPEC_CAST_INT(sip->param_spec); + + default_value = pspec->default_value; + } else { + g_assert_not_reached(); + } + + enum_class = g_type_class_ref(sip->direct_data.enum_gtype); + g_assert(g_enum_get_value(enum_class, default_value)); can_set_including_default = TRUE; + can_have_direct_data = TRUE; } else if (sip->property_type->direct_type == NM_VALUE_TYPE_FLAGS) { const GParamSpecFlags *pspec; @@ -4703,7 +4720,7 @@ test_setting_metadata(void) INFINIBAND_ALEN)); } else { g_assert(g_variant_type_equal(sip->property_type->dbus_type, "s")); - can_have_direct_set_fcn = TRUE; + can_have_direct_data = TRUE; } g_assert(sip->param_spec); g_assert(sip->param_spec->value_type == G_TYPE_STRING); @@ -4744,8 +4761,8 @@ test_setting_metadata(void) g_assert(sip->property_type->direct_type == NM_VALUE_TYPE_STRING); } - if (!can_have_direct_set_fcn) - g_assert(!sip->direct_set_fcn.set_string); + if (!can_have_direct_data) + g_assert(!sip->direct_data.set_string); if (sip->property_type->direct_type == NM_VALUE_TYPE_NONE) g_assert(!sip->direct_also_notify); diff --git a/src/libnm-core-intern/nm-core-internal.h b/src/libnm-core-intern/nm-core-internal.h index 51296ddb8..fc157c588 100644 --- a/src/libnm-core-intern/nm-core-internal.h +++ b/src/libnm-core-intern/nm-core-internal.h @@ -800,7 +800,13 @@ struct _NMSettInfoProperty { const NMSettInfoProperty *property_info, NMSetting *setting, const char *src); - } direct_set_fcn; + + /* We implement %NM_VALUE_TYPE_ENUM properties as integer GObject properties + * because using real enum triggers glib assertions when passing newer values to + * clients with old libnm. This defines the enum type that the direct_property of + * type %NM_VALUE_TYPE_ENUM will use. */ + GType enum_gtype; + } direct_data; /* For direct properties, this is the param_spec that also should be * notified on changes. */ diff --git a/src/libnm-core-public/nm-setting.h b/src/libnm-core-public/nm-setting.h index d525a6ad5..6c6fe2bfe 100644 --- a/src/libnm-core-public/nm-setting.h +++ b/src/libnm-core-public/nm-setting.h @@ -255,6 +255,9 @@ void nm_setting_option_clear_by_name(NMSetting *setting, NMUtilsPredicateStr pre const GVariantType *nm_setting_get_dbus_property_type(NMSetting *setting, const char *property_name); +NM_AVAILABLE_IN_1_46 +GType nm_setting_get_enum_property_type(GType setting_type, const char *property_name); + /*****************************************************************************/ typedef struct _NMRange NMRange; diff --git a/src/libnmc-setting/nm-meta-setting-desc.c b/src/libnmc-setting/nm-meta-setting-desc.c index 103b844e5..1e8f8809a 100644 --- a/src/libnmc-setting/nm-meta-setting-desc.c +++ b/src/libnmc-setting/nm-meta-setting-desc.c @@ -1073,7 +1073,6 @@ _get_fcn_gobject_enum(ARGS_GET_FCN) { GType gtype = 0; const NMUtilsEnumValueInfo *value_infos = NULL; - gboolean has_gtype = FALSE; nm_auto_unset_gvalue GValue gval = G_VALUE_INIT; gint64 v; gboolean format_numeric = FALSE; @@ -1087,13 +1086,6 @@ _get_fcn_gobject_enum(ARGS_GET_FCN) RETURN_UNSUPPORTED_GET_TYPE(); - if (property_info->property_typ_data) { - if (property_info->property_typ_data->subtype.gobject_enum.get_gtype) { - gtype = property_info->property_typ_data->subtype.gobject_enum.get_gtype(); - has_gtype = TRUE; - } - } - if (property_info->property_typ_data && get_type == NM_META_ACCESSOR_GET_TYPE_PRETTY && NM_FLAGS_ANY(property_info->property_typ_data->typ_flags, NM_META_PROPERTY_TYP_FLAG_ENUM_GET_PRETTY_NUMERIC @@ -1136,18 +1128,12 @@ _get_fcn_gobject_enum(ARGS_GET_FCN) nm_assert(format_text || format_numeric); + gtype = nm_meta_property_enum_get_type(property_info); + g_return_val_if_fail(gtype != G_TYPE_INVALID, NULL); + pspec = g_object_class_find_property(G_OBJECT_GET_CLASS(setting), property_info->property_name); g_return_val_if_fail(pspec, NULL); - if (has_gtype) { - /* if the property is already enum, don't set get_gtype: it's redundant and error prone */ - g_return_val_if_fail(NM_IN_SET(pspec->value_type, G_TYPE_INT, G_TYPE_UINT), FALSE); - } else { - gtype = pspec->value_type; - } - - g_return_val_if_fail(G_TYPE_IS_ENUM(gtype) || G_TYPE_IS_FLAGS(gtype), NULL); - g_value_init(&gval, pspec->value_type); g_object_get_property(G_OBJECT(setting), property_info->property_name, &gval); NM_SET_OUT(out_is_default, g_param_value_defaults(pspec, &gval)); @@ -1255,17 +1241,19 @@ nm_meta_property_int_get_range(const NMMetaPropertyInfo *property_info, GType nm_meta_property_enum_get_type(const NMMetaPropertyInfo *property_info) { - GType gtype = _property_get_spec(property_info)->value_type; + GType setting_gtype = property_info->setting_info->general->get_setting_gtype(); + GType prop_gtype = + nm_setting_get_enum_property_type(setting_gtype, property_info->property_name); if (property_info->property_typ_data && property_info->property_typ_data->subtype.gobject_enum.get_gtype) { /* if the property is already enum, don't set get_gtype: it's redundant and error prone */ - g_return_val_if_fail(NM_IN_SET(gtype, G_TYPE_INT, G_TYPE_UINT), G_TYPE_INVALID); + g_return_val_if_fail(prop_gtype == G_TYPE_INVALID, G_TYPE_INVALID); return property_info->property_typ_data->subtype.gobject_enum.get_gtype(); } - g_return_val_if_fail(G_TYPE_IS_ENUM(gtype) || G_TYPE_IS_FLAGS(gtype), G_TYPE_INVALID); - return gtype; + g_return_val_if_fail(G_TYPE_IS_ENUM(prop_gtype) || G_TYPE_IS_FLAGS(prop_gtype), G_TYPE_INVALID); + return prop_gtype; } /** @@ -1579,33 +1567,18 @@ _set_fcn_gobject_mac(ARGS_SET_FCN) static gboolean _set_fcn_gobject_enum(ARGS_SET_FCN) { - GType gtype = 0; - GType gtype_prop; - gboolean has_gtype = FALSE; - nm_auto_unset_gvalue GValue gval = G_VALUE_INIT; + GType gtype; + GType gtype_gobj; + nm_auto_unset_gvalue GValue gval = G_VALUE_INIT; gboolean is_flags; int v; if (_SET_FCN_DO_RESET_DEFAULT_WITH_SUPPORTS_REMOVE(property_info, modifier, value)) return _gobject_property_reset_default(setting, property_info->property_name); - if (property_info->property_typ_data) { - if (property_info->property_typ_data->subtype.gobject_enum.get_gtype) { - gtype = property_info->property_typ_data->subtype.gobject_enum.get_gtype(); - has_gtype = TRUE; - } - } + gtype = nm_meta_property_enum_get_type(property_info); + g_return_val_if_fail(gtype != G_TYPE_INVALID, FALSE); - gtype_prop = _gobject_property_get_gtype(G_OBJECT(setting), property_info->property_name); - - if (has_gtype) { - /* if the property is already enum, don't set get_gtype: it's redundant and error prone */ - g_return_val_if_fail(NM_IN_SET(gtype_prop, G_TYPE_INT, G_TYPE_UINT), FALSE); - } else { - gtype = gtype_prop; - } - - g_return_val_if_fail(G_TYPE_IS_FLAGS(gtype) || G_TYPE_IS_ENUM(gtype), FALSE); is_flags = G_TYPE_IS_FLAGS(gtype); if (!_nm_utils_enum_from_str_full( @@ -1641,10 +1614,12 @@ _set_fcn_gobject_enum(ARGS_SET_FCN) v = (int) (v_flag | ((guint) v)); } - g_value_init(&gval, gtype_prop); - if (gtype_prop == G_TYPE_INT) + gtype_gobj = _gobject_property_get_gtype(G_OBJECT(setting), property_info->property_name); + + g_value_init(&gval, gtype_gobj); + if (gtype_gobj == G_TYPE_INT) g_value_set_int(&gval, v); - else if (gtype_prop == G_TYPE_UINT) + else if (gtype_gobj == G_TYPE_UINT) g_value_set_uint(&gval, v); else if (is_flags) g_value_set_flags(&gval, v);