diff options
-rw-r--r-- | .bzrignore | 2 | ||||
-rw-r--r-- | src/Makefile.am | 21 | ||||
-rw-r--r-- | src/dbus-shared-names.h | 6 | ||||
-rw-r--r-- | src/indicator-session.c | 56 | ||||
-rw-r--r-- | src/session-dbus.c | 139 | ||||
-rw-r--r-- | src/session-dbus.h | 55 | ||||
-rw-r--r-- | src/session-dbus.xml | 15 | ||||
-rw-r--r-- | src/session-service.c | 12 |
8 files changed, 304 insertions, 2 deletions
@@ -55,3 +55,5 @@ indicator-session-[0-9].[0-9].tar.gz indicator-session-[0-9].[0-9].[0-9].tar.gz.asc indicator-session-[0-9].[0-9].tar.gz.asc src/consolekit-manager-client.h +src/session-dbus-client.h +src/session-dbus-server.h diff --git a/src/Makefile.am b/src/Makefile.am index cd525bd..3037a3b 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -11,6 +11,7 @@ sessionlibdir = $(INDICATORDIR) sessionlib_LTLIBRARIES = libsession.la libsession_la_SOURCES = \ indicator-session.c \ + session-dbus-client.h \ dbus-shared-names.h \ dbusmenu-shared.h \ users-service-client.h @@ -32,6 +33,20 @@ users-service-client.h: $(srcdir)/users-service.xml --output=users-service-client.h \ $(srcdir)/users-service.xml +session-dbus-client.h: $(srcdir)/session-dbus.xml + dbus-binding-tool \ + --prefix=_session_dbus_client \ + --mode=glib-client \ + --output=session-dbus-client.h \ + $(srcdir)/session-dbus.xml + +session-dbus-server.h: $(srcdir)/session-dbus.xml + dbus-binding-tool \ + --prefix=_session_dbus_server \ + --mode=glib-server \ + --output=session-dbus-server.h \ + $(srcdir)/session-dbus.xml + users-service-marshal.h: $(srcdir)/users-service.list glib-genmarshal --header \ --prefix=_users_service_marshal $(srcdir)/users-service.list \ @@ -50,6 +65,9 @@ indicator_session_service_SOURCES = \ lock-helper.c \ lock-helper.h \ session-service.c \ + session-dbus.c \ + session-dbus.h \ + session-dbus-server.h \ dbusmenu-shared.h \ gconf-helper.c \ users-service-dbus.h \ @@ -88,12 +106,15 @@ gtk_logout_helper_LDADD = \ BUILT_SOURCES = \ consolekit-manager-client.h \ + session-dbus-client.h \ + session-dbus-server.h \ users-service-client.h \ users-service-marshal.h \ users-service-marshal.c EXTRA_DIST = \ consolekit-manager.xml \ + session-dbus.xml \ users-service.xml \ users-service.list diff --git a/src/dbus-shared-names.h b/src/dbus-shared-names.h index 253cba8..11d62bb 100644 --- a/src/dbus-shared-names.h +++ b/src/dbus-shared-names.h @@ -38,8 +38,14 @@ with this program. If not, see <http://www.gnu.org/licenses/>. #define INDICATOR_SESSION_DBUS_OBJECT "/org/ayatana/indicator/session/menu" #define INDICATOR_SESSION_DBUS_VERSION 0 +#define INDICATOR_SESSION_SERVICE_DBUS_OBJECT "/org/ayatana/indicator/session/service" +#define INDICATOR_SESSION_SERVICE_DBUS_IFACE "org.ayatana.indicator.session.service" + #define USER_ITEM_TYPE "x-canonical-user-item" #define USER_ITEM_PROP_NAME "user-item-name" #define USER_ITEM_PROP_LOGGED_IN "user-item-logged-in" +#define ICON_DEFAULT "system-shutdown-panel" +#define ICON_RESTART "system-shutdown-panel" + #endif /* __DBUS_SHARED_NAMES_H__ */ diff --git a/src/indicator-session.c b/src/indicator-session.c index a815e40..de18bb3 100644 --- a/src/indicator-session.c +++ b/src/indicator-session.c @@ -35,6 +35,7 @@ with this program. If not, see <http://www.gnu.org/licenses/>. #include "dbus-shared-names.h" #include "dbusmenu-shared.h" +#include "session-dbus-client.h" #define INDICATOR_SESSION_TYPE (indicator_session_get_type ()) #define INDICATOR_SESSION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), INDICATOR_SESSION_TYPE, IndicatorSession)) @@ -55,6 +56,7 @@ struct _IndicatorSession { IndicatorServiceManager * service; GtkImage * status_image; DbusmenuGtkMenu * menu; + DBusGProxy * service_proxy; }; GType indicator_session_get_type (void); @@ -69,6 +71,8 @@ static GtkImage * get_icon (IndicatorObject * io); static GtkMenu * get_menu (IndicatorObject * io); static gboolean build_menu_switch (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client); static gboolean new_user_item (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client); +static void icon_changed (DBusGProxy * proxy, gchar * icon_name, gpointer user_data); +static void service_connection_cb (IndicatorServiceManager * sm, gboolean connected, gpointer user_data); static void indicator_session_class_init (IndicatorSessionClass *klass); static void indicator_session_init (IndicatorSession *self); @@ -101,14 +105,29 @@ indicator_session_init (IndicatorSession *self) /* Now let's fire these guys up. */ self->service = indicator_service_manager_new_version(INDICATOR_SESSION_DBUS_NAME, INDICATOR_SESSION_DBUS_VERSION); + g_signal_connect(G_OBJECT(self->service), INDICATOR_SERVICE_MANAGER_SIGNAL_CONNECTION_CHANGE, G_CALLBACK(service_connection_cb), self); - self->status_image = GTK_IMAGE(gtk_image_new_from_icon_name("system-shutdown-panel", GTK_ICON_SIZE_MENU)); + self->status_image = GTK_IMAGE(gtk_image_new_from_icon_name(ICON_DEFAULT, GTK_ICON_SIZE_MENU)); self->menu = dbusmenu_gtkmenu_new(INDICATOR_SESSION_DBUS_NAME, INDICATOR_SESSION_DBUS_OBJECT); DbusmenuClient * client = DBUSMENU_CLIENT(dbusmenu_gtkmenu_get_client(self->menu)); dbusmenu_client_add_type_handler(client, MENU_SWITCH_TYPE, build_menu_switch); dbusmenu_client_add_type_handler(client, USER_ITEM_TYPE, new_user_item); + DBusGConnection * session_bus = dbus_g_bus_get(DBUS_BUS_SESSION, NULL); + self->service_proxy = dbus_g_proxy_new_for_name(session_bus, + INDICATOR_SESSION_DBUS_NAME, + INDICATOR_SESSION_SERVICE_DBUS_OBJECT, + INDICATOR_SESSION_SERVICE_DBUS_IFACE); + + dbus_g_proxy_add_signal(self->service_proxy, "IconUpdated", + G_TYPE_STRING, G_TYPE_INVALID); + dbus_g_proxy_connect_signal(self->service_proxy, + "IconUpdated", + G_CALLBACK(icon_changed), + self, + NULL); + return; } @@ -122,6 +141,11 @@ indicator_session_dispose (GObject *object) self->service = NULL; } + if (self->service_proxy != NULL) { + g_object_unref(self->service_proxy); + self->service_proxy = NULL; + } + G_OBJECT_CLASS (indicator_session_parent_class)->dispose (object); return; } @@ -134,12 +158,42 @@ indicator_session_finalize (GObject *object) return; } +static void +icon_name_get_cb (DBusGProxy *proxy, char * OUT_name, GError *error, gpointer userdata) +{ + IndicatorSession * self = INDICATOR_SESSION(userdata); + gtk_image_set_from_icon_name(self->status_image, OUT_name, GTK_ICON_SIZE_MENU); + return; +} + +static void +service_connection_cb (IndicatorServiceManager * sm, gboolean connected, gpointer user_data) +{ + IndicatorSession * self = INDICATOR_SESSION(user_data); + + if (connected) { + org_ayatana_indicator_session_service_get_icon_async(self->service_proxy, icon_name_get_cb, user_data); + } else { + gtk_image_set_from_icon_name(self->status_image, ICON_DEFAULT, GTK_ICON_SIZE_MENU); + } + + return; +} + static GtkLabel * get_label (IndicatorObject * io) { return NULL; } +static void +icon_changed (DBusGProxy * proxy, gchar * icon_name, gpointer user_data) +{ + IndicatorSession * session = INDICATOR_SESSION(user_data); + gtk_image_set_from_icon_name(session->status_image, icon_name, GTK_ICON_SIZE_MENU); + return; +} + static GtkImage * get_icon (IndicatorObject * io) { diff --git a/src/session-dbus.c b/src/session-dbus.c new file mode 100644 index 0000000..20a0fa0 --- /dev/null +++ b/src/session-dbus.c @@ -0,0 +1,139 @@ +/* +The Dbus object on the bus for the indicator. + +Copyright 2010 Canonical Ltd. + +Authors: + Ted Gould <ted@canonical.com> + +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 +by the Free Software Foundation. + +This program is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranties of +MERCHANTABILITY, SATISFACTORY QUALITY, 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/>. +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "session-dbus.h" +#include "dbus-shared-names.h" + +static gboolean _session_dbus_server_get_icon (SessionDbus * service, gchar ** icon, GError ** error); + +#include "session-dbus-server.h" + +typedef struct _SessionDbusPrivate SessionDbusPrivate; +struct _SessionDbusPrivate { + gchar * name; +}; + +/* Signals */ +enum { + ICON_UPDATED, + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL] = { 0 }; + +#define SESSION_DBUS_GET_PRIVATE(o) \ +(G_TYPE_INSTANCE_GET_PRIVATE ((o), SESSION_DBUS_TYPE, SessionDbusPrivate)) + +static void session_dbus_class_init (SessionDbusClass *klass); +static void session_dbus_init (SessionDbus *self); +static void session_dbus_dispose (GObject *object); +static void session_dbus_finalize (GObject *object); + +G_DEFINE_TYPE (SessionDbus, session_dbus, G_TYPE_OBJECT); + +static void +session_dbus_class_init (SessionDbusClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + g_type_class_add_private (klass, sizeof (SessionDbusPrivate)); + + object_class->dispose = session_dbus_dispose; + object_class->finalize = session_dbus_finalize; + + signals[ICON_UPDATED] = g_signal_new ("icon-updated", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (SessionDbusClass, icon_updated), + NULL, NULL, + g_cclosure_marshal_VOID__STRING, + G_TYPE_NONE, 1, G_TYPE_STRING); + + dbus_g_object_type_install_info(SESSION_DBUS_TYPE, &dbus_glib__session_dbus_server_object_info); + + return; +} + +static void +session_dbus_init (SessionDbus *self) +{ + DBusGConnection * session = dbus_g_bus_get(DBUS_BUS_SESSION, NULL); + dbus_g_connection_register_g_object(session, INDICATOR_SESSION_SERVICE_DBUS_OBJECT, G_OBJECT(self)); + + SessionDbusPrivate * priv = SESSION_DBUS_GET_PRIVATE(self); + + priv->name = g_strdup(ICON_DEFAULT); + + return; +} + +static void +session_dbus_dispose (GObject *object) +{ + + G_OBJECT_CLASS (session_dbus_parent_class)->dispose (object); + return; +} + +static void +session_dbus_finalize (GObject *object) +{ + SessionDbusPrivate * priv = SESSION_DBUS_GET_PRIVATE(object); + + if (priv->name != NULL) { + g_free(priv->name); + priv->name = NULL; + } + + G_OBJECT_CLASS (session_dbus_parent_class)->finalize (object); + return; +} + +static gboolean +_session_dbus_server_get_icon (SessionDbus * service, gchar ** icon, GError ** error) +{ + SessionDbusPrivate * priv = SESSION_DBUS_GET_PRIVATE(service); + *icon = g_strdup(priv->name); + return TRUE; +} + +SessionDbus * +session_dbus_new (void) +{ + return SESSION_DBUS(g_object_new(SESSION_DBUS_TYPE, NULL)); +} + +void +session_dbus_set_name (SessionDbus * session, const gchar * name) +{ + SessionDbusPrivate * priv = SESSION_DBUS_GET_PRIVATE(session); + if (priv->name != NULL) { + g_free(priv->name); + priv->name = NULL; + } + priv->name = g_strdup(name); + g_signal_emit(G_OBJECT(session), signals[ICON_UPDATED], 0, priv->name, TRUE); + return; +} diff --git a/src/session-dbus.h b/src/session-dbus.h new file mode 100644 index 0000000..792917b --- /dev/null +++ b/src/session-dbus.h @@ -0,0 +1,55 @@ +/* +The Dbus object on the bus for the indicator. + +Copyright 2010 Canonical Ltd. + +Authors: + Ted Gould <ted@canonical.com> + +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 +by the Free Software Foundation. + +This program is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranties of +MERCHANTABILITY, SATISFACTORY QUALITY, 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/>. +*/ + +#ifndef __SESSION_DBUS_H__ +#define __SESSION_DBUS_H__ + +#include <glib.h> +#include <glib-object.h> + +G_BEGIN_DECLS + +#define SESSION_DBUS_TYPE (session_dbus_get_type ()) +#define SESSION_DBUS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SESSION_DBUS_TYPE, SessionDbus)) +#define SESSION_DBUS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SESSION_DBUS_TYPE, SessionDbusClass)) +#define IS_SESSION_DBUS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SESSION_DBUS_TYPE)) +#define IS_SESSION_DBUS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SESSION_DBUS_TYPE)) +#define SESSION_DBUS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SESSION_DBUS_TYPE, SessionDbusClass)) + +typedef struct _SessionDbus SessionDbus; +typedef struct _SessionDbusClass SessionDbusClass; + +struct _SessionDbusClass { + GObjectClass parent_class; + void (*icon_updated) (SessionDbus * session, gchar * icon, gpointer user_data); +}; + +struct _SessionDbus { + GObject parent; +}; + +GType session_dbus_get_type (void); +SessionDbus * session_dbus_new (void); +void session_dbus_set_name (SessionDbus * session, const gchar * name); + +G_END_DECLS + +#endif diff --git a/src/session-dbus.xml b/src/session-dbus.xml new file mode 100644 index 0000000..3ce1693 --- /dev/null +++ b/src/session-dbus.xml @@ -0,0 +1,15 @@ +<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd"> +<node name="/org/ayatana/indicator/session/service"> + <interface name="org.ayatana.indicator.session.service"> + + <!-- Icon --> + <method name="GetIcon"> + <arg name="name" direction="out" type="s"/> + </method> + + <signal name="IconUpdated"> + <arg name="name" type="s"/> + </signal> + + </interface> +</node> diff --git a/src/session-service.c b/src/session-service.c index febf007..75c8650 100644 --- a/src/session-service.c +++ b/src/session-service.c @@ -43,6 +43,7 @@ with this program. If not, see <http://www.gnu.org/licenses/>. #include "gconf-helper.h" +#include "session-dbus.h" #include "users-service-dbus.h" #include "lock-helper.h" @@ -65,6 +66,7 @@ struct _ActivateData static DBusGConnection *system_bus = NULL; static DBusGProxy *gdm_proxy = NULL; static UsersServiceDbus *dbus_interface = NULL; +static SessionDbus *session_dbus = NULL; static DbusmenuMenuitem *lock_menuitem = NULL; static DbusmenuMenuitem *switch_menuitem = NULL; @@ -620,13 +622,19 @@ restart_dir_changed (void) dbusmenu_menuitem_property_set(restart_mi, DBUSMENU_MENUITEM_PROP_LABEL, _("Restart Required...")); } dbusmenu_menuitem_property_set(restart_mi, DBUSMENU_MENUITEM_PROP_ICON_NAME, "emblem-important"); - } else { + if (session_dbus != NULL) { + session_dbus_set_name(session_dbus, ICON_RESTART); + } + } else { if (supress_confirmations()) { dbusmenu_menuitem_property_set(restart_mi, DBUSMENU_MENUITEM_PROP_LABEL, _("Restart")); } else { dbusmenu_menuitem_property_set(restart_mi, DBUSMENU_MENUITEM_PROP_LABEL, _("Restart...")); } dbusmenu_menuitem_property_remove(restart_mi, DBUSMENU_MENUITEM_PROP_ICON_NAME); + if (session_dbus != NULL) { + session_dbus_set_name(session_dbus, ICON_DEFAULT); + } } return; @@ -666,6 +674,8 @@ main (int argc, char ** argv) INDICATOR_SERVICE_SIGNAL_SHUTDOWN, G_CALLBACK(service_shutdown), NULL); + session_dbus = session_dbus_new(); + g_idle_add(lock_screen_setup, NULL); root_menuitem = dbusmenu_menuitem_new(); |