summaryrefslogtreecommitdiff
path: root/gst-mixer/src/element.c
diff options
context:
space:
mode:
Diffstat (limited to 'gst-mixer/src/element.c')
-rw-r--r--gst-mixer/src/element.c602
1 files changed, 0 insertions, 602 deletions
diff --git a/gst-mixer/src/element.c b/gst-mixer/src/element.c
deleted file mode 100644
index e02ffde..0000000
--- a/gst-mixer/src/element.c
+++ /dev/null
@@ -1,602 +0,0 @@
-/* MATE Volume Control
- * Copyright (C) 2003-2004 Ronald Bultje <[email protected]>
- *
- * element.c: widget representation of a single mixer element
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <string.h>
-#include <glib/gi18n.h>
-#include <gtk/gtk.h>
-
-#include "element.h"
-#include "schemas.h"
-#include "preferences.h"
-#include "track.h"
-#include "misc.h"
-#ifdef HAVE_SOUND_THEME
-#include "gvc-sound-theme-chooser.h"
-#endif
-
-G_DEFINE_TYPE (MateVolumeControlElement, mate_volume_control_element, GTK_TYPE_NOTEBOOK)
-
-static void mate_volume_control_element_class_init (MateVolumeControlElementClass *klass);
-static void mate_volume_control_element_init (MateVolumeControlElement *el);
-static void mate_volume_control_element_dispose (GObject *object);
-
-static void cb_gsettings (GSettings *settings,
- gchar *key,
- MateVolumeControlElement *el);
-
-static void
-mate_volume_control_element_class_init (MateVolumeControlElementClass *klass)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
-
- gobject_class->dispose = mate_volume_control_element_dispose;
-}
-
-static void
-mate_volume_control_element_init (MateVolumeControlElement *el)
-{
- el->settings = NULL;
- el->mixer = NULL;
-}
-
-GtkWidget *
-mate_volume_control_element_new ()
-{
- MateVolumeControlElement *el;
-
- /* element */
- el = g_object_new (MATE_VOLUME_CONTROL_TYPE_ELEMENT, NULL);
- el->settings = g_settings_new (MATE_VOLUME_CONTROL_SCHEMA);
-
- g_signal_connect (el->settings, "changed::" MATE_VOLUME_CONTROL_KEY_SHOWN_ELEMENTS,
- G_CALLBACK (cb_gsettings), el);
- g_signal_connect (el->settings, "changed::" MATE_VOLUME_CONTROL_KEY_HIDDEN_ELEMENTS,
- G_CALLBACK (cb_gsettings), el);
-
- return GTK_WIDGET (el);
-}
-
-static void
-mate_volume_control_element_dispose (GObject *object)
-{
- MateVolumeControlElement *el = MATE_VOLUME_CONTROL_ELEMENT (object);
-
- if (el->settings) {
- g_object_unref (G_OBJECT (el->settings));
- el->settings = NULL;
- }
-
- if (el->mixer) {
- /* remove g_timeout_add() mainloop handlers */
- mate_volume_control_element_change (el, NULL);
- gst_element_set_state (GST_ELEMENT (el->mixer), GST_STATE_NULL);
- gst_object_unref (GST_OBJECT (el->mixer));
- el->mixer = NULL;
- }
-
- G_OBJECT_CLASS (mate_volume_control_element_parent_class)->dispose (object);
-}
-
-/*
- * Checks if we want to show the track by default ("whitelist").
- */
-
-gboolean
-mate_volume_control_element_whitelist (GstMixer *mixer,
- GstMixerTrack *track)
-{
- gint i, pos;
- gboolean found = FALSE;
-
- /* Yes this is a hack. */
- static struct {
- gchar *label;
- gboolean done;
- } list[] = {
-
-/* Translator comment: the names below are a whitelist for which volume
- * controls to show by default. Make sure that those match the translations
- * of GStreamer-plugins' ALSA/OSS plugins. */
- { "cd", FALSE },
- { "line", FALSE },
- { "mic", FALSE },
- { "pcm", FALSE },
- { "headphone", FALSE },
- { "speaker", FALSE },
- { "volume", FALSE },
- { "master", FALSE },
- { "digital output", FALSE },
- { "recording", FALSE },
- { "front", FALSE },
- { NULL, FALSE }
- };
-
- /*
- * When the user changes devices, it is necessary to reset the whitelist
- * to a good default state. This fixes bugs LP:345645, 576022
- */
- if (track == NULL)
- {
- for (i = 0; list[i].label != NULL; i++)
- list[i].done = FALSE;
- return TRUE;
- }
-
- /* honor the mixer supplied hints about whitelisting if available */
- if (gst_mixer_get_mixer_flags (GST_MIXER (mixer)) & GST_MIXER_FLAG_HAS_WHITELIST) {
- if (GST_MIXER_TRACK_HAS_FLAG (track, GST_MIXER_TRACK_WHITELIST)) {
- return (TRUE);
- } else {
- return (FALSE);
- }
- }
-
- for (i = 0; !found && list[i].label != NULL; i++) {
- gchar *label_l = NULL;
-
- if (list[i].done)
- continue;
-
- /* make case insensitive */
- if (g_object_class_find_property (G_OBJECT_GET_CLASS (track), "untranslated-label"))
- g_object_get (track, "untranslated-label", &label_l, NULL);
- if (label_l == NULL)
- g_object_get (track, "label", &label_l, NULL);
- for (pos = 0; label_l[pos] != '\0'; pos++)
- label_l[pos] = g_ascii_tolower (label_l[pos]);
-
- if (g_strrstr (label_l, list[i].label) != NULL) {
- found = TRUE;
- list[i].done = TRUE;
- }
- g_free (label_l);
- }
-
- return found;
-}
-
-/*
- * Check if the element is to show
- */
-
-gboolean
-mate_volume_control_element_is_to_show (GSettings *settings,
- GstMixer *mixer,
- GstMixerTrack *track)
-{
- gboolean is_whitelist = FALSE;
- gboolean is_to_show = FALSE;
- gchar *name;
-
- mate_volume_control_element_whitelist (mixer, NULL);
- is_whitelist = mate_volume_control_element_whitelist (mixer, track);
- name = get_gsettings_name (mixer, track);
-
- if (is_whitelist == TRUE)
- {
- /* if element is in whitelis, user can set it hidden */
- if (schemas_is_str_in_strv (settings, MATE_VOLUME_CONTROL_KEY_HIDDEN_ELEMENTS, name) == FALSE)
- is_to_show = TRUE;
- }
- else
- {
- /* if element is not in whitelist, user can set it to show */
- if (schemas_is_str_in_strv (settings, MATE_VOLUME_CONTROL_KEY_SHOWN_ELEMENTS, name))
- is_to_show = TRUE;
- }
- g_free (name);
- return is_to_show;
-}
-
-/*
- * Hide/show notebook page.
- */
-
-static void
-update_tab_visibility (MateVolumeControlElement *el, gint page, gint tabnum)
-{
- const GList *item;
- gboolean visible = FALSE;
- GtkWidget *t;
-
- for (item = gst_mixer_list_tracks (el->mixer);
- item != NULL; item = item->next) {
- GstMixerTrack *track = item->data;
- MateVolumeControlTrack *trkw =
- g_object_get_data (G_OBJECT (track), "mate-volume-control-trkw");
-
- if (get_page_num (el->mixer, track) == page && trkw->visible) {
- visible = TRUE;
- break;
- }
- }
-
- t = gtk_notebook_get_nth_page (GTK_NOTEBOOK (el), tabnum);
- if (visible)
- gtk_widget_show (t);
- else
- gtk_widget_hide (t);
-}
-
-static void
-cb_notify_message (GstBus *bus, GstMessage *message, gpointer data)
-{
- MateVolumeControlElement *el = data;
- GstMixerMessageType type;
- MateVolumeControlTrack *trkw;
- GstMixerTrack *track = NULL;
- GstMixerOptions *options = NULL;
-
- if (GST_MESSAGE_SRC (message) != GST_OBJECT (el->mixer)) {
- /* not from our mixer - can't update anything anyway */
- return;
- }
-
- /* This code only calls refresh if the first_track changes, because the
- * refresh code only retrieves the current value from that track anyway */
- type = gst_mixer_message_get_type (message);
- if (type == GST_MIXER_MESSAGE_MUTE_TOGGLED) {
- gst_mixer_message_parse_mute_toggled (message, &track, NULL);
- } else if (type == GST_MIXER_MESSAGE_VOLUME_CHANGED) {
- gst_mixer_message_parse_volume_changed (message, &track, NULL, NULL);
- } else if (type == GST_MIXER_MESSAGE_OPTION_CHANGED) {
- gst_mixer_message_parse_option_changed (message, &options, NULL);
- track = GST_MIXER_TRACK (options);
- } else {
- return;
- }
-
- trkw = g_object_get_data (G_OBJECT (track),
- "mate-volume-control-trkw");
-
- mate_volume_control_track_update (trkw);
-}
-
-/*
- * Change the element. Basically recreates this object internally.
- */
-
-void
-mate_volume_control_element_change (MateVolumeControlElement *el,
- GstElement *element)
-{
- struct {
- GtkWidget *page, *old_sep, *new_sep, *flagbuttonbox;
- gboolean use;
- gint pos, height, width;
- MateVolumeControlTrack * (* get_track_widget) (GtkTable *table,
- gint tab_pos,
- GstMixer *mixer,
- GstMixerTrack *track,
- GtkWidget *left_sep,
- GtkWidget *right_sep,
- GtkWidget *flagbox);
-
- } content[4] = {
- { NULL, NULL, NULL, NULL, FALSE, 0, 5, 1,
- mate_volume_control_track_add_playback },
- { NULL, NULL, NULL, NULL, FALSE, 0, 5, 1,
- mate_volume_control_track_add_recording },
- { NULL, NULL, NULL, NULL, FALSE, 0, 1, 3,
- mate_volume_control_track_add_playback },
- { NULL, NULL, NULL, NULL, FALSE, 0, 1, 3,
- mate_volume_control_track_add_option }
- };
- static gboolean theme_page = FALSE;
- const GList *item;
- GstMixer *mixer;
- GstBus *bus;
- gint i;
-
- /* remove old pages, but not the "Sound Theme" page */
- i = 0;
- if (theme_page)
- i = 1;
-
- while (gtk_notebook_get_n_pages (GTK_NOTEBOOK (el)) > i) {
- gtk_notebook_remove_page (GTK_NOTEBOOK (el), 0);
- }
-
- /* take/put reference */
- if (el->mixer) {
- for (item = gst_mixer_list_tracks (el->mixer);
- item != NULL; item = item->next) {
- GstMixerTrack *track = item->data;
- MateVolumeControlTrack *trkw;
-
- trkw = g_object_get_data (G_OBJECT (track),
- "mate-volume-control-trkw");
- g_object_set_data (G_OBJECT (track), "mate-volume-control-trkw", NULL);
- mate_volume_control_track_free (trkw);
- }
- }
- if (!element)
- return;
-
- g_return_if_fail (GST_IS_MIXER (element));
- mixer = GST_MIXER (element);
- gst_object_replace ((GstObject **) &el->mixer, GST_OBJECT (element));
-
- /* Bus for notifications */
- if (GST_ELEMENT_BUS (mixer) == NULL) {
- bus = gst_bus_new ();
- gst_bus_add_signal_watch (bus);
- g_signal_connect (G_OBJECT (bus), "message::element",
- (GCallback) cb_notify_message, el);
- gst_element_set_bus (GST_ELEMENT (mixer), bus);
- }
-
- /* content pages */
- for (i = 0; i < 4; i++) {
- content[i].page = gtk_table_new (content[i].width, content[i].height, FALSE);
- gtk_container_set_border_width (GTK_CONTAINER (content[i].page), 6);
- if (i >= 2)
- gtk_table_set_row_spacings (GTK_TABLE (content[i].page), 6);
- gtk_table_set_col_spacings (GTK_TABLE (content[i].page), 6);
- content[i].flagbuttonbox = NULL;
- }
-
- /* show */
- mate_volume_control_element_whitelist (el->mixer, NULL);
- for (item = gst_mixer_list_tracks (el->mixer);
- item != NULL; item = item->next) {
- GstMixerTrack *track = item->data;
- MateVolumeControlTrack *trkw;
-
- gboolean active;
-
- i = get_page_num (el->mixer, track);
-
- /* FIXME:
- * - do not create separator if there is no more track
- * _of this type_. We currently destroy it at the
- * end, so it's not critical, but not nice either.
- */
- if (i == 3) {
- content[i].new_sep = gtk_hseparator_new ();
- } else if (i < 2) {
- content[i].new_sep = gtk_vseparator_new ();
- } else {
- content[i].new_sep = NULL;
- }
-
- /* visible? */
- active = mate_volume_control_element_is_to_show (el->settings, mixer, track);
-
- /* Show left separator if we're not the first track */
- if (active && content[i].use && content[i].old_sep) {
-
- /* Do not show separator for switches/options on Playback/Recording tab */
- if (i < 2 && track->num_channels != 0) {
- gtk_widget_show (content[i].old_sep);
- }
- }
-
- /* widget */
- trkw = content[i].get_track_widget (GTK_TABLE (content[i].page),
- content[i].pos++, el->mixer, track,
- content[i].old_sep, content[i].new_sep,
- content[i].flagbuttonbox);
- mate_volume_control_track_show (trkw, active);
-
- /* Only the first trkw on the page will return flagbuttonbox */
- if (trkw->flagbuttonbox != NULL)
- content[i].flagbuttonbox = trkw->flagbuttonbox;
- g_object_set_data (G_OBJECT (track),
- "mate-volume-control-trkw", trkw);
-
- /* separator */
- if (item->next != NULL && content[i].new_sep) {
- if (i >= 2) {
- gtk_table_attach (GTK_TABLE (content[i].page), content[i].new_sep,
- 0, 3, content[i].pos, content[i].pos + 1,
- GTK_SHRINK | GTK_FILL, 0, 0, 0);
- } else {
- gtk_table_attach (GTK_TABLE (content[i].page), content[i].new_sep,
- content[i].pos, content[i].pos + 1, 0, 6,
- 0, GTK_SHRINK | GTK_FILL, 0, 0);
- }
- content[i].pos++;
- }
-
- content[i].old_sep = content[i].new_sep;
-
- if (active) {
- content[i].use = TRUE;
- }
- }
-
- /* show - need to build the tabs backwards so that deleting the "Sound Theme"
- * page can be avoided.
- */
- for (i = 3; i >= 0; i--) {
- GtkWidget *label, *view, *viewport;
- GtkAdjustment *hadjustment, *vadjustment;
-
- /* don't show last separator */
- if (content[i].new_sep)
- gtk_widget_destroy (content[i].new_sep);
-
- /* viewport for lots of tracks */
- view = gtk_scrolled_window_new (NULL, NULL);
- gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (view),
- i >= 2 ? GTK_POLICY_NEVER :
- GTK_POLICY_AUTOMATIC,
- i >= 2 ? GTK_POLICY_AUTOMATIC :
- GTK_POLICY_NEVER);
-
- hadjustment = gtk_scrolled_window_get_hadjustment (GTK_SCROLLED_WINDOW (view));
- vadjustment = gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (view));
- viewport = gtk_viewport_new (hadjustment, vadjustment);
- gtk_viewport_set_shadow_type (GTK_VIEWPORT (viewport), GTK_SHADOW_NONE);
-
- if (content[i].flagbuttonbox != NULL) {
- GtkWidget *vbox = NULL;
- GtkWidget *hbox = NULL;
- GtkWidget *hbox2 = NULL;
- GtkWidget *separator = NULL;
-
- if (i < 2) {
- vbox = gtk_vbox_new (FALSE, 0);
- hbox = gtk_hbox_new (FALSE, 6);
- hbox2 = gtk_hbox_new (FALSE, 6);
- separator = gtk_hseparator_new ();
- gtk_box_pack_start (GTK_BOX (vbox), content[i].page, TRUE, TRUE, 6);
- gtk_box_pack_start (GTK_BOX (vbox), hbox2, FALSE, FALSE, 6);
- gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 6);
- gtk_box_pack_start (GTK_BOX (hbox2), separator, TRUE, TRUE, 6);
- gtk_box_pack_start (GTK_BOX (hbox), content[i].flagbuttonbox, TRUE,
- FALSE, 6);
- } else {
- /* orientation is rotated for these ... */
- vbox = gtk_hbox_new (FALSE, 0);
- hbox = gtk_vbox_new (FALSE, 0);
- hbox2 = gtk_vbox_new (FALSE, 0);
- gtk_box_pack_start (GTK_BOX (vbox), content[i].page, FALSE, FALSE, 6);
- gtk_box_pack_start (GTK_BOX (vbox), hbox2, FALSE, FALSE, 6);
- gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, FALSE, 6);
- gtk_box_pack_start (GTK_BOX (hbox), content[i].flagbuttonbox, TRUE,
- FALSE, 6);
- }
- gtk_widget_show_all (hbox2);
- gtk_widget_show (content[i].flagbuttonbox);
- gtk_widget_show (hbox);
- gtk_widget_show (content[i].page);
- gtk_widget_show (vbox);
-
- gtk_container_add (GTK_CONTAINER (viewport), vbox);
- gtk_container_add (GTK_CONTAINER (view), viewport);
- } else {
- gtk_container_add (GTK_CONTAINER (viewport), content[i].page);
- gtk_container_add (GTK_CONTAINER (view), viewport);
- }
-
- label = gtk_label_new (get_page_description (i));
- gtk_notebook_prepend_page (GTK_NOTEBOOK (el), view, label);
- gtk_widget_show (content[i].page);
- gtk_widget_show (viewport);
- gtk_widget_show (view);
- gtk_widget_show (label);
-
- update_tab_visibility (el, i, 0);
- }
-
- /* refresh fix */
- for (i = gtk_notebook_get_n_pages (GTK_NOTEBOOK (el)) - 1;
- i >= 0; i--) {
- gtk_notebook_set_current_page (GTK_NOTEBOOK (el), i);
- }
-
-#ifdef HAVE_SOUND_THEME
- /* Add tab for managing themes */
- if (!theme_page) {
- theme_page = TRUE;
- GtkWidget *label, *view, *viewport, *sound_theme_chooser, *vbox;
- GtkAdjustment *hadjustment, *vadjustment;
-
- label = gtk_label_new (_("Sound Theme"));
-
- view = gtk_scrolled_window_new (NULL, NULL);
- gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (view),
- GTK_POLICY_AUTOMATIC,
- GTK_POLICY_AUTOMATIC);
-
- hadjustment = gtk_scrolled_window_get_hadjustment (GTK_SCROLLED_WINDOW (view));
- vadjustment = gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (view));
- viewport = gtk_viewport_new (hadjustment, vadjustment);
- gtk_viewport_set_shadow_type (GTK_VIEWPORT (viewport), GTK_SHADOW_NONE);
- gtk_viewport_set_shadow_type (GTK_VIEWPORT (viewport), GTK_SHADOW_NONE);
-
- sound_theme_chooser = gvc_sound_theme_chooser_new ();
- vbox = gtk_vbox_new (FALSE, 0);
- gtk_box_pack_start (GTK_BOX (vbox), sound_theme_chooser, TRUE, TRUE, 6);
- gtk_container_add (GTK_CONTAINER (viewport), vbox);
- gtk_container_add (GTK_CONTAINER (view), viewport);
-
- gtk_widget_show_all (vbox);
- gtk_widget_show (sound_theme_chooser);
- gtk_widget_show (viewport);
- gtk_widget_show (view);
- gtk_widget_show (label);
-
- gtk_notebook_append_page (GTK_NOTEBOOK (el), view, label);
- }
-#endif
-}
-
-/*
- * GSettings callback.
- */
-
-static void
-cb_gsettings (GSettings *settings,
- gchar *key,
- MateVolumeControlElement *el)
-{
- const GList *item;
-
- for (item = gst_mixer_list_tracks (el->mixer); item != NULL; item = item->next)
- {
- GstMixerTrack *track = item->data;
- MateVolumeControlTrack *trkw =
- g_object_get_data (G_OBJECT (track), "mate-volume-control-trkw");
-
- gboolean active = mate_volume_control_element_is_to_show (el->settings, el->mixer, track);
-
- if (active != trkw->visible) {
- gboolean first[4] = { TRUE, TRUE, TRUE, TRUE };
- gint n, page = get_page_num (el->mixer, track);
-
- mate_volume_control_track_show (trkw, active);
-
- /* separators */
- for (item = gst_mixer_list_tracks (el->mixer); item != NULL; item = item->next)
- {
- GstMixerTrack *track = item->data;
- MateVolumeControlTrack *trkw =
- g_object_get_data (G_OBJECT (track), "mate-volume-control-trkw");
-
- n = get_page_num (el->mixer, track);
- if (trkw->visible && !first[n]) {
- if (trkw->left_separator) {
- if (n < 2 && track->num_channels == 0) {
- gtk_widget_hide (trkw->left_separator);
- } else {
- gtk_widget_show (trkw->left_separator);
- }
- }
- } else {
- if (trkw->left_separator)
- gtk_widget_hide (trkw->left_separator);
- }
-
- if (trkw->visible && first[n])
- first[n] = FALSE;
- }
- update_tab_visibility (el, page, page);
- break;
- }
- }
-}