#include /* ---------------------------------------------------------------------------------------------------- */ /* The D-Bus interface definition we want to create a GDBusProxy-derived type for: */ /* ---------------------------------------------------------------------------------------------------- */ static const gchar introspection_xml[] = "" " " " " " " " " " " " " " " " " " " " " " " ""; /* ---------------------------------------------------------------------------------------------------- */ /* Definition of the AccountsUser type */ /* ---------------------------------------------------------------------------------------------------- */ #define ACCOUNTS_TYPE_USER (accounts_user_get_type ()) #define ACCOUNTS_USER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), ACCOUNTS_TYPE_USER, AccountsUser)) #define ACCOUNTS_USER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), ACCOUNTS_TYPE_USER, AccountsUserClass)) #define ACCOUNTS_USER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), ACCOUNTS_TYPE_USER, AccountsUserClass)) #define ACCOUNTS_IS_USER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), ACCOUNTS_TYPE_USER)) #define ACCOUNTS_IS_USER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), ACCOUNTS_TYPE_USER)) typedef struct _AccountsUser AccountsUser; typedef struct _AccountsUserClass AccountsUserClass; typedef struct _AccountsUserPrivate AccountsUserPrivate; struct _AccountsUser { /*< private >*/ GDBusProxy parent_instance; AccountsUserPrivate *priv; }; struct _AccountsUserClass { /*< private >*/ GDBusProxyClass parent_class; void (*changed) (AccountsUser *user); }; GType accounts_user_get_type (void) G_GNUC_CONST; const gchar *accounts_user_get_user_name (AccountsUser *user); const gchar *accounts_user_get_real_name (AccountsUser *user); gboolean accounts_user_get_automatic_login (AccountsUser *user); void accounts_user_frobnicate (AccountsUser *user, const gchar *flux, gint baz, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data); gchar *accounts_user_frobnicate_finish (AccountsUser *user, GAsyncResult *res, GError **error); gchar *accounts_user_frobnicate_sync (AccountsUser *user, const gchar *flux, gint baz, GCancellable *cancellable, GError **error); /* ---------------------------------------------------------------------------------------------------- */ /* Implementation of the AccountsUser type */ /* ---------------------------------------------------------------------------------------------------- */ /* A more efficient approach than parsing XML is to use const static * GDBusInterfaceInfo, GDBusMethodInfo, ... structures */ static GDBusInterfaceInfo * accounts_user_get_interface_info (void) { static gsize has_info = 0; static GDBusInterfaceInfo *info = NULL; if (g_once_init_enter (&has_info)) { GDBusNodeInfo *introspection_data; introspection_data = g_dbus_node_info_new_for_xml (introspection_xml, NULL); info = introspection_data->interfaces[0]; g_once_init_leave (&has_info, 1); } return info; } enum { PROP_0, PROP_USER_NAME, PROP_REAL_NAME, PROP_AUTOMATIC_LOGIN, }; enum { CHANGED_SIGNAL, LAST_SIGNAL }; static guint signals[LAST_SIGNAL] = {0}; G_DEFINE_TYPE (AccountsUser, accounts_user, G_TYPE_DBUS_PROXY) static void accounts_user_init (AccountsUser *user) { /* Sets the expected interface */ g_dbus_proxy_set_interface_info (G_DBUS_PROXY (user), accounts_user_get_interface_info ()); } static void accounts_user_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { AccountsUser *user = ACCOUNTS_USER (object); switch (prop_id) { case PROP_USER_NAME: g_value_set_string (value, accounts_user_get_user_name (user)); break; case PROP_REAL_NAME: g_value_set_string (value, accounts_user_get_real_name (user)); break; case PROP_AUTOMATIC_LOGIN: g_value_set_boolean (value, accounts_user_get_automatic_login (user)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } } const gchar * accounts_user_get_user_name (AccountsUser *user) { GVariant *value; const gchar *ret; g_return_val_if_fail (ACCOUNTS_IS_USER (user), NULL); value = g_dbus_proxy_get_cached_property (G_DBUS_PROXY (user), "UserName"); ret = g_variant_get_string (value, NULL); g_variant_unref (value); return ret; } const gchar * accounts_user_get_real_name (AccountsUser *user) { GVariant *value; const gchar *ret; g_return_val_if_fail (ACCOUNTS_IS_USER (user), NULL); value = g_dbus_proxy_get_cached_property (G_DBUS_PROXY (user), "RealName"); ret = g_variant_get_string (value, NULL); g_variant_unref (value); return ret; } gboolean accounts_user_get_automatic_login (AccountsUser *user) { GVariant *value; gboolean ret; g_return_val_if_fail (ACCOUNTS_IS_USER (user), FALSE); value = g_dbus_proxy_get_cached_property (G_DBUS_PROXY (user), "AutomaticLogin"); ret = g_variant_get_boolean (value); g_variant_unref (value); return ret; } static void accounts_user_g_signal (GDBusProxy *proxy, const gchar *sender_name, const gchar *signal_name, GVariant *parameters) { AccountsUser *user = ACCOUNTS_USER (proxy); if (g_strcmp0 (signal_name, "Changed") == 0) g_signal_emit (user, signals[CHANGED_SIGNAL], 0); } static void accounts_user_g_properties_changed (GDBusProxy *proxy, GVariant *changed_properties, const gchar* const *invalidated_properties) { AccountsUser *user = ACCOUNTS_USER (proxy); GVariantIter *iter; const gchar *key; if (changed_properties != NULL) { g_variant_get (changed_properties, "a{sv}", &iter); while (g_variant_iter_next (iter, "{&sv}", &key, NULL)) { if (g_strcmp0 (key, "AutomaticLogin") == 0) g_object_notify (G_OBJECT (user), "automatic-login"); else if (g_strcmp0 (key, "RealName") == 0) g_object_notify (G_OBJECT (user), "real-name"); else if (g_strcmp0 (key, "UserName") == 0) g_object_notify (G_OBJECT (user), "user-name"); } g_variant_iter_free (iter); } } static void accounts_user_class_init (AccountsUserClass *klass) { GObjectClass *gobject_class; GDBusProxyClass *proxy_class; gobject_class = G_OBJECT_CLASS (klass); gobject_class->get_property = accounts_user_get_property; proxy_class = G_DBUS_PROXY_CLASS (klass); proxy_class->g_signal = accounts_user_g_signal; proxy_class->g_properties_changed = accounts_user_g_properties_changed; g_object_class_install_property (gobject_class, PROP_USER_NAME, g_param_spec_string ("user-name", "User Name", "The user name of the user", NULL, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); g_object_class_install_property (gobject_class, PROP_REAL_NAME, g_param_spec_string ("real-name", "Real Name", "The real name of the user", NULL, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); g_object_class_install_property (gobject_class, PROP_AUTOMATIC_LOGIN, g_param_spec_boolean ("automatic-login", "Automatic Login", "Whether the user is automatically logged in", FALSE, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); signals[CHANGED_SIGNAL] = g_signal_new ("changed", ACCOUNTS_TYPE_USER, G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (AccountsUserClass, changed), NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); } gchar * accounts_user_frobnicate_sync (AccountsUser *user, const gchar *flux, gint baz, GCancellable *cancellable, GError **error) { gchar *ret; GVariant *value; g_return_val_if_fail (ACCOUNTS_IS_USER (user), NULL); ret = NULL; value = g_dbus_proxy_call_sync (G_DBUS_PROXY (user), "Frobnicate", g_variant_new ("(si)", flux, baz), G_DBUS_CALL_FLAGS_NONE, -1, cancellable, error); if (value != NULL) { g_variant_get (value, "(s)", &ret); g_variant_unref (value); } return ret; } void accounts_user_frobnicate (AccountsUser *user, const gchar *flux, gint baz, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data) { g_return_if_fail (ACCOUNTS_IS_USER (user)); g_dbus_proxy_call (G_DBUS_PROXY (user), "Frobnicate", g_variant_new ("(si)", flux, baz), G_DBUS_CALL_FLAGS_NONE, -1, cancellable, callback, user_data); } gchar * accounts_user_frobnicate_finish (AccountsUser *user, GAsyncResult *res, GError **error) { gchar *ret; GVariant *value; ret = NULL; value = g_dbus_proxy_call_finish (G_DBUS_PROXY (user), res, error); if (value != NULL) { g_variant_get (value, "(s)", &ret); g_variant_unref (value); } return ret; } /* ---------------------------------------------------------------------------------------------------- */ /* Example usage of the AccountsUser type */ /* ---------------------------------------------------------------------------------------------------- */ static void print_user (AccountsUser *user) { g_print (" user-name = `%s'\n", accounts_user_get_user_name (user)); g_print (" real-name = `%s'\n", accounts_user_get_real_name (user)); g_print (" automatic-login = %s\n", accounts_user_get_automatic_login (user) ? "true" : "false"); } static void on_changed (AccountsUser *user, gpointer user_data) { g_print ("+++ Received the AccountsUser::changed signal\n"); print_user (user); } static void on_notify (GObject *object, GParamSpec *pspec, gpointer user_data) { AccountsUser *user = ACCOUNTS_USER (object); g_print ("+++ Received the GObject::notify signal for property `%s'\n", pspec->name); print_user (user); } static void on_accounts_proxy_available (GObject *object, GAsyncResult *result, gpointer user_data) { GError *error = NULL; GObject *user_object; AccountsUser *user; user_object = g_async_initable_new_finish (G_ASYNC_INITABLE (object), result, &error); if (!user_object) { g_error ("Failed to create proxy: %s", error->message); g_clear_error (&error); return; } user = ACCOUNTS_USER (user_object); g_print ("+++ Acquired proxy for user\n"); print_user (user); g_signal_connect (user, "notify", G_CALLBACK (on_notify), NULL); g_signal_connect (user, "changed", G_CALLBACK (on_changed), NULL); } static void on_accounts_appeared (GDBusConnection *connection, const gchar *name, const gchar *name_owner, gpointer user_data) { g_async_initable_new_async (ACCOUNTS_TYPE_USER, 0, NULL, on_accounts_proxy_available, "g-flags", 0, "g-interface-info", NULL, "g-unique-bus-name", name_owner, "g-connection", connection, "g-object-path", "/org/freedesktop/Accounts/User500", "g-interface-name", "org.freedesktop.Accounts.User"); } static void on_accounts_vanished (GDBusConnection *connection, const gchar *name, gpointer user_data) { } /* ---------------------------------------------------------------------------------------------------- */ gint main (gint argc, gchar *argv[]) { guint watcher_id; GMainLoop *loop; watcher_id = g_bus_watch_name (G_BUS_TYPE_SYSTEM, "org.freedesktop.Accounts", G_BUS_NAME_WATCHER_FLAGS_AUTO_START, on_accounts_appeared, on_accounts_vanished, NULL, NULL); loop = g_main_loop_new (NULL, FALSE); g_main_loop_run (loop); g_main_loop_unref (loop); g_bus_unwatch_name (watcher_id); return 0; }