aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am2
-rw-r--r--src/indicator-sound.c44
-rw-r--r--src/voip-input-widget.c252
-rw-r--r--src/voip-input-widget.h55
4 files changed, 353 insertions, 0 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 228e6a3..7525d71 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -20,6 +20,8 @@ libsoundmenu_la_SOURCES = \
title-widget.h \
volume-widget.c \
volume-widget.h \
+ voip-input-widget.c \
+ voip-input-widget.h \
gen-sound-service.xml.h \
gen-sound-service.xml.c \
dbus-shared-names.h
diff --git a/src/indicator-sound.c b/src/indicator-sound.c
index 96ab89b..138c5ac 100644
--- a/src/indicator-sound.c
+++ b/src/indicator-sound.c
@@ -79,6 +79,10 @@ static gboolean new_volume_slider_widget (DbusmenuMenuitem * newitem,
DbusmenuMenuitem * parent,
DbusmenuClient * client,
gpointer user_data);
+static gboolean new_voip_slider_widget (DbusmenuMenuitem * newitem,
+ DbusmenuMenuitem * parent,
+ DbusmenuClient * client,
+ gpointer user_data);
static gboolean new_transport_widget (DbusmenuMenuitem * newitem,
DbusmenuMenuitem * parent,
DbusmenuClient * client,
@@ -191,6 +195,9 @@ get_menu (IndicatorObject * io)
DBUSMENU_VOLUME_MENUITEM_TYPE,
new_volume_slider_widget);
dbusmenu_client_add_type_handler (DBUSMENU_CLIENT(client),
+ DBUSMENU_VOIP_INPUT_MENUITEM_TYPE,
+ new_voip_slider_widget);
+ dbusmenu_client_add_type_handler (DBUSMENU_CLIENT(client),
DBUSMENU_TRANSPORT_MENUITEM_TYPE,
new_transport_widget);
dbusmenu_client_add_type_handler (DBUSMENU_CLIENT(client),
@@ -403,6 +410,43 @@ new_volume_slider_widget(DbusmenuMenuitem * newitem,
parent);
return TRUE;
}
+static gboolean
+new_voip_slider_widget (DbusmenuMenuitem * newitem,
+ DbusmenuMenuitem * parent,
+ DbusmenuClient * client,
+ gpointer user_data)
+{
+ g_debug("indicator-sound: new_voip_slider_widget");
+/*
+ GtkWidget* voip_widget = NULL;
+ IndicatorObject *io = NULL;
+
+
+ g_return_val_if_fail(DBUSMENU_IS_MENUITEM(newitem), FALSE);
+ g_return_val_if_fail(DBUSMENU_IS_GTKCLIENT(client), FALSE);
+
+ volume_widget = volume_widget_new (newitem);
+ io = g_object_get_data (G_OBJECT (client), "indicator");
+ IndicatorSoundPrivate* priv = INDICATOR_SOUND_GET_PRIVATE(INDICATOR_SOUND (io));
+ priv->volume_widget = volume_widget;
+
+ GtkWidget* ido_slider_widget = volume_widget_get_ido_slider(VOLUME_WIDGET(priv->volume_widget));
+
+ gtk_widget_show_all(ido_slider_widget);
+ // register the style callback on this widget with state manager's style change
+ // handler (needs to remake the blocking animation for each style).
+ g_signal_connect (ido_slider_widget, "style-set",
+ G_CALLBACK(sound_state_manager_style_changed_cb),
+ priv->state_manager);
+
+ GtkMenuItem *menu_volume_item = GTK_MENU_ITEM(ido_slider_widget);
+ dbusmenu_gtkclient_newitem_base(DBUSMENU_GTKCLIENT(client),
+ newitem,
+ menu_volume_item,
+ parent);
+*/
+ return TRUE;
+}
/*******************************************************************/
//UI callbacks
diff --git a/src/voip-input-widget.c b/src/voip-input-widget.c
new file mode 100644
index 0000000..4933d7b
--- /dev/null
+++ b/src/voip-input-widget.c
@@ -0,0 +1,252 @@
+
+/*
+Copyright 2011 Canonical Ltd.
+
+Authors:
+ Conor Curran <conor.curran@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 <glib/gi18n.h>
+#include <math.h>
+#include <glib.h>
+#include "voip-input-widget.h"
+#include "common-defs.h"
+#include <libido/idoscalemenuitem.h>
+//#include "indicator-sound.h"
+
+typedef struct _VoipInputWidgetPrivate VoipInputWidgetPrivate;
+
+struct _VoipInputWidgetPrivate
+{
+ DbusmenuMenuitem* twin_item;
+ GtkWidget* ido_voip_input_slider;
+ gboolean grabbed;
+};
+
+#define VOIP_INPUT_WIDGET_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), VOIP_INPUT_WIDGET_TYPE, VoipInputWidgetPrivate))
+
+/* Prototypes */
+static void voip_input_widget_class_init (VoipInputWidgetClass *klass);
+static void voip_input_widget_init (VoipInputWidget *self);
+static void voip_input_widget_dispose (GObject *object);
+static void voip_input_widget_finalize (GObject *object);
+static void voip_input_widget_set_twin_item( VoipInputWidget* self,
+ DbusmenuMenuitem* twin_item);
+static void voip_input_widget_property_update( DbusmenuMenuitem* item, gchar* property,
+ GVariant* value, gpointer userdata );
+
+static gboolean voip_input_widget_change_value_cb (GtkRange *range,
+ GtkScrollType scroll,
+ gdouble value,
+ gpointer user_data);
+static gboolean voip_input_widget_value_changed_cb(GtkRange *range, gpointer user_data);
+static void voip_input_widget_slider_grabbed(GtkWidget *widget, gpointer user_data);
+static void voip_input_widget_slider_released(GtkWidget *widget, gpointer user_data);
+static void voip_input_widget_parent_changed (GtkWidget *widget, gpointer user_data);
+
+G_DEFINE_TYPE (VoipInputWidget, voip_input_widget, G_TYPE_OBJECT);
+
+
+static void
+voip_input_widget_class_init (VoipInputWidgetClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+ g_type_class_add_private (klass, sizeof (VoipInputWidgetPrivate));
+
+ gobject_class->dispose = voip_input_widget_dispose;
+ gobject_class->finalize = voip_input_widget_finalize;
+}
+
+static void
+voip_input_widget_init (VoipInputWidget *self)
+{
+ //g_debug("VoipInputWidget::voip_input_widget_init");
+ VoipInputWidgetPrivate * priv = VOIP_INPUT_WIDGET_GET_PRIVATE(self);
+
+ priv->ido_voip_input_slider = ido_scale_menu_item_new_with_range ("VOLUME", IDO_RANGE_STYLE_DEFAULT, 0, 0, 100, 1);
+ g_object_ref (priv->ido_voip_input_slider);
+ ido_scale_menu_item_set_style (IDO_SCALE_MENU_ITEM (priv->ido_voip_input_slider), IDO_SCALE_MENU_ITEM_STYLE_IMAGE);
+ g_object_set(priv->ido_voip_input_slider, "reverse-scroll-events", TRUE, NULL);
+
+ g_signal_connect (priv->ido_voip_input_slider,
+ "notify::parent", G_CALLBACK (voip_input_widget_parent_changed),
+ NULL);
+
+ GtkWidget* voip_input_widget = ido_scale_menu_item_get_scale((IdoScaleMenuItem*)priv->ido_voip_input_slider);
+
+ g_signal_connect(voip_input_widget, "change-value", G_CALLBACK(voip_input_widget_change_value_cb), self);
+ g_signal_connect(voip_input_widget, "value-changed", G_CALLBACK(voip_input_widget_value_changed_cb), self);
+ g_signal_connect(priv->ido_voip_input_slider, "slider-grabbed", G_CALLBACK(voip_input_widget_slider_grabbed), self);
+ g_signal_connect(priv->ido_voip_input_slider, "slider-released", G_CALLBACK(voip_input_widget_slider_released), self);
+
+ GtkWidget* primary_image = ido_scale_menu_item_get_primary_image((IdoScaleMenuItem*)priv->ido_voip_input_slider);
+ GIcon * primary_gicon = g_themed_icon_new_with_default_fallbacks("audio-volume-low-zero-panel");
+ gtk_image_set_from_gicon(GTK_IMAGE(primary_image), primary_gicon, GTK_ICON_SIZE_MENU);
+ g_object_unref(primary_gicon);
+
+ GtkWidget* secondary_image = ido_scale_menu_item_get_secondary_image((IdoScaleMenuItem*)priv->ido_voip_input_slider);
+ GIcon * secondary_gicon = g_themed_icon_new_with_default_fallbacks("audio-volume-high-panel");
+ gtk_image_set_from_gicon(GTK_IMAGE(secondary_image), secondary_gicon, GTK_ICON_SIZE_MENU);
+ g_object_unref(secondary_gicon);
+
+ GtkAdjustment *adj = gtk_range_get_adjustment (GTK_RANGE (voip_input_widget));
+ gtk_adjustment_set_step_increment(adj, 4);
+}
+
+static void
+voip_input_widget_dispose (GObject *object)
+{
+ G_OBJECT_CLASS (voip_input_widget_parent_class)->dispose (object);
+}
+
+static void
+voip_input_widget_finalize (GObject *object)
+{
+ G_OBJECT_CLASS (voip_input_widget_parent_class)->finalize (object);
+}
+
+static void
+voip_input_widget_property_update( DbusmenuMenuitem* item, gchar* property,
+ GVariant* value, gpointer userdata)
+{
+ g_return_if_fail (IS_VOIP_INPUT_WIDGET (userdata));
+ VoipInputWidget* mitem = VOIP_INPUT_WIDGET(userdata);
+ VoipInputWidgetPrivate * priv = VOIP_INPUT_WIDGET_GET_PRIVATE(mitem);
+ //g_debug("scrub-widget::property_update for prop %s", property);
+ if(g_ascii_strcasecmp(DBUSMENU_VOLUME_MENUITEM_LEVEL, property) == 0){
+ if(priv->grabbed == FALSE){
+ GtkWidget *slider = ido_scale_menu_item_get_scale((IdoScaleMenuItem*)priv->ido_voip_input_slider);
+ GtkRange *range = (GtkRange*)slider;
+ gdouble update = g_variant_get_double (value);
+ //g_debug("volume-widget - update level with value %f", update);
+ gtk_range_set_value(range, update);
+ }
+ }
+}
+
+static void
+voip_input_widget_set_twin_item(VoipInputWidget* self,
+ DbusmenuMenuitem* twin_item)
+{
+ VoipInputWidgetPrivate * priv = VOIP_INPUT_WIDGET_GET_PRIVATE(self);
+ priv->twin_item = twin_item;
+ g_object_ref(priv->twin_item);
+ g_signal_connect(G_OBJECT(twin_item), "property-changed",
+ G_CALLBACK(voip_input_widget_property_update), self);
+ gdouble initial_level = g_variant_get_double (dbusmenu_menuitem_property_get_variant(twin_item,
+ DBUSMENU_VOLUME_MENUITEM_LEVEL));
+ //g_debug("voip_input_widget_set_twin_item initial level = %f", initial_level);
+ GtkWidget *slider = ido_scale_menu_item_get_scale((IdoScaleMenuItem*)priv->ido_voip_input_slider);
+ GtkRange *range = (GtkRange*)slider;
+ gtk_range_set_value(range, initial_level);
+}
+
+static gboolean
+voip_input_widget_change_value_cb (GtkRange *range,
+ GtkScrollType scroll,
+ gdouble new_value,
+ gpointer user_data)
+{
+ g_return_val_if_fail (IS_VOIP_INPUT_WIDGET (user_data), FALSE);
+ VoipInputWidget* mitem = VOIP_INPUT_WIDGET(user_data);
+ voip_input_widget_update(mitem, new_value);
+ return FALSE;
+}
+
+/*
+ We only want this callback to catch mouse icon press events
+ which set the slider to 0 or 100. Ignore all other events.
+*/
+static gboolean
+voip_input_widget_value_changed_cb(GtkRange *range, gpointer user_data)
+{
+ g_return_val_if_fail (IS_VOIP_INPUT_WIDGET (user_data), FALSE);
+ VoipInputWidget* mitem = VOIP_INPUT_WIDGET(user_data);
+ VoipInputWidgetPrivate * priv = VOIP_INPUT_WIDGET_GET_PRIVATE(mitem);
+ GtkWidget *slider = ido_scale_menu_item_get_scale((IdoScaleMenuItem*)priv->ido_voip_input_slider);
+ gdouble current_value = CLAMP(gtk_range_get_value(GTK_RANGE(slider)), 0, 100);
+
+ if(current_value == 0 || current_value == 100){
+ voip_input_widget_update(mitem, current_value);
+ }
+ return FALSE;
+}
+
+void
+voip_input_widget_update(VoipInputWidget* self, gdouble update)
+{
+ VoipInputWidgetPrivate * priv = VOIP_INPUT_WIDGET_GET_PRIVATE(self);
+ gdouble clamped = CLAMP(update, 0, 100);
+ GVariant* new_volume = g_variant_new_double(clamped);
+ dbusmenu_menuitem_handle_event (priv->twin_item, "update", new_volume, 0);
+}
+
+GtkWidget*
+voip_input_widget_get_ido_slider(VoipInputWidget* self)
+{
+ VoipInputWidgetPrivate * priv = VOIP_INPUT_WIDGET_GET_PRIVATE(self);
+ return priv->ido_voip_input_slider;
+}
+
+static void
+voip_input_widget_parent_changed (GtkWidget *widget,
+ gpointer user_data)
+{
+ gtk_widget_set_size_request (widget, 200, -1);
+ //g_debug("voip_input_widget_parent_changed");
+}
+
+static void
+voip_input_widget_slider_grabbed(GtkWidget *widget, gpointer user_data)
+{
+ VoipInputWidget* mitem = VOIP_INPUT_WIDGET(user_data);
+ VoipInputWidgetPrivate * priv = VOIP_INPUT_WIDGET_GET_PRIVATE(mitem);
+ priv->grabbed = TRUE;
+}
+
+static void
+voip_input_widget_slider_released(GtkWidget *widget, gpointer user_data)
+{
+ VoipInputWidget* mitem = VOIP_INPUT_WIDGET(user_data);
+ VoipInputWidgetPrivate * priv = VOIP_INPUT_WIDGET_GET_PRIVATE(mitem);
+ priv->grabbed = FALSE;
+}
+
+void
+voip_input_widget_tidy_up (GtkWidget *widget)
+{
+ VoipInputWidget* mitem = VOIP_INPUT_WIDGET(widget);
+ VoipInputWidgetPrivate * priv = VOIP_INPUT_WIDGET_GET_PRIVATE(mitem);
+ gtk_widget_destroy (priv->ido_voip_input_slider);
+}
+
+/**
+ * voip_input_widget_new:
+ * @returns: a new #VoipInputWidget.
+ **/
+GtkWidget*
+voip_input_widget_new(DbusmenuMenuitem *item)
+{
+ GtkWidget* widget = g_object_new(VOIP_INPUT_WIDGET_TYPE, NULL);
+ voip_input_widget_set_twin_item((VoipInputWidget*)widget, item);
+ return widget;
+}
+
+
diff --git a/src/voip-input-widget.h b/src/voip-input-widget.h
new file mode 100644
index 0000000..29912f0
--- /dev/null
+++ b/src/voip-input-widget.h
@@ -0,0 +1,55 @@
+/*
+Copyright 2011 Canonical Ltd.
+
+Authors:
+ Conor Curran <conor.curran@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 __VOIP_INPUT_WIDGET_H__
+#define __VOIP_INPUT_WIDGET_H__
+
+#include <glib.h>
+#include <glib-object.h>
+#include <libdbusmenu-gtk/menuitem.h>
+
+G_BEGIN_DECLS
+
+#define VOIP_INPUT_WIDGET_TYPE (voip_input_widget_get_type ())
+#define VOIP_INPUT_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), VOIP_INPUT_WIDGET_TYPE, VoipInputWidget))
+#define VOIP_INPUT_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), VOIP_INPUT_WIDGET_TYPE, VoipInputWidgetClass))
+#define IS_VOIP_INPUT_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), VOIP_INPUT_WIDGET_TYPE))
+#define IS_VOIP_INPUT_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), VOIP_INPUT_WIDGET_TYPE))
+#define VOIP_INPUT_WIDGET_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), VOIP_INPUT_WIDGET_TYPE, VoipInputWidgetClass))
+
+typedef struct _VoipInputWidget VoipInputWidget;
+typedef struct _VoipInputWidgetClass VoipInputWidgetClass;
+
+struct _VoipInputWidgetClass {
+ GObjectClass parent_class;
+};
+
+struct _VoipInputWidget {
+ GObject parent;
+};
+
+GType voip_input_widget_get_type (void) G_GNUC_CONST;
+GtkWidget* voip_input_widget_new(DbusmenuMenuitem* twin_item);
+GtkWidget* voip_input_widget_get_ido_slider(VoipInputWidget* self);
+void voip_input_widget_update(VoipInputWidget* self, gdouble update);
+void voip_input_widget_tidy_up (GtkWidget *widget);
+
+G_END_DECLS
+
+#endif
+