mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager
synced 2024-10-06 16:21:50 +00:00
nm-setting: implement direct_enum as GObject property of type int
(cherry picked from commit 260865b1ac
)
This commit is contained in:
parent
fe734c5c11
commit
c31f31acbf
|
@ -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;
|
||||
|
|
|
@ -769,7 +769,7 @@
|
|||
/>
|
||||
<property name="autoconnect-ports"
|
||||
dbus-type="i"
|
||||
gprop-type="NMTernary"
|
||||
gprop-type="gint"
|
||||
/>
|
||||
<property name="autoconnect-priority"
|
||||
dbus-type="i"
|
||||
|
|
|
@ -2655,7 +2655,7 @@ nm_setting_connection_class_init(NMSettingConnectionClass *klass)
|
|||
* when this connection is activated.
|
||||
* ---end---
|
||||
*/
|
||||
prop_idx = _nm_setting_property_define_direct_enum(
|
||||
prop_idx = _nm_setting_property_define_direct_real_enum(
|
||||
properties_override,
|
||||
obj_properties,
|
||||
NM_SETTING_CONNECTION_AUTOCONNECT_SLAVES,
|
||||
|
@ -2776,16 +2776,16 @@ nm_setting_connection_class_init(NMSettingConnectionClass *klass)
|
|||
* example: CONNECTION_METERED=yes
|
||||
* ---end---
|
||||
*/
|
||||
_nm_setting_property_define_direct_enum(properties_override,
|
||||
obj_properties,
|
||||
NM_SETTING_CONNECTION_METERED,
|
||||
PROP_METERED,
|
||||
NM_TYPE_METERED,
|
||||
NM_METERED_UNKNOWN,
|
||||
NM_SETTING_PARAM_REAPPLY_IMMEDIATELY,
|
||||
NULL,
|
||||
NMSettingConnectionPrivate,
|
||||
metered);
|
||||
_nm_setting_property_define_direct_real_enum(properties_override,
|
||||
obj_properties,
|
||||
NM_SETTING_CONNECTION_METERED,
|
||||
PROP_METERED,
|
||||
NM_TYPE_METERED,
|
||||
NM_METERED_UNKNOWN,
|
||||
NM_SETTING_PARAM_REAPPLY_IMMEDIATELY,
|
||||
NULL,
|
||||
NMSettingConnectionPrivate,
|
||||
metered);
|
||||
|
||||
/**
|
||||
* NMSettingConnection:lldp:
|
||||
|
|
|
@ -6139,14 +6139,16 @@ _nm_sett_info_property_override_create_array_ip_config(int addr_family)
|
|||
obj_properties[PROP_AUTO_ROUTE_EXT_GW],
|
||||
&nm_sett_info_propert_type_direct_enum,
|
||||
.direct_offset =
|
||||
NM_STRUCT_OFFSET_ENSURE_TYPE(int, NMSettingIPConfigPrivate, auto_route_ext_gw));
|
||||
NM_STRUCT_OFFSET_ENSURE_TYPE(int, NMSettingIPConfigPrivate, auto_route_ext_gw),
|
||||
.direct_data.enum_gtype = NM_TYPE_TERNARY);
|
||||
|
||||
_nm_properties_override_gobj(
|
||||
properties_override,
|
||||
obj_properties[PROP_REPLACE_LOCAL_RULE],
|
||||
&nm_sett_info_propert_type_direct_enum,
|
||||
.direct_offset =
|
||||
NM_STRUCT_OFFSET_ENSURE_TYPE(int, NMSettingIPConfigPrivate, replace_local_rule));
|
||||
NM_STRUCT_OFFSET_ENSURE_TYPE(int, NMSettingIPConfigPrivate, replace_local_rule),
|
||||
.direct_data.enum_gtype = NM_TYPE_TERNARY);
|
||||
|
||||
_nm_properties_override_gobj(
|
||||
properties_override,
|
||||
|
|
|
@ -941,16 +941,16 @@ nm_setting_ip6_config_class_init(NMSettingIP6ConfigClass *klass)
|
|||
* example: IPV6_PRIVACY=rfc3041 IPV6_PRIVACY_PREFER_PUBLIC_IP=yes
|
||||
* ---end---
|
||||
*/
|
||||
_nm_setting_property_define_direct_enum(properties_override,
|
||||
obj_properties,
|
||||
NM_SETTING_IP6_CONFIG_IP6_PRIVACY,
|
||||
PROP_IP6_PRIVACY,
|
||||
NM_TYPE_SETTING_IP6_CONFIG_PRIVACY,
|
||||
NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN,
|
||||
NM_SETTING_PARAM_NONE,
|
||||
NULL,
|
||||
NMSettingIP6ConfigPrivate,
|
||||
ip6_privacy);
|
||||
_nm_setting_property_define_direct_real_enum(properties_override,
|
||||
obj_properties,
|
||||
NM_SETTING_IP6_CONFIG_IP6_PRIVACY,
|
||||
PROP_IP6_PRIVACY,
|
||||
NM_TYPE_SETTING_IP6_CONFIG_PRIVACY,
|
||||
NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN,
|
||||
NM_SETTING_PARAM_NONE,
|
||||
NULL,
|
||||
NMSettingIP6ConfigPrivate,
|
||||
ip6_privacy);
|
||||
|
||||
/**
|
||||
* NMSettingIP6Config:addr-gen-mode:
|
||||
|
@ -1215,7 +1215,7 @@ nm_setting_ip6_config_class_init(NMSettingIP6ConfigClass *klass)
|
|||
NM_SETTING_PARAM_NONE,
|
||||
NMSettingIP6ConfigPrivate,
|
||||
dhcp_pd_hint,
|
||||
.direct_set_fcn.set_string =
|
||||
.direct_data.set_string =
|
||||
_set_string_fcn_dhcp_pd_hint,
|
||||
.direct_string_allow_empty = TRUE);
|
||||
|
||||
|
|
|
@ -904,6 +904,13 @@ _nm_properties_override(GArray *properties_override, const NMSettInfoProperty *p
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
/* Define a direct property of type enum, but using `int` as type in the underlying
|
||||
* GObject property. This is the preferred way to define enum properties because using
|
||||
* real enums it is not possible to maintain backwards compatibility with clients
|
||||
* using an old libnm (glib asserts against new values of the enum not being valid).
|
||||
* The main difference from define_direct_real_enum is that this will accept any
|
||||
* integer value, and we'll check that it's valid in #NMSetting::verify, as doing
|
||||
* 'verify' is optional for clients. */
|
||||
#define _nm_setting_property_define_direct_enum(properties_override, \
|
||||
obj_properties, \
|
||||
prop_name, \
|
||||
|
@ -924,6 +931,58 @@ _nm_properties_override(GArray *properties_override, const NMSettInfoProperty *p
|
|||
~(NM_SETTING_PARAM_REAPPLY_IMMEDIATELY | NM_SETTING_PARAM_FUZZY_IGNORE \
|
||||
| NM_SETTING_PARAM_INFERRABLE))); \
|
||||
\
|
||||
nm_assert(G_TYPE_IS_ENUM(gtype_enum)); \
|
||||
\
|
||||
_param_spec = g_param_spec_int("" prop_name "", \
|
||||
"", \
|
||||
"", \
|
||||
G_MININT32, \
|
||||
G_MAXINT32, \
|
||||
(default_value), \
|
||||
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY \
|
||||
| G_PARAM_STATIC_STRINGS | (param_flags)); \
|
||||
\
|
||||
(obj_properties)[(prop_id)] = _param_spec; \
|
||||
_property_type = (property_type) ?: &nm_sett_info_propert_type_direct_enum; \
|
||||
\
|
||||
_nm_properties_override_gobj( \
|
||||
(properties_override), \
|
||||
_param_spec, \
|
||||
_property_type, \
|
||||
.direct_offset = \
|
||||
NM_STRUCT_OFFSET_ENSURE_TYPE(int, private_struct_type, private_struct_field), \
|
||||
.direct_data.enum_gtype = (gtype_enum), \
|
||||
__VA_ARGS__); \
|
||||
})
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/* Define an enum property using real enums in the GObject, not integers. Note that
|
||||
* this is not backwards compatible because clients with old libnm will reject
|
||||
* newer values of the enum. Generally you want to use define_direct_enum and use this
|
||||
* one only for properties that already existed as real enums */
|
||||
#define _nm_setting_property_define_direct_real_enum(properties_override, \
|
||||
obj_properties, \
|
||||
prop_name, \
|
||||
prop_id, \
|
||||
gtype_enum, \
|
||||
default_value, \
|
||||
param_flags, \
|
||||
property_type, \
|
||||
private_struct_type, \
|
||||
private_struct_field, \
|
||||
... /* extra NMSettInfoProperty fields */) \
|
||||
({ \
|
||||
GParamSpec *_param_spec; \
|
||||
const NMSettInfoPropertType *_property_type; \
|
||||
\
|
||||
G_STATIC_ASSERT( \
|
||||
!NM_FLAGS_ANY((param_flags), \
|
||||
~(NM_SETTING_PARAM_REAPPLY_IMMEDIATELY | NM_SETTING_PARAM_FUZZY_IGNORE \
|
||||
| NM_SETTING_PARAM_INFERRABLE))); \
|
||||
\
|
||||
nm_assert(G_TYPE_IS_ENUM(gtype_enum)); \
|
||||
\
|
||||
_param_spec = g_param_spec_enum("" prop_name "", \
|
||||
"", \
|
||||
"", \
|
||||
|
@ -941,11 +1000,26 @@ _nm_properties_override(GArray *properties_override, const NMSettInfoProperty *p
|
|||
_property_type, \
|
||||
.direct_offset = \
|
||||
NM_STRUCT_OFFSET_ENSURE_TYPE(int, private_struct_type, private_struct_field), \
|
||||
.direct_data.enum_gtype = (gtype_enum), \
|
||||
__VA_ARGS__); \
|
||||
})
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
#define _nm_setting_property_is_valid_direct_enum(property_info) \
|
||||
({ \
|
||||
const NMSettInfoProperty *_property_info = (property_info); \
|
||||
NMValueType direct_nmtype = _property_info->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__)
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
/**
|
||||
|
|
|
@ -682,10 +682,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);
|
||||
|
@ -805,7 +805,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:
|
||||
|
@ -940,7 +946,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;
|
||||
|
@ -1076,7 +1088,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;
|
||||
|
@ -1234,10 +1252,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:
|
||||
|
@ -1413,7 +1443,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; \
|
||||
\
|
||||
|
@ -1564,21 +1597,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;
|
||||
}
|
||||
|
||||
|
@ -1586,8 +1618,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;
|
||||
}
|
||||
|
@ -2422,7 +2464,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:
|
||||
|
@ -2430,6 +2471,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;
|
||||
|
@ -4444,6 +4516,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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue