diff options
Diffstat (limited to 'tools/gnome-session-quit.c')
-rw-r--r-- | tools/gnome-session-quit.c | 216 |
1 files changed, 216 insertions, 0 deletions
diff --git a/tools/gnome-session-quit.c b/tools/gnome-session-quit.c new file mode 100644 index 0000000..4dddbfe --- /dev/null +++ b/tools/gnome-session-quit.c @@ -0,0 +1,216 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * save-session.c - Small program to talk to session manager. + + Copyright (C) 1998 Tom Tromey + Copyright (C) 2008 Red Hat, Inc. + + 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 + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, see <http://www.gnu.org/licenses/>. +*/ + +#include <config.h> + +#include <locale.h> +#include <unistd.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#include <glib.h> +#include <glib/gi18n.h> +#include <gio/gio.h> + +#define GSM_SERVICE_DBUS "org.gnome.SessionManager" +#define GSM_PATH_DBUS "/org/gnome/SessionManager" +#define GSM_INTERFACE_DBUS "org.gnome.SessionManager" + +enum { + GSM_LOGOUT_MODE_NORMAL = 0, + GSM_LOGOUT_MODE_NO_CONFIRMATION, + GSM_LOGOUT_MODE_FORCE +}; + +static gboolean opt_logout = FALSE; +static gboolean opt_power_off = FALSE; +static gboolean opt_reboot = FALSE; +static gboolean opt_no_prompt = FALSE; +static gboolean opt_force = FALSE; + +static GOptionEntry options[] = { + {"logout", '\0', 0, G_OPTION_ARG_NONE, &opt_logout, N_("Log out"), NULL}, + {"power-off", '\0', 0, G_OPTION_ARG_NONE, &opt_power_off, N_("Power off"), NULL}, + {"reboot", '\0', 0, G_OPTION_ARG_NONE, &opt_reboot, N_("Reboot"), NULL}, + {"force", '\0', 0, G_OPTION_ARG_NONE, &opt_force, N_("Ignoring any existing inhibitors"), NULL}, + {"no-prompt", '\0', 0, G_OPTION_ARG_NONE, &opt_no_prompt, N_("Don’t prompt for user confirmation"), NULL}, + {NULL} +}; + +static void +display_error (const char *message) +{ + g_printerr ("%s\n", message); +} + +static GDBusConnection * +get_session_bus (void) +{ + GDBusConnection *bus; + GError *error = NULL; + + bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error); + + if (bus == NULL) { + g_warning ("Couldn't connect to session bus: %s", error->message); + g_error_free (error); + } + + return bus; +} + +static GDBusProxy * +get_sm_proxy (void) +{ + GDBusConnection *connection; + GDBusProxy *sm_proxy; + + connection = get_session_bus (); + if (connection == NULL) { + display_error (_("Could not connect to the session manager")); + return NULL; + } + + sm_proxy = g_dbus_proxy_new_sync (connection, + G_DBUS_PROXY_FLAGS_NONE, + NULL, + GSM_SERVICE_DBUS, + GSM_PATH_DBUS, + GSM_INTERFACE_DBUS, + NULL, NULL); + g_object_unref (connection); + + if (sm_proxy == NULL) { + display_error (_("Could not connect to the session manager")); + return NULL; + } + + return sm_proxy; +} + +static void +do_logout (unsigned int mode) +{ + GDBusProxy *sm_proxy; + GVariant *reply; + GError *error; + + sm_proxy = get_sm_proxy (); + if (sm_proxy == NULL) { + return; + } + + error = NULL; + reply = g_dbus_proxy_call_sync (sm_proxy, + "Logout", + g_variant_new ("(u)", mode), + G_DBUS_CALL_FLAGS_NONE, + -1, NULL, &error); + + if (error != NULL) { + g_warning ("Failed to call logout: %s", + error->message); + g_error_free (error); + } else { + g_variant_unref (reply); + } + g_clear_object (&sm_proxy); +} + +static void +do_power_off (const char *action) +{ + GDBusProxy *sm_proxy; + GVariant *reply; + GError *error; + + sm_proxy = get_sm_proxy (); + if (sm_proxy == NULL) { + return; + } + + error = NULL; + reply = g_dbus_proxy_call_sync (sm_proxy, + action, + NULL, + G_DBUS_CALL_FLAGS_NONE, + -1, NULL, &error); + + if (error != NULL) { + g_warning ("Failed to call %s: %s", + action, error->message); + g_error_free (error); + } else { + g_variant_unref (reply); + } + g_clear_object (&sm_proxy); +} + +int +main (int argc, char *argv[]) +{ + GError *error; + int conflicting_options; + GOptionContext *ctx; + + /* Initialize the i18n stuff */ + setlocale (LC_ALL, ""); + bindtextdomain (GETTEXT_PACKAGE, LOCALE_DIR); + bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); + textdomain (GETTEXT_PACKAGE); + + error = NULL; + ctx = g_option_context_new (""); + g_option_context_add_main_entries (ctx, options, GETTEXT_PACKAGE); + if (! g_option_context_parse (ctx, &argc, &argv, &error)) { + g_warning ("Unable to start: %s", error->message); + g_error_free (error); + exit (1); + } + g_option_context_free (ctx); + + conflicting_options = 0; + if (opt_logout) + conflicting_options++; + if (opt_power_off) + conflicting_options++; + if (opt_reboot) + conflicting_options++; + if (conflicting_options > 1) + display_error (_("Program called with conflicting options")); + + if (opt_power_off) { + do_power_off ("Shutdown"); + } else if (opt_reboot) { + do_power_off ("Reboot"); + } else { + /* default to logout */ + + if (opt_force) + do_logout (GSM_LOGOUT_MODE_FORCE); + else if (opt_no_prompt) + do_logout (GSM_LOGOUT_MODE_NO_CONFIRMATION); + else + do_logout (GSM_LOGOUT_MODE_NORMAL); + } + + return 0; +} |