Back to index

indicator-session  12.10.0
gtk-logout-helper.c
Go to the documentation of this file.
00001 /*
00002 A small wrapper utility to load indicators and put them as menu items
00003 into the gnome-panel using it's applet interface.
00004 
00005 Copyright 2009 Canonical Ltd.
00006 
00007 Authors:
00008     Ted Gould <ted@canonical.com>
00009     Christoph Korn <c_korn@gmx.de>
00010 
00011 This program is free software: you can redistribute it and/or modify it
00012 under the terms of the GNU General Public License version 3, as published
00013 by the Free Software Foundation.
00014 
00015 This program is distributed in the hope that it will be useful, but
00016 WITHOUT ANY WARRANTY; without even the implied warranties of
00017 MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
00018 PURPOSE.  See the GNU General Public License for more details.
00019 
00020 You should have received a copy of the GNU General Public License along
00021 with this program.  If not, see <http://www.gnu.org/licenses/>.
00022 */
00023 
00024 #include "config.h"
00025 
00026 #include <locale.h>
00027 #include <glib.h>
00028 #include <glib/gi18n.h> /* textdomain(), bindtextdomain() */
00029 #include <dbus/dbus-glib.h>
00030 #include <gtk/gtk.h>
00031 #include "dialog.h"
00032 #include "shared-names.h"
00033 
00034 static void
00035 consolekit_fallback (LogoutDialogType action)
00036 {
00037        g_debug("Falling back to using ConsoleKit for action");
00038 
00039        DBusGConnection * sbus = dbus_g_bus_get(DBUS_BUS_SYSTEM, NULL);
00040        g_return_if_fail(sbus != NULL); /* worst case */
00041        DBusGProxy * proxy = dbus_g_proxy_new_for_name(sbus, "org.freedesktop.ConsoleKit",
00042                                                             "/org/freedesktop/ConsoleKit/Manager",
00043                                                             "org.freedesktop.ConsoleKit.Manager");
00044 
00045        if (proxy == NULL) {
00046               g_warning("Unable to get consolekit proxy");
00047               return;
00048        }
00049 
00050        GError * error = NULL;
00051 
00052        switch (action) {
00053               case LOGOUT_DIALOG_TYPE_LOG_OUT:
00054                      g_warning("Unable to fallback to ConsoleKit for logout as it's a session issue.  We need some sort of session handler.");
00055                      break;
00056               case LOGOUT_DIALOG_TYPE_SHUTDOWN:
00057                      g_debug("Telling ConsoleKit to 'Stop'");
00058                      dbus_g_proxy_call(proxy,
00059                                        "Stop",
00060                                        &error,
00061                                        G_TYPE_INVALID,
00062                                        G_TYPE_INVALID);
00063                      break;
00064               case LOGOUT_DIALOG_TYPE_RESTART:
00065                      g_debug("Telling ConsoleKit to 'Restart'");
00066                      dbus_g_proxy_call(proxy,
00067                                        "Restart",
00068                                        &error,
00069                                        G_TYPE_INVALID,
00070                                        G_TYPE_INVALID);
00071                      break;
00072               default:
00073                      g_warning("Unknown action");
00074                      break;
00075        }
00076 
00077        g_object_unref(proxy);
00078 
00079        if (error != NULL) {
00080               g_warning("Unable to signal ConsoleKit");
00081               g_error_free(error);
00082        }
00083 
00084        return;
00085 }
00086 
00087 static void
00088 session_action (LogoutDialogType action)
00089 {
00090        DBusGConnection * sbus;
00091        DBusGProxy * sm_proxy;
00092        GError * error = NULL;
00093        gboolean res = FALSE;
00094        
00095        sbus = dbus_g_bus_get(DBUS_BUS_SESSION, NULL);
00096        if (sbus == NULL) {
00097               g_warning("Unable to get DBus session bus.");
00098               return;
00099        }
00100        sm_proxy = dbus_g_proxy_new_for_name_owner (sbus,
00101                                                  "org.gnome.SessionManager",
00102                                                  "/org/gnome/SessionManager",
00103                                                  "org.gnome.SessionManager",
00104                                                         &error);
00105        if (sm_proxy == NULL) {
00106               g_warning("Unable to get DBus proxy to SessionManager interface: %s", error->message);
00107               g_error_free(error);
00108 
00109               consolekit_fallback(action);
00110               return;
00111        }             
00112        
00113        g_clear_error (&error);
00114        
00115        if (action == LOGOUT_DIALOG_TYPE_LOG_OUT) {
00116               g_debug("Asking Session manager to 'Logout'");
00117               res = dbus_g_proxy_call_with_timeout (sm_proxy, "Logout", INT_MAX, &error,
00118                                                                                G_TYPE_UINT, 1, G_TYPE_INVALID, G_TYPE_INVALID);
00119        } else if (action == LOGOUT_DIALOG_TYPE_SHUTDOWN) {
00120               g_debug("Asking Session manager to 'RequestShutdown'");
00121               res = dbus_g_proxy_call_with_timeout (sm_proxy, "RequestShutdown", INT_MAX, &error,
00122                                                                                G_TYPE_INVALID, G_TYPE_INVALID);
00123        } else if (action == LOGOUT_DIALOG_TYPE_RESTART) {
00124               g_debug("Asking Session manager to 'RequestReboot'");
00125               res = dbus_g_proxy_call_with_timeout (sm_proxy, "RequestReboot", INT_MAX, &error,
00126                                                                                G_TYPE_INVALID, G_TYPE_INVALID);
00127        } else {
00128               g_warning ("Unknown session action");
00129        }
00130        
00131        if (!res) {
00132               if (error != NULL) {
00133                      g_warning ("SessionManager action failed: %s", error->message);
00134               } else {
00135                      g_warning ("SessionManager action failed: unknown error");
00136               }
00137 
00138               consolekit_fallback(action);
00139        }
00140        
00141        g_object_unref(sm_proxy);
00142        g_clear_error (&error);
00143        
00144        return;
00145 }      
00146 
00147 static LogoutDialogType type = LOGOUT_DIALOG_TYPE_LOG_OUT;
00148 
00149 static gboolean
00150 option_logout (const gchar * arg, const gchar * value, gpointer data, GError * error)
00151 {
00152        type = LOGOUT_DIALOG_TYPE_LOG_OUT;
00153        g_debug("Dialog type: logout");
00154        return TRUE;
00155 }
00156 
00157 static gboolean
00158 option_shutdown (const gchar * arg, const gchar * value, gpointer data, GError * error)
00159 {
00160        type = LOGOUT_DIALOG_TYPE_SHUTDOWN;
00161        g_debug("Dialog type: shutdown");
00162        return TRUE;
00163 }
00164 
00165 static gboolean
00166 option_restart (const gchar * arg, const gchar * value, gpointer data, GError * error)
00167 {
00168        type = LOGOUT_DIALOG_TYPE_RESTART;
00169        g_debug("Dialog type: restart");
00170        return TRUE;
00171 }
00172 
00173 static GOptionEntry options[] = {
00174        {"logout",     'l',  G_OPTION_FLAG_NO_ARG,  G_OPTION_ARG_CALLBACK,  option_logout,   "Log out of the current session",   NULL},
00175        {"shutdown",   's',  G_OPTION_FLAG_NO_ARG,  G_OPTION_ARG_CALLBACK,  option_shutdown, "Switch off the entire system",     NULL},
00176        {"restart",    'r',  G_OPTION_FLAG_NO_ARG,  G_OPTION_ARG_CALLBACK,  option_restart,  "Restart the system",               NULL},
00177 
00178        {NULL}
00179 };
00180 
00181 static gboolean
00182 suppress_confirmations (void)
00183 {
00184   GSettings * s = g_settings_new (SESSION_SCHEMA);
00185   const gboolean suppress = g_settings_get_boolean (s, SUPPRESS_KEY);
00186   g_clear_object (&s);
00187   return suppress;
00188 }
00189 
00190 
00191 
00192 int
00193 main (int argc, char * argv[])
00194 {
00195        gtk_init(&argc, &argv);
00196 
00197        /* Setting up i18n and gettext.  Apparently, we need
00198           all of these. */
00199        setlocale (LC_ALL, "");
00200        bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR);
00201        textdomain (GETTEXT_PACKAGE);
00202 
00203        GError * error = NULL;
00204        GOptionContext * context = g_option_context_new(" - logout of the current session");
00205        g_option_context_add_main_entries(context, options, "gtk-logout-helper");
00206        g_option_context_add_group(context, gtk_get_option_group(TRUE));
00207        g_option_context_set_help_enabled(context, TRUE);
00208 
00209        if (!g_option_context_parse(context, &argc, &argv, &error)) {
00210               g_debug("Option parsing failed: %s", error->message);
00211               g_error_free(error);
00212               return 1;
00213        }
00214 
00215        /* Init some theme/icon stuff */
00216        gtk_icon_theme_append_search_path(gtk_icon_theme_get_default(),
00217                                          INDICATOR_ICONS_DIR);
00218 
00219        GtkWidget * dialog = NULL;
00220        if (!suppress_confirmations()) {
00221               g_debug("Showing dialog to ask for user confirmation");
00222               dialog = GTK_WIDGET(logout_dialog_new(type));
00223        }
00224 
00225        if (dialog != NULL) {
00226               GtkResponseType response = gtk_dialog_run(GTK_DIALOG(dialog));
00227               gtk_widget_hide(dialog);
00228 
00229               if (response == GTK_RESPONSE_OK) {
00230                      g_debug("Dialog return response: 'okay'");
00231               } else if (response == GTK_RESPONSE_HELP) {
00232                      g_debug("Dialog return response: 'help'");
00233               } else {
00234                      g_debug("Dialog return response: %d", response);
00235               }
00236 
00237               if (response == GTK_RESPONSE_HELP) {
00238                      type = LOGOUT_DIALOG_TYPE_RESTART;
00239                      response = GTK_RESPONSE_OK;
00240               }
00241 
00242               if (response != GTK_RESPONSE_OK) {
00243                      g_debug("Final response was not okay, quiting");
00244                      return 0;
00245               }
00246        }
00247 
00248        session_action(type);
00249        g_debug("Finished action, quiting");
00250 
00251        return 0;
00252 }