diff options
Diffstat (limited to 'gst-mixer/src/element.c')
-rw-r--r-- | gst-mixer/src/element.c | 602 |
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; - } - } -} |