diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/gtk-dialog/Makefile.am | 4 | ||||
-rw-r--r-- | src/gtk-dialog/ck-pk-helper.c | 98 | ||||
-rw-r--r-- | src/gtk-dialog/ck-pk-helper.h | 4 | ||||
-rw-r--r-- | src/gtk-dialog/gconf-helper.c | 49 | ||||
-rw-r--r-- | src/gtk-dialog/gconf-helper.h | 21 | ||||
-rw-r--r-- | src/gtk-dialog/gtk-logout-helper.c | 12 | ||||
-rw-r--r-- | src/gtk-dialog/logout-dialog.c | 3 | ||||
-rw-r--r-- | src/session-service.c | 50 | ||||
-rw-r--r-- | src/status-provider-pidgin.c | 83 | ||||
-rw-r--r-- | src/status-provider-telepathy.c | 78 | ||||
-rw-r--r-- | src/status-provider.h | 1 | ||||
-rw-r--r-- | src/status-service.c | 98 | ||||
-rw-r--r-- | src/users-service.c | 94 |
13 files changed, 432 insertions, 163 deletions
diff --git a/src/gtk-dialog/Makefile.am b/src/gtk-dialog/Makefile.am index 90a6209..3f14d78 100644 --- a/src/gtk-dialog/Makefile.am +++ b/src/gtk-dialog/Makefile.am @@ -10,6 +10,6 @@ gtk_logout_helper_SOURCES = \ logout-dialog.c \ logout-dialog.h -gtk_logout_helper_CFLAGS = $(GTKLOGOUTHELPER_CFLAGS) $(GCONF_CFLAGS) -Wall -Werror -gtk_logout_helper_LDADD = $(GTKLOGOUTHELPER_LIBS) $(GCONF_LIBS) +gtk_logout_helper_CFLAGS = $(SESSIONSERVICE_CFLAGS) $(GTKLOGOUTHELPER_CFLAGS) $(GCONF_CFLAGS) -Wall -Werror -DINDICATOR_ICONS_DIR="\"$(INDICATORICONSDIR)\"" +gtk_logout_helper_LDADD = $(SESSIONSERVICE_LIBS) $(GTKLOGOUTHELPER_LIBS) $(GCONF_LIBS) diff --git a/src/gtk-dialog/ck-pk-helper.c b/src/gtk-dialog/ck-pk-helper.c index 466ccbc..dc7d900 100644 --- a/src/gtk-dialog/ck-pk-helper.c +++ b/src/gtk-dialog/ck-pk-helper.c @@ -24,7 +24,7 @@ with this program. If not, see <http://www.gnu.org/licenses/>. #include <unistd.h> #include <glib.h> #include <dbus/dbus-glib.h> -#include <polkit-gnome/polkit-gnome.h> +#include <polkit/polkit.h> #include "logout-dialog.h" #include "ck-pk-helper.h" @@ -170,67 +170,53 @@ pk_require_auth (LogoutDialogAction action) { } } - PolKitResult polres; + PolkitAuthorizationResult *polres = NULL; + gboolean ret = FALSE; if (pk_can_do_action(pk_action, &polres)) { - if (polres == POLKIT_RESULT_YES) { - return FALSE; + if (polkit_authorization_result_get_is_challenge (polres)) { + ret = TRUE; } - return TRUE; + g_debug ("pk_require_auth(%s): authorized, is_challenge: %i", pk_action, ret); + } else { + g_debug ("pk_require_auth(%s): not authorized", pk_action); + } + if (polres) { + g_object_unref (polres); } - return FALSE; + return ret; } gboolean -pk_can_do_action (const gchar *action_id, PolKitResult * pol_result) +pk_can_do_action (const gchar *action_id, PolkitAuthorizationResult ** pol_result) { - PolKitGnomeContext *gnome_context; - PolKitAction *action; - PolKitCaller *caller; - DBusError dbus_error; - PolKitError *error; - PolKitResult result; - - gnome_context = polkit_gnome_context_get (NULL); - - if (gnome_context == NULL) { - return FALSE; - } - - if (gnome_context->pk_tracker == NULL) { - return FALSE; - } - - dbus_error_init (&dbus_error); - caller = polkit_tracker_get_caller_from_pid (gnome_context->pk_tracker, - getpid (), - &dbus_error); - dbus_error_free (&dbus_error); - - if (caller == NULL) { - return FALSE; - } - - action = polkit_action_new (); - if (!polkit_action_set_action_id (action, action_id)) { - polkit_action_unref (action); - polkit_caller_unref (caller); - return FALSE; - } - - result = POLKIT_RESULT_UNKNOWN; - error = NULL; - result = polkit_context_is_caller_authorized (gnome_context->pk_context, - action, caller, FALSE, - &error); - if (polkit_error_is_set (error)) { - polkit_error_free (error); - } - polkit_action_unref (action); - polkit_caller_unref (caller); - - if (pol_result != NULL) { - *pol_result = result; - } + PolkitAuthority *authority; + PolkitSubject *subject; + PolkitAuthorizationResult *result; + gboolean ret; + + authority = polkit_authority_get(); + if (!authority) { + g_warning ("Could not get PolicyKit authority instance"); + return FALSE; + } + subject = polkit_unix_process_new (getpid()); - return result != POLKIT_RESULT_NO && result != POLKIT_RESULT_UNKNOWN; + result = polkit_authority_check_authorization_sync (authority, subject, action_id, NULL, 0, NULL, NULL); + g_object_unref (authority); + + ret = FALSE; + if (result) { + ret = polkit_authorization_result_get_is_authorized (result) || + polkit_authorization_result_get_is_challenge (result); + g_debug ("pk_can_do_action(%s): %i", action_id, ret); + } else { + g_warning ("pk_can_do_action(%s): check_authorization returned NULL", action_id); + } + if (pol_result) { + *pol_result = result; + } else { + g_object_unref (result); + } + return ret; + } diff --git a/src/gtk-dialog/ck-pk-helper.h b/src/gtk-dialog/ck-pk-helper.h index 98bce56..501a8c8 100644 --- a/src/gtk-dialog/ck-pk-helper.h +++ b/src/gtk-dialog/ck-pk-helper.h @@ -24,9 +24,9 @@ with this program. If not, see <http://www.gnu.org/licenses/>. #ifndef __CK_PK_HELPER_H__ #define __CK_PK_HELPER_H__ 1 -#include <polkit-gnome/polkit-gnome.h> +#include <polkit/polkit.h> gboolean pk_require_auth (LogoutDialogAction action); -gboolean pk_can_do_action (const gchar *action_id, PolKitResult * pol_result); +gboolean pk_can_do_action (const gchar *action_id, PolkitAuthorizationResult ** pol_result); #endif /* __CK_PK_HELPER__ */ diff --git a/src/gtk-dialog/gconf-helper.c b/src/gtk-dialog/gconf-helper.c index 0bd21ad..213592e 100644 --- a/src/gtk-dialog/gconf-helper.c +++ b/src/gtk-dialog/gconf-helper.c @@ -1,6 +1,5 @@ /* -A small wrapper utility to load indicators and put them as menu items -into the gnome-panel using it's applet interface. +A small wrapper utility for connecting to gconf. Copyright 2009 Canonical Ltd. @@ -23,10 +22,52 @@ with this program. If not, see <http://www.gnu.org/licenses/>. #include <gconf/gconf-client.h> +#include <glib/gi18n.h> + +#include <dbus/dbus-glib.h> +#include <dbus/dbus-glib-bindings.h> + +#include <libdbusmenu-glib/server.h> +#include <libdbusmenu-glib/menuitem.h> + #include "gconf-helper.h" +static GConfClient * gconf_client = NULL; + gboolean supress_confirmations (void) { - GConfClient *client = gconf_client_get_default (); - return gconf_client_get_bool (client, SUPPRESS_KEY, NULL) ; + if(!gconf_client) { + gconf_client = gconf_client_get_default (); + } + return gconf_client_get_bool (gconf_client, SUPPRESS_KEY, NULL) ; +} + +static void update_menu_entries_callback (GConfClient *client, guint cnxn_id, GConfEntry *entry, gpointer data) { + RestartShutdownLogoutMenuItems * restart_shutdown_logout_mi = (RestartShutdownLogoutMenuItems*) data; + GConfValue * value = gconf_entry_get_value (entry); + const gchar * key = gconf_entry_get_key (entry); + + if(g_strcmp0 (key, SUPPRESS_KEY) == 0) { + if (gconf_value_get_bool (value)) { + dbusmenu_menuitem_property_set(restart_shutdown_logout_mi->logout_mi, DBUSMENU_MENUITEM_PROP_LABEL, _("Log Out")); + dbusmenu_menuitem_property_set(restart_shutdown_logout_mi->restart_mi, DBUSMENU_MENUITEM_PROP_LABEL, _("Restart")); + dbusmenu_menuitem_property_set(restart_shutdown_logout_mi->shutdown_mi, DBUSMENU_MENUITEM_PROP_LABEL, _("Shutdown")); + } else { + dbusmenu_menuitem_property_set(restart_shutdown_logout_mi->logout_mi, DBUSMENU_MENUITEM_PROP_LABEL, _("Log Out...")); + dbusmenu_menuitem_property_set(restart_shutdown_logout_mi->restart_mi, DBUSMENU_MENUITEM_PROP_LABEL, _("Restart...")); + dbusmenu_menuitem_property_set(restart_shutdown_logout_mi->shutdown_mi, DBUSMENU_MENUITEM_PROP_LABEL, _("Shutdown...")); + } + } } + +void +update_menu_entries(RestartShutdownLogoutMenuItems * restart_shutdown_logout_mi) { + if(!gconf_client) { + gconf_client = gconf_client_get_default (); + } + gconf_client_add_dir (gconf_client, GLOBAL_DIR, + GCONF_CLIENT_PRELOAD_ONELEVEL, NULL); + gconf_client_notify_add (gconf_client, SUPPRESS_KEY, + update_menu_entries_callback, restart_shutdown_logout_mi, NULL, NULL); +} + diff --git a/src/gtk-dialog/gconf-helper.h b/src/gtk-dialog/gconf-helper.h index 1d78fd8..951bb0f 100644 --- a/src/gtk-dialog/gconf-helper.h +++ b/src/gtk-dialog/gconf-helper.h @@ -1,6 +1,5 @@ /* -A small wrapper utility to load indicators and put them as menu items -into the gnome-panel using it's applet interface. +A small wrapper utility for connecting to gconf. Copyright 2009 Canonical Ltd. @@ -26,8 +25,26 @@ with this program. If not, see <http://www.gnu.org/licenses/>. #include <gconf/gconf-client.h> +#include <glib/gi18n.h> + +#include <dbus/dbus-glib.h> +#include <dbus/dbus-glib-bindings.h> + +#include <libdbusmenu-glib/server.h> +#include <libdbusmenu-glib/menuitem.h> + #define SUPPRESS_KEY "/apps/indicator-session/suppress_logout_restart_shutdown" +#define GLOBAL_DIR "/apps/indicator-session" + +typedef struct _RestartShutdownLogoutMenuItems +{ + DbusmenuMenuitem * logout_mi; + DbusmenuMenuitem * restart_mi; + DbusmenuMenuitem * shutdown_mi; +} +RestartShutdownLogoutMenuItems; +void update_menu_entries(RestartShutdownLogoutMenuItems*); gboolean supress_confirmations (void); #endif /* __GCONF_HELPER__ */ diff --git a/src/gtk-dialog/gtk-logout-helper.c b/src/gtk-dialog/gtk-logout-helper.c index 13991ca..0c03e86 100644 --- a/src/gtk-dialog/gtk-logout-helper.c +++ b/src/gtk-dialog/gtk-logout-helper.c @@ -21,7 +21,7 @@ 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 <glib.h> #include <gtk/gtk.h> #include <dbus/dbus-glib.h> @@ -121,6 +121,12 @@ main (int argc, char * argv[]) { gtk_init(&argc, &argv); + /* Setting up i18n and gettext. Apparently, we need + all of these. */ + setlocale (LC_ALL, ""); + bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR); + textdomain (GETTEXT_PACKAGE); + GError * error = NULL; GOptionContext * context = g_option_context_new(" - logout of the current session"); g_option_context_add_main_entries(context, options, "gtk-logout-helper"); @@ -133,6 +139,10 @@ main (int argc, char * argv[]) return 1; } + /* Init some theme/icon stuff */ + gtk_icon_theme_append_search_path(gtk_icon_theme_get_default(), + INDICATOR_ICONS_DIR); + GtkWidget * dialog = NULL; if (!pk_require_auth(type) && !supress_confirmations()) { dialog = logout_dialog_new(type); diff --git a/src/gtk-dialog/logout-dialog.c b/src/gtk-dialog/logout-dialog.c index a80dbef..a94c649 100644 --- a/src/gtk-dialog/logout-dialog.c +++ b/src/gtk-dialog/logout-dialog.c @@ -298,8 +298,9 @@ logout_dialog_init (LogoutDialog *logout_dialog) GTK_RESPONSE_OK); gtk_widget_grab_default (logout_dialog->ok_button); - /* Title */ + /* Window Title and Icon */ gtk_window_set_title (GTK_WINDOW(logout_dialog), _(title_strings[logout_dialog->action])); + gtk_window_set_icon_name (GTK_WINDOW(logout_dialog), icon_strings[logout_dialog->action]); /* hbox */ logout_dialog->hbox = gtk_hbox_new (FALSE, 12); diff --git a/src/session-service.c b/src/session-service.c index 9e5cbb2..9c3c4ef 100644 --- a/src/session-service.c +++ b/src/session-service.c @@ -6,6 +6,7 @@ Copyright 2009 Canonical Ltd. Authors: Ted Gould <ted@canonical.com> + Christoph Korn <c_korn@gmx.de> This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License version 3, as published @@ -20,6 +21,7 @@ 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 <glib/gi18n.h> @@ -47,6 +49,9 @@ static DBusGProxyCall * hibernate_call = NULL; static DbusmenuMenuitem * hibernate_mi = NULL; static DbusmenuMenuitem * suspend_mi = NULL; +static DbusmenuMenuitem * logout_mi = NULL; +static DbusmenuMenuitem * restart_mi = NULL; +static DbusmenuMenuitem * shutdown_mi = NULL; /* Let's put this machine to sleep, with some info on how it should sleep. */ @@ -222,16 +227,14 @@ show_dialog (DbusmenuMenuitem * mi, gchar * type) provides in the UI. It also connects them to the callbacks. */ static void create_items (DbusmenuMenuitem * root) { - DbusmenuMenuitem * mi = NULL; - - mi = dbusmenu_menuitem_new(); + logout_mi = dbusmenu_menuitem_new(); if (supress_confirmations()) { - dbusmenu_menuitem_property_set(mi, DBUSMENU_MENUITEM_PROP_LABEL, _("Log Out")); + dbusmenu_menuitem_property_set(logout_mi, DBUSMENU_MENUITEM_PROP_LABEL, _("Log Out")); } else { - dbusmenu_menuitem_property_set(mi, DBUSMENU_MENUITEM_PROP_LABEL, _("Log Out ...")); + dbusmenu_menuitem_property_set(logout_mi, DBUSMENU_MENUITEM_PROP_LABEL, _("Log Out...")); } - dbusmenu_menuitem_child_append(root, mi); - g_signal_connect(G_OBJECT(mi), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK(show_dialog), "logout"); + dbusmenu_menuitem_child_append(root, logout_mi); + g_signal_connect(G_OBJECT(logout_mi), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK(show_dialog), "logout"); suspend_mi = dbusmenu_menuitem_new(); dbusmenu_menuitem_property_set(suspend_mi, DBUSMENU_MENUITEM_PROP_VISIBLE, "false"); @@ -245,23 +248,30 @@ create_items (DbusmenuMenuitem * root) { dbusmenu_menuitem_child_append(root, hibernate_mi); g_signal_connect(G_OBJECT(hibernate_mi), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK(sleep), "Hibernate"); - mi = dbusmenu_menuitem_new(); + restart_mi = dbusmenu_menuitem_new(); if (supress_confirmations()) { - dbusmenu_menuitem_property_set(mi, DBUSMENU_MENUITEM_PROP_LABEL, _("Restart")); + dbusmenu_menuitem_property_set(restart_mi, DBUSMENU_MENUITEM_PROP_LABEL, _("Restart")); } else { - dbusmenu_menuitem_property_set(mi, DBUSMENU_MENUITEM_PROP_LABEL, _("Restart ...")); + dbusmenu_menuitem_property_set(restart_mi, DBUSMENU_MENUITEM_PROP_LABEL, _("Restart...")); } - dbusmenu_menuitem_child_append(root, mi); - g_signal_connect(G_OBJECT(mi), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK(show_dialog), "restart"); + dbusmenu_menuitem_child_append(root, restart_mi); + g_signal_connect(G_OBJECT(restart_mi), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK(show_dialog), "restart"); - mi = dbusmenu_menuitem_new(); + shutdown_mi = dbusmenu_menuitem_new(); if (supress_confirmations()) { - dbusmenu_menuitem_property_set(mi, DBUSMENU_MENUITEM_PROP_LABEL, _("Shutdown")); + dbusmenu_menuitem_property_set(shutdown_mi, DBUSMENU_MENUITEM_PROP_LABEL, _("Shut Down")); } else { - dbusmenu_menuitem_property_set(mi, DBUSMENU_MENUITEM_PROP_LABEL, _("Shutdown ...")); + dbusmenu_menuitem_property_set(shutdown_mi, DBUSMENU_MENUITEM_PROP_LABEL, _("Shut Down...")); } - dbusmenu_menuitem_child_append(root, mi); - g_signal_connect(G_OBJECT(mi), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK(show_dialog), "shutdown"); + dbusmenu_menuitem_child_append(root, shutdown_mi); + g_signal_connect(G_OBJECT(shutdown_mi), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK(show_dialog), "shutdown"); + + RestartShutdownLogoutMenuItems * restart_shutdown_logout_mi = g_new0 (RestartShutdownLogoutMenuItems, 1); + restart_shutdown_logout_mi->logout_mi = logout_mi; + restart_shutdown_logout_mi->restart_mi = restart_mi; + restart_shutdown_logout_mi->shutdown_mi = shutdown_mi; + + update_menu_entries(restart_shutdown_logout_mi); return; } @@ -273,6 +283,12 @@ main (int argc, char ** argv) { g_type_init(); + /* Setting up i18n and gettext. Apparently, we need + all of these. */ + setlocale (LC_ALL, ""); + bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR); + textdomain (GETTEXT_PACKAGE); + DBusGConnection * connection = dbus_g_bus_get(DBUS_BUS_SESSION, NULL); DBusGProxy * bus_proxy = dbus_g_proxy_new_for_name(connection, DBUS_SERVICE_DBUS, DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS); GError * error = NULL; diff --git a/src/status-provider-pidgin.c b/src/status-provider-pidgin.c index 052ce12..3c0ca15 100644 --- a/src/status-provider-pidgin.c +++ b/src/status-provider-pidgin.c @@ -59,12 +59,14 @@ static const pg_status_t sp_to_pg_map[STATUS_PROVIDER_STATUS_LAST] = { /* STATUS_PROVIDER_STATUS_AWAY, */ PG_STATUS_AWAY, /* STATUS_PROVIDER_STATUS_DND */ PG_STATUS_UNAVAILABLE, /* STATUS_PROVIDER_STATUS_INVISIBLE*/ PG_STATUS_INVISIBLE, - /* STATUS_PROVIDER_STATUS_OFFLINE */ PG_STATUS_OFFLINE + /* STATUS_PROVIDER_STATUS_OFFLINE */ PG_STATUS_OFFLINE, + /* STATUS_PROVIDER_STATUS_DISCONNECTED*/ PG_STATUS_OFFLINE }; typedef struct _StatusProviderPidginPrivate StatusProviderPidginPrivate; struct _StatusProviderPidginPrivate { DBusGProxy * proxy; + DBusGProxy * dbus_proxy; pg_status_t pg_status; }; @@ -80,6 +82,8 @@ static void status_provider_pidgin_finalize (GObject *object); /* Internal Funcs */ static void set_status (StatusProvider * sp, StatusProviderStatus status); static StatusProviderStatus get_status (StatusProvider * sp); +static void setup_pidgin_proxy (StatusProviderPidgin * self); +static void dbus_namechange (DBusGProxy * proxy, const gchar * name, const gchar * prev, const gchar * new, StatusProviderPidgin * self); G_DEFINE_TYPE (StatusProviderPidgin, status_provider_pidgin, STATUS_PROVIDER_TYPE); @@ -183,22 +187,85 @@ status_provider_pidgin_init (StatusProviderPidgin *self) all non-DBus stuff should be done */ GError * error = NULL; + + /* Set up the dbus Proxy */ + priv->dbus_proxy = dbus_g_proxy_new_for_name_owner (bus, + DBUS_SERVICE_DBUS, + DBUS_PATH_DBUS, + DBUS_INTERFACE_DBUS, + &error); + if (error != NULL) { + g_warning("Unable to connect to DBus events: %s", error->message); + g_error_free(error); + return; + } + + /* Configure the name owner changing */ + dbus_g_proxy_add_signal(priv->dbus_proxy, "NameOwnerChanged", + G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, + G_TYPE_INVALID); + dbus_g_proxy_connect_signal(priv->dbus_proxy, "NameOwnerChanged", + G_CALLBACK(dbus_namechange), + self, NULL); + + setup_pidgin_proxy(self); + + return; +} + +/* Watch to see if the Pidgin comes up on Dbus */ +static void +dbus_namechange (DBusGProxy * proxy, const gchar * name, const gchar * prev, const gchar * new, StatusProviderPidgin * self) +{ + g_return_if_fail(name != NULL); + g_return_if_fail(new != NULL); + + if (g_strcmp0(name, "im.pidgin.purple.PurpleService") == 0) { + setup_pidgin_proxy(self); + } + return; +} + +/* Setup the Pidgin proxy so that we can talk to it + and get signals from it. */ +static void +setup_pidgin_proxy (StatusProviderPidgin * self) +{ + StatusProviderPidginPrivate * priv = STATUS_PROVIDER_PIDGIN_GET_PRIVATE(self); + + if (priv->proxy != NULL) { + g_debug("Odd, we were asked to set up a Pidgin proxy when we already had one."); + return; + } + + DBusGConnection * bus = dbus_g_bus_get(DBUS_BUS_SESSION, NULL); + g_return_if_fail(bus != NULL); /* Can't do anymore DBus stuff without this, + all non-DBus stuff should be done */ + + GError * error = NULL; + + /* Set up the Pidgin Proxy */ priv->proxy = dbus_g_proxy_new_for_name_owner (bus, "im.pidgin.purple.PurpleService", "/im/pidgin/purple/PurpleObject", "im.pidgin.purple.PurpleInterface", &error); + /* Report any errors */ if (error != NULL) { g_debug("Unable to get Pidgin proxy: %s", error->message); g_error_free(error); - return; } + /* If we have a proxy, let's start using it */ if (priv->proxy != NULL) { + /* Set the proxy to NULL if it's destroyed */ g_object_add_weak_pointer (G_OBJECT(priv->proxy), (gpointer *)&priv->proxy); + /* If it's destroyed, let's clean up as well */ g_signal_connect(G_OBJECT(priv->proxy), "destroy", G_CALLBACK(proxy_destroy), self); + /* Watching for the status change coming from the + Pidgin side of things. */ g_debug("Adding Pidgin Signals"); dbus_g_object_register_marshaller(_status_provider_pidgin_marshal_VOID__INT_INT, G_TYPE_NONE, @@ -216,6 +283,8 @@ status_provider_pidgin_init (StatusProviderPidgin *self) (void *)self, NULL); + /* Get the current status to update our cached + value of the status. */ dbus_g_proxy_begin_call(priv->proxy, "PurpleSavedstatusGetCurrent", savedstatus_cb, @@ -346,11 +415,17 @@ set_status (StatusProvider * sp, StatusProviderStatus status) } /* Takes the cached Pidgin status and makes it into the generic - Status provider status */ + Status provider status. If there is no Pidgin proxy then it + returns the disconnected state. */ static StatusProviderStatus get_status (StatusProvider * sp) { - g_return_val_if_fail(IS_STATUS_PROVIDER_PIDGIN(sp), STATUS_PROVIDER_STATUS_OFFLINE); + g_return_val_if_fail(IS_STATUS_PROVIDER_PIDGIN(sp), STATUS_PROVIDER_STATUS_DISCONNECTED); StatusProviderPidginPrivate * priv = STATUS_PROVIDER_PIDGIN_GET_PRIVATE(sp); + + if (priv->proxy == NULL) { + return STATUS_PROVIDER_STATUS_DISCONNECTED; + } + return pg_to_sp_map[priv->pg_status]; } diff --git a/src/status-provider-telepathy.c b/src/status-provider-telepathy.c index e22c27d..f2815fb 100644 --- a/src/status-provider-telepathy.c +++ b/src/status-provider-telepathy.c @@ -55,12 +55,14 @@ static mc_status_t sp_to_mc_map[] = { /* STATUS_PROVIDER_STATUS_AWAY, */ MC_STATUS_AWAY, /* STATUS_PROVIDER_STATUS_DND */ MC_STATUS_DND, /* STATUS_PROVIDER_STATUS_INVISIBLE*/ MC_STATUS_HIDDEN, - /* STATUS_PROVIDER_STATUS_OFFLINE */ MC_STATUS_OFFLINE + /* STATUS_PROVIDER_STATUS_OFFLINE */ MC_STATUS_OFFLINE, + /* STATUS_PROVIDER_STATUS_DISCONNECTED*/MC_STATUS_OFFLINE }; typedef struct _StatusProviderTelepathyPrivate StatusProviderTelepathyPrivate; struct _StatusProviderTelepathyPrivate { DBusGProxy * proxy; + DBusGProxy * dbus_proxy; mc_status_t mc_status; }; @@ -74,6 +76,8 @@ static void status_provider_telepathy_init (StatusProviderTelepathy *self) static void status_provider_telepathy_dispose (GObject *object); static void status_provider_telepathy_finalize (GObject *object); /* Internal Funcs */ +static void build_telepathy_proxy (StatusProviderTelepathy * self); +static void dbus_namechange (DBusGProxy * proxy, const gchar * name, const gchar * prev, const gchar * new, StatusProviderTelepathy * self); static void set_status (StatusProvider * sp, StatusProviderStatus status); static StatusProviderStatus get_status (StatusProvider * sp); static void changed_status (DBusGProxy * proxy, guint status, gchar * message, StatusProvider * sp); @@ -107,10 +111,61 @@ status_provider_telepathy_init (StatusProviderTelepathy *self) StatusProviderTelepathyPrivate * priv = STATUS_PROVIDER_TELEPATHY_GET_PRIVATE(self); priv->proxy = NULL; + priv->dbus_proxy = NULL; priv->mc_status = MC_STATUS_OFFLINE; GError * error = NULL; + /* Grabbing the session bus */ + DBusGConnection * bus = dbus_g_bus_get(DBUS_BUS_SESSION, &error); + if (bus == NULL) { + g_warning("Unable to connect to Session Bus: %s", error == NULL ? "No message" : error->message); + g_error_free(error); + return; + } + + /* Set up the dbus Proxy */ + priv->dbus_proxy = dbus_g_proxy_new_for_name_owner (bus, + DBUS_SERVICE_DBUS, + DBUS_PATH_DBUS, + DBUS_INTERFACE_DBUS, + &error); + if (error != NULL) { + g_warning("Unable to connect to DBus events: %s", error->message); + g_error_free(error); + return; + } + + /* Configure the name owner changing */ + dbus_g_proxy_add_signal(priv->dbus_proxy, "NameOwnerChanged", + G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, + G_TYPE_INVALID); + dbus_g_proxy_connect_signal(priv->dbus_proxy, "NameOwnerChanged", + G_CALLBACK(dbus_namechange), + self, NULL); + + build_telepathy_proxy(self); + + return; +} + +/* Builds up the proxy to Mission Control and configures all of the + signals for getting info from the proxy. Also does a call to get + the inital value of the status. */ +static void +build_telepathy_proxy (StatusProviderTelepathy * self) +{ + g_debug("Building Telepathy Proxy"); + StatusProviderTelepathyPrivate * priv = STATUS_PROVIDER_TELEPATHY_GET_PRIVATE(self); + + if (priv->proxy != NULL) { + g_debug("Hmm, being asked to build a proxy we alredy have."); + return; + } + + GError * error = NULL; + + /* Grabbing the session bus */ DBusGConnection * session_bus = dbus_g_bus_get(DBUS_BUS_SESSION, &error); if (session_bus == NULL) { g_warning("Unable to connect to Session Bus: %s", error == NULL ? "No message" : error->message); @@ -118,7 +173,7 @@ status_provider_telepathy_init (StatusProviderTelepathy *self) return; } - priv->proxy = NULL; + /* Get the proxy to Mission Control */ priv->proxy = dbus_g_proxy_new_for_name_owner(session_bus, "org.freedesktop.Telepathy.MissionControl", "/org/freedesktop/Telepathy/MissionControl", @@ -126,10 +181,13 @@ status_provider_telepathy_init (StatusProviderTelepathy *self) &error); if (priv->proxy != NULL) { + /* If it goes, we set the proxy to NULL */ g_object_add_weak_pointer (G_OBJECT(priv->proxy), (gpointer *)&priv->proxy); + /* And we clean up other variables associated */ g_signal_connect(G_OBJECT(priv->proxy), "destroy", G_CALLBACK(proxy_destroy), self); + /* Set up the signal handler for watching when status changes. */ dbus_g_object_register_marshaller(_status_provider_telepathy_marshal_VOID__UINT_STRING, G_TYPE_NONE, G_TYPE_UINT, @@ -163,6 +221,19 @@ status_provider_telepathy_init (StatusProviderTelepathy *self) return; } +/* Watch to see if the Mission Control comes up on Dbus */ +static void +dbus_namechange (DBusGProxy * proxy, const gchar * name, const gchar * prev, const gchar * new, StatusProviderTelepathy * self) +{ + g_return_if_fail(name != NULL); + g_return_if_fail(new != NULL); + + if (g_strcmp0(name, "org.freedesktop.Telepathy.MissionControl") == 0) { + build_telepathy_proxy(self); + } + return; +} + static void status_provider_telepathy_dispose (GObject *object) { @@ -258,10 +329,11 @@ set_status (StatusProvider * sp, StatusProviderStatus status) static StatusProviderStatus get_status (StatusProvider * sp) { + g_return_val_if_fail(IS_STATUS_PROVIDER_TELEPATHY(sp), STATUS_PROVIDER_STATUS_DISCONNECTED); StatusProviderTelepathyPrivate * priv = STATUS_PROVIDER_TELEPATHY_GET_PRIVATE(sp); if (priv->proxy == NULL) { - return mc_to_sp_map[MC_STATUS_OFFLINE]; + return STATUS_PROVIDER_STATUS_DISCONNECTED; } return mc_to_sp_map[priv->mc_status]; diff --git a/src/status-provider.h b/src/status-provider.h index 522e61b..a0e1c55 100644 --- a/src/status-provider.h +++ b/src/status-provider.h @@ -42,6 +42,7 @@ typedef enum STATUS_PROVIDER_STATUS_DND, STATUS_PROVIDER_STATUS_INVISIBLE, STATUS_PROVIDER_STATUS_OFFLINE, + STATUS_PROVIDER_STATUS_DISCONNECTED, /* Leave as last */ STATUS_PROVIDER_STATUS_LAST } diff --git a/src/status-service.c b/src/status-service.c index 542317a..247726b 100644 --- a/src/status-service.c +++ b/src/status-service.c @@ -20,6 +20,7 @@ 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 <sys/types.h> #include <pwd.h> @@ -55,29 +56,34 @@ static const gchar * status_strings [STATUS_PROVIDER_STATUS_LAST] = { /* STATUS_PROVIDER_STATUS_AWAY, */ N_("Away"), /* STATUS_PROVIDER_STATUS_DND */ N_("Busy"), /* STATUS_PROVIDER_STATUS_INVISIBLE */ N_("Invisible"), - /* STATUS_PROVIDER_STATUS_OFFLINE, */ N_("Offline") + /* STATUS_PROVIDER_STATUS_OFFLINE, */ N_("Offline"), + /* STATUS_PROVIDER_STATUS_DISCONNECTED*/ N_("Offline") }; static const gchar * status_icons[STATUS_PROVIDER_STATUS_LAST] = { - /* STATUS_PROVIDER_STATUS_ONLINE, */ "user-online", + /* STATUS_PROVIDER_STATUS_ONLINE, */ "user-available", /* STATUS_PROVIDER_STATUS_AWAY, */ "user-away", /* STATUS_PROVIDER_STATUS_DND, */ "user-busy", /* STATUS_PROVIDER_STATUS_INVISIBLE, */ "user-invisible", - /* STATUS_PROVIDER_STATUS_OFFLINE */ "user-offline" + /* STATUS_PROVIDER_STATUS_OFFLINE */ "user-offline", + /* STATUS_PROVIDER_STATUS_DISCONNECTED */"user-offline" }; static DbusmenuMenuitem * root_menuitem = NULL; static DbusmenuMenuitem * status_menuitem = NULL; +static DbusmenuMenuitem * status_menuitems[STATUS_PROVIDER_STATUS_LAST] = {0}; static GMainLoop * mainloop = NULL; static StatusServiceDbus * dbus_interface = NULL; -static StatusProviderStatus global_status = STATUS_PROVIDER_STATUS_OFFLINE; +static StatusProviderStatus global_status = STATUS_PROVIDER_STATUS_DISCONNECTED; static void status_update (void) { StatusProviderStatus oldglobal = global_status; - global_status = STATUS_PROVIDER_STATUS_OFFLINE; + global_status = STATUS_PROVIDER_STATUS_DISCONNECTED; + /* Ask everyone what they think the status should be, if + they're more connected, up the global level */ int i; for (i = 0; i < STATUS_PROVIDER_CNT; i++) { StatusProviderStatus localstatus = status_provider_get_status(status_providers[i]); @@ -86,39 +92,33 @@ status_update (void) { } } + /* If changed */ if (global_status != oldglobal) { g_debug("Global status changed to: %s", _(status_strings[global_status])); - dbusmenu_menuitem_property_set(status_menuitem, DBUSMENU_MENUITEM_PROP_LABEL, _(status_strings[global_status])); + /* Configure the icon on the panel */ status_service_dbus_set_status(dbus_interface, status_icons[global_status]); - } - - return; -} - -/* A fun little function to actually lock the screen. If, - that's what you want, let's do it! */ -static void -lock_screen (DbusmenuMenuitem * mi, gpointer data) -{ - g_debug("Lock Screen"); - - DBusGConnection * session_bus = dbus_g_bus_get(DBUS_BUS_SESSION, NULL); - g_return_if_fail(session_bus != NULL); - - DBusGProxy * proxy = dbus_g_proxy_new_for_name_owner(session_bus, - "org.gnome.ScreenSaver", - "/", - "org.gnome.ScreenSaver", - NULL); - g_return_if_fail(proxy != NULL); - dbus_g_proxy_call_no_reply(proxy, - "Lock", - G_TYPE_INVALID, - G_TYPE_INVALID); + /* If we're now disconnected, make setting the statuses + insensitive. */ + if (global_status == STATUS_PROVIDER_STATUS_DISCONNECTED) { + StatusProviderStatus i; + for (i = STATUS_PROVIDER_STATUS_ONLINE; i < STATUS_PROVIDER_STATUS_LAST; i++) { + if (status_menuitems[i] == NULL) continue; + dbusmenu_menuitem_property_set(status_menuitems[i], DBUSMENU_MENUITEM_PROP_SENSITIVE, "false"); + } + } - g_object_unref(proxy); + /* If we're now back to a state where we have an IM client + connected then we need to resensitize the items. */ + if (oldglobal == STATUS_PROVIDER_STATUS_DISCONNECTED) { + StatusProviderStatus i; + for (i = STATUS_PROVIDER_STATUS_ONLINE; i < STATUS_PROVIDER_STATUS_LAST; i++) { + if (status_menuitems[i] == NULL) continue; + dbusmenu_menuitem_property_set(status_menuitems[i], DBUSMENU_MENUITEM_PROP_SENSITIVE, "true"); + } + } + } return; } @@ -190,28 +190,32 @@ build_menu (gpointer data) build_user_item(root); status_menuitem = dbusmenu_menuitem_new(); - dbusmenu_menuitem_property_set(status_menuitem, DBUSMENU_MENUITEM_PROP_LABEL, _(status_strings[global_status])); + dbusmenu_menuitem_property_set(status_menuitem, DBUSMENU_MENUITEM_PROP_LABEL, _("Set Status")); dbusmenu_menuitem_child_append(root, status_menuitem); StatusProviderStatus i; for (i = STATUS_PROVIDER_STATUS_ONLINE; i < STATUS_PROVIDER_STATUS_LAST; i++) { - DbusmenuMenuitem * mi = dbusmenu_menuitem_new(); + if (i == STATUS_PROVIDER_STATUS_DISCONNECTED) { + /* We don't want an item for the disconnected status. Users + can't set that value through the menu :) */ + continue; + } - dbusmenu_menuitem_property_set(mi, "type", DBUSMENU_CLIENT_TYPES_IMAGE); - dbusmenu_menuitem_property_set(mi, DBUSMENU_MENUITEM_PROP_LABEL, _(status_strings[i])); - dbusmenu_menuitem_property_set(mi, DBUSMENU_MENUITEM_PROP_ICON, status_icons[i]); - g_signal_connect(G_OBJECT(mi), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK(status_menu_click), GINT_TO_POINTER(i)); + status_menuitems[i] = dbusmenu_menuitem_new(); - dbusmenu_menuitem_child_append(status_menuitem, mi); + dbusmenu_menuitem_property_set(status_menuitems[i], "type", DBUSMENU_CLIENT_TYPES_IMAGE); + dbusmenu_menuitem_property_set(status_menuitems[i], DBUSMENU_MENUITEM_PROP_LABEL, _(status_strings[i])); + dbusmenu_menuitem_property_set(status_menuitems[i], DBUSMENU_MENUITEM_PROP_ICON, status_icons[i]); + if (global_status == STATUS_PROVIDER_STATUS_DISCONNECTED) { + dbusmenu_menuitem_property_set(status_menuitems[i], DBUSMENU_MENUITEM_PROP_SENSITIVE, "false"); + } + g_signal_connect(G_OBJECT(status_menuitems[i]), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK(status_menu_click), GINT_TO_POINTER(i)); + + dbusmenu_menuitem_child_append(status_menuitem, status_menuitems[i]); g_debug("Built %s", status_strings[i]); } - DbusmenuMenuitem * mi = dbusmenu_menuitem_new(); - dbusmenu_menuitem_property_set(mi, DBUSMENU_MENUITEM_PROP_LABEL, _("Lock Screen")); - g_signal_connect(G_OBJECT(mi), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK(lock_screen), GINT_TO_POINTER(i)); - dbusmenu_menuitem_child_append(root, mi); - return FALSE; } @@ -220,6 +224,12 @@ main (int argc, char ** argv) { g_type_init(); + /* Setting up i18n and gettext. Apparently, we need + all of these. */ + setlocale (LC_ALL, ""); + bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR); + textdomain (GETTEXT_PACKAGE); + DBusGConnection * connection = dbus_g_bus_get(DBUS_BUS_SESSION, NULL); DBusGProxy * bus_proxy = dbus_g_proxy_new_for_name(connection, DBUS_SERVICE_DBUS, DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS); GError * error = NULL; diff --git a/src/users-service.c b/src/users-service.c index 4d1b367..9fd123f 100644 --- a/src/users-service.c +++ b/src/users-service.c @@ -21,6 +21,8 @@ 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 <unistd.h> #include <glib/gi18n.h> @@ -122,14 +124,39 @@ activate_new_session (DbusmenuMenuitem * mi, gpointer user_data) return; } +/* A fun little function to actually lock the screen. If, + that's what you want, let's do it! */ +static void +lock_screen (DbusmenuMenuitem * mi, gpointer data) +{ + g_debug("Lock Screen"); + + DBusGConnection * session_bus = dbus_g_bus_get(DBUS_BUS_SESSION, NULL); + g_return_if_fail(session_bus != NULL); + + DBusGProxy * proxy = dbus_g_proxy_new_for_name_owner(session_bus, + "org.gnome.ScreenSaver", + "/", + "org.gnome.ScreenSaver", + NULL); + g_return_if_fail(proxy != NULL); + + dbus_g_proxy_call_no_reply(proxy, + "Lock", + G_TYPE_INVALID, + G_TYPE_INVALID); + + g_object_unref(proxy); + + return; +} + static void activate_user_session (DbusmenuMenuitem *mi, gpointer user_data) { UserData *user = (UserData *)user_data; UsersServiceDbus *service = user->service; - g_print ("activating user session for %s\n", user->user_name); - users_service_dbus_activate_user_session (service, user); } @@ -151,12 +178,18 @@ rebuild_items (DbusmenuMenuitem *root, dbusmenu_menuitem_foreach (root, remove_menu_item, NULL); - if (check_guest_session ()) { - mi = dbusmenu_menuitem_new (); - dbusmenu_menuitem_property_set (mi, DBUSMENU_MENUITEM_PROP_LABEL, _("Guest Session")); - dbusmenu_menuitem_child_append (root, mi); - g_signal_connect (G_OBJECT (mi), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK (activate_guest_session), NULL); - } + mi = dbusmenu_menuitem_new(); + dbusmenu_menuitem_property_set(mi, DBUSMENU_MENUITEM_PROP_LABEL, _("Lock Screen")); + g_signal_connect(G_OBJECT(mi), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK(lock_screen), NULL); + dbusmenu_menuitem_child_append(root, mi); + + if (check_guest_session ()) + { + mi = dbusmenu_menuitem_new (); + dbusmenu_menuitem_property_set (mi, DBUSMENU_MENUITEM_PROP_LABEL, _("Guest Session")); + dbusmenu_menuitem_child_append (root, mi); + g_signal_connect (G_OBJECT (mi), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK (activate_guest_session), NULL); + } if (count > 1 && count < 7) { @@ -173,27 +206,13 @@ rebuild_items (DbusmenuMenuitem *root, } } - if (check_new_session ()) { - mi = dbusmenu_menuitem_new (); - dbusmenu_menuitem_property_set (mi, DBUSMENU_MENUITEM_PROP_LABEL, _("New Session...")); - dbusmenu_menuitem_child_append (root, mi); - g_signal_connect (G_OBJECT (mi), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK (activate_new_session), NULL); - } -} - -static void -create_items (DbusmenuMenuitem *root, - UsersServiceDbus *service) -{ - g_return_if_fail (IS_USERS_SERVICE_DBUS (service)); - - count = users_service_dbus_get_user_count (service); - if (count > 1 && count < 7) + if (check_new_session ()) { - users = users_service_dbus_get_user_list (service); + mi = dbusmenu_menuitem_new (); + dbusmenu_menuitem_property_set (mi, DBUSMENU_MENUITEM_PROP_LABEL, _("New Session...")); + dbusmenu_menuitem_child_append (root, mi); + g_signal_connect (G_OBJECT (mi), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK (activate_new_session), NULL); } - - rebuild_items (root, service); } static void @@ -220,11 +239,32 @@ user_removed (UsersServiceDbus *service, rebuild_items (root, service); } +static void +create_items (DbusmenuMenuitem *root, + UsersServiceDbus *service) +{ + g_return_if_fail (IS_USERS_SERVICE_DBUS (service)); + + count = users_service_dbus_get_user_count (service); + if (count > 1 && count < 7) + { + users = users_service_dbus_get_user_list (service); + } + + rebuild_items (root, service); +} + int main (int argc, char ** argv) { g_type_init(); + /* Setting up i18n and gettext. Apparently, we need + all of these. */ + setlocale (LC_ALL, ""); + bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR); + textdomain (GETTEXT_PACKAGE); + session_bus = dbus_g_bus_get(DBUS_BUS_SESSION, NULL); bus_proxy = dbus_g_proxy_new_for_name (session_bus, DBUS_SERVICE_DBUS, DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS); GError * error = NULL; |