nm-setting: implement direct_enum as GObject property of type int
This commit is contained in:
@@ -1966,4 +1966,5 @@ global:
|
|||||||
nm_setting_hsr_get_type;
|
nm_setting_hsr_get_type;
|
||||||
nm_setting_hsr_new;
|
nm_setting_hsr_new;
|
||||||
nm_setting_ip_config_get_dhcp_dscp;
|
nm_setting_ip_config_get_dhcp_dscp;
|
||||||
|
nm_setting_get_enum_property_type;
|
||||||
} libnm_1_44_0;
|
} libnm_1_44_0;
|
||||||
|
@@ -769,7 +769,7 @@
|
|||||||
/>
|
/>
|
||||||
<property name="autoconnect-ports"
|
<property name="autoconnect-ports"
|
||||||
dbus-type="i"
|
dbus-type="i"
|
||||||
gprop-type="NMTernary"
|
gprop-type="gint"
|
||||||
/>
|
/>
|
||||||
<property name="autoconnect-priority"
|
<property name="autoconnect-priority"
|
||||||
dbus-type="i"
|
dbus-type="i"
|
||||||
|
@@ -2655,7 +2655,7 @@ nm_setting_connection_class_init(NMSettingConnectionClass *klass)
|
|||||||
* when this connection is activated.
|
* when this connection is activated.
|
||||||
* ---end---
|
* ---end---
|
||||||
*/
|
*/
|
||||||
prop_idx = _nm_setting_property_define_direct_enum(
|
prop_idx = _nm_setting_property_define_direct_real_enum(
|
||||||
properties_override,
|
properties_override,
|
||||||
obj_properties,
|
obj_properties,
|
||||||
NM_SETTING_CONNECTION_AUTOCONNECT_SLAVES,
|
NM_SETTING_CONNECTION_AUTOCONNECT_SLAVES,
|
||||||
@@ -2776,16 +2776,16 @@ nm_setting_connection_class_init(NMSettingConnectionClass *klass)
|
|||||||
* example: CONNECTION_METERED=yes
|
* example: CONNECTION_METERED=yes
|
||||||
* ---end---
|
* ---end---
|
||||||
*/
|
*/
|
||||||
_nm_setting_property_define_direct_enum(properties_override,
|
_nm_setting_property_define_direct_real_enum(properties_override,
|
||||||
obj_properties,
|
obj_properties,
|
||||||
NM_SETTING_CONNECTION_METERED,
|
NM_SETTING_CONNECTION_METERED,
|
||||||
PROP_METERED,
|
PROP_METERED,
|
||||||
NM_TYPE_METERED,
|
NM_TYPE_METERED,
|
||||||
NM_METERED_UNKNOWN,
|
NM_METERED_UNKNOWN,
|
||||||
NM_SETTING_PARAM_REAPPLY_IMMEDIATELY,
|
NM_SETTING_PARAM_REAPPLY_IMMEDIATELY,
|
||||||
NULL,
|
NULL,
|
||||||
NMSettingConnectionPrivate,
|
NMSettingConnectionPrivate,
|
||||||
metered);
|
metered);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* NMSettingConnection:lldp:
|
* 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],
|
obj_properties[PROP_AUTO_ROUTE_EXT_GW],
|
||||||
&nm_sett_info_propert_type_direct_enum,
|
&nm_sett_info_propert_type_direct_enum,
|
||||||
.direct_offset =
|
.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(
|
_nm_properties_override_gobj(
|
||||||
properties_override,
|
properties_override,
|
||||||
obj_properties[PROP_REPLACE_LOCAL_RULE],
|
obj_properties[PROP_REPLACE_LOCAL_RULE],
|
||||||
&nm_sett_info_propert_type_direct_enum,
|
&nm_sett_info_propert_type_direct_enum,
|
||||||
.direct_offset =
|
.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(
|
_nm_properties_override_gobj(
|
||||||
properties_override,
|
properties_override,
|
||||||
|
@@ -941,16 +941,16 @@ nm_setting_ip6_config_class_init(NMSettingIP6ConfigClass *klass)
|
|||||||
* example: IPV6_PRIVACY=rfc3041 IPV6_PRIVACY_PREFER_PUBLIC_IP=yes
|
* example: IPV6_PRIVACY=rfc3041 IPV6_PRIVACY_PREFER_PUBLIC_IP=yes
|
||||||
* ---end---
|
* ---end---
|
||||||
*/
|
*/
|
||||||
_nm_setting_property_define_direct_enum(properties_override,
|
_nm_setting_property_define_direct_real_enum(properties_override,
|
||||||
obj_properties,
|
obj_properties,
|
||||||
NM_SETTING_IP6_CONFIG_IP6_PRIVACY,
|
NM_SETTING_IP6_CONFIG_IP6_PRIVACY,
|
||||||
PROP_IP6_PRIVACY,
|
PROP_IP6_PRIVACY,
|
||||||
NM_TYPE_SETTING_IP6_CONFIG_PRIVACY,
|
NM_TYPE_SETTING_IP6_CONFIG_PRIVACY,
|
||||||
NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN,
|
NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN,
|
||||||
NM_SETTING_PARAM_NONE,
|
NM_SETTING_PARAM_NONE,
|
||||||
NULL,
|
NULL,
|
||||||
NMSettingIP6ConfigPrivate,
|
NMSettingIP6ConfigPrivate,
|
||||||
ip6_privacy);
|
ip6_privacy);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* NMSettingIP6Config:addr-gen-mode:
|
* NMSettingIP6Config:addr-gen-mode:
|
||||||
@@ -1215,7 +1215,7 @@ nm_setting_ip6_config_class_init(NMSettingIP6ConfigClass *klass)
|
|||||||
NM_SETTING_PARAM_NONE,
|
NM_SETTING_PARAM_NONE,
|
||||||
NMSettingIP6ConfigPrivate,
|
NMSettingIP6ConfigPrivate,
|
||||||
dhcp_pd_hint,
|
dhcp_pd_hint,
|
||||||
.direct_set_fcn.set_string =
|
.direct_data.set_string =
|
||||||
_set_string_fcn_dhcp_pd_hint,
|
_set_string_fcn_dhcp_pd_hint,
|
||||||
.direct_string_allow_empty = TRUE);
|
.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, \
|
#define _nm_setting_property_define_direct_enum(properties_override, \
|
||||||
obj_properties, \
|
obj_properties, \
|
||||||
prop_name, \
|
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_REAPPLY_IMMEDIATELY | NM_SETTING_PARAM_FUZZY_IGNORE \
|
||||||
| NM_SETTING_PARAM_INFERRABLE))); \
|
| 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 "", \
|
_param_spec = g_param_spec_enum("" prop_name "", \
|
||||||
"", \
|
"", \
|
||||||
"", \
|
"", \
|
||||||
@@ -941,11 +1000,26 @@ _nm_properties_override(GArray *properties_override, const NMSettInfoProperty *p
|
|||||||
_property_type, \
|
_property_type, \
|
||||||
.direct_offset = \
|
.direct_offset = \
|
||||||
NM_STRUCT_OFFSET_ENSURE_TYPE(int, private_struct_type, private_struct_field), \
|
NM_STRUCT_OFFSET_ENSURE_TYPE(int, private_struct_type, private_struct_field), \
|
||||||
|
.direct_data.enum_gtype = (gtype_enum), \
|
||||||
__VA_ARGS__); \
|
__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, \
|
#define _nm_setting_property_define_direct_ternary_enum(properties_override, \
|
||||||
obj_properties, \
|
obj_properties, \
|
||||||
prop_name, \
|
prop_name, \
|
||||||
@@ -954,17 +1028,17 @@ _nm_properties_override(GArray *properties_override, const NMSettInfoProperty *p
|
|||||||
private_struct_type, \
|
private_struct_type, \
|
||||||
private_struct_field, \
|
private_struct_field, \
|
||||||
...) \
|
...) \
|
||||||
_nm_setting_property_define_direct_enum((properties_override), \
|
_nm_setting_property_define_direct_real_enum((properties_override), \
|
||||||
(obj_properties), \
|
(obj_properties), \
|
||||||
prop_name, \
|
prop_name, \
|
||||||
(prop_id), \
|
(prop_id), \
|
||||||
NM_TYPE_TERNARY, \
|
NM_TYPE_TERNARY, \
|
||||||
NM_TERNARY_DEFAULT, \
|
NM_TERNARY_DEFAULT, \
|
||||||
(param_flags), \
|
(param_flags), \
|
||||||
NULL, \
|
NULL, \
|
||||||
private_struct_type, \
|
private_struct_type, \
|
||||||
private_struct_field, \
|
private_struct_field, \
|
||||||
__VA_ARGS__)
|
__VA_ARGS__)
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
@@ -2361,8 +2361,7 @@ nm_setting_wireguard_class_init(NMSettingWireGuardClass *klass)
|
|||||||
NM_SETTING_PARAM_SECRET,
|
NM_SETTING_PARAM_SECRET,
|
||||||
NMSettingWireGuard,
|
NMSettingWireGuard,
|
||||||
_priv.private_key,
|
_priv.private_key,
|
||||||
.direct_set_fcn.set_string =
|
.direct_data.set_string = _set_string_fcn_public_key,
|
||||||
_set_string_fcn_public_key,
|
|
||||||
.direct_string_allow_empty = TRUE);
|
.direct_string_allow_empty = TRUE);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -684,10 +684,10 @@ _property_direct_set_string(const NMSettInfoSetting *sett_info,
|
|||||||
+ (!!property_info->direct_string_is_refstr)
|
+ (!!property_info->direct_string_is_refstr)
|
||||||
+ (property_info->direct_set_string_mac_address_len > 0)
|
+ (property_info->direct_set_string_mac_address_len > 0)
|
||||||
+ (property_info->direct_set_string_ip_address_addr_family != 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) {
|
if (property_info->direct_data.set_string) {
|
||||||
return property_info->direct_set_fcn.set_string(sett_info, property_info, setting, src);
|
return property_info->direct_data.set_string(sett_info, property_info, setting, src);
|
||||||
}
|
}
|
||||||
|
|
||||||
dst = _nm_setting_get_private_field(setting, sett_info, property_info);
|
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);
|
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;
|
return;
|
||||||
}
|
}
|
||||||
case NM_VALUE_TYPE_FLAGS:
|
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 *p_val = _nm_setting_get_private_field(setting, sett_info, property_info);
|
||||||
int v;
|
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)
|
if (*p_val == v)
|
||||||
return;
|
return;
|
||||||
*p_val = v;
|
*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 *p_val = _nm_setting_get_private_field(setting, sett_info, property_info);
|
||||||
int def_val;
|
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));
|
nm_assert(NM_IN_SET(*p_val, 0, property_info->direct_is_aliased_field ? def_val : 0));
|
||||||
*p_val = def_val;
|
*p_val = def_val;
|
||||||
break;
|
break;
|
||||||
@@ -1255,10 +1273,22 @@ _nm_setting_property_to_dbus_fcn_direct(_NM_SETT_INFO_PROP_TO_DBUS_FCN_ARGS _nm_
|
|||||||
{
|
{
|
||||||
int val;
|
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));
|
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))
|
if (!property_info->to_dbus_including_default) {
|
||||||
return NULL;
|
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);
|
return nm_g_variant_maybe_singleton_i(val);
|
||||||
}
|
}
|
||||||
case NM_VALUE_TYPE_FLAGS:
|
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); \
|
GVariant *_value = (value); \
|
||||||
gboolean _success = FALSE; \
|
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) { \
|
if (_property_info->property_type->from_dbus_direct_allow_transform) { \
|
||||||
nm_auto_unset_gvalue GValue _gvalue = G_VALUE_INIT; \
|
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:
|
case NM_VALUE_TYPE_ENUM:
|
||||||
{
|
{
|
||||||
const GParamSpecEnum *param_spec;
|
int *p_val;
|
||||||
int *p_val;
|
int v;
|
||||||
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)) {
|
if (g_variant_is_of_type(value, G_VARIANT_TYPE_INT32)) {
|
||||||
G_STATIC_ASSERT(sizeof(int) >= sizeof(gint32));
|
G_STATIC_ASSERT(sizeof(int) >= sizeof(gint32));
|
||||||
v = g_variant_get_int32(value);
|
v = g_variant_get_int32(value);
|
||||||
} else {
|
} else {
|
||||||
if (!_variant_get_value_transform(property_info,
|
GType gtype = G_TYPE_IS_ENUM(property_info->param_spec->value_type)
|
||||||
value,
|
? property_info->param_spec->value_type
|
||||||
G_TYPE_FROM_CLASS(param_spec->enum_class),
|
: G_TYPE_INT;
|
||||||
g_value_get_flags,
|
|
||||||
&v))
|
if (!_variant_get_value_transform(property_info, value, gtype, g_value_get_flags, &v))
|
||||||
goto out_error_wrong_dbus_type;
|
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)
|
if (*p_val == v)
|
||||||
goto out_unchanged;
|
goto out_unchanged;
|
||||||
|
|
||||||
if (!g_enum_get_value(param_spec->enum_class, v))
|
/* To avoid that clients with old libnm fails setting a newer value received
|
||||||
goto out_error_param_spec_validation;
|
* 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;
|
*p_val = v;
|
||||||
goto out_notify;
|
goto out_notify;
|
||||||
}
|
}
|
||||||
@@ -2443,7 +2485,6 @@ _verify_properties(NMSetting *setting, GError **error)
|
|||||||
case NM_VALUE_TYPE_BOOL:
|
case NM_VALUE_TYPE_BOOL:
|
||||||
case NM_VALUE_TYPE_BYTES:
|
case NM_VALUE_TYPE_BYTES:
|
||||||
case NM_VALUE_TYPE_STRV:
|
case NM_VALUE_TYPE_STRV:
|
||||||
case NM_VALUE_TYPE_ENUM:
|
|
||||||
case NM_VALUE_TYPE_FLAGS:
|
case NM_VALUE_TYPE_FLAGS:
|
||||||
case NM_VALUE_TYPE_INT32:
|
case NM_VALUE_TYPE_INT32:
|
||||||
case NM_VALUE_TYPE_INT64:
|
case NM_VALUE_TYPE_INT64:
|
||||||
@@ -2451,6 +2492,37 @@ _verify_properties(NMSetting *setting, GError **error)
|
|||||||
case NM_VALUE_TYPE_UINT32:
|
case NM_VALUE_TYPE_UINT32:
|
||||||
case NM_VALUE_TYPE_UINT64:
|
case NM_VALUE_TYPE_UINT64:
|
||||||
break;
|
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:
|
case NM_VALUE_TYPE_STRING:
|
||||||
{
|
{
|
||||||
const char *val;
|
const char *val;
|
||||||
@@ -4465,6 +4537,43 @@ nm_range_from_str(const char *str, GError **error)
|
|||||||
return nm_range_new(start, end);
|
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
|
static void
|
||||||
|
@@ -4565,7 +4565,7 @@ test_setting_metadata(void)
|
|||||||
GArray *property_types_data;
|
GArray *property_types_data;
|
||||||
guint prop_idx_val;
|
guint prop_idx_val;
|
||||||
gboolean can_set_including_default = FALSE;
|
gboolean can_set_including_default = FALSE;
|
||||||
gboolean can_have_direct_set_fcn = FALSE;
|
gboolean can_have_direct_data = FALSE;
|
||||||
int n_special_options;
|
int n_special_options;
|
||||||
|
|
||||||
g_assert(sip->name);
|
g_assert(sip->name);
|
||||||
@@ -4662,18 +4662,35 @@ test_setting_metadata(void)
|
|||||||
|
|
||||||
can_set_including_default = TRUE;
|
can_set_including_default = TRUE;
|
||||||
} else if (sip->property_type->direct_type == NM_VALUE_TYPE_ENUM) {
|
} 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(g_variant_type_equal(sip->property_type->dbus_type, "i"));
|
||||||
g_assert(sip->param_spec);
|
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);
|
if (G_TYPE_IS_ENUM(sip->param_spec->value_type)) {
|
||||||
g_assert(G_TYPE_FROM_CLASS(pspec->enum_class) == sip->param_spec->value_type);
|
const GParamSpecEnum *pspec = NM_G_PARAM_SPEC_CAST_ENUM(sip->param_spec);
|
||||||
g_assert(g_enum_get_value(pspec->enum_class, pspec->default_value));
|
|
||||||
|
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_set_including_default = TRUE;
|
||||||
|
can_have_direct_data = TRUE;
|
||||||
} else if (sip->property_type->direct_type == NM_VALUE_TYPE_FLAGS) {
|
} else if (sip->property_type->direct_type == NM_VALUE_TYPE_FLAGS) {
|
||||||
const GParamSpecFlags *pspec;
|
const GParamSpecFlags *pspec;
|
||||||
|
|
||||||
@@ -4703,7 +4720,7 @@ test_setting_metadata(void)
|
|||||||
INFINIBAND_ALEN));
|
INFINIBAND_ALEN));
|
||||||
} else {
|
} else {
|
||||||
g_assert(g_variant_type_equal(sip->property_type->dbus_type, "s"));
|
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);
|
||||||
g_assert(sip->param_spec->value_type == G_TYPE_STRING);
|
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);
|
g_assert(sip->property_type->direct_type == NM_VALUE_TYPE_STRING);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!can_have_direct_set_fcn)
|
if (!can_have_direct_data)
|
||||||
g_assert(!sip->direct_set_fcn.set_string);
|
g_assert(!sip->direct_data.set_string);
|
||||||
|
|
||||||
if (sip->property_type->direct_type == NM_VALUE_TYPE_NONE)
|
if (sip->property_type->direct_type == NM_VALUE_TYPE_NONE)
|
||||||
g_assert(!sip->direct_also_notify);
|
g_assert(!sip->direct_also_notify);
|
||||||
|
@@ -800,7 +800,13 @@ struct _NMSettInfoProperty {
|
|||||||
const NMSettInfoProperty *property_info,
|
const NMSettInfoProperty *property_info,
|
||||||
NMSetting *setting,
|
NMSetting *setting,
|
||||||
const char *src);
|
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
|
/* For direct properties, this is the param_spec that also should be
|
||||||
* notified on changes. */
|
* 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 GVariantType *nm_setting_get_dbus_property_type(NMSetting *setting,
|
||||||
const char *property_name);
|
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;
|
typedef struct _NMRange NMRange;
|
||||||
|
@@ -1073,7 +1073,6 @@ _get_fcn_gobject_enum(ARGS_GET_FCN)
|
|||||||
{
|
{
|
||||||
GType gtype = 0;
|
GType gtype = 0;
|
||||||
const NMUtilsEnumValueInfo *value_infos = NULL;
|
const NMUtilsEnumValueInfo *value_infos = NULL;
|
||||||
gboolean has_gtype = FALSE;
|
|
||||||
nm_auto_unset_gvalue GValue gval = G_VALUE_INIT;
|
nm_auto_unset_gvalue GValue gval = G_VALUE_INIT;
|
||||||
gint64 v;
|
gint64 v;
|
||||||
gboolean format_numeric = FALSE;
|
gboolean format_numeric = FALSE;
|
||||||
@@ -1087,13 +1086,6 @@ _get_fcn_gobject_enum(ARGS_GET_FCN)
|
|||||||
|
|
||||||
RETURN_UNSUPPORTED_GET_TYPE();
|
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
|
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_FLAGS_ANY(property_info->property_typ_data->typ_flags,
|
||||||
NM_META_PROPERTY_TYP_FLAG_ENUM_GET_PRETTY_NUMERIC
|
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);
|
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);
|
pspec = g_object_class_find_property(G_OBJECT_GET_CLASS(setting), property_info->property_name);
|
||||||
g_return_val_if_fail(pspec, NULL);
|
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_value_init(&gval, pspec->value_type);
|
||||||
g_object_get_property(G_OBJECT(setting), property_info->property_name, &gval);
|
g_object_get_property(G_OBJECT(setting), property_info->property_name, &gval);
|
||||||
NM_SET_OUT(out_is_default, g_param_value_defaults(pspec, &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
|
GType
|
||||||
nm_meta_property_enum_get_type(const NMMetaPropertyInfo *property_info)
|
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
|
if (property_info->property_typ_data
|
||||||
&& property_info->property_typ_data->subtype.gobject_enum.get_gtype) {
|
&& 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 */
|
/* 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();
|
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);
|
g_return_val_if_fail(G_TYPE_IS_ENUM(prop_gtype) || G_TYPE_IS_FLAGS(prop_gtype), G_TYPE_INVALID);
|
||||||
return gtype;
|
return prop_gtype;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1579,33 +1567,18 @@ _set_fcn_gobject_mac(ARGS_SET_FCN)
|
|||||||
static gboolean
|
static gboolean
|
||||||
_set_fcn_gobject_enum(ARGS_SET_FCN)
|
_set_fcn_gobject_enum(ARGS_SET_FCN)
|
||||||
{
|
{
|
||||||
GType gtype = 0;
|
GType gtype;
|
||||||
GType gtype_prop;
|
GType gtype_gobj;
|
||||||
gboolean has_gtype = FALSE;
|
nm_auto_unset_gvalue GValue gval = G_VALUE_INIT;
|
||||||
nm_auto_unset_gvalue GValue gval = G_VALUE_INIT;
|
|
||||||
gboolean is_flags;
|
gboolean is_flags;
|
||||||
int v;
|
int v;
|
||||||
|
|
||||||
if (_SET_FCN_DO_RESET_DEFAULT_WITH_SUPPORTS_REMOVE(property_info, modifier, value))
|
if (_SET_FCN_DO_RESET_DEFAULT_WITH_SUPPORTS_REMOVE(property_info, modifier, value))
|
||||||
return _gobject_property_reset_default(setting, property_info->property_name);
|
return _gobject_property_reset_default(setting, property_info->property_name);
|
||||||
|
|
||||||
if (property_info->property_typ_data) {
|
gtype = nm_meta_property_enum_get_type(property_info);
|
||||||
if (property_info->property_typ_data->subtype.gobject_enum.get_gtype) {
|
g_return_val_if_fail(gtype != G_TYPE_INVALID, FALSE);
|
||||||
gtype = property_info->property_typ_data->subtype.gobject_enum.get_gtype();
|
|
||||||
has_gtype = TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
is_flags = G_TYPE_IS_FLAGS(gtype);
|
||||||
|
|
||||||
if (!_nm_utils_enum_from_str_full(
|
if (!_nm_utils_enum_from_str_full(
|
||||||
@@ -1641,10 +1614,12 @@ _set_fcn_gobject_enum(ARGS_SET_FCN)
|
|||||||
v = (int) (v_flag | ((guint) v));
|
v = (int) (v_flag | ((guint) v));
|
||||||
}
|
}
|
||||||
|
|
||||||
g_value_init(&gval, gtype_prop);
|
gtype_gobj = _gobject_property_get_gtype(G_OBJECT(setting), property_info->property_name);
|
||||||
if (gtype_prop == G_TYPE_INT)
|
|
||||||
|
g_value_init(&gval, gtype_gobj);
|
||||||
|
if (gtype_gobj == G_TYPE_INT)
|
||||||
g_value_set_int(&gval, v);
|
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);
|
g_value_set_uint(&gval, v);
|
||||||
else if (is_flags)
|
else if (is_flags)
|
||||||
g_value_set_flags(&gval, v);
|
g_value_set_flags(&gval, v);
|
||||||
|
Reference in New Issue
Block a user