diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile.am | 107 | ||||
-rw-r--r-- | src/dbus-shared-names.h | 1 | ||||
-rw-r--r-- | src/indicator-session.c | 529 | ||||
-rw-r--r-- | src/session-service.c | 308 | ||||
-rw-r--r-- | src/status-provider-mc5.c | 322 | ||||
-rw-r--r-- | src/status-provider-mc5.h | 56 | ||||
-rw-r--r-- | src/status-provider-mc5.list | 1 | ||||
-rw-r--r-- | src/status-provider-pidgin.c | 431 | ||||
-rw-r--r-- | src/status-provider-pidgin.h | 56 | ||||
-rw-r--r-- | src/status-provider-pidgin.list | 1 | ||||
-rw-r--r-- | src/status-provider-telepathy.c | 383 | ||||
-rw-r--r-- | src/status-provider-telepathy.h | 56 | ||||
-rw-r--r-- | src/status-provider-telepathy.list | 1 | ||||
-rw-r--r-- | src/status-provider.c | 101 | ||||
-rw-r--r-- | src/status-provider.h | 78 | ||||
-rw-r--r-- | src/status-service-dbus.c | 205 | ||||
-rw-r--r-- | src/status-service-dbus.h | 59 | ||||
-rw-r--r-- | src/status-service.c | 264 | ||||
-rw-r--r-- | src/status-service.xml | 25 | ||||
-rw-r--r-- | src/users-service.c | 326 |
20 files changed, 310 insertions, 3000 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index 6a5fc44..e5d5a3c 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,6 +1,6 @@ SUBDIRS = gtk-dialog -libexec_PROGRAMS = indicator-status-service indicator-users-service indicator-session-service +libexec_PROGRAMS = indicator-session-service ################### # Indicator Stuff @@ -11,41 +11,11 @@ sessionlib_LTLIBRARIES = libsession.la libsession_la_SOURCES = \ indicator-session.c \ dbus-shared-names.h \ - status-service-client.h \ users-service-client.h libsession_la_CFLAGS = $(APPLET_CFLAGS) -Wall -Werror libsession_la_LIBADD = $(APPLET_LIBS) libsession_la_LDFLAGS = -module -avoid-version -################ -# Status Stuff -################ - -indicator_status_service_SOURCES = \ - status-service.c \ - status-service-dbus.h \ - status-service-dbus.c \ - status-service-server.h \ - users-service-dbus.h \ - users-service-dbus.c \ - users-service-marshal.c \ - users-service-marshal.h \ - status-provider.h \ - status-provider.c \ - status-provider-mc5.h \ - status-provider-mc5.c \ - status-provider-mc5-marshal.h \ - status-provider-mc5-marshal.c \ - status-provider-pidgin.h \ - status-provider-pidgin.c \ - status-provider-pidgin-marshal.h \ - status-provider-pidgin-marshal.c \ - status-provider-telepathy.h \ - status-provider-telepathy.c \ - status-provider-telepathy-marshal.h \ - status-provider-telepathy-marshal.c -indicator_status_service_CFLAGS = $(STATUSSERVICE_CFLAGS) -Wall -Werror -indicator_status_service_LDADD = $(STATUSSERVICE_LIBS) users-service-client.h: $(srcdir)/users-service.xml dbus-binding-tool \ @@ -54,20 +24,6 @@ users-service-client.h: $(srcdir)/users-service.xml --output=users-service-client.h \ $(srcdir)/users-service.xml -status-service-client.h: $(srcdir)/status-service.xml - dbus-binding-tool \ - --prefix=_status_service_client \ - --mode=glib-client \ - --output=status-service-client.h \ - $(srcdir)/status-service.xml - -status-service-server.h: $(srcdir)/status-service.xml - dbus-binding-tool \ - --prefix=_status_service_server \ - --mode=glib-server \ - --output=status-service-server.h \ - $(srcdir)/status-service.xml - users-service-marshal.h: $(srcdir)/users-service.list glib-genmarshal --header \ --prefix=_users_service_marshal $(srcdir)/users-service.list \ @@ -78,49 +34,6 @@ users-service-marshal.c: $(srcdir)/users-service.list --prefix=_users_service_marshal $(srcdir)/users-service.list \ > users-service-marshal.c -status-provider-pidgin-marshal.h: $(srcdir)/status-provider-pidgin.list - glib-genmarshal --header \ - --prefix=_status_provider_pidgin_marshal $(srcdir)/status-provider-pidgin.list \ - > status-provider-pidgin-marshal.h - -status-provider-pidgin-marshal.c: $(srcdir)/status-provider-pidgin.list - glib-genmarshal --body \ - --prefix=_status_provider_pidgin_marshal $(srcdir)/status-provider-pidgin.list \ - > status-provider-pidgin-marshal.c - -status-provider-telepathy-marshal.h: $(srcdir)/status-provider-telepathy.list - glib-genmarshal --header \ - --prefix=_status_provider_telepathy_marshal $(srcdir)/status-provider-telepathy.list \ - > status-provider-telepathy-marshal.h - -status-provider-telepathy-marshal.c: $(srcdir)/status-provider-telepathy.list - glib-genmarshal --body \ - --prefix=_status_provider_telepathy_marshal $(srcdir)/status-provider-telepathy.list \ - > status-provider-telepathy-marshal.c - -status-provider-mc5-marshal.h: $(srcdir)/status-provider-mc5.list - glib-genmarshal --header \ - --prefix=_status_provider_mc5_marshal $(srcdir)/status-provider-mc5.list \ - > status-provider-mc5-marshal.h - -status-provider-mc5-marshal.c: $(srcdir)/status-provider-mc5.list - glib-genmarshal --body \ - --prefix=_status_provider_mc5_marshal $(srcdir)/status-provider-mc5.list \ - > status-provider-mc5-marshal.c - -############### -# Users Stuff -############### - -indicator_users_service_SOURCES = \ - lock-helper.c \ - lock-helper.h \ - users-service.c \ - users-service-dbus.c \ - users-service-marshal.c -indicator_users_service_CFLAGS = $(USERSSERVICE_CFLAGS) -Wall -Werror -indicator_users_service_LDADD = $(USERSSERVICE_LIBS) - ################# # Session Stuff ################# @@ -129,7 +42,9 @@ indicator_session_service_SOURCES = \ lock-helper.c \ lock-helper.h \ session-service.c \ - gtk-dialog/gconf-helper.c + gtk-dialog/gconf-helper.c \ + users-service-dbus.c \ + users-service-marshal.c indicator_session_service_CFLAGS = $(SESSIONSERVICE_CFLAGS) $(GCONF_CFLAGS) -DLIBEXECDIR=\"$(libexecdir)\" -Wall -Werror indicator_session_service_LDADD = $(SESSIONSERVICE_LIBS) $(GCONF_LIBS) @@ -139,22 +54,10 @@ indicator_session_service_LDADD = $(SESSIONSERVICE_LIBS) $(GCONF_LIBS) BUILT_SOURCES = \ users-service-client.h \ - status-service-client.h \ - status-service-server.h \ - status-provider-mc5-marshal.h \ - status-provider-mc5-marshal.c \ users-service-marshal.h \ - users-service-marshal.c \ - status-provider-pidgin-marshal.h \ - status-provider-pidgin-marshal.c \ - status-provider-telepathy-marshal.h \ - status-provider-telepathy-marshal.c + users-service-marshal.c EXTRA_DIST = \ - status-service.xml \ - status-provider-mc5.list \ - status-provider-pidgin.list \ - status-provider-telepathy.list \ users-service.xml \ users-service.list diff --git a/src/dbus-shared-names.h b/src/dbus-shared-names.h index 7e7d456..1fd256f 100644 --- a/src/dbus-shared-names.h +++ b/src/dbus-shared-names.h @@ -36,5 +36,6 @@ with this program. If not, see <http://www.gnu.org/licenses/>. #define INDICATOR_SESSION_DBUS_NAME "org.ayatana.indicator.session" #define INDICATOR_SESSION_DBUS_OBJECT "/org/ayatana/indicator/session/menu" +#define INDICATOR_SESSION_DBUS_VERSION 0 #endif /* __DBUS_SHARED_NAMES_H__ */ diff --git a/src/indicator-session.c b/src/indicator-session.c index 410ad12..dda8c76 100644 --- a/src/indicator-session.c +++ b/src/indicator-session.c @@ -23,16 +23,16 @@ with this program. If not, see <http://www.gnu.org/licenses/>. #include <glib.h> #include <glib-object.h> #include <gtk/gtk.h> -#include <libdbusmenu-gtk/client.h> +#include <libdbusmenu-gtk/menu.h> #include <dbus/dbus-glib.h> #include <dbus/dbus-glib-bindings.h> #include <libindicator/indicator.h> #include <libindicator/indicator-object.h> +#include <libindicator/indicator-service-manager.h> #include "dbus-shared-names.h" -#include "status-service-client.h" #define INDICATOR_SESSION_TYPE (indicator_session_get_type ()) #define INDICATOR_SESSION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), INDICATOR_SESSION_TYPE, IndicatorSession)) @@ -50,6 +50,7 @@ struct _IndicatorSessionClass { struct _IndicatorSession { IndicatorObject parent; + IndicatorServiceManager * service; }; GType indicator_session_get_type (void); @@ -58,38 +59,7 @@ GType indicator_session_get_type (void); INDICATOR_SET_VERSION INDICATOR_SET_TYPE(INDICATOR_SESSION_TYPE) -/* Globals */ -static DbusmenuGtkClient * status_client = NULL; -static DbusmenuGtkClient * users_client = NULL; -static DbusmenuGtkClient * session_client = NULL; - -static GtkMenu * main_menu = NULL; -static GtkImage * status_image = NULL; - -static GtkWidget * status_separator = NULL; -static GtkWidget * users_separator = NULL; -#define SEPARATOR_SHOWN(sep) (sep != NULL && GTK_WIDGET_VISIBLE(sep)) -static GtkWidget * loading_item = NULL; - -static DBusGConnection * connection = NULL; -static DBusGProxy * proxy = NULL; -static DBusGProxy * status_proxy = NULL; - -typedef enum { - STATUS_SECTION, - USERS_SECTION, - SESSION_SECTION, - END_OF_SECTIONS -} section_t; - /* Prototypes */ -static void child_added (DbusmenuMenuitem * parent, DbusmenuMenuitem * child, guint position, gpointer section); -static guint status_menu_pos_offset (void); -static guint users_menu_pos_offset (void); -static guint session_menu_pos_offset (void); -static void child_realized (DbusmenuMenuitem * child, gpointer userdata); -static gboolean start_service (gpointer userdata); -static void start_service_phase2 (DBusGProxy * proxy, guint status, GError * error, gpointer data); static GtkLabel * get_label (IndicatorObject * io); static GtkImage * get_icon (IndicatorObject * io); static GtkMenu * get_menu (IndicatorObject * io); @@ -120,6 +90,11 @@ indicator_session_class_init (IndicatorSessionClass *klass) static void indicator_session_init (IndicatorSession *self) { + /* Set good defaults */ + self->service = NULL; + + /* Now let's fire these guys up. */ + self->service = indicator_service_manager_new_version(INDICATOR_SESSION_DBUS_NAME, INDICATOR_SESSION_DBUS_VERSION); return; } @@ -127,6 +102,12 @@ indicator_session_init (IndicatorSession *self) static void indicator_session_dispose (GObject *object) { + IndicatorSession * self = INDICATOR_SESSION(object); + + if (self->service != NULL) { + g_object_unref(G_OBJECT(self->service)); + self->service = NULL; + } G_OBJECT_CLASS (indicator_session_parent_class)->dispose (object); return; @@ -143,500 +124,24 @@ indicator_session_finalize (GObject *object) static GtkLabel * get_label (IndicatorObject * io) { - GtkLabel * returnval = GTK_LABEL(gtk_label_new(g_get_user_name())); - gtk_widget_show(GTK_WIDGET(returnval)); - return returnval; + return NULL; } static GtkImage * get_icon (IndicatorObject * io) { - g_debug("Changing status icon: '%s'", "system-shutdown-panel"); - status_image = GTK_IMAGE(gtk_image_new_from_icon_name("system-shutdown-panel", GTK_ICON_SIZE_MENU)); + GtkImage * status_image = GTK_IMAGE(gtk_image_new_from_icon_name("system-shutdown-panel", GTK_ICON_SIZE_MENU)); gtk_widget_show(GTK_WIDGET(status_image)); return status_image; } -typedef struct _realized_data_t realized_data_t; -struct _realized_data_t { - section_t section; -}; - -static void -resort_menu (void) -{ - guint location = 0; - guint clientnum; - - for (clientnum = 0; clientnum < 3; clientnum++) { - DbusmenuGtkClient * client = NULL; - if (clientnum == 0) client = status_client; - if (clientnum == 1) client = users_client; - if (clientnum == 2) client = session_client; - - if (client == NULL) continue; - - DbusmenuMenuitem * root = dbusmenu_client_get_root(DBUSMENU_CLIENT(client)); - - GList * children = dbusmenu_menuitem_get_children(root); - if (children == NULL) { - continue; - } - - GList * child; - for (child = children; child != NULL; child = g_list_next(child)) { - GtkMenuItem * widget = dbusmenu_gtkclient_menuitem_get(client, DBUSMENU_MENUITEM(child->data)); - if (widget != NULL) { - gtk_menu_reorder_child(main_menu, GTK_WIDGET(widget), location); - location++; - } - } - - if (clientnum == 0) { - gtk_menu_reorder_child(main_menu, status_separator, location); - location++; - } - if (clientnum == 1) { - gtk_menu_reorder_child(main_menu, users_separator, location); - location++; - } - } - - return; -} - -static void -child_added (DbusmenuMenuitem * parent, DbusmenuMenuitem * child, guint position, gpointer section) -{ - realized_data_t * data = g_new0(realized_data_t, 1); - if (data == NULL) { - g_warning("Unable to allocate data for realization of item"); - return; - } - - data->section = GPOINTER_TO_UINT(section); - - g_signal_connect(G_OBJECT(child), DBUSMENU_MENUITEM_SIGNAL_REALIZED, G_CALLBACK(child_realized), data); - return; -} - -static void -child_realized (DbusmenuMenuitem * child, gpointer userdata) -{ - g_return_if_fail(userdata != NULL); - g_return_if_fail(DBUSMENU_IS_MENUITEM(child)); - - realized_data_t * data = (realized_data_t *)userdata; - section_t section = data->section; - g_free(data); - - DbusmenuGtkClient * client = NULL; - gchar * errorstr = NULL; - guint (*posfunc) (void) = NULL; - - switch (section) { - case STATUS_SECTION: - client = status_client; - errorstr = "Status"; - posfunc = status_menu_pos_offset; - break; - case USERS_SECTION: - client = users_client; - errorstr = "Users"; - posfunc = users_menu_pos_offset; - break; - case SESSION_SECTION: - client = session_client; - errorstr = "Session"; - posfunc = session_menu_pos_offset; - break; - default: - g_warning("Child Added called with an unknown position function!"); - return; - } - - if (client == NULL) { - g_warning("Child realized for a menu we don't have? Section: %s", errorstr); - return; - } - - GtkMenuItem * widget = dbusmenu_gtkclient_menuitem_get(client, child); - - if (widget == NULL) { - g_warning("Had a menu item added to the %s menu, but yet it didn't have a GtkWidget with it. Can't add that to a menu now can we? You need to figure this @#$# out!", errorstr); - return; - } - - gtk_menu_append(main_menu, GTK_WIDGET(widget)); - gtk_widget_show(GTK_WIDGET(widget)); - - resort_menu(); - - gtk_widget_hide(loading_item); - - return; -} - -static void -child_moved (DbusmenuMenuitem * parent, DbusmenuMenuitem * child, guint newpos, guint oldpos, guint (*posfunc) (void)) -{ - - -} - - -/* Status Menu */ -static guint -status_menu_pos_offset (void) -{ - return 0; -} - -static void -status_menu_added (DbusmenuMenuitem * root, DbusmenuMenuitem * child, guint position, gpointer user_data) -{ - gtk_widget_show(GTK_WIDGET(status_separator)); - return; -} - -static void -status_menu_removed (DbusmenuMenuitem * root, DbusmenuMenuitem * child, gpointer user_data) -{ - if (g_list_length(dbusmenu_menuitem_get_children(root)) == 0) { - gtk_widget_hide(GTK_WIDGET(status_separator)); - } - - return; -} - -static void -status_menu_root_changed(DbusmenuGtkClient * client, DbusmenuMenuitem * newroot, GtkMenu * main) -{ - if (newroot == NULL) { - gtk_widget_hide(GTK_WIDGET(status_separator)); - return; - } - - g_signal_connect(G_OBJECT(newroot), DBUSMENU_MENUITEM_SIGNAL_CHILD_ADDED, G_CALLBACK(child_added), GUINT_TO_POINTER(STATUS_SECTION)); - g_signal_connect(G_OBJECT(newroot), DBUSMENU_MENUITEM_SIGNAL_CHILD_REMOVED, G_CALLBACK(status_menu_added), NULL); - g_signal_connect(G_OBJECT(newroot), DBUSMENU_MENUITEM_SIGNAL_CHILD_REMOVED, G_CALLBACK(status_menu_removed), NULL); - g_signal_connect(G_OBJECT(newroot), DBUSMENU_MENUITEM_SIGNAL_CHILD_MOVED, G_CALLBACK(child_moved), GUINT_TO_POINTER(STATUS_SECTION)); - - GList * child = NULL; - guint count = 0; - for (child = dbusmenu_menuitem_get_children(newroot); child != NULL; child = g_list_next(child), count++) { - child_added(newroot, DBUSMENU_MENUITEM(child->data), count, GUINT_TO_POINTER(STATUS_SECTION)); - } - - if (count > 0) { - gtk_widget_show(GTK_WIDGET(status_separator)); - } - - return; -} - -static void -status_icon_cb (DBusGProxy * proxy, char * icons, GError *error, gpointer userdata) -{ - g_return_if_fail(status_image != NULL); - g_return_if_fail(icons != NULL); - g_return_if_fail(icons[0] != '\0'); - - g_debug("Changing status icon: '%s'", icons); - gtk_image_set_from_icon_name(status_image, icons, GTK_ICON_SIZE_MENU); - - return; -} - -static void -status_icon_changed (DBusGProxy * proxy, gchar * icon, gpointer userdata) -{ - return status_icon_cb(proxy, icon, NULL, NULL); -} - - -static gboolean -connect_to_status (gpointer userdata) -{ - if (status_proxy == NULL) { - GError * error = NULL; - - DBusGConnection * sbus = dbus_g_bus_get(DBUS_BUS_SESSION, NULL); - - status_proxy = dbus_g_proxy_new_for_name_owner(sbus, - INDICATOR_STATUS_DBUS_NAME, - INDICATOR_STATUS_SERVICE_DBUS_OBJECT, - INDICATOR_STATUS_SERVICE_DBUS_INTERFACE, - &error); - - if (error != NULL) { - g_warning("Unable to get status proxy: %s", error->message); - g_error_free(error); - return FALSE; - } - - dbus_g_proxy_add_signal(status_proxy, "StatusIconsChanged", G_TYPE_STRING, G_TYPE_INVALID); - dbus_g_proxy_connect_signal(status_proxy, "StatusIconsChanged", G_CALLBACK(status_icon_changed), NULL, NULL); - } - - org_ayatana_indicator_status_service_status_icons_async(status_proxy, status_icon_cb, NULL); - - return FALSE; -} - -/* Follow up the service being started by connecting - up the DBus Menu Client and creating our separator. - Also creates an idle func to connect to the service for - getting the icon that we should be using on the panel. */ -static void -status_followup (void) -{ - status_client = dbusmenu_gtkclient_new(INDICATOR_STATUS_DBUS_NAME, INDICATOR_STATUS_DBUS_OBJECT); - g_signal_connect(G_OBJECT(status_client), DBUSMENU_GTKCLIENT_SIGNAL_ROOT_CHANGED, G_CALLBACK(status_menu_root_changed), main_menu); - - status_separator = gtk_separator_menu_item_new(); - gtk_menu_shell_append(GTK_MENU_SHELL(main_menu), status_separator); - gtk_widget_hide(status_separator); /* Should be default, I'm just being explicit. $(%*#$ hide already! */ - - g_idle_add(connect_to_status, NULL); - - return; -} - -/* Users menu */ - -static guint -users_menu_pos_offset (void) -{ - guint position = 0; - if (SEPARATOR_SHOWN(status_separator)) { - GList * location = g_list_find(GTK_MENU_SHELL(main_menu)->children, status_separator); - position = g_list_position(GTK_MENU_SHELL(main_menu)->children, location) + 1; - } - - return position; -} - -static void -users_menu_added (DbusmenuMenuitem * root, DbusmenuMenuitem * child, guint position, gpointer user_data) -{ - gtk_widget_show(GTK_WIDGET(users_separator)); - return; -} - -static void -users_menu_removed (DbusmenuMenuitem * root, DbusmenuMenuitem * child, gpointer user_data) -{ - if (g_list_length(dbusmenu_menuitem_get_children(root)) == 0) { - gtk_widget_hide(GTK_WIDGET(users_separator)); - } - - return; -} - -static void -users_menu_root_changed(DbusmenuGtkClient * client, DbusmenuMenuitem * newroot, GtkMenu * main) -{ - if (newroot == NULL) { - gtk_widget_hide(GTK_WIDGET(users_separator)); - return; - } - - g_signal_connect(G_OBJECT(newroot), DBUSMENU_MENUITEM_SIGNAL_CHILD_ADDED, G_CALLBACK(child_added), GUINT_TO_POINTER(USERS_SECTION)); - g_signal_connect(G_OBJECT(newroot), DBUSMENU_MENUITEM_SIGNAL_CHILD_REMOVED, G_CALLBACK(users_menu_added), NULL); - g_signal_connect(G_OBJECT(newroot), DBUSMENU_MENUITEM_SIGNAL_CHILD_REMOVED, G_CALLBACK(users_menu_removed), NULL); - g_signal_connect(G_OBJECT(newroot), DBUSMENU_MENUITEM_SIGNAL_CHILD_MOVED, G_CALLBACK(child_moved), GUINT_TO_POINTER(USERS_SECTION)); - - GList * child = NULL; - guint count = 0; - for (child = dbusmenu_menuitem_get_children(newroot); child != NULL; child = g_list_next(child), count++) { - child_added(newroot, DBUSMENU_MENUITEM(child->data), count, GUINT_TO_POINTER(USERS_SECTION)); - } - - if (count > 0) { - gtk_widget_show(GTK_WIDGET(users_separator)); - } - - return; -} - -/* Follow up the service being started by connecting - up the DBus Menu Client and creating our separator. */ -static void -users_followup (void) -{ - users_client = dbusmenu_gtkclient_new(INDICATOR_USERS_DBUS_NAME, INDICATOR_USERS_DBUS_OBJECT); - g_signal_connect(G_OBJECT(users_client), DBUSMENU_GTKCLIENT_SIGNAL_ROOT_CHANGED, G_CALLBACK(users_menu_root_changed), main_menu); - - users_separator = gtk_separator_menu_item_new(); - gtk_menu_shell_append(GTK_MENU_SHELL(main_menu), users_separator); - gtk_widget_hide(users_separator); /* Should be default, I'm just being explicit. $(%*#$ hide already! */ - - return; -} - -/* Session Menu Stuff */ - -static guint -session_menu_pos_offset (void) -{ - guint position = 0; - if (SEPARATOR_SHOWN(users_separator)) { - GList * location = g_list_find(GTK_MENU_SHELL(main_menu)->children, users_separator); - position = g_list_position(GTK_MENU_SHELL(main_menu)->children, location) + 1; - } else if (SEPARATOR_SHOWN(status_separator)) { - GList * location = g_list_find(GTK_MENU_SHELL(main_menu)->children, status_separator); - position = g_list_position(GTK_MENU_SHELL(main_menu)->children, location) + 1; - } - - return position; -} - -static void -session_menu_removed (DbusmenuMenuitem * root, DbusmenuMenuitem * child, gpointer user_data) -{ - return; -} - -static void -session_menu_root_changed(DbusmenuGtkClient * client, DbusmenuMenuitem * newroot, GtkMenu * main) -{ - if (newroot == NULL) { - /* We're assuming this'll crash the least so it doesn't - hide a separator. May be a bad choice. */ - return; - } - - g_signal_connect(G_OBJECT(newroot), DBUSMENU_MENUITEM_SIGNAL_CHILD_ADDED, G_CALLBACK(child_added), GUINT_TO_POINTER(SESSION_SECTION)); - g_signal_connect(G_OBJECT(newroot), DBUSMENU_MENUITEM_SIGNAL_CHILD_REMOVED, G_CALLBACK(session_menu_removed), NULL); - g_signal_connect(G_OBJECT(newroot), DBUSMENU_MENUITEM_SIGNAL_CHILD_MOVED, G_CALLBACK(child_moved), GUINT_TO_POINTER(SESSION_SECTION)); - - GList * child = NULL; - guint count = 0; - for (child = dbusmenu_menuitem_get_children(newroot); child != NULL; child = g_list_next(child), count++) { - child_added(newroot, DBUSMENU_MENUITEM(child->data), count, GUINT_TO_POINTER(SESSION_SECTION)); - } - - return; -} - -/* Follow up the service being started by connecting - up the DBus Menu Client. */ -static void -session_followup (void) -{ - session_client = dbusmenu_gtkclient_new(INDICATOR_SESSION_DBUS_NAME, INDICATOR_SESSION_DBUS_OBJECT); - g_signal_connect(G_OBJECT(session_client), DBUSMENU_GTKCLIENT_SIGNAL_ROOT_CHANGED, G_CALLBACK(session_menu_root_changed), main_menu); - - return; -} - -/* Base menu stuff */ - -/* This takes the response to the service starting up. - It checks to see if it's started and if so, continues - with the follow function for the particular area that - it's working in. */ -static void -start_service_phase2 (DBusGProxy * proxy, guint status, GError * error, gpointer data) -{ - /* If we've got an error respond to it */ - if (error != NULL) { - g_critical("Starting service has resulted in error."); - g_error_free(error); - /* Try it all again, we need to get this started! */ - g_idle_add(start_service, data); - return; - } - - /* If it's not running or we started it, try again */ - if (status != DBUS_START_REPLY_SUCCESS && status != DBUS_START_REPLY_ALREADY_RUNNING) { - g_critical("Return value isn't indicative of success: %d", status); - /* Try it all again, we need to get this started! */ - g_idle_add(start_service, data); - return; - } - - /* Check which part of the menu we're in and do the - appropriate follow up from the service being started. */ - switch (GPOINTER_TO_INT(data)) { - case STATUS_SECTION: - status_followup(); - break; - case USERS_SECTION: - users_followup(); - break; - case SESSION_SECTION: - session_followup(); - break; - default: - g_critical("Oh, how can we get a value that we don't know!"); - break; - } - - return; -} - -/* Our idle service starter. It looks at the section that - we're doing and then asks async for that service to be - started by dbus. Probably not really useful to be in - the idle loop as it's so quick, but why not. */ -static gboolean -start_service (gpointer userdata) -{ - g_debug("Starting a service"); - - if (proxy == NULL) { - /* If we don't have DBus, let's stay in the idle loop */ - return TRUE; - } - - const gchar * service = NULL; - switch (GPOINTER_TO_INT(userdata)) { - case STATUS_SECTION: - service = INDICATOR_STATUS_DBUS_NAME; - break; - case USERS_SECTION: - service = INDICATOR_USERS_DBUS_NAME; - break; - case SESSION_SECTION: - service = INDICATOR_SESSION_DBUS_NAME; - break; - default: - g_critical("Oh, how can we get a value that we don't know!"); - return FALSE; - } - - org_freedesktop_DBus_start_service_by_name_async (proxy, service, 0 /* Flags */, start_service_phase2, userdata); - - return FALSE; -} - /* Indicator based function to get the menu for the whole applet. This starts up asking for the parts of the menu from the various services. */ static GtkMenu * get_menu (IndicatorObject * io) { - connection = dbus_g_bus_get(DBUS_BUS_SESSION, NULL); - proxy = dbus_g_proxy_new_for_name(connection, DBUS_SERVICE_DBUS, DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS); - if (proxy == NULL) { - g_warning("Unable to get proxy for DBus itself. Seriously."); - } - - /* Startup in the idle loop */ - g_idle_add(start_service, GINT_TO_POINTER(STATUS_SECTION)); - g_idle_add(start_service, GINT_TO_POINTER(USERS_SECTION)); - g_idle_add(start_service, GINT_TO_POINTER(SESSION_SECTION)); - - /* Build a temp menu incase someone can ask for it - before the services start. Fast user! */ - main_menu = GTK_MENU(gtk_menu_new()); - loading_item = gtk_menu_item_new_with_label("Loading..."); - gtk_menu_shell_append(GTK_MENU_SHELL(main_menu), loading_item); - gtk_widget_show(GTK_WIDGET(loading_item)); - - return main_menu; + return GTK_MENU(dbusmenu_gtkmenu_new(INDICATOR_SESSION_DBUS_NAME, INDICATOR_SESSION_DBUS_OBJECT)); } diff --git a/src/session-service.c b/src/session-service.c index a91170f..bec7749 100644 --- a/src/session-service.c +++ b/src/session-service.c @@ -7,6 +7,7 @@ Copyright 2009 Canonical Ltd. Authors: Ted Gould <ted@canonical.com> Christoph Korn <c_korn@gmx.de> + Cody Russell <crussell@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 @@ -23,6 +24,8 @@ with this program. If not, see <http://www.gnu.org/licenses/>. #include <config.h> +#include <unistd.h> + #include <glib/gi18n.h> #include <dbus/dbus-glib.h> @@ -30,17 +33,39 @@ with this program. If not, see <http://www.gnu.org/licenses/>. #include <libdbusmenu-glib/server.h> #include <libdbusmenu-glib/menuitem.h> +#include <libdbusmenu-glib/client.h> + +#include <libindicator/indicator-service.h> #include "dbus-shared-names.h" #include "gtk-dialog/gconf-helper.h" +#include "users-service-dbus.h" #include "lock-helper.h" #define DKP_ADDRESS "org.freedesktop.DeviceKit.Power" #define DKP_OBJECT "/org/freedesktop/DeviceKit/Power" #define DKP_INTERFACE "org.freedesktop.DeviceKit.Power" +#define GUEST_SESSION_LAUNCHER "/usr/share/gdm/guest-session/guest-session-launch" + +typedef struct _ActivateData ActivateData; +struct _ActivateData +{ + UsersServiceDbus *service; + UserData *user; +}; + +static DBusGConnection *system_bus = NULL; +static DBusGProxy *gdm_proxy = NULL; +static UsersServiceDbus *dbus_interface = NULL; + +static DbusmenuMenuitem *lock_menuitem = NULL; + +static gint count; +static GList *users; + static DbusmenuMenuitem * root_menuitem = NULL; static GMainLoop * mainloop = NULL; static DBusGProxy * dkp_main_proxy = NULL; @@ -67,7 +92,7 @@ sleep_response (DBusGProxy * proxy, DBusGProxyCall * call, gpointer data) /* Let's put this machine to sleep, with some info on how it should sleep. */ static void -sleep (DbusmenuMenuitem * mi, gpointer userdata) +machine_sleep (DbusmenuMenuitem * mi, gpointer userdata) { gchar * type = (gchar *)userdata; @@ -239,10 +264,194 @@ show_dialog (DbusmenuMenuitem * mi, gchar * type) return; } -/* This function creates all of the menuitems that the service - provides in the UI. It also connects them to the callbacks. */ +/* Respond to the signal of autologin changing to see if the + setting for timed login changes. */ +static void +gdm_settings_change (void) +{ + if (!will_lock_screen()) { + dbusmenu_menuitem_property_set_bool(lock_menuitem, DBUSMENU_MENUITEM_PROP_SENSITIVE, FALSE); + } else { + dbusmenu_menuitem_property_set_bool(lock_menuitem, DBUSMENU_MENUITEM_PROP_SENSITIVE, TRUE); + } + + return; +} + +/* Checks to see if we should show the guest suession item */ +static gboolean +check_guest_session (void) +{ + if (geteuid() < 500) { + /* System users shouldn't have guest account shown. Mosly + this would be the case of the guest user itself. */ + return FALSE; + } + if (!g_file_test(GUEST_SESSION_LAUNCHER, G_FILE_TEST_IS_EXECUTABLE)) { + /* It doesn't appear that the Guest session stuff is + installed. So let's not use it then! */ + return FALSE; + } + + return TRUE; +} + +/* Called when someone clicks on the guest session item. */ +static void +activate_guest_session (DbusmenuMenuitem * mi, gpointer user_data) +{ + GError * error = NULL; + if (!g_spawn_command_line_async(GUEST_SESSION_LAUNCHER, &error)) { + g_warning("Unable to start guest session: %s", error->message); + g_error_free(error); + } + + return; +} + +/* Checks to see if we can create sessions and get a proxy + to the display manager (GDM) */ +static gboolean +check_new_session (void) +{ + if (system_bus == NULL) { + system_bus = dbus_g_bus_get(DBUS_BUS_SYSTEM, NULL); + } + + if (system_bus == NULL) { + return FALSE; + } + + if (gdm_proxy == NULL) { + gdm_proxy = dbus_g_proxy_new_for_name(system_bus, + "org.gnome.DisplayManager", + "/org/gnome/DisplayManager/LocalDisplayFactory", + "org.gnome.DisplayManager.LocalDisplayFactory"); + } + + if (gdm_proxy == NULL) { + return FALSE; + } + + return TRUE; +} + +/* Starts a new generic session */ +static void +activate_new_session (DbusmenuMenuitem * mi, gpointer user_data) +{ + GError * error = NULL; + if (!g_spawn_command_line_async("gdmflexiserver --startnew", &error)) { + g_warning("Unable to start new session: %s", error->message); + g_error_free(error); + } + + return; +} + +/* Activates a session for a particular user. */ static void -create_items (DbusmenuMenuitem * root) { +activate_user_session (DbusmenuMenuitem *mi, gpointer user_data) +{ + UserData *user = (UserData *)user_data; + UsersServiceDbus *service = user->service; + + users_service_dbus_activate_user_session (service, user); +} + +/* Comparison function to look into the UserData struct + to compare by using the username value */ +static gint +compare_users_by_username (const gchar *a, + const gchar *b) +{ + UserData *user1 = (UserData *)a; + UserData *user2 = (UserData *)b; + + return g_strcmp0 (user1->user_name, user2->user_name); +} + +/* Builds up the menu for us */ +static void +rebuild_items (DbusmenuMenuitem *root, + UsersServiceDbus *service) +{ + DbusmenuMenuitem *mi = NULL; + GList *u; + UserData *user; + gboolean can_activate; + GList *children; + + can_activate = users_service_dbus_can_activate_session (service); + + children = dbusmenu_menuitem_take_children (root); + g_list_foreach (children, (GFunc)g_object_unref, NULL); + g_list_free (children); + + lock_menuitem = dbusmenu_menuitem_new(); + dbusmenu_menuitem_property_set(lock_menuitem, DBUSMENU_MENUITEM_PROP_LABEL, _("Lock Screen")); + g_signal_connect(G_OBJECT(lock_menuitem), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK(lock_screen), NULL); + dbusmenu_menuitem_child_append(root, lock_menuitem); + if (!will_lock_screen()) { + dbusmenu_menuitem_property_set_bool(lock_menuitem, DBUSMENU_MENUITEM_PROP_SENSITIVE, FALSE); + } else { + dbusmenu_menuitem_property_set_bool(lock_menuitem, DBUSMENU_MENUITEM_PROP_SENSITIVE, TRUE); + } + + if (can_activate == TRUE) + { + 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 > MINIMUM_USERS && count < MAXIMUM_USERS) + { + if (users != NULL) + { + GList *l = NULL; + + for (l = users; l != NULL; l = l->next) + { + users = g_list_delete_link (users, l); + } + + users = NULL; + } + + users = users_service_dbus_get_user_list (service); + + users = g_list_sort (users, (GCompareFunc)compare_users_by_username); + + for (u = users; u != NULL; u = g_list_next (u)) + { + user = u->data; + + user->service = service; + + mi = dbusmenu_menuitem_new (); + dbusmenu_menuitem_property_set (mi, DBUSMENU_MENUITEM_PROP_LABEL, user->real_name); + dbusmenu_menuitem_child_append (root, mi); + g_signal_connect (G_OBJECT (mi), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK (activate_user_session), user); + } + } + + if (check_new_session ()) + { + mi = dbusmenu_menuitem_new (); + dbusmenu_menuitem_property_set (mi, DBUSMENU_MENUITEM_PROP_LABEL, _("Switch User...")); + dbusmenu_menuitem_child_append (root, mi); + g_signal_connect (G_OBJECT (mi), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK (activate_new_session), NULL); + } + } + + DbusmenuMenuitem * separator = dbusmenu_menuitem_new(); + dbusmenu_menuitem_property_set(separator, DBUSMENU_MENUITEM_PROP_TYPE, DBUSMENU_CLIENT_TYPES_SEPARATOR); + dbusmenu_menuitem_child_append(root, separator); + logout_mi = dbusmenu_menuitem_new(); if (supress_confirmations()) { dbusmenu_menuitem_property_set(logout_mi, DBUSMENU_MENUITEM_PROP_LABEL, _("Log Out")); @@ -256,13 +465,13 @@ create_items (DbusmenuMenuitem * root) { dbusmenu_menuitem_property_set_bool(suspend_mi, DBUSMENU_MENUITEM_PROP_VISIBLE, FALSE); dbusmenu_menuitem_property_set(suspend_mi, DBUSMENU_MENUITEM_PROP_LABEL, _("Suspend")); dbusmenu_menuitem_child_append(root, suspend_mi); - g_signal_connect(G_OBJECT(suspend_mi), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK(sleep), "Suspend"); + g_signal_connect(G_OBJECT(suspend_mi), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK(machine_sleep), "Suspend"); hibernate_mi = dbusmenu_menuitem_new(); dbusmenu_menuitem_property_set_bool(hibernate_mi, DBUSMENU_MENUITEM_PROP_VISIBLE, FALSE); dbusmenu_menuitem_property_set(hibernate_mi, DBUSMENU_MENUITEM_PROP_LABEL, _("Hibernate")); dbusmenu_menuitem_child_append(root, hibernate_mi); - g_signal_connect(G_OBJECT(hibernate_mi), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK(sleep), "Hibernate"); + g_signal_connect(G_OBJECT(hibernate_mi), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK(machine_sleep), "Hibernate"); restart_mi = dbusmenu_menuitem_new(); if (supress_confirmations()) { @@ -292,6 +501,59 @@ create_items (DbusmenuMenuitem * root) { return; } +/* Signal called when a user is added. It updates the count and + rebuilds the menu */ +static void +user_added (UsersServiceDbus *service, + UserData *user, + gpointer user_data) +{ + DbusmenuMenuitem *root = (DbusmenuMenuitem *)user_data; + + count++; + + rebuild_items (root, service); +} + +/* Signal called when a user is deleted. It updates the count and + rebuilds the menu */ +static void +user_removed (UsersServiceDbus *service, + UserData *user, + gpointer user_data) +{ + DbusmenuMenuitem *root = (DbusmenuMenuitem *)user_data; + + count--; + + rebuild_items (root, service); +} + +/* Wrapper around rebuild_items that is used on the first call + so that we can initialize the count variable. */ +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); + + rebuild_items (root, service); +} + +/* When the service interface starts to shutdown, we + should follow it. */ +void +service_shutdown (IndicatorService * service, gpointer user_data) +{ + if (mainloop != NULL) { + g_debug("Service shutdown"); + g_main_loop_quit(mainloop); + } + return; +} + /* Main, is well, main. It brings everything up and throws us into the mainloop of no return. */ int @@ -305,27 +567,31 @@ main (int argc, char ** argv) 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; - guint nameret = 0; - - if (!org_freedesktop_DBus_request_name(bus_proxy, INDICATOR_SESSION_DBUS_NAME, 0, &nameret, &error)) { - g_error("Unable to call to request name"); - return 1; - } - - if (nameret != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) { - g_error("Unable to get name"); - return 1; - } + IndicatorService * service = indicator_service_new_version(INDICATOR_SESSION_DBUS_NAME, + INDICATOR_SESSION_DBUS_VERSION); + g_signal_connect(G_OBJECT(service), + INDICATOR_SERVICE_SIGNAL_SHUTDOWN, + G_CALLBACK(service_shutdown), NULL); g_idle_add(lock_screen_setup, NULL); + lock_screen_gdm_cb_set(gdm_settings_change); root_menuitem = dbusmenu_menuitem_new(); g_debug("Root ID: %d", dbusmenu_menuitem_get_id(root_menuitem)); - create_items(root_menuitem); + dbus_interface = g_object_new (USERS_SERVICE_DBUS_TYPE, NULL); + + create_items (root_menuitem, dbus_interface); + + g_signal_connect (G_OBJECT (dbus_interface), + "user-added", + G_CALLBACK (user_added), + root_menuitem); + g_signal_connect (G_OBJECT (dbus_interface), + "user-removed", + G_CALLBACK (user_removed), + root_menuitem); + setup_dkp(); DbusmenuServer * server = dbusmenu_server_new(INDICATOR_SESSION_DBUS_OBJECT); diff --git a/src/status-provider-mc5.c b/src/status-provider-mc5.c deleted file mode 100644 index d65a482..0000000 --- a/src/status-provider-mc5.c +++ /dev/null @@ -1,322 +0,0 @@ -/* -A small wrapper utility to load indicators and put them as menu items -into the gnome-panel using it's applet interface. - -Copyright 2009 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 <telepathy-glib/account-manager.h> - -#include "status-provider.h" -#include "status-provider-mc5.h" -#include "status-provider-mc5-marshal.h" - -#include <dbus/dbus-glib.h> -#include <dbus/dbus-glib-bindings.h> - -static gchar * sp_to_mc_map[STATUS_PROVIDER_STATUS_LAST] = { - /* STATUS_PROVIDER_STATUS_ONLINE, */ "available", - /* STATUS_PROVIDER_STATUS_AWAY, */ "away", - /* STATUS_PROVIDER_STATUS_DND */ "busy", - /* STATUS_PROVIDER_STATUS_INVISIBLE*/ "hidden", - /* STATUS_PROVIDER_STATUS_OFFLINE */ "offline", - /* STATUS_PROVIDER_STATUS_DISCONNECTED*/NULL -}; - -static TpConnectionPresenceType sp_to_tp_map[STATUS_PROVIDER_STATUS_LAST] = { - /* STATUS_PROVIDER_STATUS_ONLINE, */ TP_CONNECTION_PRESENCE_TYPE_AVAILABLE, - /* STATUS_PROVIDER_STATUS_AWAY, */ TP_CONNECTION_PRESENCE_TYPE_AWAY, - /* STATUS_PROVIDER_STATUS_DND */ TP_CONNECTION_PRESENCE_TYPE_BUSY, - /* STATUS_PROVIDER_STATUS_INVISIBLE*/ TP_CONNECTION_PRESENCE_TYPE_HIDDEN, - /* STATUS_PROVIDER_STATUS_OFFLINE */ TP_CONNECTION_PRESENCE_TYPE_OFFLINE, - /* STATUS_PROVIDER_STATUS_DISCONNECTED*/ TP_CONNECTION_PRESENCE_TYPE_UNSET -}; - -static StatusProviderStatus tp_to_sp_map[TP_CONNECTION_PRESENCE_TYPE_ERROR + 1] = { - /* TP_CONNECTION_PRESENCE_TYPE_UNSET */ STATUS_PROVIDER_STATUS_DISCONNECTED, - /* TP_CONNECTION_PRESENCE_TYPE_OFFLINE */ STATUS_PROVIDER_STATUS_OFFLINE, - /* TP_CONNECTION_PRESENCE_TYPE_AVAILABLE */ STATUS_PROVIDER_STATUS_ONLINE, - /* TP_CONNECTION_PRESENCE_TYPE_AWAY */ STATUS_PROVIDER_STATUS_AWAY, - /* TP_CONNECTION_PRESENCE_TYPE_EXTENDED_AWAY */ STATUS_PROVIDER_STATUS_AWAY, - /* TP_CONNECTION_PRESENCE_TYPE_HIDDEN */ STATUS_PROVIDER_STATUS_INVISIBLE, - /* TP_CONNECTION_PRESENCE_TYPE_BUSY */ STATUS_PROVIDER_STATUS_DND, - /* TP_CONNECTION_PRESENCE_TYPE_UNKNOWN */ STATUS_PROVIDER_STATUS_DISCONNECTED, - /* TP_CONNECTION_PRESENCE_TYPE_ERROR */ STATUS_PROVIDER_STATUS_DISCONNECTED -}; - -typedef struct _StatusProviderMC5Private StatusProviderMC5Private; -struct _StatusProviderMC5Private { - TpAccountManager * manager; - StatusProviderStatus status; - DBusGProxy * dbus_proxy; -}; - -#define STATUS_PROVIDER_MC5_GET_PRIVATE(o) \ -(G_TYPE_INSTANCE_GET_PRIVATE ((o), STATUS_PROVIDER_MC5_TYPE, StatusProviderMC5Private)) -#define MC5_WELL_KNOWN_NAME "org.freedesktop.Telepathy.MissionControl5" - -/* Prototypes */ -/* GObject stuff */ -static void status_provider_mc5_class_init (StatusProviderMC5Class *klass); -static void status_provider_mc5_init (StatusProviderMC5 *self); -static void status_provider_mc5_dispose (GObject *object); -static void status_provider_mc5_finalize (GObject *object); -/* Internal Funcs */ -static void set_status (StatusProvider * sp, StatusProviderStatus status); -static StatusProviderStatus get_status (StatusProvider * sp); -static void presence_changed (TpAccountManager * eam, guint type, const gchar * type_str, const gchar * message, StatusProviderMC5 * sp); -static void dbus_namechange (DBusGProxy * proxy, const gchar * name, const gchar * prev, const gchar * new, StatusProviderMC5 * self); -static void mc5_exists_cb (DBusGProxy * proxy, gboolean exists, GError * error, gpointer userdata); - -G_DEFINE_TYPE (StatusProviderMC5, status_provider_mc5, STATUS_PROVIDER_TYPE); - -/* Create the class. We over ride a few functions but nothing - really shocking. Most interesting is the set and get status. */ -static void -status_provider_mc5_class_init (StatusProviderMC5Class *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - g_type_class_add_private (klass, sizeof (StatusProviderMC5Private)); - - object_class->dispose = status_provider_mc5_dispose; - object_class->finalize = status_provider_mc5_finalize; - - StatusProviderClass * spclass = STATUS_PROVIDER_CLASS(klass); - - spclass->set_status = set_status; - spclass->get_status = get_status; - - return; -} - -/* Build our telepathy account manager instance if we don't - have one. */ -static void -build_eam (StatusProviderMC5 * self) -{ - StatusProviderMC5Private * priv = STATUS_PROVIDER_MC5_GET_PRIVATE(self); - static TpDBusDaemon *daemon = NULL; - GError *error = NULL; - - if (priv->manager != NULL) { - return; - } - /* the daemon is used to communicate via DBus */ - daemon = tp_dbus_daemon_dup(&error); - - if (daemon == NULL) - { - g_debug("Cannot create DBus daemon: %s\n", error->message); - g_error_free(error); - return; - } - - priv->manager = TP_ACCOUNT_MANAGER (g_object_new (TP_TYPE_ACCOUNT_MANAGER, - "dbus-daemon", daemon, - "dbus-connection", ((TpProxy *) daemon)->dbus_connection, - "bus-name", "org.freedesktop.Telepathy.MissionControl5", - "object-path", "/org/freedesktop/Telepathy/AccountManager", - NULL)); - g_signal_connect(G_OBJECT(priv->manager), "most-available-presence-changed", G_CALLBACK(presence_changed), self); - - return; -} - -/* Creating an instance of the status provider. We set the variables - and create an TpAccountManager object. It does all the hard - work in this module of tracking MissionControl and enumerating the - accounts and all that jazz. */ -static void -status_provider_mc5_init (StatusProviderMC5 *self) -{ - StatusProviderMC5Private * priv = STATUS_PROVIDER_MC5_GET_PRIVATE(self); - - priv->status = STATUS_PROVIDER_STATUS_DISCONNECTED; - priv->manager = NULL; - - 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 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); - - org_freedesktop_DBus_name_has_owner_async(priv->dbus_proxy, MC5_WELL_KNOWN_NAME, mc5_exists_cb, self); - - return; -} - -/* Unref the account manager and move on. Sadly, we're - leaving the show. */ -static void -status_provider_mc5_dispose (GObject *object) -{ - StatusProviderMC5Private * priv = STATUS_PROVIDER_MC5_GET_PRIVATE(object); - - if (priv->manager != NULL) { - g_object_unref(priv->manager); - priv->manager = NULL; - } - - if (priv->dbus_proxy != NULL) { - g_object_unref(priv->dbus_proxy); - priv->dbus_proxy = NULL; - } - - G_OBJECT_CLASS (status_provider_mc5_parent_class)->dispose (object); - return; -} - -/* Pass to superclass */ -static void -status_provider_mc5_finalize (GObject *object) -{ - - G_OBJECT_CLASS (status_provider_mc5_parent_class)->finalize (object); - return; -} - -/* Watch for MC5 Coming on and off the bus. */ -static void -dbus_namechange (DBusGProxy * proxy, const gchar * name, const gchar * prev, const gchar * new, StatusProviderMC5 * self) -{ - /* g_debug("DBUS NAMECHANGE: %s %s %s", name, prev, new); */ - - if (prev[0] == '\0' && g_strcmp0(name, MC5_WELL_KNOWN_NAME) == 0) { - g_debug("MC5 Coming online"); - build_eam(self); - } - if (new[0] == '\0' && g_strcmp0(name, MC5_WELL_KNOWN_NAME) == 0) { - g_debug("MC5 going offline"); - StatusProviderMC5Private * priv = STATUS_PROVIDER_MC5_GET_PRIVATE(self); - if (priv->manager != NULL) { - g_object_unref(priv->manager); - priv->manager = NULL; - } - - priv->status = STATUS_PROVIDER_STATUS_DISCONNECTED; - g_signal_emit(G_OBJECT(self), STATUS_PROVIDER_SIGNAL_STATUS_CHANGED_ID, 0, priv->status, TRUE); - } - - return; -} - -/* Callback for the Dbus command to do HasOwner on - the MC5 service. If it exists, we want to have an - account manager. */ -static void -mc5_exists_cb (DBusGProxy * proxy, gboolean exists, GError * error, gpointer userdata) -{ - if (error) { - g_warning("Unable to check if MC5 is running: %s", error->message); - return; - } - - if (exists) { - build_eam(STATUS_PROVIDER_MC5(userdata)); - } - - return; -} - -/** - status_provider_mc5_new: - - Creates a new #StatusProviderMC5 object. No parameters or anything - like that. Just a convience function. - - Return value: A new instance of #StatusProviderMC5 -*/ -StatusProvider * -status_provider_mc5_new (void) -{ - return STATUS_PROVIDER(g_object_new(STATUS_PROVIDER_MC5_TYPE, NULL)); -} - -/* Setting the status in the empathy account manager. We're - basically requesting a global status. This may or may not - get applied to all accounts. It's really the best we can - hope to do. */ -static void -set_status (StatusProvider * sp, StatusProviderStatus status) -{ - StatusProviderMC5Private * priv = STATUS_PROVIDER_MC5_GET_PRIVATE(sp); - - build_eam(STATUS_PROVIDER_MC5(sp)); - tp_account_manager_set_all_requested_presences(priv->manager, sp_to_tp_map[status], sp_to_mc_map[status], ""); - - return; -} - -/* Gets the status, uses the cached value that we have. Asking - would just be painful. */ -static StatusProviderStatus -get_status (StatusProvider * sp) -{ - g_return_val_if_fail(IS_STATUS_PROVIDER_MC5(sp), STATUS_PROVIDER_STATUS_DISCONNECTED); - StatusProviderMC5Private * priv = STATUS_PROVIDER_MC5_GET_PRIVATE(sp); - - if (priv->manager == NULL) { - return STATUS_PROVIDER_STATUS_DISCONNECTED; - } - - return priv->status; -} - -/* A signal handler for when the TpAccountManager believes - that the global status has changed. It roughly calculates this - by finding the most available of all accounts that are active. */ -static void -presence_changed (TpAccountManager * eam, guint type, const gchar * type_str, const gchar * message, StatusProviderMC5 * sp) -{ - StatusProviderMC5Private * priv = STATUS_PROVIDER_MC5_GET_PRIVATE(sp); - - g_debug("MC5 Status changed: %d %s %s", type, type_str, message); - - if (priv->status != tp_to_sp_map[type]) { - priv->status = tp_to_sp_map[type]; - g_signal_emit(G_OBJECT(sp), STATUS_PROVIDER_SIGNAL_STATUS_CHANGED_ID, 0, priv->status, TRUE); - } - - return; -} - diff --git a/src/status-provider-mc5.h b/src/status-provider-mc5.h deleted file mode 100644 index 4d5659d..0000000 --- a/src/status-provider-mc5.h +++ /dev/null @@ -1,56 +0,0 @@ -/* -A small wrapper utility to load indicators and put them as menu items -into the gnome-panel using it's applet interface. - -Copyright 2009 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 __STATUS_PROVIDER_MC5_H__ -#define __STATUS_PROVIDER_MC5_H__ - -#include <glib.h> -#include <glib-object.h> - -#include "status-provider.h" - -G_BEGIN_DECLS - -#define STATUS_PROVIDER_MC5_TYPE (status_provider_mc5_get_type ()) -#define STATUS_PROVIDER_MC5(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), STATUS_PROVIDER_MC5_TYPE, StatusProviderMC5)) -#define STATUS_PROVIDER_MC5_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), STATUS_PROVIDER_MC5_TYPE, StatusProviderMC5Class)) -#define IS_STATUS_PROVIDER_MC5(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), STATUS_PROVIDER_MC5_TYPE)) -#define IS_STATUS_PROVIDER_MC5_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), STATUS_PROVIDER_MC5_TYPE)) -#define STATUS_PROVIDER_MC5_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), STATUS_PROVIDER_MC5_TYPE, StatusProviderMC5Class)) - - -typedef struct _StatusProviderMC5Class StatusProviderMC5Class; -struct _StatusProviderMC5Class { - StatusProviderClass parent_class; -}; - -typedef struct _StatusProviderMC5 StatusProviderMC5; -struct _StatusProviderMC5 { - StatusProvider parent; -}; - -GType status_provider_mc5_get_type (void); -StatusProvider * status_provider_mc5_new (void); - -G_END_DECLS - -#endif diff --git a/src/status-provider-mc5.list b/src/status-provider-mc5.list deleted file mode 100644 index 5ab45bf..0000000 --- a/src/status-provider-mc5.list +++ /dev/null @@ -1 +0,0 @@ -VOID:UINT,STRING diff --git a/src/status-provider-pidgin.c b/src/status-provider-pidgin.c deleted file mode 100644 index 3c0ca15..0000000 --- a/src/status-provider-pidgin.c +++ /dev/null @@ -1,431 +0,0 @@ -/* -A small wrapper utility to load indicators and put them as menu items -into the gnome-panel using it's applet interface. - -Copyright 2009 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 "status-provider.h" -#include "status-provider-pidgin.h" -#include "status-provider-pidgin-marshal.h" - -#include <dbus/dbus-glib.h> - -typedef enum { - PG_STATUS_UNKNOWN, - PG_STATUS_OFFLINE, - PG_STATUS_AVAILABLE, - PG_STATUS_UNAVAILABLE, - PG_STATUS_INVISIBLE, - PG_STATUS_AWAY, - PG_STATUS_EXTENDEND_AWAY, - PG_STATUS_MOBILE, - PG_STATUS_TUNE -} pg_status_t; - -static const StatusProviderStatus pg_to_sp_map[] = { - /* PG_STATUS_UNKNOWN, */ STATUS_PROVIDER_STATUS_OFFLINE, - /* PG_STATUS_OFFLINE, */ STATUS_PROVIDER_STATUS_OFFLINE, - /* PG_STATUS_AVAILABLE, */ STATUS_PROVIDER_STATUS_ONLINE, - /* PG_STATUS_UNAVAILABLE, */ STATUS_PROVIDER_STATUS_DND, - /* PG_STATUS_INVISIBLE, */ STATUS_PROVIDER_STATUS_INVISIBLE, - /* PG_STATUS_AWAY, */ STATUS_PROVIDER_STATUS_AWAY, - /* PG_STATUS_EXTENDEND_AWAY, */ STATUS_PROVIDER_STATUS_AWAY, - /* PG_STATUS_MOBILE, */ STATUS_PROVIDER_STATUS_OFFLINE, - /* PG_STATUS_TUNE */ STATUS_PROVIDER_STATUS_OFFLINE -}; - -static const pg_status_t sp_to_pg_map[STATUS_PROVIDER_STATUS_LAST] = { - /* STATUS_PROVIDER_STATUS_ONLINE, */ PG_STATUS_AVAILABLE, - /* 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_DISCONNECTED*/ PG_STATUS_OFFLINE -}; - -typedef struct _StatusProviderPidginPrivate StatusProviderPidginPrivate; -struct _StatusProviderPidginPrivate { - DBusGProxy * proxy; - DBusGProxy * dbus_proxy; - pg_status_t pg_status; -}; - -#define STATUS_PROVIDER_PIDGIN_GET_PRIVATE(o) \ -(G_TYPE_INSTANCE_GET_PRIVATE ((o), STATUS_PROVIDER_PIDGIN_TYPE, StatusProviderPidginPrivate)) - -/* Prototypes */ -/* GObject stuff */ -static void status_provider_pidgin_class_init (StatusProviderPidginClass *klass); -static void status_provider_pidgin_init (StatusProviderPidgin *self); -static void status_provider_pidgin_dispose (GObject *object); -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); - -static void -status_provider_pidgin_class_init (StatusProviderPidginClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - g_type_class_add_private (klass, sizeof (StatusProviderPidginPrivate)); - - object_class->dispose = status_provider_pidgin_dispose; - object_class->finalize = status_provider_pidgin_finalize; - - StatusProviderClass * spclass = STATUS_PROVIDER_CLASS(klass); - - spclass->set_status = set_status; - spclass->get_status = get_status; - - return; -} - -static void -type_cb (DBusGProxy * proxy, DBusGProxyCall * call, gpointer userdata) -{ - GError * error = NULL; - gint status = 0; - if (!dbus_g_proxy_end_call(proxy, call, &error, G_TYPE_INT, &status, G_TYPE_INVALID)) { - g_warning("Unable to get type from Pidgin: %s", error->message); - g_error_free(error); - return; - } - - StatusProviderPidginPrivate * priv = STATUS_PROVIDER_PIDGIN_GET_PRIVATE(userdata); - if (status != priv->pg_status) { - priv->pg_status = status; - - g_signal_emit(G_OBJECT(userdata), STATUS_PROVIDER_SIGNAL_STATUS_CHANGED_ID, 0, pg_to_sp_map[priv->pg_status], TRUE); - } - - return; -} - -static void -saved_status_to_type (StatusProviderPidgin * spp, gint savedstatus) -{ - StatusProviderPidginPrivate * priv = STATUS_PROVIDER_PIDGIN_GET_PRIVATE(spp); - - g_debug("Pidgin figuring out type for %d", savedstatus); - dbus_g_proxy_begin_call(priv->proxy, - "PurpleSavedstatusGetType", type_cb, spp, NULL, - G_TYPE_INT, savedstatus, G_TYPE_INVALID); - - return; -} - -static void -savedstatus_cb (DBusGProxy * proxy, DBusGProxyCall * call, gpointer userdata) -{ - GError * error = NULL; - gint status = 0; - if (!dbus_g_proxy_end_call(proxy, call, &error, G_TYPE_INT, &status, G_TYPE_INVALID)) { - g_warning("Unable to get saved status from Pidgin: %s", error->message); - g_error_free(error); - return; - } - - saved_status_to_type(STATUS_PROVIDER_PIDGIN(userdata), status); - return; -} - - -static void -changed_status (DBusGProxy * proxy, gint savedstatus, GError ** error, StatusProviderPidgin * spp) -{ - saved_status_to_type(spp, savedstatus); - return; -} - -static void -proxy_destroy (DBusGProxy * proxy, StatusProviderPidgin * spp) -{ - StatusProviderPidginPrivate * priv = STATUS_PROVIDER_PIDGIN_GET_PRIVATE(spp); - - priv->proxy = NULL; - priv->pg_status = PG_STATUS_OFFLINE; - - g_signal_emit(G_OBJECT(spp), STATUS_PROVIDER_SIGNAL_STATUS_CHANGED_ID, 0, pg_to_sp_map[priv->pg_status], TRUE); - return; -} - -static void -status_provider_pidgin_init (StatusProviderPidgin *self) -{ - StatusProviderPidginPrivate * priv = STATUS_PROVIDER_PIDGIN_GET_PRIVATE(self); - - priv->proxy = NULL; - priv->pg_status = PG_STATUS_OFFLINE; - - 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 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); - } - - /* 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, - G_TYPE_INT, - G_TYPE_INT, - G_TYPE_INVALID); - dbus_g_proxy_add_signal (priv->proxy, - "SavedstatusChanged", - G_TYPE_INT, - G_TYPE_INT, - G_TYPE_INVALID); - dbus_g_proxy_connect_signal(priv->proxy, - "SavedstatusChanged", - G_CALLBACK(changed_status), - (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, - self, - NULL, - G_TYPE_INVALID); - } - - return; -} - -static void -status_provider_pidgin_dispose (GObject *object) -{ - StatusProviderPidginPrivate * priv = STATUS_PROVIDER_PIDGIN_GET_PRIVATE(object); - - if (priv->proxy != NULL) { - g_object_unref(priv->proxy); - priv->proxy = NULL; - } - - G_OBJECT_CLASS (status_provider_pidgin_parent_class)->dispose (object); - return; -} - -static void -status_provider_pidgin_finalize (GObject *object) -{ - - G_OBJECT_CLASS (status_provider_pidgin_parent_class)->finalize (object); - return; -} - -/** - status_provider_pidgin_new: - - Creates a new #StatusProviderPidgin object. No parameters or anything - like that. Just a convience function. - - Return value: A new instance of #StatusProviderPidgin -*/ -StatusProvider * -status_provider_pidgin_new (void) -{ - return STATUS_PROVIDER(g_object_new(STATUS_PROVIDER_PIDGIN_TYPE, NULL)); -} - -/* Takes the status provided generically for Status providers - and turns it into a Pidgin status and sends it to Pidgin. */ -static void -set_status (StatusProvider * sp, StatusProviderStatus status) -{ - gchar * message = ""; - - g_return_if_fail(IS_STATUS_PROVIDER_PIDGIN(sp)); - StatusProviderPidginPrivate * priv = STATUS_PROVIDER_PIDGIN_GET_PRIVATE(sp); - - g_debug("\tPidgin set status to %d", status); - if (priv->proxy == NULL) { - return; - } - - priv->pg_status = sp_to_pg_map[status]; - gint status_val = 0; - gboolean ret = FALSE; - GError * error = NULL; - - ret = dbus_g_proxy_call(priv->proxy, - "PurpleSavedstatusFindTransientByTypeAndMessage", &error, - G_TYPE_INT, priv->pg_status, - G_TYPE_STRING, message, - G_TYPE_INVALID, - G_TYPE_INT, &status_val, - G_TYPE_INVALID); - - if (!ret) { - if (error != NULL) { - g_error_free(error); - } - error = NULL; - status_val = 0; - g_debug("No Pidgin saved status to apply"); - } - - if (status_val == 0) { - ret = dbus_g_proxy_call(priv->proxy, - "PurpleSavedstatusNew", &error, - G_TYPE_STRING, message, - G_TYPE_INT, priv->pg_status, - G_TYPE_INVALID, - G_TYPE_INT, &status_val, - G_TYPE_INVALID); - - if (!ret) { - status_val = 0; - if (error != NULL) { - g_warning("Unable to create Pidgin status for %d: %s", status, error->message); - g_error_free(error); - } else { - g_warning("Unable to create Pidgin status for %d", status); - } - error = NULL; - } - } - - if (status_val == 0) { - return; - } - - ret = dbus_g_proxy_call(priv->proxy, - "PurpleSavedstatusActivate", &error, - G_TYPE_INT, status_val, - G_TYPE_INVALID, - G_TYPE_INVALID); - - if (!ret) { - if (error != NULL) { - g_warning("Pidgin unable to change to status: %s", error->message); - g_error_free(error); - } else { - g_warning("Pidgin unable to change to status"); - } - error = NULL; - } - - g_signal_emit(G_OBJECT(sp), STATUS_PROVIDER_SIGNAL_STATUS_CHANGED_ID, 0, pg_to_sp_map[priv->pg_status], TRUE); - return; -} - -/* Takes the cached Pidgin status and makes it into the generic - 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_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-pidgin.h b/src/status-provider-pidgin.h deleted file mode 100644 index 54b1718..0000000 --- a/src/status-provider-pidgin.h +++ /dev/null @@ -1,56 +0,0 @@ -/* -A small wrapper utility to load indicators and put them as menu items -into the gnome-panel using it's applet interface. - -Copyright 2009 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 __STATUS_PROVIDER_PIDGIN_H__ -#define __STATUS_PROVIDER_PIDGIN_H__ - -#include <glib.h> -#include <glib-object.h> - -#include "status-provider.h" - -G_BEGIN_DECLS - -#define STATUS_PROVIDER_PIDGIN_TYPE (status_provider_pidgin_get_type ()) -#define STATUS_PROVIDER_PIDGIN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), STATUS_PROVIDER_PIDGIN_TYPE, StatusProviderPidgin)) -#define STATUS_PROVIDER_PIDGIN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), STATUS_PROVIDER_PIDGIN_TYPE, StatusProviderPidginClass)) -#define IS_STATUS_PROVIDER_PIDGIN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), STATUS_PROVIDER_PIDGIN_TYPE)) -#define IS_STATUS_PROVIDER_PIDGIN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), STATUS_PROVIDER_PIDGIN_TYPE)) -#define STATUS_PROVIDER_PIDGIN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), STATUS_PROVIDER_PIDGIN_TYPE, StatusProviderPidginClass)) - - -typedef struct _StatusProviderPidginClass StatusProviderPidginClass; -struct _StatusProviderPidginClass { - StatusProviderClass parent_class; -}; - -typedef struct _StatusProviderPidgin StatusProviderPidgin; -struct _StatusProviderPidgin { - StatusProvider parent; -}; - -GType status_provider_pidgin_get_type (void); -StatusProvider * status_provider_pidgin_new (void); - -G_END_DECLS - -#endif diff --git a/src/status-provider-pidgin.list b/src/status-provider-pidgin.list deleted file mode 100644 index 1f953dd..0000000 --- a/src/status-provider-pidgin.list +++ /dev/null @@ -1 +0,0 @@ -VOID:INT,INT diff --git a/src/status-provider-telepathy.c b/src/status-provider-telepathy.c deleted file mode 100644 index f2815fb..0000000 --- a/src/status-provider-telepathy.c +++ /dev/null @@ -1,383 +0,0 @@ -/* -A small wrapper utility to load indicators and put them as menu items -into the gnome-panel using it's applet interface. - -Copyright 2009 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 "status-provider.h" -#include "status-provider-telepathy.h" -#include "status-provider-telepathy-marshal.h" - -#include <dbus/dbus-glib.h> - -typedef enum { - MC_STATUS_UNSET, - MC_STATUS_OFFLINE, - MC_STATUS_AVAILABLE, - MC_STATUS_AWAY, - MC_STATUS_EXTENDED_AWAY, - MC_STATUS_HIDDEN, - MC_STATUS_DND -} mc_status_t; - -static StatusProviderStatus mc_to_sp_map[] = { - /* MC_STATUS_UNSET, */ STATUS_PROVIDER_STATUS_OFFLINE, - /* MC_STATUS_OFFLINE, */ STATUS_PROVIDER_STATUS_OFFLINE, - /* MC_STATUS_AVAILABLE, */ STATUS_PROVIDER_STATUS_ONLINE, - /* MC_STATUS_AWAY, */ STATUS_PROVIDER_STATUS_AWAY, - /* MC_STATUS_EXTENDED_AWAY, */ STATUS_PROVIDER_STATUS_AWAY, - /* MC_STATUS_HIDDEN, */ STATUS_PROVIDER_STATUS_INVISIBLE, - /* MC_STATUS_DND */ STATUS_PROVIDER_STATUS_DND -}; - -static mc_status_t sp_to_mc_map[] = { - /* STATUS_PROVIDER_STATUS_ONLINE, */ MC_STATUS_AVAILABLE, - /* 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_DISCONNECTED*/MC_STATUS_OFFLINE -}; - -typedef struct _StatusProviderTelepathyPrivate StatusProviderTelepathyPrivate; -struct _StatusProviderTelepathyPrivate { - DBusGProxy * proxy; - DBusGProxy * dbus_proxy; - mc_status_t mc_status; -}; - -#define STATUS_PROVIDER_TELEPATHY_GET_PRIVATE(o) \ -(G_TYPE_INSTANCE_GET_PRIVATE ((o), STATUS_PROVIDER_TELEPATHY_TYPE, StatusProviderTelepathyPrivate)) - -/* Prototypes */ -/* GObject stuff */ -static void status_provider_telepathy_class_init (StatusProviderTelepathyClass *klass); -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); -static void proxy_destroy (DBusGProxy * proxy, StatusProvider * sp); -static void get_status_async (DBusGProxy * proxy, DBusGProxyCall * call, gpointer userdata); - -G_DEFINE_TYPE (StatusProviderTelepathy, status_provider_telepathy, STATUS_PROVIDER_TYPE); - -static void -status_provider_telepathy_class_init (StatusProviderTelepathyClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - g_type_class_add_private (klass, sizeof (StatusProviderTelepathyPrivate)); - - object_class->dispose = status_provider_telepathy_dispose; - object_class->finalize = status_provider_telepathy_finalize; - - StatusProviderClass * spclass = STATUS_PROVIDER_CLASS(klass); - - spclass->set_status = set_status; - spclass->get_status = get_status; - - return; -} - - -static void -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); - g_error_free(error); - return; - } - - /* 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", - "org.freedesktop.Telepathy.MissionControl", - &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, - G_TYPE_STRING, - G_TYPE_INVALID); - dbus_g_proxy_add_signal (priv->proxy, - "PresenceChanged", - G_TYPE_UINT, - G_TYPE_STRING, - G_TYPE_INVALID); - dbus_g_proxy_connect_signal(priv->proxy, - "PresenceChanged", - G_CALLBACK(changed_status), - (void *)self, - NULL); - - /* Do a get here, to init the status */ - dbus_g_proxy_begin_call(priv->proxy, - "GetStatus", - get_status_async, - self, - NULL, - G_TYPE_INVALID); - } else { - g_warning("Unable to connect to Mission Control"); - if (error != NULL) { - g_error_free(error); - } - } - - 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) -{ - StatusProviderTelepathyPrivate * priv = STATUS_PROVIDER_TELEPATHY_GET_PRIVATE(object); - - if (priv->proxy != NULL) { - g_object_unref(priv->proxy); - priv->proxy = NULL; - } - - G_OBJECT_CLASS (status_provider_telepathy_parent_class)->dispose (object); - return; -} - -static void -status_provider_telepathy_finalize (GObject *object) -{ - - G_OBJECT_CLASS (status_provider_telepathy_parent_class)->finalize (object); - return; -} - -/** - status_provider_telepathy_new: - - Creates a new #StatusProviderTelepathy object. No parameters or anything - like that. Just a convience function. - - Return value: A new instance of #StatusProviderTelepathy -*/ -StatusProvider * -status_provider_telepathy_new (void) -{ - return STATUS_PROVIDER(g_object_new(STATUS_PROVIDER_TELEPATHY_TYPE, NULL)); -} - -static void -set_status (StatusProvider * sp, StatusProviderStatus status) -{ - StatusProviderTelepathyPrivate * priv = STATUS_PROVIDER_TELEPATHY_GET_PRIVATE(sp); - if (priv->proxy == NULL) { - priv->mc_status = MC_STATUS_OFFLINE; - return; - } - - priv->mc_status = sp_to_mc_map[status]; - - guint mcstatus = MC_STATUS_UNSET; - gboolean ret = FALSE; - GError * error = NULL; - - ret = dbus_g_proxy_call(priv->proxy, - "GetPresence", &error, - G_TYPE_INVALID, - G_TYPE_UINT, &priv->mc_status, - G_TYPE_INVALID); - - /* If we can't get the get call to work, let's not set */ - if (!ret) { - if (error != NULL) { - g_error_free(error); - } - return; - } - - /* If the get call doesn't return a status, that means that there - are no clients connected. We don't want to connect them by telling - MC that we're going online -- we'd like to be more passive than that. */ - if (mcstatus == MC_STATUS_UNSET) { - return; - } - - ret = dbus_g_proxy_call(priv->proxy, - "SetPresence", &error, - G_TYPE_UINT, priv->mc_status, - G_TYPE_STRING, "", - G_TYPE_INVALID, - G_TYPE_INVALID); - - if (!ret) { - if (error != NULL) { - g_warning("Unable to set Mission Control Presence: %s", error->message); - g_error_free(error); - } else { - g_warning("Unable to set Mission Control Presence"); - } - return; - } - - return; -} - -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 STATUS_PROVIDER_STATUS_DISCONNECTED; - } - - return mc_to_sp_map[priv->mc_status]; -} - -static void -changed_status (DBusGProxy * proxy, guint status, gchar * message, StatusProvider * sp) -{ - StatusProviderTelepathyPrivate * priv = STATUS_PROVIDER_TELEPATHY_GET_PRIVATE(sp); - priv->mc_status = status; - g_signal_emit(G_OBJECT(sp), STATUS_PROVIDER_SIGNAL_STATUS_CHANGED_ID, 0, mc_to_sp_map[priv->mc_status], TRUE); -} - -static void -proxy_destroy (DBusGProxy * proxy, StatusProvider * sp) -{ - g_debug("Signal: Mission Control proxy destroyed"); - g_signal_emit(G_OBJECT(sp), STATUS_PROVIDER_SIGNAL_STATUS_CHANGED_ID, 0, STATUS_PROVIDER_STATUS_OFFLINE, TRUE); - return; -} - -static void -get_status_async (DBusGProxy * proxy, DBusGProxyCall * call, gpointer userdata) -{ - GError * error = NULL; - guint status = 0; - if (!dbus_g_proxy_end_call(proxy, call, &error, G_TYPE_UINT, &status, G_TYPE_INVALID)) { - g_warning("Unable to get type from Mission Control: %s", error->message); - g_error_free(error); - return; - } - - StatusProviderTelepathyPrivate * priv = STATUS_PROVIDER_TELEPATHY_GET_PRIVATE(userdata); - - gboolean changed = FALSE; - if (status != priv->mc_status) { - changed = TRUE; - } - - priv->mc_status = status; - - if (changed) { - g_signal_emit(G_OBJECT(userdata), STATUS_PROVIDER_SIGNAL_STATUS_CHANGED_ID, 0, mc_to_sp_map[priv->mc_status], TRUE); - } - - return; -} diff --git a/src/status-provider-telepathy.h b/src/status-provider-telepathy.h deleted file mode 100644 index a67ee40..0000000 --- a/src/status-provider-telepathy.h +++ /dev/null @@ -1,56 +0,0 @@ -/* -A small wrapper utility to load indicators and put them as menu items -into the gnome-panel using it's applet interface. - -Copyright 2009 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 __STATUS_PROVIDER_TELEPATHY_H__ -#define __STATUS_PROVIDER_TELEPATHY_H__ - -#include <glib.h> -#include <glib-object.h> - -#include "status-provider.h" - -G_BEGIN_DECLS - -#define STATUS_PROVIDER_TELEPATHY_TYPE (status_provider_telepathy_get_type ()) -#define STATUS_PROVIDER_TELEPATHY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), STATUS_PROVIDER_TELEPATHY_TYPE, StatusProviderTelepathy)) -#define STATUS_PROVIDER_TELEPATHY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), STATUS_PROVIDER_TELEPATHY_TYPE, StatusProviderTelepathyClass)) -#define IS_STATUS_PROVIDER_TELEPATHY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), STATUS_PROVIDER_TELEPATHY_TYPE)) -#define IS_STATUS_PROVIDER_TELEPATHY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), STATUS_PROVIDER_TELEPATHY_TYPE)) -#define STATUS_PROVIDER_TELEPATHY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), STATUS_PROVIDER_TELEPATHY_TYPE, StatusProviderTelepathyClass)) - - -typedef struct _StatusProviderTelepathyClass StatusProviderTelepathyClass; -struct _StatusProviderTelepathyClass { - StatusProviderClass parent_class; -}; - -typedef struct _StatusProviderTelepathy StatusProviderTelepathy; -struct _StatusProviderTelepathy { - StatusProvider parent; -}; - -GType status_provider_telepathy_get_type (void); -StatusProvider * status_provider_telepathy_new (void); - -G_END_DECLS - -#endif diff --git a/src/status-provider-telepathy.list b/src/status-provider-telepathy.list deleted file mode 100644 index 5ab45bf..0000000 --- a/src/status-provider-telepathy.list +++ /dev/null @@ -1 +0,0 @@ -VOID:UINT,STRING diff --git a/src/status-provider.c b/src/status-provider.c deleted file mode 100644 index 1139e54..0000000 --- a/src/status-provider.c +++ /dev/null @@ -1,101 +0,0 @@ -/* -A small wrapper utility to load indicators and put them as menu items -into the gnome-panel using it's applet interface. - -Copyright 2009 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 "status-provider.h" - -/* Signals */ -enum { - STATUS_CHANGED, - LAST_SIGNAL -}; - -static guint signals[LAST_SIGNAL] = { 0 }; - -/* GObject Boilerplate */ -static void status_provider_class_init (StatusProviderClass *klass); -static void status_provider_init (StatusProvider *self); - -G_DEFINE_TYPE (StatusProvider, status_provider, G_TYPE_OBJECT); - -static void -status_provider_class_init (StatusProviderClass *klass) -{ - // GObjectClass *object_class = G_OBJECT_CLASS (klass); - - klass->status_changed = NULL; - - klass->set_status = NULL; - klass->get_status = NULL; - - /** - StatusProvider::status-changed: - @arg0: The #StatusProvider object. - @arg1: The new status #StatusProviderStatus - - Should be emitted by subclasses everytime that the status - changes externally to us. - */ - signals[STATUS_CHANGED] = g_signal_new(STATUS_PROVIDER_SIGNAL_STATUS_CHANGED, - G_TYPE_FROM_CLASS(klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET(StatusProviderClass, status_changed), - NULL, NULL, - g_cclosure_marshal_VOID__UINT, - G_TYPE_NONE, 1, G_TYPE_UINT); - - return; -} - -static void -status_provider_init (StatusProvider *self) -{ - - return; -} - -void -status_provider_set_status (StatusProvider * sp, StatusProviderStatus status) -{ - g_return_if_fail(IS_STATUS_PROVIDER(sp)); - - StatusProviderClass * class = STATUS_PROVIDER_GET_CLASS(sp); - g_return_if_fail(class != NULL); - g_return_if_fail(class->set_status != NULL); - - return class->set_status(sp, status); -} - -StatusProviderStatus -status_provider_get_status (StatusProvider * sp) -{ - g_return_val_if_fail(IS_STATUS_PROVIDER(sp), STATUS_PROVIDER_STATUS_OFFLINE); - - StatusProviderClass * class = STATUS_PROVIDER_GET_CLASS(sp); - g_return_val_if_fail(class->get_status != NULL, STATUS_PROVIDER_STATUS_OFFLINE); - - return class->get_status(sp); -} - diff --git a/src/status-provider.h b/src/status-provider.h deleted file mode 100644 index a0e1c55..0000000 --- a/src/status-provider.h +++ /dev/null @@ -1,78 +0,0 @@ -/* -A small wrapper utility to load indicators and put them as menu items -into the gnome-panel using it's applet interface. - -Copyright 2009 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 __STATUS_PROVIDER_H__ -#define __STATUS_PROVIDER_H__ - -#include <glib.h> -#include <glib-object.h> - -G_BEGIN_DECLS - -#define STATUS_PROVIDER_TYPE (status_provider_get_type ()) -#define STATUS_PROVIDER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), STATUS_PROVIDER_TYPE, StatusProvider)) -#define STATUS_PROVIDER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), STATUS_PROVIDER_TYPE, StatusProviderClass)) -#define IS_STATUS_PROVIDER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), STATUS_PROVIDER_TYPE)) -#define IS_STATUS_PROVIDER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), STATUS_PROVIDER_TYPE)) -#define STATUS_PROVIDER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), STATUS_PROVIDER_TYPE, StatusProviderClass)) - -typedef enum -{ - STATUS_PROVIDER_STATUS_ONLINE, - STATUS_PROVIDER_STATUS_AWAY, - STATUS_PROVIDER_STATUS_DND, - STATUS_PROVIDER_STATUS_INVISIBLE, - STATUS_PROVIDER_STATUS_OFFLINE, - STATUS_PROVIDER_STATUS_DISCONNECTED, - /* Leave as last */ - STATUS_PROVIDER_STATUS_LAST -} -StatusProviderStatus; - -#define STATUS_PROVIDER_SIGNAL_STATUS_CHANGED "status-changed" -#define STATUS_PROVIDER_SIGNAL_STATUS_CHANGED_ID (g_signal_lookup(STATUS_PROVIDER_SIGNAL_STATUS_CHANGED, STATUS_PROVIDER_TYPE)) - -typedef struct _StatusProvider StatusProvider; -struct _StatusProvider { - GObject parent; -}; - -typedef struct _StatusProviderClass StatusProviderClass; -struct _StatusProviderClass { - GObjectClass parent_class; - - /* Signals */ - void (*status_changed) (StatusProviderStatus newstatus); - - /* Virtual Functions */ - void (*set_status) (StatusProvider * sp, StatusProviderStatus newstatus); - StatusProviderStatus (*get_status) (StatusProvider * sp); -}; - -GType status_provider_get_type (void); - -void status_provider_set_status (StatusProvider * sp, StatusProviderStatus status); -StatusProviderStatus status_provider_get_status (StatusProvider * sp); - -G_END_DECLS - -#endif diff --git a/src/status-service-dbus.c b/src/status-service-dbus.c deleted file mode 100644 index 65de499..0000000 --- a/src/status-service-dbus.c +++ /dev/null @@ -1,205 +0,0 @@ -/* -A small wrapper utility to load indicators and put them as menu items -into the gnome-panel using it's applet interface. - -Copyright 2009 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 <dbus/dbus-glib.h> - -#include "dbus-shared-names.h" -#include "status-service-dbus.h" - -static void status_service_dbus_class_init (StatusServiceDbusClass *klass); -static void status_service_dbus_init (StatusServiceDbus *self); -static void status_service_dbus_dispose (GObject *object); -static void status_service_dbus_finalize (GObject *object); -static gboolean _status_service_server_watch (StatusServiceDbus * service, GError ** error); -static gboolean _status_service_server_status_icons (StatusServiceDbus * service, gchar ** icon, GError ** error); -static gboolean _status_service_server_pretty_user_name (StatusServiceDbus * service, gchar ** username, GError ** error); - -#include "status-service-server.h" - -/* Private */ -typedef struct _StatusServiceDbusPrivate StatusServiceDbusPrivate; -struct _StatusServiceDbusPrivate -{ - gchar * name; - gchar * icon; -}; - -#define STATUS_SERVICE_DBUS_GET_PRIVATE(o) \ - (G_TYPE_INSTANCE_GET_PRIVATE ((o), STATUS_SERVICE_DBUS_TYPE, StatusServiceDbusPrivate)) - -/* Signals */ -enum { - USER_CHANGED, - STATUS_ICONS_CHANGED, - LAST_SIGNAL -}; - -static guint signals[LAST_SIGNAL] = { 0 }; - -/* GObject Boilerplate */ -G_DEFINE_TYPE (StatusServiceDbus, status_service_dbus, G_TYPE_OBJECT); - -static void -status_service_dbus_class_init (StatusServiceDbusClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - g_type_class_add_private (object_class, sizeof(StatusServiceDbusPrivate)); - - object_class->dispose = status_service_dbus_dispose; - object_class->finalize = status_service_dbus_finalize; - - /** - StatusServiceDbus::user-changed: - @arg0: The #StatusServiceDbus object. - @arg1: The place to put the new user name - - Signals that the user name has changed and gives the - new user name. - */ - signals[USER_CHANGED] = g_signal_new("user-changed", - G_TYPE_FROM_CLASS(klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET(StatusServiceDbusClass, user_changed), - NULL, NULL, - g_cclosure_marshal_VOID__POINTER, - G_TYPE_NONE, 1, G_TYPE_POINTER); - - /** - StatusServiceDbus::status-icons-changed: - @arg0: The #StatusServiceDbus object. - @arg1: The list of icon names representing the statuses in - the order they should be displayed. Left to right. - - Signals that the user status set has changed and that - new icons may need to be loaded. The list of icons will - always be complete. - */ - signals[STATUS_ICONS_CHANGED] = g_signal_new("status-icons-changed", - G_TYPE_FROM_CLASS(klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET(StatusServiceDbusClass, status_icons_changed), - NULL, NULL, - g_cclosure_marshal_VOID__STRING, - G_TYPE_NONE, 1, G_TYPE_STRING); - - dbus_g_object_type_install_info(STATUS_SERVICE_DBUS_TYPE, &dbus_glib__status_service_server_object_info); - - return; -} - -static void -status_service_dbus_init (StatusServiceDbus *self) -{ - - DBusGConnection * connection = dbus_g_bus_get(DBUS_BUS_SESSION, NULL); - dbus_g_connection_register_g_object(connection, - INDICATOR_STATUS_SERVICE_DBUS_OBJECT, - G_OBJECT(self)); - - StatusServiceDbusPrivate * priv = STATUS_SERVICE_DBUS_GET_PRIVATE(self); - priv->name = NULL; - priv->icon = NULL; - - return; -} - -static void -status_service_dbus_dispose (GObject *object) -{ - - G_OBJECT_CLASS (status_service_dbus_parent_class)->dispose (object); - return; -} - -static void -status_service_dbus_finalize (GObject *object) -{ - - G_OBJECT_CLASS (status_service_dbus_parent_class)->finalize (object); - return; -} - -static gboolean -_status_service_server_watch (StatusServiceDbus * service, GError ** error) -{ - - return TRUE; -} - -static gboolean -_status_service_server_status_icons (StatusServiceDbus * service, gchar ** icon, GError ** error) -{ - if (!IS_STATUS_SERVICE_DBUS(service)) { - g_warning("NO BAD EVIL!"); - return FALSE; - } - - StatusServiceDbusPrivate * priv = STATUS_SERVICE_DBUS_GET_PRIVATE(service); - if (priv->icon == NULL) { - *icon = g_strdup(""); - } else { - *icon = g_strdup(priv->icon); - } - - return TRUE; -} - -static gboolean -_status_service_server_pretty_user_name (StatusServiceDbus * service, gchar ** username, GError ** error) -{ - if (!IS_STATUS_SERVICE_DBUS(service)) { - g_warning("NO BAD EVIL!"); - return FALSE; - } - - StatusServiceDbusPrivate * priv = STATUS_SERVICE_DBUS_GET_PRIVATE(service); - if (priv->name == NULL) { - *username = g_strdup(""); - } else { - *username = g_strdup(priv->name); - } - - return TRUE; -} - -void -status_service_dbus_set_status (StatusServiceDbus * self, const gchar * icon) -{ - g_return_if_fail(IS_STATUS_SERVICE_DBUS(self)); - - g_debug("Setting icon to: %s", icon); - - StatusServiceDbusPrivate * priv = STATUS_SERVICE_DBUS_GET_PRIVATE(self); - - if (priv->icon != NULL) { - g_free(priv->icon); - } - priv->icon = g_strdup(icon); - - g_signal_emit(G_OBJECT(self), signals[STATUS_ICONS_CHANGED], 0, priv->icon, TRUE); - return; -} diff --git a/src/status-service-dbus.h b/src/status-service-dbus.h deleted file mode 100644 index 34a9c3c..0000000 --- a/src/status-service-dbus.h +++ /dev/null @@ -1,59 +0,0 @@ -/* -A small wrapper utility to load indicators and put them as menu items -into the gnome-panel using it's applet interface. - -Copyright 2009 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 __STATUS_SERVICE_DBUS_H__ -#define __STATUS_SERVICE_DBUS_H__ - -#include <glib.h> -#include <glib-object.h> - -G_BEGIN_DECLS - -#define STATUS_SERVICE_DBUS_TYPE (status_service_dbus_get_type ()) -#define STATUS_SERVICE_DBUS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), STATUS_SERVICE_DBUS_TYPE, StatusServiceDbus)) -#define STATUS_SERVICE_DBUS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), STATUS_SERVICE_DBUS_TYPE, StatusServiceDbusClass)) -#define IS_STATUS_SERVICE_DBUS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), STATUS_SERVICE_DBUS_TYPE)) -#define IS_STATUS_SERVICE_DBUS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), STATUS_SERVICE_DBUS_TYPE)) -#define STATUS_SERVICE_DBUS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), STATUS_SERVICE_DBUS_TYPE, StatusServiceDbusClass)) - -typedef struct _StatusServiceDbus StatusServiceDbus; -typedef struct _StatusServiceDbusClass StatusServiceDbusClass; - -struct _StatusServiceDbusClass { - GObjectClass parent_class; - - /* Signals */ - gboolean (*user_changed) (StatusServiceDbus * self, gchar ** name, gpointer user_data); - gboolean (*status_icons_changed) (StatusServiceDbus * self, GArray ** icons, gpointer user_data); - -}; - -struct _StatusServiceDbus { - GObject parent; -}; - -GType status_service_dbus_get_type (void); -void status_service_dbus_set_status (StatusServiceDbus * self, const gchar * icon); - -G_END_DECLS - -#endif diff --git a/src/status-service.c b/src/status-service.c deleted file mode 100644 index c07b875..0000000 --- a/src/status-service.c +++ /dev/null @@ -1,264 +0,0 @@ -/* -A small wrapper utility to load indicators and put them as menu items -into the gnome-panel using it's applet interface. - -Copyright 2009 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/>. -*/ - -#include <config.h> - -#include <sys/types.h> -#include <pwd.h> -#include <unistd.h> - -#include <glib/gi18n.h> - -#include <dbus/dbus-glib.h> -#include <dbus/dbus-glib-bindings.h> - -#include <libdbusmenu-glib/client.h> -#include <libdbusmenu-glib/server.h> -#include <libdbusmenu-glib/menuitem.h> - -#include "dbus-shared-names.h" - -#include "status-service-dbus.h" - -#include "status-provider.h" -#include "status-provider-mc5.h" -#include "status-provider-pidgin.h" -#include "status-provider-telepathy.h" - -typedef StatusProvider * (*newfunc) (void); -#define STATUS_PROVIDER_CNT 3 -static newfunc status_provider_newfuncs[STATUS_PROVIDER_CNT] = { - status_provider_mc5_new, - status_provider_pidgin_new, - status_provider_telepathy_new -}; -static StatusProvider * status_providers[STATUS_PROVIDER_CNT] = { 0 }; - -static const gchar * status_strings [STATUS_PROVIDER_STATUS_LAST] = { - /* STATUS_PROVIDER_STATUS_ONLINE, */ N_("Available"), - /* 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_DISCONNECTED*/ N_("Offline") -}; - -static const gchar * status_icons[STATUS_PROVIDER_STATUS_LAST] = { - /* 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_DISCONNECTED */"system-shutdown-panel" -}; - - -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_DISCONNECTED; - -static void -status_update (void) { - StatusProviderStatus oldglobal = global_status; - 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]); - if (localstatus < global_status) { - global_status = localstatus; - } - } - - /* If changed */ - if (global_status != oldglobal) { - g_debug("Global status changed to: %s", _(status_strings[global_status])); - - /* Configure the icon on the panel */ - status_service_dbus_set_status(dbus_interface, status_icons[global_status]); - - /* 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_bool(status_menuitems[i], DBUSMENU_MENUITEM_PROP_SENSITIVE, FALSE); - } - } - - /* 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_bool(status_menuitems[i], DBUSMENU_MENUITEM_PROP_SENSITIVE, TRUE); - } - } - } - - return; -} - -static void -status_menu_click (DbusmenuMenuitem * mi, gpointer data) -{ - StatusProviderStatus status = (StatusProviderStatus)GPOINTER_TO_INT(data); - g_debug("Setting status: %d", status); - int i; - for (i = 0; i < STATUS_PROVIDER_CNT; i++) { - status_provider_set_status(status_providers[i], status); - } - - return; -} - -static gboolean -build_providers (gpointer data) -{ - int i; - for (i = 0; i < STATUS_PROVIDER_CNT; i++) { - status_providers[i] = status_provider_newfuncs[i](); - - if (status_providers[i] != NULL) { - g_signal_connect(G_OBJECT(status_providers[i]), STATUS_PROVIDER_SIGNAL_STATUS_CHANGED, G_CALLBACK(status_update), NULL); - } - } - - status_update(); - - return FALSE; -} - -static void -build_user_item (DbusmenuMenuitem * root) -{ - struct passwd * pwd = NULL; - - pwd = getpwuid(getuid()); - - if (pwd != NULL && pwd->pw_gecos != NULL) { - gchar * name = g_strdup(pwd->pw_gecos); - gchar * walker = name; - while (*walker != '\0' && *walker != ',') { walker++; } - *walker = '\0'; - - if (name[0] != '\0') { - DbusmenuMenuitem * useritem = dbusmenu_menuitem_new(); - dbusmenu_menuitem_property_set(useritem, DBUSMENU_MENUITEM_PROP_LABEL, name); - dbusmenu_menuitem_property_set_bool(useritem, DBUSMENU_MENUITEM_PROP_SENSITIVE, FALSE); - dbusmenu_menuitem_child_append(root, useritem); - } - - g_free(name); - } else { - g_debug("PWD: %s", (pwd == NULL ? "(pwd null)" : (pwd->pw_gecos == NULL ? "(gecos null)" : pwd->pw_gecos))); - } - - return; -} - -static gboolean -build_menu (gpointer data) -{ - DbusmenuMenuitem * root = DBUSMENU_MENUITEM(data); - g_return_val_if_fail(root != NULL, FALSE); - - build_user_item(root); - - status_menuitem = dbusmenu_menuitem_new(); - 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++) { - 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; - } - - status_menuitems[i] = dbusmenu_menuitem_new(); - - 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_bool(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]); - } - - return FALSE; -} - -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); - - 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; - guint nameret = 0; - - if (!org_freedesktop_DBus_request_name(bus_proxy, INDICATOR_STATUS_DBUS_NAME, 0, &nameret, &error)) { - g_error("Unable to call to request name"); - return 1; - } - - if (nameret != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) { - g_error("Unable to get name"); - return 1; - } - - g_idle_add(build_providers, NULL); - - root_menuitem = dbusmenu_menuitem_new(); - DbusmenuServer * server = dbusmenu_server_new(INDICATOR_STATUS_DBUS_OBJECT); - dbusmenu_server_set_root(server, root_menuitem); - - g_idle_add(build_menu, root_menuitem); - - dbus_interface = g_object_new(STATUS_SERVICE_DBUS_TYPE, NULL); - - mainloop = g_main_loop_new(NULL, FALSE); - g_main_loop_run(mainloop); - - return 0; -} - diff --git a/src/status-service.xml b/src/status-service.xml deleted file mode 100644 index 977b338..0000000 --- a/src/status-service.xml +++ /dev/null @@ -1,25 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<node name="/"> - <interface name="org.ayatana.indicator.status.service"> - -<!-- Methods --> - <method name="Watch"> - <annotation name="org.freedesktop.DBus.GLib.Async" value="true" /> - </method> - <method name="StatusIcons"> - <arg type="s" name="icons" direction="out" /> - </method> - <method name="PrettyUserName"> - <arg type="s" name="name" direction="out" /> - </method> - -<!-- Signals --> - <signal name="UserChanged"> - <arg type="s" name="name" direction="out" /> - </signal> - <signal name="StatusIconsChanged"> - <arg type="s" name="icons" direction="out" /> - </signal> - - </interface> -</node> diff --git a/src/users-service.c b/src/users-service.c deleted file mode 100644 index 0297f01..0000000 --- a/src/users-service.c +++ /dev/null @@ -1,326 +0,0 @@ -/* - * A small wrapper utility to load indicators and put them as menu items - * into the gnome-panel using it's applet interface. - * - * Copyright 2009 Canonical Ltd. - * - * Authors: - * Ted Gould <ted@canonical.com> - * Cody Russell <crussell@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/>. - */ - -#include <config.h> - -#include <unistd.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 "dbus-shared-names.h" -#include "users-service-dbus.h" -#include "lock-helper.h" - -#define GUEST_SESSION_LAUNCHER "/usr/share/gdm/guest-session/guest-session-launch" - -typedef struct _ActivateData ActivateData; -struct _ActivateData -{ - UsersServiceDbus *service; - UserData *user; -}; - -static DBusGConnection *session_bus = NULL; -static DBusGConnection *system_bus = NULL; -static DBusGProxy *bus_proxy = NULL; -static DBusGProxy *gdm_proxy = NULL; -static DbusmenuMenuitem *root_menuitem = NULL; -static GMainLoop *mainloop = NULL; -static UsersServiceDbus *dbus_interface = NULL; - -static DbusmenuMenuitem *lock_menuitem = NULL; - -static gint count; -static GList *users; - -/* Respond to the signal of autologin changing to see if the - setting for timed login changes. */ -static void -gdm_settings_change (void) -{ - if (!will_lock_screen()) { - dbusmenu_menuitem_property_set_bool(lock_menuitem, DBUSMENU_MENUITEM_PROP_SENSITIVE, FALSE); - } else { - dbusmenu_menuitem_property_set_bool(lock_menuitem, DBUSMENU_MENUITEM_PROP_SENSITIVE, TRUE); - } - - return; -} - -static gboolean -check_guest_session (void) -{ - if (geteuid() < 500) { - /* System users shouldn't have guest account shown. Mosly - this would be the case of the guest user itself. */ - return FALSE; - } - if (!g_file_test(GUEST_SESSION_LAUNCHER, G_FILE_TEST_IS_EXECUTABLE)) { - /* It doesn't appear that the Guest session stuff is - installed. So let's not use it then! */ - return FALSE; - } - - return TRUE; -} - -static void -activate_guest_session (DbusmenuMenuitem * mi, gpointer user_data) -{ - GError * error = NULL; - if (!g_spawn_command_line_async(GUEST_SESSION_LAUNCHER, &error)) { - g_warning("Unable to start guest session: %s", error->message); - g_error_free(error); - } - - return; -} - -static gboolean -check_new_session (void) -{ - if (system_bus == NULL) { - system_bus = dbus_g_bus_get(DBUS_BUS_SYSTEM, NULL); - } - - if (system_bus == NULL) { - return FALSE; - } - - if (gdm_proxy == NULL) { - gdm_proxy = dbus_g_proxy_new_for_name(system_bus, - "org.gnome.DisplayManager", - "/org/gnome/DisplayManager/LocalDisplayFactory", - "org.gnome.DisplayManager.LocalDisplayFactory"); - } - - if (gdm_proxy == NULL) { - return FALSE; - } - - return TRUE; -} - -static void -activate_new_session (DbusmenuMenuitem * mi, gpointer user_data) -{ - GError * error = NULL; - if (!g_spawn_command_line_async("gdmflexiserver --startnew", &error)) { - g_warning("Unable to start guest session: %s", error->message); - g_error_free(error); - } - - return; -} - -static void -activate_user_session (DbusmenuMenuitem *mi, gpointer user_data) -{ - UserData *user = (UserData *)user_data; - UsersServiceDbus *service = user->service; - - users_service_dbus_activate_user_session (service, user); -} - -static gint -compare_users_by_username (const gchar *a, - const gchar *b) -{ - UserData *user1 = (UserData *)a; - UserData *user2 = (UserData *)b; - - return g_strcmp0 (user1->user_name, user2->user_name); -} - -static void -rebuild_items (DbusmenuMenuitem *root, - UsersServiceDbus *service) -{ - DbusmenuMenuitem *mi = NULL; - GList *u; - UserData *user; - gboolean can_activate; - GList *children; - - can_activate = users_service_dbus_can_activate_session (service); - - children = dbusmenu_menuitem_take_children (root); - g_list_foreach (children, (GFunc)g_object_unref, NULL); - g_list_free (children); - - lock_menuitem = dbusmenu_menuitem_new(); - dbusmenu_menuitem_property_set(lock_menuitem, DBUSMENU_MENUITEM_PROP_LABEL, _("Lock Screen")); - g_signal_connect(G_OBJECT(lock_menuitem), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK(lock_screen), NULL); - dbusmenu_menuitem_child_append(root, lock_menuitem); - if (!will_lock_screen()) { - dbusmenu_menuitem_property_set_bool(lock_menuitem, DBUSMENU_MENUITEM_PROP_SENSITIVE, FALSE); - } else { - dbusmenu_menuitem_property_set_bool(lock_menuitem, DBUSMENU_MENUITEM_PROP_SENSITIVE, TRUE); - } - - if (can_activate == TRUE) - { - 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 > MINIMUM_USERS && count < MAXIMUM_USERS) - { - if (users != NULL) - { - GList *l = NULL; - - for (l = users; l != NULL; l = l->next) - { - users = g_list_delete_link (users, l); - } - - users = NULL; - } - - users = users_service_dbus_get_user_list (service); - - users = g_list_sort (users, (GCompareFunc)compare_users_by_username); - - for (u = users; u != NULL; u = g_list_next (u)) - { - user = u->data; - - user->service = service; - - mi = dbusmenu_menuitem_new (); - dbusmenu_menuitem_property_set (mi, DBUSMENU_MENUITEM_PROP_LABEL, user->real_name); - dbusmenu_menuitem_child_append (root, mi); - g_signal_connect (G_OBJECT (mi), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK (activate_user_session), user); - } - } - - if (check_new_session ()) - { - mi = dbusmenu_menuitem_new (); - dbusmenu_menuitem_property_set (mi, DBUSMENU_MENUITEM_PROP_LABEL, _("Switch User...")); - 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 -user_added (UsersServiceDbus *service, - UserData *user, - gpointer user_data) -{ - DbusmenuMenuitem *root = (DbusmenuMenuitem *)user_data; - - count++; - - rebuild_items (root, service); -} - -static void -user_removed (UsersServiceDbus *service, - UserData *user, - gpointer user_data) -{ - DbusmenuMenuitem *root = (DbusmenuMenuitem *)user_data; - - count--; - - 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); - - 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; - guint nameret = 0; - - if (!org_freedesktop_DBus_request_name(bus_proxy, INDICATOR_USERS_DBUS_NAME, 0, &nameret, &error)) { - g_error("Unable to call to request name"); - return 1; - } - - if (nameret != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) { - g_error("Unable to get name"); - return 1; - } - - g_idle_add(lock_screen_setup, NULL); - lock_screen_gdm_cb_set(gdm_settings_change); - - dbus_interface = g_object_new (USERS_SERVICE_DBUS_TYPE, NULL); - - root_menuitem = dbusmenu_menuitem_new (); - g_debug ("Root ID: %d", dbusmenu_menuitem_get_id (root_menuitem)); - - create_items (root_menuitem, dbus_interface); - - DbusmenuServer * server = dbusmenu_server_new(INDICATOR_USERS_DBUS_OBJECT); - dbusmenu_server_set_root(server, root_menuitem); - - g_signal_connect (G_OBJECT (dbus_interface), - "user-added", - G_CALLBACK (user_added), - root_menuitem); - g_signal_connect (G_OBJECT (dbus_interface), - "user-removed", - G_CALLBACK (user_removed), - root_menuitem); - - mainloop = g_main_loop_new(NULL, FALSE); - g_main_loop_run(mainloop); - - return 0; -} - |