diff options
Diffstat (limited to 'src/libnm-client-impl/nm-dbus-helpers.c')
-rw-r--r-- | src/libnm-client-impl/nm-dbus-helpers.c | 110 |
1 files changed, 110 insertions, 0 deletions
diff --git a/src/libnm-client-impl/nm-dbus-helpers.c b/src/libnm-client-impl/nm-dbus-helpers.c new file mode 100644 index 0000000000..3b5f9ff88a --- /dev/null +++ b/src/libnm-client-impl/nm-dbus-helpers.c @@ -0,0 +1,110 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2013 Red Hat, Inc. + */ + +#include "libnm-client-impl/nm-default-libnm.h" + +#include "nm-dbus-helpers.h" + +#include "nm-dbus-interface.h" + +GBusType +_nm_dbus_bus_type(void) +{ + static volatile int bus_type = G_BUS_TYPE_NONE; + int v; + + v = g_atomic_int_get(&bus_type); + if (G_UNLIKELY(v == G_BUS_TYPE_NONE)) { + v = G_BUS_TYPE_SYSTEM; + if (g_getenv("LIBNM_USE_SESSION_BUS")) + v = G_BUS_TYPE_SESSION; + if (!g_atomic_int_compare_and_exchange(&bus_type, G_BUS_TYPE_NONE, v)) + v = g_atomic_int_get(&bus_type); + nm_assert(v != G_BUS_TYPE_NONE); + } + return v; +} + +/* Binds the properties on a generated server-side GDBus object to the + * corresponding properties on the public object. + */ +void +_nm_dbus_bind_properties(gpointer object, gpointer skeleton) +{ + GParamSpec **properties; + guint n_properties; + int i; + + properties = g_object_class_list_properties(G_OBJECT_GET_CLASS(skeleton), &n_properties); + for (i = 0; i < n_properties; i++) { + if (g_str_has_prefix(properties[i]->name, "g-")) + continue; + + g_object_bind_property(object, + properties[i]->name, + skeleton, + properties[i]->name, + G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE); + } + g_free(properties); +} + +static char * +signal_name_from_method_name(const char *method_name) +{ + GString * signal_name; + const char *p; + + signal_name = g_string_new("handle"); + for (p = method_name; *p; p++) { + if (g_ascii_isupper(*p)) + g_string_append_c(signal_name, '-'); + g_string_append_c(signal_name, g_ascii_tolower(*p)); + } + + return g_string_free(signal_name, FALSE); +} + +static void +_nm_dbus_method_meta_marshal(GClosure * closure, + GValue * return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data) +{ + closure->marshal(closure, + return_value, + n_param_values, + param_values, + invocation_hint, + ((GCClosure *) closure)->callback); + + g_value_set_boolean(return_value, TRUE); +} + +/* Takes (method_name, handler_func) pairs and connects the handlers to the + * signals on skeleton, with object as the user_data, but swapped so it comes + * first in the argument list, and handling the return value automatically. + */ +void +_nm_dbus_bind_methods(gpointer object, gpointer skeleton, ...) +{ + va_list ap; + const char *method_name; + char * signal_name; + GCallback handler; + GClosure * closure; + + va_start(ap, skeleton); + while ((method_name = va_arg(ap, const char *)) && (handler = va_arg(ap, GCallback))) { + signal_name = signal_name_from_method_name(method_name); + closure = g_cclosure_new_swap(handler, object, NULL); + g_closure_set_meta_marshal(closure, NULL, _nm_dbus_method_meta_marshal); + g_signal_connect_closure(skeleton, signal_name, closure, FALSE); + g_free(signal_name); + } + va_end(ap); +} |