From ac85b1dc21843e432ae09b01c29ad2845cf2b41b Mon Sep 17 00:00:00 2001 From: Mark Doffman Date: Sun, 15 Nov 2009 21:19:23 +0000 Subject: Add participation in gnome session management. Patch provided by: Li Yuan --- registryd/registry-main.c | 137 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 136 insertions(+), 1 deletion(-) (limited to 'registryd/registry-main.c') diff --git a/registryd/registry-main.c b/registryd/registry-main.c index 57049032..52fd9b2a 100644 --- a/registryd/registry-main.c +++ b/registryd/registry-main.c @@ -27,6 +27,7 @@ #include #include +#include #include "paths.h" #include "registry.h" @@ -36,14 +37,139 @@ #error "No introspection XML directory defined" #endif +static GMainLoop *mainloop; static gchar *dbus_name = NULL; +static DBusGConnection *bus_connection = NULL; +static DBusGProxy *sm_proxy = NULL; +static char *client_id = NULL; +static DBusGProxy *client_proxy = NULL; + static GOptionEntry optentries[] = { {"dbus-name", 0, 0, G_OPTION_ARG_STRING, &dbus_name, "Well-known name to register with D-Bus", NULL}, {NULL} }; +#define SM_DBUS_NAME "org.gnome.SessionManager" +#define SM_DBUS_PATH "/org/gnome/SessionManager" +#define SM_DBUS_INTERFACE "org.gnome.SessionManager" + +#define SM_CLIENT_DBUS_INTERFACE "org.gnome.SessionManager.ClientPrivate" + +static void registry_session_init (const char *previous_client_id, const char *exe); + +static gboolean +session_manager_connect (void) +{ + + if (bus_connection == NULL) { + GError *error; + + error = NULL; + bus_connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error); + if (bus_connection == NULL) { + g_message ("Failed to connect to the session bus: %s", + error->message); + g_error_free (error); + exit (1); + } + } + + sm_proxy = dbus_g_proxy_new_for_name (bus_connection, + SM_DBUS_NAME, + SM_DBUS_PATH, + SM_DBUS_INTERFACE); + return (sm_proxy != NULL); +} + +static void +stop_cb (gpointer data) +{ + g_main_loop_quit (mainloop); +} + +static gboolean +end_session_response (gboolean is_okay, const gchar *reason) +{ + gboolean ret; + GError *error = NULL; + + ret = dbus_g_proxy_call (client_proxy, "EndSessionResponse", + &error, + G_TYPE_BOOLEAN, is_okay, + G_TYPE_STRING, reason, + G_TYPE_INVALID, + G_TYPE_INVALID); + + if (!ret) { + g_warning ("Failed to send session response %s", error->message); + g_error_free (error); + } + + return ret; +} + +static void +query_end_session_cb (guint flags, gpointer data) +{ + end_session_response (TRUE, NULL); +} + +static void +end_session_cb (guint flags, gpointer data) +{ + end_session_response (TRUE, NULL); + g_main_loop_quit (mainloop); +} +static gboolean +register_client (void) +{ + GError *error; + gboolean res; + const char *startup_id; + const char *app_id; + + startup_id = g_getenv ("DESKTOP_AUTOSTART_ID"); + app_id = "at-spi-registryd.desktop"; + + error = NULL; + res = dbus_g_proxy_call (sm_proxy, + "RegisterClient", + &error, + G_TYPE_STRING, app_id, + G_TYPE_STRING, startup_id, + G_TYPE_INVALID, + DBUS_TYPE_G_OBJECT_PATH, &client_id, + G_TYPE_INVALID); + if (! res) { + g_warning ("Failed to register client: %s", error->message); + g_error_free (error); + return FALSE; + } + + client_proxy = dbus_g_proxy_new_for_name (bus_connection, + SM_DBUS_NAME, + client_id, + SM_CLIENT_DBUS_INTERFACE); + + dbus_g_proxy_add_signal (client_proxy, "Stop", G_TYPE_INVALID); + dbus_g_proxy_connect_signal (client_proxy, "Stop", + G_CALLBACK (stop_cb), NULL, NULL); + + dbus_g_proxy_add_signal (client_proxy, "QueryEndSession", G_TYPE_UINT, G_TYPE_INVALID); + dbus_g_proxy_connect_signal (client_proxy, "QueryEndSession", + G_CALLBACK (query_end_session_cb), NULL, NULL); + + dbus_g_proxy_add_signal (client_proxy, "EndSession", G_TYPE_UINT, G_TYPE_INVALID); + dbus_g_proxy_connect_signal (client_proxy, "EndSession", + G_CALLBACK (end_session_cb), NULL, NULL); + + g_unsetenv ("DESKTOP_AUTOSTART_ID"); + + return TRUE; +} + int main (int argc, char **argv) { @@ -51,7 +177,6 @@ main (int argc, char **argv) SpiDEController *dec; gchar *introspection_directory; - GMainLoop *mainloop; DBusConnection *bus; GOptionContext *opt; @@ -103,6 +228,16 @@ main (int argc, char **argv) registry = spi_registry_new (bus); dec = spi_registry_dec_new (registry, bus); + if (!session_manager_connect ()) + { + g_warning ("Unable to connect to session manager"); + } + + if (!register_client ()) + { + g_warning ("Unable to register client with session manager"); + } + g_main_loop_run (mainloop); return 0; } -- cgit v1.2.1