summaryrefslogtreecommitdiff
path: root/mate-settings-daemon/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'mate-settings-daemon/main.c')
-rw-r--r--mate-settings-daemon/main.c362
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);
}