Add a GIcon accessor for GvcMixerUIDevices

This will allow to have different icons for internal audio cards
(which are flagged generically as "audio-card"), depending on which
port is in use (ie. headphones or speakers).
This requires the new icon information, which is only exported by
PulseAudio 3.0. If it's not available, we fallback to card icons
like before.

https://bugzilla.gnome.org/show_bug.cgi?id=689931
This commit is contained in:
Giovanni Campagna 2013-02-15 22:42:41 +01:00
parent 03894efbcd
commit 74c08620b4
5 changed files with 85 additions and 1 deletions

View File

@ -276,7 +276,6 @@ gvc_mixer_card_get_profiles (GvcMixerCard *card)
return card->priv->profiles; return card->priv->profiles;
} }
/** /**
* gvc_mixer_card_get_ports: * gvc_mixer_card_get_ports:
* *
@ -339,6 +338,17 @@ gvc_mixer_card_get_gicon (GvcMixerCard *card)
return g_themed_icon_new_with_default_fallbacks (card->priv->icon_name); return g_themed_icon_new_with_default_fallbacks (card->priv->icon_name);
} }
static void
free_port (GvcMixerCardPort *port)
{
g_free (port->port);
g_free (port->human_port);
g_free (port->icon_name);
g_list_free (port->profiles);
g_free (port);
}
/** /**
* gvc_mixer_card_set_ports: * gvc_mixer_card_set_ports:
* @ports: (transfer full) (element-type GvcMixerCardPort): * @ports: (transfer full) (element-type GvcMixerCardPort):
@ -350,6 +360,7 @@ gvc_mixer_card_set_ports (GvcMixerCard *card,
g_return_val_if_fail (GVC_IS_MIXER_CARD (card), FALSE); g_return_val_if_fail (GVC_IS_MIXER_CARD (card), FALSE);
g_return_val_if_fail (card->priv->ports == NULL, FALSE); g_return_val_if_fail (card->priv->ports == NULL, FALSE);
g_list_free_full (card->priv->ports, (GDestroyNotify) free_port);
card->priv->ports = ports; card->priv->ports = ports;
return TRUE; return TRUE;
@ -563,6 +574,9 @@ gvc_mixer_card_finalize (GObject *object)
g_list_free (mixer_card->priv->profiles); g_list_free (mixer_card->priv->profiles);
mixer_card->priv->profiles = NULL; mixer_card->priv->profiles = NULL;
g_list_free_full (mixer_card->priv->ports, (GDestroyNotify) free_port);
mixer_card->priv->ports = NULL;
G_OBJECT_CLASS (gvc_mixer_card_parent_class)->finalize (object); G_OBJECT_CLASS (gvc_mixer_card_parent_class)->finalize (object);
} }

View File

@ -62,6 +62,7 @@ typedef struct
{ {
char *port; char *port;
char *human_port; char *human_port;
char *icon_name;
guint priority; guint priority;
gint available; gint available;
gint direction; gint direction;

View File

@ -1911,6 +1911,7 @@ create_ui_device_from_port (GvcMixerControl* control,
"description", port->human_port, "description", port->human_port,
"origin", gvc_mixer_card_get_name (card), "origin", gvc_mixer_card_get_name (card),
"port-available", available, "port-available", available,
"icon-name", port->icon_name,
NULL); NULL);
uidevice = GVC_MIXER_UI_DEVICE (object); uidevice = GVC_MIXER_UI_DEVICE (object);
@ -2102,6 +2103,7 @@ update_card (GvcMixerControl *control,
port->priority = info->ports[i]->priority; port->priority = info->ports[i]->priority;
port->available = info->ports[i]->available; port->available = info->ports[i]->available;
port->direction = info->ports[i]->direction; port->direction = info->ports[i]->direction;
port->icon_name = g_strdup (pa_proplist_gets (info->ports[i]->proplist, "device.icon_name"));
port->profiles = determine_profiles_for_port (info->ports[i], profile_list); port->profiles = determine_profiles_for_port (info->ports[i], profile_list);
port_list = g_list_prepend (port_list, port); port_list = g_list_prepend (port_list, port);
} }

View File

@ -32,6 +32,7 @@ struct GvcMixerUIDevicePrivate
GvcMixerCard *card; GvcMixerCard *card;
gchar *port_name; gchar *port_name;
char *icon_name;
gint stream_id; gint stream_id;
guint id; guint id;
gboolean port_available; gboolean port_available;
@ -55,12 +56,16 @@ enum
PROP_STREAM_ID, PROP_STREAM_ID,
PROP_UI_DEVICE_TYPE, PROP_UI_DEVICE_TYPE,
PROP_PORT_AVAILABLE, PROP_PORT_AVAILABLE,
PROP_ICON_NAME,
}; };
static void gvc_mixer_ui_device_class_init (GvcMixerUIDeviceClass *klass); static void gvc_mixer_ui_device_class_init (GvcMixerUIDeviceClass *klass);
static void gvc_mixer_ui_device_init (GvcMixerUIDevice *device); static void gvc_mixer_ui_device_init (GvcMixerUIDevice *device);
static void gvc_mixer_ui_device_finalize (GObject *object); static void gvc_mixer_ui_device_finalize (GObject *object);
static void gvc_mixer_ui_device_set_icon_name (GvcMixerUIDevice *device,
const char *icon_name);
G_DEFINE_TYPE (GvcMixerUIDevice, gvc_mixer_ui_device, G_TYPE_OBJECT); G_DEFINE_TYPE (GvcMixerUIDevice, gvc_mixer_ui_device, G_TYPE_OBJECT);
static guint32 static guint32
@ -107,6 +112,9 @@ gvc_mixer_ui_device_get_property (GObject *object,
case PROP_PORT_AVAILABLE: case PROP_PORT_AVAILABLE:
g_value_set_boolean (value, self->priv->port_available); g_value_set_boolean (value, self->priv->port_available);
break; break;
case PROP_ICON_NAME:
g_value_set_string (value, gvc_mixer_ui_device_get_icon_name (self));
break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break; break;
@ -158,6 +166,9 @@ gvc_mixer_ui_device_set_property (GObject *object,
g_debug ("gvc-mixer-output-set-property - port available %i, value passed in %i \n", g_debug ("gvc-mixer-output-set-property - port available %i, value passed in %i \n",
self->priv->port_available, g_value_get_boolean (value)); self->priv->port_available, g_value_get_boolean (value));
break; break;
case PROP_ICON_NAME:
gvc_mixer_ui_device_set_icon_name (self, g_value_get_string (value));
break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break; break;
@ -197,6 +208,7 @@ gvc_mixer_ui_device_dispose (GObject *object)
device = GVC_MIXER_UI_DEVICE (object); device = GVC_MIXER_UI_DEVICE (object);
g_clear_pointer (&device->priv->port_name, g_free); g_clear_pointer (&device->priv->port_name, g_free);
g_clear_pointer (&device->priv->icon_name, g_free);
g_clear_pointer (&device->priv->first_line_desc, g_free); g_clear_pointer (&device->priv->first_line_desc, g_free);
g_clear_pointer (&device->priv->second_line_desc, g_free); g_clear_pointer (&device->priv->second_line_desc, g_free);
g_clear_pointer (&device->priv->profiles, g_list_free); g_clear_pointer (&device->priv->profiles, g_list_free);
@ -274,6 +286,13 @@ gvc_mixer_ui_device_class_init (GvcMixerUIDeviceClass *klass)
G_PARAM_READWRITE); G_PARAM_READWRITE);
g_object_class_install_property (object_class, PROP_PORT_AVAILABLE, pspec); g_object_class_install_property (object_class, PROP_PORT_AVAILABLE, pspec);
pspec = g_param_spec_string ("icon-name",
"Icon Name",
"Name of icon to display for this card",
NULL,
G_PARAM_READWRITE|G_PARAM_CONSTRUCT);
g_object_class_install_property (object_class, PROP_ICON_NAME, pspec);
g_type_class_add_private (klass, sizeof (GvcMixerUIDevicePrivate)); g_type_class_add_private (klass, sizeof (GvcMixerUIDevicePrivate));
} }
@ -601,6 +620,51 @@ gvc_mixer_ui_device_get_description (GvcMixerUIDevice *device)
return device->priv->first_line_desc; return device->priv->first_line_desc;
} }
const char *
gvc_mixer_ui_device_get_icon_name (GvcMixerUIDevice *device)
{
g_return_val_if_fail (GVC_IS_MIXER_UI_DEVICE (device), NULL);
if (device->priv->icon_name)
return device->priv->icon_name;
if (device->priv->card)
return gvc_mixer_card_get_icon_name (device->priv->card);
return NULL;
}
static void
gvc_mixer_ui_device_set_icon_name (GvcMixerUIDevice *device,
const char *icon_name)
{
g_return_if_fail (GVC_IS_MIXER_UI_DEVICE (device));
g_free (device->priv->icon_name);
device->priv->icon_name = g_strdup (icon_name);
g_object_notify (G_OBJECT (device), "icon-name");
}
/**
* gvc_mixer_ui_device_get_gicon:
* @device:
*
* Returns: (transfer full):
*/
GIcon *
gvc_mixer_ui_device_get_gicon (GvcMixerUIDevice *device)
{
const char *icon_name;
icon_name = gvc_mixer_ui_device_get_icon_name (device);
if (icon_name != NULL)
return g_themed_icon_new_with_default_fallbacks (icon_name);
else
return NULL;
}
const gchar * const gchar *
gvc_mixer_ui_device_get_origin (GvcMixerUIDevice *device) gvc_mixer_ui_device_get_origin (GvcMixerUIDevice *device)
{ {

View File

@ -20,6 +20,7 @@
#define _GVC_MIXER_UI_DEVICE_H_ #define _GVC_MIXER_UI_DEVICE_H_
#include <glib-object.h> #include <glib-object.h>
#include <gio/gio.h>
G_BEGIN_DECLS G_BEGIN_DECLS
@ -56,6 +57,8 @@ GType gvc_mixer_ui_device_get_type (void) G_GNUC_CONST;
guint gvc_mixer_ui_device_get_id (GvcMixerUIDevice *device); guint gvc_mixer_ui_device_get_id (GvcMixerUIDevice *device);
gint gvc_mixer_ui_device_get_stream_id (GvcMixerUIDevice *device); gint gvc_mixer_ui_device_get_stream_id (GvcMixerUIDevice *device);
const gchar * gvc_mixer_ui_device_get_description (GvcMixerUIDevice *device); const gchar * gvc_mixer_ui_device_get_description (GvcMixerUIDevice *device);
const gchar * gvc_mixer_ui_device_get_icon_name (GvcMixerUIDevice *device);
GIcon * gvc_mixer_ui_device_get_gicon (GvcMixerUIDevice *device);
const gchar * gvc_mixer_ui_device_get_origin (GvcMixerUIDevice *device); const gchar * gvc_mixer_ui_device_get_origin (GvcMixerUIDevice *device);
const gchar * gvc_mixer_ui_device_get_port (GvcMixerUIDevice *device); const gchar * gvc_mixer_ui_device_get_port (GvcMixerUIDevice *device);
const gchar * gvc_mixer_ui_device_get_best_profile (GvcMixerUIDevice *device, const gchar * gvc_mixer_ui_device_get_best_profile (GvcMixerUIDevice *device,