diff options
Diffstat (limited to 'mate-settings-daemon/main.c')
-rw-r--r-- | mate-settings-daemon/main.c | 362 |
1 files changed, 211 insertions, 151 deletions
diff --git a/mate-settings-daemon/main.c b/mate-settings-daemon/main.c index b0581c5..11d8687 100644 --- a/mate-settings-daemon/main.c +++ b/mate-settings-daemon/main.c @@ -1,7 +1,7 @@ /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- - * vim: set ts=8 sts=8 sw=8 expandtab: * * Copyright (C) 2007 William Jon McCann <[email protected]> + * Copyright (C) 2012-2021 MATE Developers * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -31,6 +31,7 @@ #include <glib/gi18n.h> #include <glib/gstdio.h> +#include <glib-unix.h> #include <gio/gio.h> #include <gtk/gtk.h> @@ -54,92 +55,194 @@ #define MATE_SESSION_PRIVATE_DBUS_INTERFACE "org.gnome.SessionManager.ClientPrivate" /* this is kept only for compatibility with custom .desktop files */ -static gboolean no_daemon = TRUE; static gboolean replace = FALSE; static gboolean debug = FALSE; static gboolean do_timed_exit = FALSE; +static guint name_id = 0; static int term_signal_pipe_fds[2]; +static MateSettingsManager *manager = NULL; static GOptionEntry entries[] = { { "debug", 0, 0, G_OPTION_ARG_NONE, &debug, N_("Enable debugging code"), NULL }, { "replace", 0, 0, G_OPTION_ARG_NONE, &replace, N_("Replace the current daemon"), NULL }, - { "no-daemon", 0, G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_NONE, &no_daemon, N_("Don't become a daemon"), NULL }, { "timed-exit", 0, 0, G_OPTION_ARG_NONE, &do_timed_exit, N_("Exit after a time (for debugging)"), NULL }, - { NULL } + { NULL, 0, 0, G_OPTION_ARG_NONE, NULL, NULL, NULL } }; static gboolean timed_exit_cb (void) { + g_debug ("Doing timed exit"); gtk_main_quit (); - return FALSE; + return G_SOURCE_REMOVE; } static void -on_session_signal (GDBusProxy *proxy G_GNUC_UNUSED, - gchar *sender_name G_GNUC_UNUSED, - gchar *signal_name G_GNUC_UNUSED, - GVariant *parameters G_GNUC_UNUSED, - gpointer user_data G_GNUC_UNUSED) +stop_manager (void) { - /* not used, see on_session_end instead */ + gtk_main_quit (); } static void -on_private_signal (GDBusProxy *proxy, - gchar *sender_name G_GNUC_UNUSED, - gchar *signal_name, - GVariant *parameters G_GNUC_UNUSED, - gpointer user_data) +on_session_over (GDBusProxy *proxy, + gchar *sender_name, + gchar *signal_name, + GVariant *parameters, + gpointer user_data) { - MateSettingsManager *manager; - GVariant *variant; - GError *error = NULL; + if (g_strcmp0 (signal_name, "SessionOver") == 0) { + g_debug ("Got a SessionOver signal - stopping"); + stop_manager (); + } +} - manager = MATE_SETTINGS_MANAGER (user_data); +static void +respond_to_end_session (GDBusProxy *proxy) +{ + /* we must answer with "EndSessionResponse" */ + g_dbus_proxy_call (proxy, "EndSessionResponse", + g_variant_new ("(bs)", + TRUE, ""), + G_DBUS_CALL_FLAGS_NONE, + -1, NULL, NULL, NULL); +} +static void +client_proxy_signal_cb (GDBusProxy *proxy, + gchar *sender_name, + gchar *signal_name, + GVariant *parameters, + gpointer user_data) +{ if (g_strcmp0 (signal_name, "QueryEndSession") == 0) { - /* send response */ - variant = g_dbus_proxy_call_sync (proxy, - "EndSessionResponse", - g_variant_new ("(bs)", TRUE, NULL), - G_DBUS_CALL_FLAGS_NONE, - -1, - NULL, - &error); - if (variant == NULL) { - g_warning ("failed to send session response: %s", error->message); - g_error_free (error); - } else { - g_variant_unref (variant); - } + g_debug ("Got QueryEndSession signal"); + respond_to_end_session (proxy); } else if (g_strcmp0 (signal_name, "EndSession") == 0) { - /* send response */ - variant = g_dbus_proxy_call_sync (proxy, - "EndSessionResponse", - g_variant_new ("(bs)", TRUE, NULL), - G_DBUS_CALL_FLAGS_NONE, - -1, - NULL, - &error); - if (variant == NULL) { - g_warning ("failed to send session response: %s", error->message); + g_debug ("Got EndSession signal"); + respond_to_end_session (proxy); + } else if (g_strcmp0 (signal_name, "Stop") == 0) { + g_debug ("Got Stop signal"); + stop_manager (); + } +} + +static void +got_client_proxy (GObject *object, + GAsyncResult *res, + gpointer user_data) +{ + GDBusProxy *client_proxy; + GError *error = NULL; + + client_proxy = g_dbus_proxy_new_for_bus_finish (res, &error); + + if (error != NULL) { + g_debug ("Unable to get the session client proxy: %s", error->message); + g_error_free (error); + return; + } + + g_signal_connect (client_proxy, "g-signal", + G_CALLBACK (client_proxy_signal_cb), manager); +} + +static void +start_settings_manager (void) +{ + gboolean res; + GError *error; + + mate_settings_profile_start ("mate_settings_manager_new"); + manager = mate_settings_manager_new (); + mate_settings_profile_end ("mate_settings_manager_new"); + if (manager == NULL) { + g_warning ("Unable to register object"); + gtk_main_quit (); + } + + /* If we aren't started by dbus then load the plugins automatically during the + * Initialization phase. Otherwise, wait for an Awake etc. */ + if (g_getenv ("DBUS_STARTER_BUS_TYPE") == NULL) { + error = NULL; + res = mate_settings_manager_start (manager, PLUGIN_LOAD_INIT, &error); + if (! res) { + g_warning ("Unable to start: %s", error->message); g_error_free (error); - } else { - g_variant_unref (variant); } + } +} - mate_settings_manager_stop (manager); - gtk_main_quit (); +static void +on_client_registered (GObject *source_object, + GAsyncResult *res, + gpointer user_data) +{ + GVariant *variant; + GError *error = NULL; + gchar *object_path = NULL; + + variant = g_dbus_proxy_call_finish (G_DBUS_PROXY (source_object), res, &error); + if (error != NULL) { + g_warning ("Unable to register client: %s", error->message); + g_error_free (error); + } else { + g_variant_get (variant, "(o)", &object_path); + + g_debug ("Registered client at path %s", object_path); + + g_dbus_proxy_new_for_bus (G_BUS_TYPE_SESSION, 0, NULL, + MATE_SESSION_DBUS_NAME, + object_path, + MATE_SESSION_PRIVATE_DBUS_INTERFACE, + NULL, + got_client_proxy, + manager); + + g_free (object_path); + g_variant_unref (variant); } } static void -on_term_signal (int signal) +register_with_mate_session (void) +{ + const char *startup_id; + GError *error = NULL; + GDBusProxy *proxy; + + proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION, + G_DBUS_PROXY_FLAGS_NONE, + NULL, + MATE_SESSION_DBUS_NAME, + MATE_SESSION_DBUS_OBJECT, + MATE_SESSION_DBUS_INTERFACE, + NULL, + &error); + + if (proxy == NULL) { + g_warning ("Unable to contact session manager daemon: %s\n", error->message); + g_error_free (error); + } + g_signal_connect (G_OBJECT (proxy), "g-signal", + G_CALLBACK (on_session_over), NULL); + startup_id = g_getenv ("DESKTOP_AUTOSTART_ID"); + g_dbus_proxy_call (proxy, + "RegisterClient", + g_variant_new ("(ss)", "mate-settings-daemon", startup_id ? startup_id : ""), + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + (GAsyncReadyCallback) on_client_registered, + manager); +} + +static gboolean +on_term_signal (gpointer signal) { /* Wake up main loop to tell it to shutdown */ close (term_signal_pipe_fds[1]); term_signal_pipe_fds[1] = -1; + return G_SOURCE_REMOVE; } static gboolean @@ -157,7 +260,7 @@ on_term_signal_pipe_closed (GIOChannel *source, } static void -watch_for_term_signal (MateSettingsManager *manager) +watch_for_term_signal (void) { GIOChannel *channel; @@ -174,77 +277,66 @@ watch_for_term_signal (MateSettingsManager *manager) g_io_add_watch (channel, G_IO_HUP, on_term_signal_pipe_closed, manager); g_io_channel_unref (channel); - signal (SIGTERM, on_term_signal); - + g_unix_signal_add (SIGTERM, on_term_signal, manager); } static void -set_session_over_handler (MateSettingsManager *manager) +name_acquired_handler (GDBusConnection *connection, + const gchar *name, + gpointer user_data) { - GDBusProxy *session_proxy; - GDBusProxy *private_proxy; - gchar *client_id = NULL; - const char *startup_id; - GError *error = NULL; + gboolean res; + g_autoptr (GError) error = NULL; - mate_settings_profile_start (NULL); + start_settings_manager (); + register_with_mate_session (); - session_proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION, - G_DBUS_PROXY_FLAGS_NONE, - NULL, - MATE_SESSION_DBUS_NAME, - MATE_SESSION_DBUS_OBJECT, - MATE_SESSION_DBUS_INTERFACE, - NULL, - &error); - if (session_proxy == NULL) { - g_warning ("Unable to contact session manager daemon: %s\n", error->message); - g_error_free (error); - } - - g_signal_connect (G_OBJECT (session_proxy), "g-signal", G_CALLBACK (on_session_signal), NULL); - - /* Register with mate-session */ - startup_id = g_getenv ("DESKTOP_AUTOSTART_ID"); - if (startup_id != NULL && *startup_id != '\0') { - GVariant *variant; - variant = g_dbus_proxy_call_sync (session_proxy, - "RegisterClient", - g_variant_new ("(ss)", "mate-settings-daemon", startup_id), - G_DBUS_CALL_FLAGS_NONE, - -1, - NULL, - &error); - if (variant == NULL) { - g_warning ("Could not ask session manager to log out: %s", error->message); + /* If we aren't started by dbus then load the plugins automatically after + * mate-settings-daemon has registered itself. Otherwise, wait for an Awake etc. */ + if (g_getenv ("DBUS_STARTER_BUS_TYPE") == NULL) { + error = NULL; + res = mate_settings_manager_start (manager, PLUGIN_LOAD_DEFER, &error); + if (! res) { + g_warning ("Unable to start: %s", error->message); g_error_free (error); - } else { - g_variant_get (variant, "(o)", &client_id); - g_variant_unref (variant); - - private_proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION, - G_DBUS_PROXY_FLAGS_NONE, - NULL, - MATE_SESSION_DBUS_NAME, - client_id, - MATE_SESSION_PRIVATE_DBUS_INTERFACE, - NULL, - &error); - if (private_proxy == NULL) { - g_warning ("DBUS error: %s", error->message); - g_error_free (error); - } - - g_signal_connect (G_OBJECT (private_proxy), - "g-signal", - G_CALLBACK (on_private_signal), - manager); - g_free (client_id); + gtk_main_quit (); } } - watch_for_term_signal (manager); - mate_settings_profile_end (NULL); + watch_for_term_signal (); +} + +static void +name_lost_handler (GDBusConnection *connection, + const gchar *name, + gpointer user_data) +{ + /* Name was already taken, or the bus went away */ + + g_warning ("Name taken or bus went away - shutting down"); + + gtk_main_quit (); + +} + +static void +bus_register (void) +{ + GBusNameOwnerFlags flags; + + flags = G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT; + + if (replace) + flags |= G_BUS_NAME_OWNER_FLAGS_REPLACE; + + name_id = g_bus_own_name (G_BUS_TYPE_SESSION, + MSD_DBUS_NAME, + flags, + NULL, + (GBusNameAcquiredCallback) name_acquired_handler, + (GBusNameLostCallback) name_lost_handler, + NULL, + NULL); } static void @@ -273,7 +365,6 @@ parse_args (int *argc, char ***argv) mate_settings_profile_start (NULL); - context = g_option_context_new (NULL); g_option_context_add_main_entries (context, entries, NULL); @@ -315,9 +406,6 @@ static void debug_changed (GSettings *settings, int main (int argc, char *argv[]) { - MateSettingsManager *manager; - gboolean res; - GError *error; GSettings *debug_settings = NULL; manager = NULL; @@ -352,53 +440,25 @@ main (int argc, char *argv[]) g_log_set_default_handler (msd_log_default_handler, NULL); + bus_register (); #ifdef HAVE_LIBNOTIFY notify_init ("mate-settings-daemon"); #endif /* HAVE_LIBNOTIFY */ - manager = mate_settings_manager_new (replace); - mate_settings_profile_start ("mate_settings_manager_new"); - mate_settings_profile_end ("mate_settings_manager_new"); - if (manager == NULL) { - g_warning ("Unable to register object"); - goto out; - } - - /* If we aren't started by dbus then load the plugins automatically during the - * Initialization phase. Otherwise, wait for an Awake etc. */ - if (g_getenv ("DBUS_STARTER_BUS_TYPE") == NULL) { - error = NULL; - mate_settings_manager_set_init_flag (manager, PLUGIN_LOAD_INIT); - res = mate_settings_manager_load (manager, &error); - if (! res) { - g_warning ("Unable to start: %s", error->message); - g_error_free (error); - } - } - - set_session_over_handler (manager); - - /* If we aren't started by dbus then load the plugins automatically after - * mate-settings-daemon has registered itself. Otherwise, wait for an Awake etc. */ - if (g_getenv ("DBUS_STARTER_BUS_TYPE") == NULL) { - error = NULL; - mate_settings_manager_set_init_flag (manager, PLUGIN_LOAD_DEFER); - res = mate_settings_manager_load (manager, &error); - if (! res) { - g_warning ("Unable to start: %s", error->message); - g_error_free (error); - goto out; - } - } if (do_timed_exit) { - g_timeout_add_seconds (30, (GSourceFunc) timed_exit_cb, NULL); + g_timeout_add_seconds (30, G_SOURCE_FUNC (timed_exit_cb), NULL); } gtk_main (); -out: + g_debug ("Shutting down"); + + if (name_id > 0) { + g_bus_unown_name (name_id); + name_id = 0; + } if (manager != NULL) { g_object_unref (manager); } |