~ubuntu-branches/ubuntu/trusty/indicator-sound-gtk2/trusty-proposed

« back to all changes in this revision

Viewing changes to src/slider-menu-item.c

  • Committer: Package Import Robot
  • Author(s): Lionel Le Folgoc
  • Date: 2012-09-10 00:09:01 UTC
  • Revision ID: package-import@ubuntu.com-20120910000901-q6469svv5d3pmn0y
Tags: upstream-12.10.0.1
ImportĀ upstreamĀ versionĀ 12.10.0.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
Copyright 2010 Canonical Ltd.
 
3
 
 
4
Authors:
 
5
    Conor Curran <conor.curran@canonical.com>
 
6
 
 
7
This program is free software: you can redistribute it and/or modify it
 
8
under the terms of the GNU General Public License version 3, as published
 
9
by the Free Software Foundation.
 
10
 
 
11
This program is distributed in the hope that it will be useful, but
 
12
WITHOUT ANY WARRANTY; without even the implied warranties of
 
13
MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
 
14
PURPOSE.  See the GNU General Public License for more details.
 
15
 
 
16
You should have received a copy of the GNU General Public License along
 
17
with this program.  If not, see <http://www.gnu.org/licenses/>.
 
18
*/
 
19
#ifdef HAVE_CONFIG_H
 
20
#include "config.h"
 
21
#endif
 
22
 
 
23
#include <glib/gi18n.h>
 
24
#include "slider-menu-item.h"
 
25
#include "common-defs.h"
 
26
#include "pulseaudio-mgr.h"
 
27
 
 
28
typedef struct _SliderMenuItemPrivate SliderMenuItemPrivate;
 
29
 
 
30
struct _SliderMenuItemPrivate {
 
31
  Device*             a_sink;
 
32
  gint                index;
 
33
  gchar*              name;
 
34
  gboolean            mute;
 
35
  pa_cvolume          volume;
 
36
  pa_channel_map      channel_map;
 
37
  pa_volume_t         base_volume;
 
38
};
 
39
 
 
40
#define SLIDER_MENU_ITEM_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), SLIDER_MENU_ITEM_TYPE, SliderMenuItemPrivate))
 
41
 
 
42
/* Prototypes */
 
43
static void slider_menu_item_class_init (SliderMenuItemClass *klass);
 
44
static void slider_menu_item_init       (SliderMenuItem *self);
 
45
static void slider_menu_item_dispose    (GObject *object);
 
46
static void slider_menu_item_finalize   (GObject *object);
 
47
static void handle_event (DbusmenuMenuitem * mi, const gchar * name, 
 
48
                          GVariant * value, guint timestamp);
 
49
static pa_cvolume slider_menu_item_construct_mono_volume (const pa_cvolume* vol);
 
50
static void slider_menu_item_update_volume (SliderMenuItem* self, gdouble percent);
 
51
 
 
52
G_DEFINE_TYPE (SliderMenuItem, slider_menu_item, DBUSMENU_TYPE_MENUITEM);
 
53
 
 
54
static void
 
55
slider_menu_item_class_init (SliderMenuItemClass *klass)
 
56
{
 
57
  GObjectClass *object_class = G_OBJECT_CLASS (klass);
 
58
 
 
59
  g_type_class_add_private (klass, sizeof (SliderMenuItemPrivate));
 
60
 
 
61
  object_class->dispose = slider_menu_item_dispose;
 
62
  object_class->finalize = slider_menu_item_finalize;
 
63
 
 
64
  DbusmenuMenuitemClass * mclass = DBUSMENU_MENUITEM_CLASS(klass);
 
65
  mclass->handle_event = handle_event;
 
66
  return;
 
67
}
 
68
 
 
69
static void
 
70
slider_menu_item_init (SliderMenuItem *self)
 
71
{
 
72
  dbusmenu_menuitem_property_set( DBUSMENU_MENUITEM(self),
 
73
                                  DBUSMENU_MENUITEM_PROP_TYPE,
 
74
                                  DBUSMENU_VOLUME_MENUITEM_TYPE );
 
75
 
 
76
  SliderMenuItemPrivate* priv = SLIDER_MENU_ITEM_GET_PRIVATE (self);
 
77
 
 
78
  priv->index = NOT_ACTIVE;
 
79
  priv->name = NULL;
 
80
 
 
81
  return;
 
82
}
 
83
 
 
84
static void
 
85
slider_menu_item_dispose (GObject *object)
 
86
{
 
87
  G_OBJECT_CLASS (slider_menu_item_parent_class)->dispose (object);
 
88
  return;
 
89
}
 
90
 
 
91
static void
 
92
slider_menu_item_finalize (GObject *object)
 
93
{
 
94
  G_OBJECT_CLASS (slider_menu_item_parent_class)->finalize (object);
 
95
}
 
96
 
 
97
static void
 
98
handle_event (DbusmenuMenuitem * mi,
 
99
              const gchar * name,
 
100
              GVariant * value,
 
101
              guint timestamp)
 
102
{
 
103
  g_return_if_fail (g_variant_is_of_type (value, G_VARIANT_TYPE_DOUBLE));
 
104
  g_return_if_fail (IS_SLIDER_MENU_ITEM (mi));
 
105
 
 
106
  SliderMenuItemPrivate* priv = SLIDER_MENU_ITEM_GET_PRIVATE (SLIDER_MENU_ITEM (mi));
 
107
  gdouble volume_input = g_variant_get_double (value);
 
108
 
 
109
/*
 
110
  g_debug ("slider menu item handle event with value %f on name %s",
 
111
           volume_input,
 
112
           name);
 
113
*/
 
114
 
 
115
  slider_menu_item_update_volume (SLIDER_MENU_ITEM (mi), volume_input);
 
116
  if (volume_input > 0)  
 
117
    device_ensure_sink_is_unmuted (priv->a_sink);
 
118
}
 
119
 
 
120
 
 
121
void
 
122
slider_menu_item_populate (SliderMenuItem* self, const pa_sink_info* update)
 
123
{
 
124
  SliderMenuItemPrivate* priv = SLIDER_MENU_ITEM_GET_PRIVATE (self);
 
125
  priv->name = g_strdup (update->name);
 
126
  priv->index = update->index;
 
127
  priv->volume = slider_menu_item_construct_mono_volume (&update->volume);
 
128
  priv->base_volume = update->base_volume;
 
129
  priv->channel_map = update->channel_map;
 
130
  priv->mute = update->mute;
 
131
 
 
132
  pa_volume_t vol = pa_cvolume_max (&update->volume);
 
133
  gdouble volume_percent = ((gdouble) vol * 100) / PA_VOLUME_NORM;
 
134
  GVariant* new_volume = g_variant_new_double (volume_percent);
 
135
  dbusmenu_menuitem_property_set_variant (DBUSMENU_MENUITEM(self),
 
136
                                          DBUSMENU_VOLUME_MENUITEM_LEVEL,
 
137
                                          new_volume);
 
138
  GVariant* new_mute_update = g_variant_new_boolean (update->mute == 1);
 
139
  dbusmenu_menuitem_property_set_variant (DBUSMENU_MENUITEM(self),
 
140
                                          DBUSMENU_VOLUME_MENUITEM_MUTE,
 
141
                                          new_mute_update);
 
142
 
 
143
  slider_menu_item_enable (self, TRUE);
 
144
}
 
145
 
 
146
// From the UI
 
147
static void
 
148
slider_menu_item_update_volume (SliderMenuItem* self, gdouble percent)
 
149
{
 
150
  g_return_if_fail (IS_SLIDER_MENU_ITEM (self));
 
151
 
 
152
  pa_cvolume mono_new_volume;
 
153
  pa_cvolume_init(&mono_new_volume);
 
154
  mono_new_volume.channels = 1;
 
155
  pa_volume_t new_volume_value = (pa_volume_t) ((percent * PA_VOLUME_NORM) / 100);
 
156
  
 
157
  if (new_volume_value == PA_VOLUME_INVALID || new_volume_value >= PA_VOLUME_MAX){
 
158
    g_warning ("slider_menu_item_update_volume - volume is out of range !");
 
159
    return;
 
160
  }
 
161
  
 
162
  pa_cvolume_set(&mono_new_volume, 1, new_volume_value);
 
163
 
 
164
  SliderMenuItemPrivate* priv = SLIDER_MENU_ITEM_GET_PRIVATE (self);
 
165
  if (!pa_cvolume_valid (&mono_new_volume)){
 
166
    g_warning ("Invalid volume - ignore it!");
 
167
    return;
 
168
  }
 
169
  if (!pa_channel_map_valid(&priv->channel_map)){
 
170
    g_warning ("Invalid channel map - ignore update volume!");
 
171
    return;      
 
172
  }
 
173
  pa_cvolume_set(&priv->volume, priv->channel_map.channels, new_volume_value);
 
174
  pm_update_volume (priv->index, mono_new_volume);
 
175
}
 
176
 
 
177
// To the UI
 
178
void
 
179
slider_menu_item_update (SliderMenuItem* self, const pa_sink_info* update)
 
180
{
 
181
  SliderMenuItemPrivate* priv = SLIDER_MENU_ITEM_GET_PRIVATE (self);
 
182
 
 
183
  priv->volume = slider_menu_item_construct_mono_volume (&update->volume);
 
184
  priv->base_volume = update->base_volume;
 
185
  priv->channel_map = update->channel_map;
 
186
 
 
187
  pa_volume_t vol = pa_cvolume_max (&update->volume);
 
188
  gdouble volume_percent = ((gdouble) vol * 100) / PA_VOLUME_NORM;
 
189
 
 
190
  GVariant* new_volume = g_variant_new_double (volume_percent);
 
191
 
 
192
/*
 
193
  g_debug ("slider menu item update - volume update to ui to %f", volume_percent);
 
194
*/
 
195
 
 
196
  dbusmenu_menuitem_property_set_variant (DBUSMENU_MENUITEM(self),
 
197
                                          DBUSMENU_VOLUME_MENUITEM_LEVEL,
 
198
                                          new_volume);
 
199
 
 
200
  if (priv->mute != update->mute){
 
201
    priv->mute = update->mute;
 
202
/*
 
203
    g_debug ("volume menu item - update - mute on ui = %i", update->mute);
 
204
*/
 
205
    GVariant* new_mute_update = g_variant_new_boolean (update->mute == 1);
 
206
    dbusmenu_menuitem_property_set_variant (DBUSMENU_MENUITEM(self),
 
207
                                            DBUSMENU_VOLUME_MENUITEM_MUTE,
 
208
                                            new_mute_update);
 
209
  }
 
210
}
 
211
 
 
212
/*
 
213
 * Enable/Disabled can be considered the equivalent of whether we have an active
 
214
 * sink or not, let the widget have inherent state.
 
215
 */
 
216
void
 
217
slider_menu_item_enable (SliderMenuItem* self, gboolean active)
 
218
{
 
219
  SliderMenuItemPrivate* priv = SLIDER_MENU_ITEM_GET_PRIVATE (self);
 
220
 
 
221
  dbusmenu_menuitem_property_set_bool (DBUSMENU_MENUITEM(self),
 
222
                                       DBUSMENU_MENUITEM_PROP_ENABLED,
 
223
                                       active);
 
224
  if(active == FALSE){
 
225
    priv->index = NOT_ACTIVE;
 
226
    if(priv->name != NULL){
 
227
      g_free(priv->name);
 
228
      priv->name = NULL;
 
229
    }
 
230
  }
 
231
}
 
232
 
 
233
gint
 
234
slider_menu_item_get_sink_index (SliderMenuItem* self)
 
235
{
 
236
  SliderMenuItemPrivate* priv = SLIDER_MENU_ITEM_GET_PRIVATE (self);
 
237
  return priv->index;
 
238
}
 
239
 
 
240
static pa_cvolume
 
241
slider_menu_item_construct_mono_volume (const pa_cvolume* vol)
 
242
{
 
243
  pa_cvolume new_volume;
 
244
  pa_cvolume_init(&new_volume);
 
245
  new_volume.channels = 1;
 
246
  pa_volume_t max_vol = pa_cvolume_max(vol);
 
247
  pa_cvolume_set(&new_volume, 1, max_vol);
 
248
  return new_volume;
 
249
}
 
250
 
 
251
SliderMenuItem*
 
252
slider_menu_item_new (Device* sink)
 
253
 
254
  SliderMenuItem *self = g_object_new(SLIDER_MENU_ITEM_TYPE, NULL);
 
255
  SliderMenuItemPrivate* priv = SLIDER_MENU_ITEM_GET_PRIVATE (self);
 
256
  priv->a_sink = sink;
 
257
  return self;
 
258
}