~xavi-garcia-mena/indicator-sound/bluetooth-icons-bug-1415480

« back to all changes in this revision

Viewing changes to src/indicator-sound.c

  • Committer: Conor Curran
  • Date: 2010-02-24 14:19:01 UTC
  • mto: (36.2.5 indicator-sound)
  • mto: This revision was merged to the branch mainline in revision 41.
  • Revision ID: conor.curran@canonical.com-20100224141901-bm3xaiil2rtp43sr
unit tests for the indicator side added

Show diffs side-by-side

added added

removed removed

Lines of Context:
100
100
static void prepare_state_machine();
101
101
static void determine_state_from_volume(gdouble volume_percent);
102
102
static void update_state(const gint state);
 
103
 
103
104
static const gint STATE_MUTED = 0;
104
105
static const gint STATE_ZERO = 1;
105
106
static const gint STATE_LOW = 2;
106
107
static const gint STATE_MEDIUM = 3;
107
108
static const gint STATE_HIGH = 4;
108
109
static const gint STATE_MUTED_WHILE_INPUT = 5;
109
 
static const gint STATE_SINKS_NONE = 5;
 
110
static const gint STATE_SINKS_NONE = 6;
 
111
 
110
112
static GHashTable *volume_states = NULL;
111
113
static GtkImage *speaker_image = NULL;
112
114
static GtkWidget* primary_image = NULL;
115
117
static gdouble initial_volume_percent = 0;
116
118
static gboolean initial_mute = FALSE;
117
119
 
 
120
// Construction
118
121
static void
119
122
indicator_sound_class_init (IndicatorSoundClass *klass)
120
123
{
147
150
    return;
148
151
}
149
152
 
150
 
 
151
 
/*
152
 
Prepare states Array.
153
 
*/
154
 
static void prepare_state_machine()
155
 
{
156
 
    // TODO we need three more images
157
 
    volume_states = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, g_free);
158
 
    g_hash_table_insert(volume_states, GINT_TO_POINTER(STATE_MUTED), g_strdup("audio-volume-muted-panel"));
159
 
    g_hash_table_insert(volume_states, GINT_TO_POINTER(STATE_ZERO), g_strdup("audio-volume-zero-panel"));
160
 
    g_hash_table_insert(volume_states, GINT_TO_POINTER(STATE_LOW), g_strdup("audio-volume-low-panel"));
161
 
    g_hash_table_insert(volume_states, GINT_TO_POINTER(STATE_MEDIUM), g_strdup("audio-volume-medium-panel"));
162
 
    g_hash_table_insert(volume_states, GINT_TO_POINTER(STATE_HIGH), g_strdup("audio-volume-high-panel"));
163
 
    g_hash_table_insert(volume_states, GINT_TO_POINTER(STATE_MUTED_WHILE_INPUT), g_strdup("audio-volume-muted-blocking-panel"));
164
 
    g_hash_table_insert(volume_states, GINT_TO_POINTER(STATE_SINKS_NONE), g_strdup("audio-output-none-panel"));
 
153
static void
 
154
indicator_sound_dispose (GObject *object)
 
155
{
 
156
        IndicatorSound * self = INDICATOR_SOUND(object);
 
157
 
 
158
        if (self->service != NULL) {
 
159
                g_object_unref(G_OBJECT(self->service));
 
160
                self->service = NULL;
 
161
        }
 
162
    g_hash_table_destroy(volume_states);
 
163
        G_OBJECT_CLASS (indicator_sound_parent_class)->dispose (object);
 
164
        return;
 
165
}
 
166
 
 
167
static void
 
168
indicator_sound_finalize (GObject *object)
 
169
{
 
170
        G_OBJECT_CLASS (indicator_sound_parent_class)->finalize (object);
 
171
        return;
 
172
}
 
173
 
 
174
static GtkLabel *
 
175
get_label (IndicatorObject * io)
 
176
{
 
177
        return NULL;
 
178
}
 
179
 
 
180
static GtkImage *
 
181
get_icon (IndicatorObject * io)
 
182
{
 
183
    gchar* current_name = g_hash_table_lookup(volume_states, GINT_TO_POINTER(current_state));
 
184
    //g_debug("At start-up attempting to set the image to %s", current_name);
 
185
        speaker_image = GTK_IMAGE(gtk_image_new_from_icon_name(current_name, GTK_ICON_SIZE_MENU));
 
186
        gtk_widget_show(GTK_WIDGET(speaker_image));
 
187
        return speaker_image;
 
188
}
 
189
 
 
190
/* Indicator based function to get the menu for the whole
 
191
   applet.  This starts up asking for the parts of the menu
 
192
   from the various services. */
 
193
static GtkMenu *
 
194
get_menu (IndicatorObject * io)
 
195
{
 
196
    DbusmenuGtkMenu *menu = dbusmenu_gtkmenu_new(INDICATOR_SOUND_DBUS_NAME, INDICATOR_SOUND_DBUS_OBJECT);    
 
197
        DbusmenuGtkClient *client = dbusmenu_gtkmenu_get_client(menu);  
 
198
    dbusmenu_client_add_type_handler(DBUSMENU_CLIENT(client), DBUSMENU_SLIDER_MENUITEM_TYPE, new_slider_item);
 
199
 
 
200
    // register Key-press listening on the menu widget as the slider does not allow this.
 
201
    g_signal_connect(menu, "key-press-event", G_CALLBACK(key_press_cb), NULL);         
 
202
 
 
203
    return GTK_MENU(menu);
 
204
}
 
205
 
 
206
/**
 
207
new_slider_item:
 
208
Create a new dBusMenu Slider item.
 
209
**/
 
210
static gboolean new_slider_item(DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client)
 
211
{
 
212
        g_return_val_if_fail(DBUSMENU_IS_MENUITEM(newitem), FALSE);
 
213
        g_return_val_if_fail(DBUSMENU_IS_GTKCLIENT(client), FALSE);
 
214
    
 
215
    volume_slider = ido_scale_menu_item_new_with_range ("Volume", initial_volume_percent, 0, 100, 0.5);
 
216
        g_object_set(volume_slider, "reverse-scroll-events", TRUE, NULL);
 
217
 
 
218
    GtkMenuItem *menu_volume_slider = GTK_MENU_ITEM(volume_slider);
 
219
 
 
220
        dbusmenu_gtkclient_newitem_base(DBUSMENU_GTKCLIENT(client), newitem, menu_volume_slider, parent);
 
221
        g_signal_connect(G_OBJECT(newitem), DBUSMENU_MENUITEM_SIGNAL_PROPERTY_CHANGED, G_CALLBACK(slider_prop_change_cb), volume_slider);
 
222
    
 
223
    // register slider changes listening on the range
 
224
    GtkWidget* slider = ido_scale_menu_item_get_scale((IdoScaleMenuItem*)volume_slider);  
 
225
    g_signal_connect(slider, "value-changed", G_CALLBACK(value_changed_event_cb), newitem);     
 
226
    // alternative callback mechanism which i could use again at some point.
 
227
/*    g_signal_connect(slider, "change-value", G_CALLBACK(user_change_value_event_cb), newitem);     */
 
228
    
 
229
    // Set images on the ido
 
230
    primary_image = ido_scale_menu_item_get_primary_image((IdoScaleMenuItem*)volume_slider);    
 
231
    gtk_image_set_from_icon_name(GTK_IMAGE(primary_image), g_hash_table_lookup(volume_states, GINT_TO_POINTER(STATE_ZERO)), GTK_ICON_SIZE_MENU);
 
232
    GtkWidget* secondary_image = ido_scale_menu_item_get_secondary_image((IdoScaleMenuItem*)volume_slider);                 
 
233
    gtk_image_set_from_icon_name(GTK_IMAGE(secondary_image), g_hash_table_lookup(volume_states, GINT_TO_POINTER(STATE_HIGH)), GTK_ICON_SIZE_MENU);
 
234
 
 
235
    gtk_widget_show_all(volume_slider);
 
236
 
 
237
        return TRUE;
165
238
}
166
239
 
167
240
static void
205
278
        return;
206
279
}
207
280
 
 
281
 
 
282
 
 
283
 
 
284
/*
 
285
Prepare states Array.
 
286
*/
 
287
static void prepare_state_machine()
 
288
{
 
289
    // TODO we need three more images
 
290
    volume_states = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, g_free);
 
291
    g_hash_table_insert(volume_states, GINT_TO_POINTER(STATE_MUTED), g_strdup("audio-volume-muted-panel"));
 
292
    g_hash_table_insert(volume_states, GINT_TO_POINTER(STATE_ZERO), g_strdup("audio-volume-low-zero-panel"));
 
293
    g_hash_table_insert(volume_states, GINT_TO_POINTER(STATE_LOW), g_strdup("audio-volume-low-panel"));
 
294
    g_hash_table_insert(volume_states, GINT_TO_POINTER(STATE_MEDIUM), g_strdup("audio-volume-medium-panel"));
 
295
    g_hash_table_insert(volume_states, GINT_TO_POINTER(STATE_HIGH), g_strdup("audio-volume-high-panel"));
 
296
    g_hash_table_insert(volume_states, GINT_TO_POINTER(STATE_MUTED_WHILE_INPUT), g_strdup("audio-volume-muted-blocking-panel"));
 
297
    g_hash_table_insert(volume_states, GINT_TO_POINTER(STATE_SINKS_NONE), g_strdup("audio-output-none-panel"));
 
298
}
 
299
 
 
300
 
 
301
 
 
302
static void update_state(const gint state)
 
303
{
 
304
/*    g_debug("update state beginning - previous_state = %i", previous_state);*/
 
305
 
 
306
    previous_state = current_state;
 
307
 
 
308
/*    g_debug("update state 3rd line - previous_state = %i", previous_state);*/
 
309
 
 
310
    current_state = state;
 
311
    gchar* image_name = g_hash_table_lookup(volume_states, GINT_TO_POINTER(current_state));
 
312
    gtk_image_set_from_icon_name(speaker_image, image_name, GTK_ICON_SIZE_MENU);
 
313
}
 
314
 
 
315
 
 
316
static void determine_state_from_volume(gdouble volume_percent)
 
317
{
 
318
/*    g_debug("determine_state_from_volume - previous_state = %i", previous_state);*/
 
319
 
 
320
    gint state = previous_state;
 
321
    if (volume_percent < 30.0 && volume_percent > 0){
 
322
        state = STATE_LOW;
 
323
    }
 
324
    else if(volume_percent < 70.0 && volume_percent >= 30.0){
 
325
        state = STATE_MEDIUM;
 
326
    }
 
327
    else if(volume_percent >= 70.0){
 
328
        state = STATE_HIGH;
 
329
    }
 
330
    else if(volume_percent == 0.0){
 
331
        state = STATE_ZERO;
 
332
    }    
 
333
    update_state(state);   
 
334
}
 
335
 
 
336
 
 
337
 
208
338
static void fetch_volume_percent_from_dbus()
209
339
{
210
340
    GError * error = NULL;
270
400
    g_debug("signal caught - sink mute update with mute value: %i", mute_value);
271
401
    gtk_widget_set_sensitive(volume_slider, !mute_value);
272
402
}
273
 
 
274
 
 
275
 
static void
276
 
indicator_sound_dispose (GObject *object)
277
 
{
278
 
        IndicatorSound * self = INDICATOR_SOUND(object);
279
 
 
280
 
        if (self->service != NULL) {
281
 
                g_object_unref(G_OBJECT(self->service));
282
 
                self->service = NULL;
283
 
        }
284
 
    g_hash_table_destroy(volume_states);
285
 
        G_OBJECT_CLASS (indicator_sound_parent_class)->dispose (object);
286
 
        return;
287
 
}
288
 
 
289
 
static void
290
 
indicator_sound_finalize (GObject *object)
291
 
{
292
 
        G_OBJECT_CLASS (indicator_sound_parent_class)->finalize (object);
293
 
        return;
294
 
}
295
 
 
296
 
static GtkLabel *
297
 
get_label (IndicatorObject * io)
298
 
{
299
 
        return NULL;
300
 
}
301
 
 
302
 
static GtkImage *
303
 
get_icon (IndicatorObject * io)
304
 
{
305
 
    gchar* current_name = g_hash_table_lookup(volume_states, GINT_TO_POINTER(current_state));
306
 
    g_debug("At start-up attempting to set the image to %s", current_name);
307
 
        speaker_image = GTK_IMAGE(gtk_image_new_from_icon_name(current_name, GTK_ICON_SIZE_MENU));
308
 
        gtk_widget_show(GTK_WIDGET(speaker_image));
309
 
        return speaker_image;
310
 
}
311
 
 
312
 
static void update_state(const gint state)
313
 
{
314
 
/*    g_debug("update state beginning - previous_state = %i", previous_state);*/
315
 
 
316
 
    previous_state = current_state;
317
 
 
318
 
/*    g_debug("update state 3rd line - previous_state = %i", previous_state);*/
319
 
 
320
 
    current_state = state;
321
 
    gchar* image_name = g_hash_table_lookup(volume_states, GINT_TO_POINTER(current_state));
322
 
    gtk_image_set_from_icon_name(speaker_image, image_name, GTK_ICON_SIZE_MENU);
323
 
}
324
 
 
325
 
 
326
 
static void determine_state_from_volume(gdouble volume_percent)
327
 
{
328
 
/*    g_debug("determine_state_from_volume - previous_state = %i", previous_state);*/
329
 
 
330
 
    gint state = previous_state;
331
 
    if (volume_percent < 30.0 && volume_percent > 0){
332
 
        state = STATE_LOW;
333
 
    }
334
 
    else if(volume_percent < 70.0 && volume_percent > 30.0){
335
 
        state = STATE_MEDIUM;
336
 
    }
337
 
    else if(volume_percent > 70.0){
338
 
        state = STATE_HIGH;
339
 
    }
340
 
    else if(volume_percent == 0.0){
341
 
        state = STATE_ZERO;
342
 
    }    
343
 
    update_state(state);   
344
 
}
345
 
 
346
 
 
347
 
/* Indicator based function to get the menu for the whole
348
 
   applet.  This starts up asking for the parts of the menu
349
 
   from the various services. */
350
 
static GtkMenu *
351
 
get_menu (IndicatorObject * io)
352
 
{
353
 
    DbusmenuGtkMenu *menu = dbusmenu_gtkmenu_new(INDICATOR_SOUND_DBUS_NAME, INDICATOR_SOUND_DBUS_OBJECT);    
354
 
        DbusmenuGtkClient *client = dbusmenu_gtkmenu_get_client(menu);  
355
 
    dbusmenu_client_add_type_handler(DBUSMENU_CLIENT(client), DBUSMENU_SLIDER_MENUITEM_TYPE, new_slider_item);
356
 
 
357
 
    // register Key-press listening on the menu widget as the slider does not allow this.
358
 
    g_signal_connect(menu, "key-press-event", G_CALLBACK(key_press_cb), NULL);         
359
 
 
360
 
    return GTK_MENU(menu);
361
 
}
362
 
 
363
 
/**
364
 
new_slider_item:
365
 
Create a new dBusMenu Slider item, register the 
366
 
**/
367
 
static gboolean new_slider_item(DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client)
368
 
{
369
 
        g_return_val_if_fail(DBUSMENU_IS_MENUITEM(newitem), FALSE);
370
 
        g_return_val_if_fail(DBUSMENU_IS_GTKCLIENT(client), FALSE);
371
 
    
372
 
    volume_slider = ido_scale_menu_item_new_with_range ("Volume", initial_volume_percent, 0, 100, 0.5);
373
 
        g_object_set(volume_slider, "reverse-scroll-events", TRUE, NULL);
374
 
 
375
 
    GtkMenuItem *menu_volume_slider = GTK_MENU_ITEM(volume_slider);
376
 
 
377
 
        dbusmenu_gtkclient_newitem_base(DBUSMENU_GTKCLIENT(client), newitem, menu_volume_slider, parent);
378
 
        g_signal_connect(G_OBJECT(newitem), DBUSMENU_MENUITEM_SIGNAL_PROPERTY_CHANGED, G_CALLBACK(slider_prop_change_cb), volume_slider);
379
 
    
380
 
    // register slider changes listening on the range
381
 
    GtkWidget* slider = ido_scale_menu_item_get_scale((IdoScaleMenuItem*)volume_slider);  
382
 
    g_signal_connect(slider, "value-changed", G_CALLBACK(value_changed_event_cb), newitem);     
383
 
    // alternative callback mechanism which i could use again at some point.
384
 
/*    g_signal_connect(slider, "change-value", G_CALLBACK(user_change_value_event_cb), newitem);     */
385
 
    
386
 
    // Set images on the ido
387
 
    primary_image = ido_scale_menu_item_get_primary_image((IdoScaleMenuItem*)volume_slider);    
388
 
    gtk_image_set_from_icon_name(GTK_IMAGE(primary_image), g_hash_table_lookup(volume_states, GINT_TO_POINTER(STATE_ZERO)), GTK_ICON_SIZE_MENU);
389
 
    GtkWidget* secondary_image = ido_scale_menu_item_get_secondary_image((IdoScaleMenuItem*)volume_slider);                 
390
 
    gtk_image_set_from_icon_name(GTK_IMAGE(secondary_image), g_hash_table_lookup(volume_states, GINT_TO_POINTER(STATE_HIGH)), GTK_ICON_SIZE_MENU);
391
 
 
392
 
    gtk_widget_show_all(volume_slider);
393
 
 
394
 
        return TRUE;
395
 
}
396
 
 
397
403
/**
398
404
slider_prop_change_cb:
399
405
Whenever we have a property change on a DbusmenuMenuitem this will be called.