aboutsummaryrefslogtreecommitdiff
path: root/src/indicator-sound.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/indicator-sound.c')
-rw-r--r--src/indicator-sound.c182
1 files changed, 117 insertions, 65 deletions
diff --git a/src/indicator-sound.c b/src/indicator-sound.c
index 34f5ed9..53bb366 100644
--- a/src/indicator-sound.c
+++ b/src/indicator-sound.c
@@ -29,8 +29,7 @@ with this program. If not, see <http://www.gnu.org/licenses/>.
#include <libdbusmenu-gtk/menu.h>
#include <libido/idoscalemenuitem.h>
-#include <dbus/dbus-glib.h>
-#include <dbus/dbus-glib-bindings.h>
+#include <gio/gio.h>
#include "indicator-sound.h"
#include "transport-widget.h"
@@ -39,7 +38,8 @@ with this program. If not, see <http://www.gnu.org/licenses/>.
#include "volume-widget.h"
#include "dbus-shared-names.h"
-#include "sound-service-client.h"
+
+#include "gen-sound-service-xml.h"
#include "common-defs.h"
typedef struct _IndicatorSoundPrivate IndicatorSoundPrivate;
@@ -48,6 +48,7 @@ struct _IndicatorSoundPrivate
{
GtkWidget* volume_widget;
GList* transport_widgets_list;
+ GDBusProxy *dbus_proxy;
};
#define INDICATOR_SOUND_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), INDICATOR_SOUND_TYPE, IndicatorSoundPrivate))
@@ -81,8 +82,20 @@ static gboolean new_metadata_widget(DbusmenuMenuitem * newitem, DbusmenuMenuitem
static gboolean new_title_widget(DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client);
// DBUS communication
-static DBusGProxy *sound_dbus_proxy = NULL;
-static void connection_changed (IndicatorServiceManager * sm, gboolean connected, gpointer userdata);
+
+static GDBusNodeInfo *node_info = NULL;
+static GDBusInterfaceInfo *interface_info = NULL;
+
+static void connection_changed (IndicatorServiceManager * sm,
+ gboolean connected,
+ gpointer userdata);
+
+static void g_signal_cb ( GDBusProxy *proxy,
+ const gchar *sender_name,
+ const gchar *signal_name,
+ GVariant *parameters,
+ gpointer user_data)
+
static void catch_signal_sink_input_while_muted(DBusGProxy * proxy, gboolean value, gpointer userdata);
static void catch_signal_sink_mute_update(DBusGProxy *proxy, gboolean mute_value, gpointer userdata);
static void catch_signal_sink_availability_update(DBusGProxy *proxy, gboolean available_value, gpointer userdata);
@@ -146,7 +159,8 @@ static void
indicator_sound_init (IndicatorSound *self)
{
self->service = NULL;
- self->service = indicator_service_manager_new_version(INDICATOR_SOUND_DBUS_NAME, INDICATOR_SOUND_DBUS_VERSION);
+ self->service = indicator_service_manager_new_version(INDICATOR_SOUND_DBUS_NAME,
+ INDICATOR_SOUND_DBUS_VERSION);
prepare_state_machine();
prepare_blocked_animation();
animation_id = 0;
@@ -156,13 +170,13 @@ indicator_sound_init (IndicatorSound *self)
IndicatorSoundPrivate* priv = INDICATOR_SOUND_GET_PRIVATE(self);
priv->volume_widget = NULL;
+ priv->dbus_proxy = NULL;
GList* t_list = NULL;
priv->transport_widgets_list = t_list;
g_signal_connect(G_OBJECT(self->service),
INDICATOR_SERVICE_MANAGER_SIGNAL_CONNECTION_CHANGE,
G_CALLBACK(connection_changed), self);
- return;
}
static void
@@ -290,11 +304,11 @@ new_metadata_widget(DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, Dbusm
static gboolean
new_title_widget(DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client)
{
- //g_debug("indicator-sound: new_title_widget");
g_return_val_if_fail(DBUSMENU_IS_MENUITEM(newitem), FALSE);
g_return_val_if_fail(DBUSMENU_IS_GTKCLIENT(client), FALSE);
- //g_debug ("%s (\"%s\")", __func__, dbusmenu_menuitem_property_get(newitem, DBUSMENU_TITLE_MENUITEM_NAME));
+ //g_debug ("%s (\"%s\")", __func__,
+ //dbusmenu_menuitem_property_get(newitem, DBUSMENU_TITLE_MENUITEM_NAME));
GtkWidget* title = NULL;
@@ -345,64 +359,81 @@ new_volume_slider_widget(DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent,
static void
-connection_changed (IndicatorServiceManager * sm, gboolean connected, gpointer user_data)
-{
- if (connected) {
- gboolean service_restart = FALSE;
- if (sound_dbus_proxy != NULL) {
- g_object_unref (sound_dbus_proxy);
- sound_dbus_proxy = NULL;
- service_restart = TRUE;
- }
- GError * error = NULL;
-
- DBusGConnection * sbus = dbus_g_bus_get(DBUS_BUS_SESSION, NULL);
-
- sound_dbus_proxy = dbus_g_proxy_new_for_name_owner(sbus,
- INDICATOR_SOUND_DBUS_NAME,
- INDICATOR_SOUND_SERVICE_DBUS_OBJECT,
- INDICATOR_SOUND_SERVICE_DBUS_INTERFACE,
- &error);
+connection_changed (IndicatorServiceManager * sm,
+ gboolean connected,
+ gpointer user_data)
+{
+ IndicatorSound* indicator = INDICATOR_SOUND(user_data);
+ g_return_if_fail ( IS_INDICATOR_SOUND (indicator) );
+ IndicatorSoundPrivate* priv = INDICATOR_SOUND_GET_PRIVATE(self);
+ if (connected == FALSE){
+ return;
+ //TODO: Gracefully handle disconnection
+ // do a timeout to wait for reconnection
+ // for 5 seconds and then if no connection message
+ // is received put the state at 'sink not available'
+ }
+ // If we connection is back on and the proxy is not null
+ // we don't need to anything gdbus takes care of the rest - bless.
+ if (priv->dbus_proxy!= NULL){
+ return;
+ }
+
+ if ( node_info == NULL ){
+ node_info = g_dbus_node_info_new_for_xml ( _sound_service,
+ &error );
if (error != NULL) {
- g_warning("Unable to get status proxy: %s", error->message);
+ g_warning( "Failed to get create interface info from xml: %s",
+ error->message );
g_error_free(error);
+ return;
}
- //g_debug("about to connect to the signals");
- dbus_g_proxy_add_signal(sound_dbus_proxy, SIGNAL_SINK_INPUT_WHILE_MUTED, G_TYPE_BOOLEAN, G_TYPE_INVALID);
- dbus_g_proxy_connect_signal(sound_dbus_proxy, SIGNAL_SINK_INPUT_WHILE_MUTED, G_CALLBACK(catch_signal_sink_input_while_muted), NULL, NULL);
- dbus_g_proxy_add_signal(sound_dbus_proxy, SIGNAL_SINK_MUTE_UPDATE, G_TYPE_BOOLEAN, G_TYPE_INVALID);
- dbus_g_proxy_connect_signal(sound_dbus_proxy, SIGNAL_SINK_MUTE_UPDATE, G_CALLBACK(catch_signal_sink_mute_update), user_data, NULL);
- dbus_g_proxy_add_signal(sound_dbus_proxy, SIGNAL_SINK_AVAILABLE_UPDATE, G_TYPE_BOOLEAN, G_TYPE_INVALID);
- dbus_g_proxy_connect_signal(sound_dbus_proxy, SIGNAL_SINK_AVAILABLE_UPDATE, G_CALLBACK(catch_signal_sink_availability_update), NULL, NULL);
-
- if( service_restart == TRUE){
- fetch_mute_value_from_dbus();
- // Ensure UI is in sync with service again.
- IndicatorSound* indicator = INDICATOR_SOUND(user_data);
- fetch_sink_availability_from_dbus(indicator);
- IndicatorSoundPrivate* priv = INDICATOR_SOUND_GET_PRIVATE(indicator);
- if(priv->volume_widget != NULL){
- determine_state_from_volume (volume_widget_get_current_volume(priv->volume_widget));
- }
+ }
+
+ if (interface_info == NULL) {
+ interface_info = g_dbus_node_info_lookup_interface (node_info,
+ INDICATOR_SOUND_SERVICE_DBUS_INTERFACE);
+ if (interface_info == NULL) {
+ g_error("Unable to find interface '" INDICATOR_SOUND_SERVICE_DBUS_INTERFACE "'");
}
- }
- else{
- g_warning("Indicator has been disconnected from the service -> SHOCK HORROR");
- IndicatorSound* indicator = INDICATOR_SOUND(user_data);
- IndicatorSoundPrivate* priv = INDICATOR_SOUND_GET_PRIVATE(indicator);
-
- if(priv->volume_widget != NULL){
- g_warning("indicator still has a slider, service must have crashed");
- volume_widget_tidy_up(priv->volume_widget);
- g_object_unref(G_OBJECT(priv->volume_widget));
- priv->volume_widget = NULL;
- }
- device_available = FALSE;
- update_state(STATE_SINKS_NONE);
}
+
+ g_dbus_proxy_new_for_bus( G_BUS_TYPE_SESSION,
+ G_DBUS_PROXY_FLAGS_NONE,
+ interface_info,
+ INDICATOR_SOUND_DBUS_NAME,
+ INDICATOR_SOUND_SERVICE_DBUS_OBJECT,
+ INDICATOR_SOUND_SERVICE_DBUS_INTERFACE,
+ NULL,
+ create_connection_to_service,
+ indicator );
}
+static void create_connection_to_service (GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ IndicatorSound *self = INDICATOR_SOUND(user_data);
+ GError *error = NULL;
+
+ g_return_if_fail(self != NULL);
+
+ IndicatorSoundPrivate* priv = INDICATOR_SOUND_GET_PRIVATE(self);
+
+ priv->dbus_proxy = g_dbus_proxy_new_finish(res, &error);
+
+ if (error != NULL) {
+ g_warning("Failed to get dbus proxy: %s", error->message);
+ g_error_free(error);
+ return;
+ }
+
+ g_signal_connect(self->dbus_proxy, "g-signal", G_CALLBACK(g_signal), self);
+
+}
+
+
/*
Prepare states Array.
*/
@@ -609,10 +640,32 @@ fetch_mute_value_from_dbus()
}
/*******************************************************************/
-//DBus signal catchers
+// Signal reactions
/*******************************************************************/
+static void g_signal_cb ( GDBusProxy *proxy,
+ const gchar *sender_name,
+ const gchar *signal_name,
+ GVariant *parameters,
+ gpointer user_data)
+{
+ IndicatorSound *self = INDICATOR_SOUND(user_data);
+ GError *error = NULL;
+ gboolean input = g_variant_get_boolean (parameters);
+ g_return_if_fail ( IS_INDICATOR_SOUND(self) );
+
+ if (g_strcmp0(signal_name, INDICATOR_SOUND_SIGNAL_SINK_AVAILABLE_UPDATE) == 0){
+ react_signal_sink_availability_update ( input, self );
+ }
+ else if (g_strcmp0(signal_name, INDICATOR_SOUND_SIGNAL_SINK_MUTE_UPDATE) == 0){
+ react_signal_sink_mute_update ( input, self );
+ }
+ else if (g_strcmp0(signal_name, INDICATOR_SOUND_SIGNAL_SINK_INPUT_WHILE_MUTED) == 0){
+ react_signal_sink_input_while_muted ( input, self );
+ }
+}
+
static void
-catch_signal_sink_input_while_muted(DBusGProxy * proxy, gboolean block_value, gpointer userdata)
+react_signal_sink_input_while_muted(gboolean block_value, IndicatorSound* self)
{
//g_debug("signal caught - sink input while muted with value %i", block_value);
if (block_value == 1 && blocked_id == 0 && animation_id == 0 && blocked_animation_list != NULL) {
@@ -627,7 +680,7 @@ catch_signal_sink_input_while_muted(DBusGProxy * proxy, gboolean block_value, gp
UNMUTE's force a volume update therefore icon is updated appropriately => no need for unmute handling here.
*/
static void
-catch_signal_sink_mute_update(DBusGProxy *proxy, gboolean mute_value, gpointer userdata)
+react_signal_sink_mute_update(gboolean mute_value, IndicatorSound* self)
{
if (mute_value == TRUE && device_available == TRUE) {
update_state(STATE_MUTED);
@@ -636,8 +689,7 @@ catch_signal_sink_mute_update(DBusGProxy *proxy, gboolean mute_value, gpointer u
}
//g_debug("signal caught - sink mute update with mute value: %i", mute_value);
g_return_if_fail(IS_INDICATOR_SOUND(userdata));
- IndicatorSound* indicator = INDICATOR_SOUND(userdata);
- IndicatorSoundPrivate* priv = INDICATOR_SOUND_GET_PRIVATE(indicator);
+ IndicatorSoundPrivate* priv = INDICATOR_SOUND_GET_PRIVATE(self);
if(priv->volume_widget == NULL){
return;
@@ -648,7 +700,7 @@ catch_signal_sink_mute_update(DBusGProxy *proxy, gboolean mute_value, gpointer u
static void
-catch_signal_sink_availability_update(DBusGProxy *proxy, gboolean available_value, gpointer userdata)
+react_signal_sink_availability_update(gboolean available_value, IndicatorSound* self)
{
device_available = available_value;
if (device_available == FALSE) {