gnome-shell-3.6.3.1/src/gvc/gvc-mixer-card.c

No issues found

Incomplete coverage

Tool Failure ID Location Function Message Data
clang-analyzer no-output-found gvc/gvc-mixer-card.c Message(text='Unable to locate XML output from invoke-clang-analyzer') None
Failure running clang-analyzer ('no-output-found')
Message
Unable to locate XML output from invoke-clang-analyzer
  1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
  2  *
  3  * Copyright (C) 2008 William Jon McCann
  4  * Copyright (C) 2009 Bastien Nocera
  5  *
  6  * This program is free software; you can redistribute it and/or modify
  7  * it under the terms of the GNU General Public License as published by
  8  * the Free Software Foundation; either version 2 of the License, or
  9  * (at your option) any later version.
 10  *
 11  * This program is distributed in the hope that it will be useful,
 12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 14  * GNU General Public License for more details.
 15  *
 16  * You should have received a copy of the GNU General Public License
 17  * along with this program; if not, write to the Free Software
 18  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 19  *
 20  */
 21 
 22 #include "config.h"
 23 
 24 #include <stdlib.h>
 25 #include <stdio.h>
 26 #include <unistd.h>
 27 
 28 #include <glib.h>
 29 #include <glib/gi18n-lib.h>
 30 
 31 #include <pulse/pulseaudio.h>
 32 
 33 #include "gvc-mixer-card.h"
 34 #include "gvc-mixer-card-private.h"
 35 
 36 #define GVC_MIXER_CARD_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GVC_TYPE_MIXER_CARD, GvcMixerCardPrivate))
 37 
 38 static guint32 card_serial = 1;
 39 
 40 struct GvcMixerCardPrivate
 41 {
 42         pa_context    *pa_context;
 43         guint          id;
 44         guint          index;
 45         char          *name;
 46         char          *icon_name;
 47         char          *profile;
 48         char          *target_profile;
 49         char          *human_profile;
 50         GList         *profiles;
 51         pa_operation  *profile_op;
 52 };
 53 
 54 enum
 55 {
 56         PROP_0,
 57         PROP_ID,
 58         PROP_PA_CONTEXT,
 59         PROP_INDEX,
 60         PROP_NAME,
 61         PROP_ICON_NAME,
 62         PROP_PROFILE,
 63         PROP_HUMAN_PROFILE,
 64 };
 65 
 66 static void     gvc_mixer_card_class_init (GvcMixerCardClass *klass);
 67 static void     gvc_mixer_card_init       (GvcMixerCard      *mixer_card);
 68 static void     gvc_mixer_card_finalize   (GObject            *object);
 69 
 70 G_DEFINE_TYPE (GvcMixerCard, gvc_mixer_card, G_TYPE_OBJECT)
 71 
 72 static guint32
 73 get_next_card_serial (void)
 74 {
 75         guint32 serial;
 76 
 77         serial = card_serial++;
 78 
 79         if ((gint32)card_serial < 0) {
 80                 card_serial = 1;
 81         }
 82 
 83         return serial;
 84 }
 85 
 86 pa_context *
 87 gvc_mixer_card_get_pa_context (GvcMixerCard *card)
 88 {
 89         g_return_val_if_fail (GVC_IS_MIXER_CARD (card), 0);
 90         return card->priv->pa_context;
 91 }
 92 
 93 guint
 94 gvc_mixer_card_get_index (GvcMixerCard *card)
 95 {
 96         g_return_val_if_fail (GVC_IS_MIXER_CARD (card), 0);
 97         return card->priv->index;
 98 }
 99 
100 guint
101 gvc_mixer_card_get_id (GvcMixerCard *card)
102 {
103         g_return_val_if_fail (GVC_IS_MIXER_CARD (card), 0);
104         return card->priv->id;
105 }
106 
107 const char *
108 gvc_mixer_card_get_name (GvcMixerCard *card)
109 {
110         g_return_val_if_fail (GVC_IS_MIXER_CARD (card), NULL);
111         return card->priv->name;
112 }
113 
114 gboolean
115 gvc_mixer_card_set_name (GvcMixerCard *card,
116                          const char     *name)
117 {
118         g_return_val_if_fail (GVC_IS_MIXER_CARD (card), FALSE);
119 
120         g_free (card->priv->name);
121         card->priv->name = g_strdup (name);
122         g_object_notify (G_OBJECT (card), "name");
123 
124         return TRUE;
125 }
126 
127 const char *
128 gvc_mixer_card_get_icon_name (GvcMixerCard *card)
129 {
130         g_return_val_if_fail (GVC_IS_MIXER_CARD (card), NULL);
131         return card->priv->icon_name;
132 }
133 
134 gboolean
135 gvc_mixer_card_set_icon_name (GvcMixerCard *card,
136                               const char     *icon_name)
137 {
138         g_return_val_if_fail (GVC_IS_MIXER_CARD (card), FALSE);
139 
140         g_free (card->priv->icon_name);
141         card->priv->icon_name = g_strdup (icon_name);
142         g_object_notify (G_OBJECT (card), "icon-name");
143 
144         return TRUE;
145 }
146 
147 /**
148  * gvc_mixer_card_get_profile: (skip)
149  * @card:
150  *
151  * Returns:
152  */
153 GvcMixerCardProfile *
154 gvc_mixer_card_get_profile (GvcMixerCard *card)
155 {
156         GList *l;
157 
158         g_return_val_if_fail (GVC_IS_MIXER_CARD (card), NULL);
159         g_return_val_if_fail (card->priv->profiles != NULL, NULL);
160 
161         for (l = card->priv->profiles; l != NULL; l = l->next) {
162                 GvcMixerCardProfile *p = l->data;
163                 if (g_str_equal (card->priv->profile, p->profile)) {
164                         return p;
165                 }
166         }
167 
168         g_assert_not_reached ();
169 
170         return NULL;
171 }
172 
173 gboolean
174 gvc_mixer_card_set_profile (GvcMixerCard *card,
175                             const char     *profile)
176 {
177         GList *l;
178 
179         g_return_val_if_fail (GVC_IS_MIXER_CARD (card), FALSE);
180         g_return_val_if_fail (card->priv->profiles != NULL, FALSE);
181 
182         g_free (card->priv->profile);
183         card->priv->profile = g_strdup (profile);
184 
185         g_free (card->priv->human_profile);
186         card->priv->human_profile = NULL;
187 
188         for (l = card->priv->profiles; l != NULL; l = l->next) {
189                 GvcMixerCardProfile *p = l->data;
190                 if (g_str_equal (card->priv->profile, p->profile)) {
191                         card->priv->human_profile = g_strdup (p->human_profile);
192                         break;
193                 }
194         }
195 
196         g_object_notify (G_OBJECT (card), "profile");
197 
198         return TRUE;
199 }
200 
201 static void
202 _pa_context_set_card_profile_by_index_cb (pa_context                       *context,
203                                           int                               success,
204                                           void                             *userdata)
205 {
206         GvcMixerCard *card = GVC_MIXER_CARD (userdata);
207 
208         g_assert (card->priv->target_profile);
209 
210         if (success > 0) {
211                 gvc_mixer_card_set_profile (card, card->priv->target_profile);
212         } else {
213                 g_debug ("Failed to switch profile on '%s' from '%s' to '%s'",
214                          card->priv->name,
215                          card->priv->profile,
216                          card->priv->target_profile);
217         }
218         g_free (card->priv->target_profile);
219         card->priv->target_profile = NULL;
220 
221         pa_operation_unref (card->priv->profile_op);
222         card->priv->profile_op = NULL;
223 }
224 
225 gboolean
226 gvc_mixer_card_change_profile (GvcMixerCard *card,
227                                const char *profile)
228 {
229         g_return_val_if_fail (GVC_IS_MIXER_CARD (card), FALSE);
230         g_return_val_if_fail (card->priv->profiles != NULL, FALSE);
231 
232         /* Same profile, or already requested? */
233         if (g_strcmp0 (card->priv->profile, profile) == 0)
234                 return TRUE;
235         if (g_strcmp0 (profile, card->priv->target_profile) == 0)
236                 return TRUE;
237         if (card->priv->profile_op != NULL) {
238                 pa_operation_cancel (card->priv->profile_op);
239                 pa_operation_unref (card->priv->profile_op);
240                 card->priv->profile_op = NULL;
241         }
242 
243         if (card->priv->profile != NULL) {
244                 g_free (card->priv->target_profile);
245                 card->priv->target_profile = g_strdup (profile);
246 
247                 card->priv->profile_op = pa_context_set_card_profile_by_index (card->priv->pa_context,
248                                                                                card->priv->index,
249                                                                                card->priv->target_profile,
250                                                                                _pa_context_set_card_profile_by_index_cb,
251                                                                                card);
252 
253                 if (card->priv->profile_op == NULL) {
254                         g_warning ("pa_context_set_card_profile_by_index() failed");
255                         return FALSE;
256                 }
257         } else {
258                 g_assert (card->priv->human_profile == NULL);
259                 card->priv->profile = g_strdup (profile);
260         }
261 
262         return TRUE;
263 }
264 
265 /**
266  * gvc_mixer_card_get_profiles:
267  *
268  * Return value: (transfer none) (element-type GvcMixerCardProfile):
269  */
270 const GList *
271 gvc_mixer_card_get_profiles (GvcMixerCard *card)
272 {
273         g_return_val_if_fail (GVC_IS_MIXER_CARD (card), NULL);
274         return card->priv->profiles;
275 }
276 
277 static int
278 sort_profiles (GvcMixerCardProfile *a,
279                GvcMixerCardProfile *b)
280 {
281         if (a->priority == b->priority)
282                 return 0;
283         if (a->priority > b->priority)
284                 return 1;
285         return -1;
286 }
287 
288 /**
289  * gvc_mixer_card_set_profiles:
290  * @profiles: (transfer full) (element-type GvcMixerCardProfile):
291  */
292 gboolean
293 gvc_mixer_card_set_profiles (GvcMixerCard *card,
294                              GList        *profiles)
295 {
296         g_return_val_if_fail (GVC_IS_MIXER_CARD (card), FALSE);
297         g_return_val_if_fail (card->priv->profiles == NULL, FALSE);
298 
299         card->priv->profiles = g_list_sort (profiles, (GCompareFunc) sort_profiles);
300 
301         return TRUE;
302 }
303 
304 static void
305 gvc_mixer_card_set_property (GObject       *object,
306                              guint          prop_id,
307                              const GValue  *value,
308                              GParamSpec    *pspec)
309 {
310         GvcMixerCard *self = GVC_MIXER_CARD (object);
311 
312         switch (prop_id) {
313         case PROP_PA_CONTEXT:
314                 self->priv->pa_context = g_value_get_pointer (value);
315                 break;
316         case PROP_INDEX:
317                 self->priv->index = g_value_get_ulong (value);
318                 break;
319         case PROP_ID:
320                 self->priv->id = g_value_get_ulong (value);
321                 break;
322         case PROP_NAME:
323                 gvc_mixer_card_set_name (self, g_value_get_string (value));
324                 break;
325         case PROP_ICON_NAME:
326                 gvc_mixer_card_set_icon_name (self, g_value_get_string (value));
327                 break;
328         case PROP_PROFILE:
329                 gvc_mixer_card_set_profile (self, g_value_get_string (value));
330                 break;
331         default:
332                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
333                 break;
334         }
335 }
336 
337 static void
338 gvc_mixer_card_get_property (GObject     *object,
339                              guint        prop_id,
340                              GValue      *value,
341                              GParamSpec  *pspec)
342 {
343         GvcMixerCard *self = GVC_MIXER_CARD (object);
344 
345         switch (prop_id) {
346         case PROP_PA_CONTEXT:
347                 g_value_set_pointer (value, self->priv->pa_context);
348                 break;
349         case PROP_INDEX:
350                 g_value_set_ulong (value, self->priv->index);
351                 break;
352         case PROP_ID:
353                 g_value_set_ulong (value, self->priv->id);
354                 break;
355         case PROP_NAME:
356                 g_value_set_string (value, self->priv->name);
357                 break;
358         case PROP_ICON_NAME:
359                 g_value_set_string (value, self->priv->icon_name);
360                 break;
361         case PROP_PROFILE:
362                 g_value_set_string (value, self->priv->profile);
363                 break;
364         case PROP_HUMAN_PROFILE:
365                 g_value_set_string (value, self->priv->human_profile);
366                 break;
367         default:
368                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
369                 break;
370         }
371 }
372 
373 static GObject *
374 gvc_mixer_card_constructor (GType                  type,
375                             guint                  n_construct_properties,
376                             GObjectConstructParam *construct_params)
377 {
378         GObject       *object;
379         GvcMixerCard *self;
380 
381         object = G_OBJECT_CLASS (gvc_mixer_card_parent_class)->constructor (type, n_construct_properties, construct_params);
382 
383         self = GVC_MIXER_CARD (object);
384 
385         self->priv->id = get_next_card_serial ();
386 
387         return object;
388 }
389 
390 static void
391 gvc_mixer_card_class_init (GvcMixerCardClass *klass)
392 {
393         GObjectClass   *gobject_class = G_OBJECT_CLASS (klass);
394 
395         gobject_class->constructor = gvc_mixer_card_constructor;
396         gobject_class->finalize = gvc_mixer_card_finalize;
397 
398         gobject_class->set_property = gvc_mixer_card_set_property;
399         gobject_class->get_property = gvc_mixer_card_get_property;
400 
401         g_object_class_install_property (gobject_class,
402                                          PROP_INDEX,
403                                          g_param_spec_ulong ("index",
404                                                              "Index",
405                                                              "The index for this card",
406                                                              0, G_MAXULONG, 0,
407                                                              G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY));
408         g_object_class_install_property (gobject_class,
409                                          PROP_ID,
410                                          g_param_spec_ulong ("id",
411                                                              "id",
412                                                              "The id for this card",
413                                                              0, G_MAXULONG, 0,
414                                                              G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY));
415         g_object_class_install_property (gobject_class,
416                                          PROP_PA_CONTEXT,
417                                          g_param_spec_pointer ("pa-context",
418                                                                "PulseAudio context",
419                                                                "The PulseAudio context for this card",
420                                                                G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY));
421         g_object_class_install_property (gobject_class,
422                                          PROP_NAME,
423                                          g_param_spec_string ("name",
424                                                               "Name",
425                                                               "Name to display for this card",
426                                                               NULL,
427                                                               G_PARAM_READWRITE|G_PARAM_CONSTRUCT));
428         g_object_class_install_property (gobject_class,
429                                          PROP_ICON_NAME,
430                                          g_param_spec_string ("icon-name",
431                                                               "Icon Name",
432                                                               "Name of icon to display for this card",
433                                                               NULL,
434                                                               G_PARAM_READWRITE|G_PARAM_CONSTRUCT));
435         g_object_class_install_property (gobject_class,
436                                          PROP_PROFILE,
437                                          g_param_spec_string ("profile",
438                                                               "Profile",
439                                                               "Name of current profile for this card",
440                                                               NULL,
441                                                               G_PARAM_READWRITE));
442         g_object_class_install_property (gobject_class,
443                                          PROP_HUMAN_PROFILE,
444                                          g_param_spec_string ("human-profile",
445                                                               "Profile (Human readable)",
446                                                               "Name of current profile for this card in human readable form",
447                                                               NULL,
448                                                               G_PARAM_READABLE));
449 
450         g_type_class_add_private (klass, sizeof (GvcMixerCardPrivate));
451 }
452 
453 static void
454 gvc_mixer_card_init (GvcMixerCard *card)
455 {
456         card->priv = GVC_MIXER_CARD_GET_PRIVATE (card);
457 }
458 
459 GvcMixerCard *
460 gvc_mixer_card_new (pa_context *context,
461                     guint       index)
462 {
463         GObject *object;
464 
465         object = g_object_new (GVC_TYPE_MIXER_CARD,
466                                "index", index,
467                                "pa-context", context,
468                                NULL);
469         return GVC_MIXER_CARD (object);
470 }
471 
472 static void
473 free_profile (GvcMixerCardProfile *p)
474 {
475         g_free (p->profile);
476         g_free (p->human_profile);
477         g_free (p->status);
478         g_free (p);
479 }
480 
481 static void
482 gvc_mixer_card_finalize (GObject *object)
483 {
484         GvcMixerCard *mixer_card;
485 
486         g_return_if_fail (object != NULL);
487         g_return_if_fail (GVC_IS_MIXER_CARD (object));
488 
489         mixer_card = GVC_MIXER_CARD (object);
490 
491         g_return_if_fail (mixer_card->priv != NULL);
492 
493         g_free (mixer_card->priv->name);
494         mixer_card->priv->name = NULL;
495 
496         g_free (mixer_card->priv->icon_name);
497         mixer_card->priv->icon_name = NULL;
498 
499         g_free (mixer_card->priv->target_profile);
500         mixer_card->priv->target_profile = NULL;
501 
502         g_free (mixer_card->priv->profile);
503         mixer_card->priv->profile = NULL;
504 
505         g_free (mixer_card->priv->human_profile);
506         mixer_card->priv->human_profile = NULL;
507 
508         g_list_foreach (mixer_card->priv->profiles, (GFunc) free_profile, NULL);
509         g_list_free (mixer_card->priv->profiles);
510         mixer_card->priv->profiles = NULL;
511 
512         G_OBJECT_CLASS (gvc_mixer_card_parent_class)->finalize (object);
513 }