summaryrefslogtreecommitdiff
path: root/src/libnm-client-impl/nm-dbus-helpers.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libnm-client-impl/nm-dbus-helpers.c')
-rw-r--r--src/libnm-client-impl/nm-dbus-helpers.c110
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);
+}