From 439df114d9dbaf985fb46069f2e745cd867ad3f9 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Tue, 18 Aug 2009 09:17:32 -0500 Subject: Changing the name from SUS to Session --- src/Makefile.am | 14 +- src/indicator-session.c | 456 ++++++++++++++++++++++++++++++++++++++++++++++++ src/indicator-sus.c | 456 ------------------------------------------------ 3 files changed, 463 insertions(+), 463 deletions(-) create mode 100644 src/indicator-session.c delete mode 100644 src/indicator-sus.c (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index bc3c9d9..bd35910 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -6,15 +6,15 @@ libexec_PROGRAMS = indicator-status-service indicator-users-service indicator-se # Indicator Stuff ################### -status_users_sessionlibdir = $(INDICATORDIR) -status_users_sessionlib_LTLIBRARIES = libstatus-users-session.la -libstatus_users_session_la_SOURCES = \ - indicator-sus.c \ +sessionlibdir = $(INDICATORDIR) +sessionlib_LTLIBRARIES = libsession.la +libsession_la_SOURCES = \ + indicator-session.c \ dbus-shared-names.h \ status-service-client.h -libstatus_users_session_la_CFLAGS = $(APPLET_CFLAGS) -Wall -Werror -libstatus_users_session_la_LIBADD = $(APPLET_LIBS) -libstatus_users_session_la_LDFLAGS = -module -avoid-version +libsession_la_CFLAGS = $(APPLET_CFLAGS) -Wall -Werror +libsession_la_LIBADD = $(APPLET_LIBS) +libsession_la_LDFLAGS = -module -avoid-version ################ # Status Stuff diff --git a/src/indicator-session.c b/src/indicator-session.c new file mode 100644 index 0000000..07efc86 --- /dev/null +++ b/src/indicator-session.c @@ -0,0 +1,456 @@ +/* +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 + +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 . +*/ + + +#include +#include + +#include +#include + +#include +INDICATOR_SET_VERSION +INDICATOR_SET_NAME("users-status-session") + +#include "dbus-shared-names.h" +#include "status-service-client.h" + +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; + +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); + +GtkLabel * +get_label (void) +{ + GtkLabel * returnval = GTK_LABEL(gtk_label_new(g_get_user_name())); + gtk_widget_show(GTK_WIDGET(returnval)); + return returnval; +} + +GtkImage * +get_icon (void) +{ + g_debug("Changing status icon: '%s'", "user-offline"); + status_image = GTK_IMAGE(gtk_image_new_from_icon_name("user-offline", GTK_ICON_SIZE_MENU)); + gtk_widget_show(GTK_WIDGET(status_image)); + return status_image; +} + +static void +child_added (DbusmenuMenuitem * parent, DbusmenuMenuitem * child, guint position, gpointer section) +{ + DbusmenuGtkClient * client = NULL; + gchar * errorstr = NULL; + guint (*posfunc) (void) = NULL; + + switch (GPOINTER_TO_UINT(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; + } + + position += posfunc(); + g_debug("SUS: Adding child: %d", position); + 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_insert(main_menu, GTK_WIDGET(widget), position); + gtk_widget_show(GTK_WIDGET(widget)); + + 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; +} + +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; +} + +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; +} + +static gboolean +build_status_menu (gpointer userdata) +{ + g_debug("Building Status Menu"); + guint returnval = 0; + GError * error = NULL; + + if (proxy == NULL) { + /* If we don't have DBus, let's stay in the idle loop */ + return TRUE; + } + + if (!org_freedesktop_DBus_start_service_by_name (proxy, INDICATOR_STATUS_DBUS_NAME, 0, &returnval, &error)) { + g_error("Unable to send message to DBus to start service: %s", error != NULL ? error->message : "(NULL error)" ); + g_error_free(error); + return FALSE; + } + + if (returnval != DBUS_START_REPLY_SUCCESS && returnval != DBUS_START_REPLY_ALREADY_RUNNING) { + g_error("Return value isn't indicative of success: %d", returnval); + return FALSE; + } + + 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 FALSE; +} + +/* 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; +} + +static gboolean +build_users_menu (gpointer userdata) +{ + g_debug("Building Users Menu"); + guint returnval = 0; + GError * error = NULL; + + if (proxy == NULL) { + /* If we don't have DBus, let's stay in the idle loop */ + return TRUE; + } + + if (!org_freedesktop_DBus_start_service_by_name (proxy, INDICATOR_USERS_DBUS_NAME, 0, &returnval, &error)) { + g_error("Unable to send message to DBus to start service: %s", error != NULL ? error->message : "(NULL error)" ); + g_error_free(error); + return FALSE; + } + + if (returnval != DBUS_START_REPLY_SUCCESS && returnval != DBUS_START_REPLY_ALREADY_RUNNING) { + g_error("Return value isn't indicative of success: %d", returnval); + return FALSE; + } + + 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 FALSE; +} + +/* 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; +} + +static gboolean +build_session_menu (gpointer userdata) +{ + g_debug("Building Session Menu"); + guint returnval = 0; + GError * error = NULL; + + if (proxy == NULL) { + /* If we don't have DBus, let's stay in the idle loop */ + return TRUE; + } + + if (!org_freedesktop_DBus_start_service_by_name (proxy, INDICATOR_SESSION_DBUS_NAME, 0, &returnval, &error)) { + g_error("Unable to send message to DBus to start service: %s", error != NULL ? error->message : "(NULL error)" ); + g_error_free(error); + return FALSE; + } + + if (returnval != DBUS_START_REPLY_SUCCESS && returnval != DBUS_START_REPLY_ALREADY_RUNNING) { + g_error("Return value isn't indicative of success: %d", returnval); + return FALSE; + } + + 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 FALSE; +} + +/* Base menu stuff */ + +GtkMenu * +get_menu (void) +{ + 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."); + } + + g_idle_add(build_status_menu, NULL); + g_idle_add(build_users_menu, NULL); + g_idle_add(build_session_menu, NULL); + + 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; +} + + diff --git a/src/indicator-sus.c b/src/indicator-sus.c deleted file mode 100644 index 07efc86..0000000 --- a/src/indicator-sus.c +++ /dev/null @@ -1,456 +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 - -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 . -*/ - - -#include -#include - -#include -#include - -#include -INDICATOR_SET_VERSION -INDICATOR_SET_NAME("users-status-session") - -#include "dbus-shared-names.h" -#include "status-service-client.h" - -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; - -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); - -GtkLabel * -get_label (void) -{ - GtkLabel * returnval = GTK_LABEL(gtk_label_new(g_get_user_name())); - gtk_widget_show(GTK_WIDGET(returnval)); - return returnval; -} - -GtkImage * -get_icon (void) -{ - g_debug("Changing status icon: '%s'", "user-offline"); - status_image = GTK_IMAGE(gtk_image_new_from_icon_name("user-offline", GTK_ICON_SIZE_MENU)); - gtk_widget_show(GTK_WIDGET(status_image)); - return status_image; -} - -static void -child_added (DbusmenuMenuitem * parent, DbusmenuMenuitem * child, guint position, gpointer section) -{ - DbusmenuGtkClient * client = NULL; - gchar * errorstr = NULL; - guint (*posfunc) (void) = NULL; - - switch (GPOINTER_TO_UINT(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; - } - - position += posfunc(); - g_debug("SUS: Adding child: %d", position); - 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_insert(main_menu, GTK_WIDGET(widget), position); - gtk_widget_show(GTK_WIDGET(widget)); - - 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; -} - -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; -} - -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; -} - -static gboolean -build_status_menu (gpointer userdata) -{ - g_debug("Building Status Menu"); - guint returnval = 0; - GError * error = NULL; - - if (proxy == NULL) { - /* If we don't have DBus, let's stay in the idle loop */ - return TRUE; - } - - if (!org_freedesktop_DBus_start_service_by_name (proxy, INDICATOR_STATUS_DBUS_NAME, 0, &returnval, &error)) { - g_error("Unable to send message to DBus to start service: %s", error != NULL ? error->message : "(NULL error)" ); - g_error_free(error); - return FALSE; - } - - if (returnval != DBUS_START_REPLY_SUCCESS && returnval != DBUS_START_REPLY_ALREADY_RUNNING) { - g_error("Return value isn't indicative of success: %d", returnval); - return FALSE; - } - - 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 FALSE; -} - -/* 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; -} - -static gboolean -build_users_menu (gpointer userdata) -{ - g_debug("Building Users Menu"); - guint returnval = 0; - GError * error = NULL; - - if (proxy == NULL) { - /* If we don't have DBus, let's stay in the idle loop */ - return TRUE; - } - - if (!org_freedesktop_DBus_start_service_by_name (proxy, INDICATOR_USERS_DBUS_NAME, 0, &returnval, &error)) { - g_error("Unable to send message to DBus to start service: %s", error != NULL ? error->message : "(NULL error)" ); - g_error_free(error); - return FALSE; - } - - if (returnval != DBUS_START_REPLY_SUCCESS && returnval != DBUS_START_REPLY_ALREADY_RUNNING) { - g_error("Return value isn't indicative of success: %d", returnval); - return FALSE; - } - - 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 FALSE; -} - -/* 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; -} - -static gboolean -build_session_menu (gpointer userdata) -{ - g_debug("Building Session Menu"); - guint returnval = 0; - GError * error = NULL; - - if (proxy == NULL) { - /* If we don't have DBus, let's stay in the idle loop */ - return TRUE; - } - - if (!org_freedesktop_DBus_start_service_by_name (proxy, INDICATOR_SESSION_DBUS_NAME, 0, &returnval, &error)) { - g_error("Unable to send message to DBus to start service: %s", error != NULL ? error->message : "(NULL error)" ); - g_error_free(error); - return FALSE; - } - - if (returnval != DBUS_START_REPLY_SUCCESS && returnval != DBUS_START_REPLY_ALREADY_RUNNING) { - g_error("Return value isn't indicative of success: %d", returnval); - return FALSE; - } - - 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 FALSE; -} - -/* Base menu stuff */ - -GtkMenu * -get_menu (void) -{ - 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."); - } - - g_idle_add(build_status_menu, NULL); - g_idle_add(build_users_menu, NULL); - g_idle_add(build_session_menu, NULL); - - 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; -} - - -- cgit v1.2.3