diff options
Diffstat (limited to 'mate-volume-control/src')
21 files changed, 0 insertions, 8709 deletions
diff --git a/mate-volume-control/src/Makefile.am b/mate-volume-control/src/Makefile.am deleted file mode 100644 index 38f63ea..0000000 --- a/mate-volume-control/src/Makefile.am +++ /dev/null @@ -1,73 +0,0 @@ -NULL = - -bin_PROGRAMS = \ - mate-volume-control-applet \ - mate-volume-control \ - $(NULL) - -AM_CPPFLAGS = \ - $(WARN_CFLAGS) \ - -I$(top_srcdir)/sound-theme \ - $(VOLUME_CONTROL_CFLAGS) \ - $(DISABLE_DEPRECATED) \ - -DLOCALE_DIR=\""$(datadir)/locale"\" \ - -DLIBEXECDIR=\"$(libexecdir)\" \ - -DGLADEDIR=\""$(pkgdatadir)"\" \ - -DICON_DATA_DIR="\"$(pkgdatadir)/icons\"" \ - $(NULL) - -noinst_LTLIBRARIES = libmatevolumecontrol.la -libmatevolumecontrol_la_SOURCES = \ - gvc-channel-bar.h \ - gvc-channel-bar.c \ - gvc-utils.c \ - gvc-utils.h \ - $(NULL) - -mate_volume_control_applet_LDADD = \ - -lm \ - libmatevolumecontrol.la \ - $(VOLUME_CONTROL_LIBS) \ - $(NULL) - -mate_volume_control_applet_SOURCES = \ - gvc-stream-status-icon.h \ - gvc-stream-status-icon.c \ - gvc-applet.h \ - gvc-applet.c \ - applet-main.c \ - $(NULL) - -mate_volume_control_LDADD = \ - -lm \ - libmatevolumecontrol.la \ - $(top_builddir)/sound-theme/libsoundtheme.la \ - $(VOLUME_CONTROL_LIBS) \ - $(NULL) - -mate_volume_control_SOURCES = \ - gvc-balance-bar.h \ - gvc-balance-bar.c \ - gvc-level-bar.h \ - gvc-level-bar.c \ - gvc-combo-box.h \ - gvc-combo-box.c \ - gvc-speaker-test.h \ - gvc-speaker-test.c \ - gvc-mixer-dialog.h \ - gvc-mixer-dialog.c \ - dialog-main.c \ - $(NULL) - -BUILT_SOURCES = \ - $(NULL) - -CLEANFILES = \ - $(BUILT_SOURCES) \ - $(NULL) - -MAINTAINERCLEANFILES = \ - *~ \ - Makefile.in - --include $(top_srcdir)/git.mk diff --git a/mate-volume-control/src/applet-main.c b/mate-volume-control/src/applet-main.c deleted file mode 100644 index 1b4bb0a..0000000 --- a/mate-volume-control/src/applet-main.c +++ /dev/null @@ -1,94 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- - * - * Copyright (C) 2008 Red Hat, Inc. - * Copyright (C) 2014 Michal Ratajsky <[email protected]> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -#include "config.h" - -#include <glib.h> -#include <glib/gi18n.h> -#include <glib-object.h> -#include <gtk/gtk.h> - -#include <libintl.h> -#include <unique/uniqueapp.h> -#include <libmatemixer/matemixer.h> - -#include "gvc-applet.h" - -static gboolean show_version = FALSE; -static gboolean debug = FALSE; - -int -main (int argc, char **argv) -{ - GError *error = NULL; - GvcApplet *applet; - UniqueApp *app; - GOptionEntry entries[] = { - { "version", 'v', 0, G_OPTION_ARG_NONE, &show_version, N_("Version of this application"), NULL }, - { "debug", 'd', 0, G_OPTION_ARG_NONE, &debug, N_("Enable debug"), NULL }, - { NULL } - }; - - bindtextdomain (GETTEXT_PACKAGE, LOCALE_DIR); - bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); - textdomain (GETTEXT_PACKAGE); - - gtk_init_with_args (&argc, &argv, - _(" — MATE Volume Control Applet"), - entries, GETTEXT_PACKAGE, - &error); - - if (error != NULL) { - g_warning ("%s", error->message); - return 1; - } - if (show_version == TRUE) { - g_print ("%s %s\n", argv[0], VERSION); - return 0; - } - if (debug == TRUE) { - g_setenv ("G_MESSAGES_DEBUG", "all", FALSE); - } - - app = unique_app_new (GVC_APPLET_DBUS_NAME, NULL); - - if (unique_app_is_running (app) == TRUE) { - g_warning ("Applet is already running, exiting"); - return 0; - } - if (mate_mixer_init () == FALSE) { - g_warning ("libmatemixer initialization failed, exiting"); - return 1; - } - - gtk_icon_theme_append_search_path (gtk_icon_theme_get_default (), - ICON_DATA_DIR); - - applet = gvc_applet_new (); - - gvc_applet_start (applet); - gtk_main (); - - g_object_unref (applet); - g_object_unref (app); - - return 0; -} diff --git a/mate-volume-control/src/dialog-main.c b/mate-volume-control/src/dialog-main.c deleted file mode 100644 index 08c55fc..0000000 --- a/mate-volume-control/src/dialog-main.c +++ /dev/null @@ -1,274 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- - * - * Copyright (C) 2008 Red Hat, Inc. - * Copyright (C) 2014 Michal Ratajsky <[email protected]> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -#include "config.h" - -#include <glib.h> -#include <glib/gi18n.h> -#include <gtk/gtk.h> - -#include <libintl.h> -#include <unique/uniqueapp.h> -#include <libmatemixer/matemixer.h> - -#include "gvc-mixer-dialog.h" - -#define DIALOG_POPUP_TIMEOUT 3 - -static guint popup_id = 0; -static gboolean debug = FALSE; -static gboolean show_version = FALSE; - -static gchar *page = NULL; -static GtkWidget *app_dialog = NULL; -static GtkWidget *warning_dialog = NULL; - -static void -on_dialog_response (GtkDialog *dialog, guint response_id, gpointer data) -{ - gboolean destroy = GPOINTER_TO_INT (data); - - if (destroy == TRUE) - gtk_widget_destroy (GTK_WIDGET (dialog)); - - gtk_main_quit (); -} - -static void -on_dialog_close (GtkDialog *dialog, gpointer data) -{ - gboolean destroy = GPOINTER_TO_INT (data); - - if (destroy == TRUE) - gtk_widget_destroy (GTK_WIDGET (dialog)); - - gtk_main_quit (); -} - -static UniqueResponse -on_app_message_received (UniqueApp *app, - int command, - UniqueMessageData *message_data, - guint time_, - gpointer user_data) -{ - gtk_window_present (GTK_WINDOW (user_data)); - - return UNIQUE_RESPONSE_OK; -} - -static void -remove_warning_dialog (void) -{ - if (popup_id != 0) { - g_source_remove (popup_id); - popup_id = 0; - } - - g_clear_pointer (&warning_dialog, gtk_widget_destroy); -} - -static void -context_ready (MateMixerContext *context, UniqueApp *app) -{ - /* The dialog might be already created, e.g. when reconnected - * to a sound server */ - if (app_dialog != NULL) - return; - - app_dialog = GTK_WIDGET (gvc_mixer_dialog_new (context)); - - g_signal_connect (G_OBJECT (app_dialog), - "response", - G_CALLBACK (on_dialog_response), - GINT_TO_POINTER (FALSE)); - g_signal_connect (G_OBJECT (app_dialog), - "close", - G_CALLBACK (on_dialog_close), - GINT_TO_POINTER (FALSE)); - - gvc_mixer_dialog_set_page (GVC_MIXER_DIALOG (app_dialog), page); - - g_signal_connect (G_OBJECT (app), - "message-received", - G_CALLBACK (on_app_message_received), - app_dialog); - - gtk_widget_show (app_dialog); -} - -static void -on_context_state_notify (MateMixerContext *context, - GParamSpec *pspec, - UniqueApp *app) -{ - MateMixerState state = mate_mixer_context_get_state (context); - - if (state == MATE_MIXER_STATE_READY) { - remove_warning_dialog (); - context_ready (context, app); - } - else if (state == MATE_MIXER_STATE_FAILED) { - GtkWidget *dialog; - - remove_warning_dialog (); - - dialog = gtk_message_dialog_new (GTK_WINDOW (app_dialog), - 0, - GTK_MESSAGE_ERROR, - GTK_BUTTONS_CLOSE, - _("Sound system is not available")); - - g_signal_connect (G_OBJECT (dialog), - "response", - G_CALLBACK (on_dialog_response), - GINT_TO_POINTER (TRUE)); - g_signal_connect (G_OBJECT (dialog), - "close", - G_CALLBACK (on_dialog_close), - GINT_TO_POINTER (TRUE)); - - gtk_widget_show (dialog); - } -} - -static gboolean -dialog_popup_timeout (gpointer data) -{ - warning_dialog = gtk_message_dialog_new (GTK_WINDOW (app_dialog), - 0, - GTK_MESSAGE_INFO, - GTK_BUTTONS_CANCEL, - _("Waiting for sound system to respond")); - - g_signal_connect (G_OBJECT (warning_dialog), - "response", - G_CALLBACK (on_dialog_response), - GINT_TO_POINTER (TRUE)); - g_signal_connect (G_OBJECT (warning_dialog), - "close", - G_CALLBACK (on_dialog_close), - GINT_TO_POINTER (TRUE)); - - gtk_widget_show (warning_dialog); - - return FALSE; -} - -int -main (int argc, char **argv) -{ - GError *error = NULL; - gchar *backend = NULL; - MateMixerContext *context; - UniqueApp *app; - GOptionEntry entries[] = { - { "backend", 'b', 0, G_OPTION_ARG_STRING, &backend, N_("Sound system backend"), "pulse|alsa|oss|null" }, - { "debug", 'd', 0, G_OPTION_ARG_NONE, &debug, N_("Enable debug"), NULL }, - { "page", 'p', 0, G_OPTION_ARG_STRING, &page, N_("Startup page"), "effects|hardware|input|output|applications" }, - { "version", 'v', 0, G_OPTION_ARG_NONE, &show_version, N_("Version of this application"), NULL }, - { NULL } - }; - - bindtextdomain (GETTEXT_PACKAGE, LOCALE_DIR); - bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); - textdomain (GETTEXT_PACKAGE); - - gtk_init_with_args (&argc, &argv, - _(" — MATE Volume Control"), - entries, GETTEXT_PACKAGE, - &error); - - if (error != NULL) { - g_warning ("%s", error->message); - return 1; - } - if (show_version == TRUE) { - g_print ("%s %s\n", argv[0], VERSION); - return 0; - } - if (debug == TRUE) { - g_setenv ("G_MESSAGES_DEBUG", "all", FALSE); - } - - app = unique_app_new (GVC_DIALOG_DBUS_NAME, NULL); - - if (unique_app_is_running (app) == TRUE) { - unique_app_send_message (app, UNIQUE_ACTIVATE, NULL); - return 0; - } - if (mate_mixer_init () == FALSE) { - g_warning ("libmatemixer initialization failed, exiting"); - return 1; - } - - context = mate_mixer_context_new (); - - if (backend != NULL) { - if (strcmp (backend, "pulse") == 0) - mate_mixer_context_set_backend_type (context, MATE_MIXER_BACKEND_PULSEAUDIO); - else if (strcmp (backend, "alsa") == 0) - mate_mixer_context_set_backend_type (context, MATE_MIXER_BACKEND_ALSA); - else if (strcmp (backend, "oss") == 0) - mate_mixer_context_set_backend_type (context, MATE_MIXER_BACKEND_OSS); - else if (strcmp (backend, "null") == 0) - mate_mixer_context_set_backend_type (context, MATE_MIXER_BACKEND_NULL); - else { - g_warning ("Invalid backend: %s", backend); - g_object_unref (context); - g_object_unref (app); - g_free (backend); - return 1; - } - - g_free (backend); - } - - mate_mixer_context_set_app_name (context, _("Volume Control")); - mate_mixer_context_set_app_id (context, GVC_DIALOG_DBUS_NAME); - mate_mixer_context_set_app_version (context, VERSION); - mate_mixer_context_set_app_icon (context, "multimedia-volume-control"); - - g_signal_connect (G_OBJECT (context), - "notify::state", - G_CALLBACK (on_context_state_notify), - app); - - mate_mixer_context_open (context); - - if (mate_mixer_context_get_state (context) == MATE_MIXER_STATE_CONNECTING) { - popup_id = g_timeout_add_seconds (DIALOG_POPUP_TIMEOUT, - dialog_popup_timeout, - NULL); - } - - gtk_icon_theme_append_search_path (gtk_icon_theme_get_default (), - ICON_DATA_DIR); - - gtk_window_set_default_icon_name ("multimedia-volume-control"); - - gtk_main (); - - g_object_unref (context); - g_object_unref (app); - - return 0; -} diff --git a/mate-volume-control/src/gvc-applet.c b/mate-volume-control/src/gvc-applet.c deleted file mode 100644 index 3cb691f..0000000 --- a/mate-volume-control/src/gvc-applet.c +++ /dev/null @@ -1,357 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- - * - * Copyright (C) 2008 Red Hat, Inc. - * Copyright (C) 2014 Michal Ratajsky <[email protected]> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ - -#include "config.h" - -#include <string.h> -#include <glib.h> -#include <glib/gi18n.h> -#include <glib-object.h> -#include <gtk/gtk.h> - -#include <libmatemixer/matemixer.h> - -#include "gvc-applet.h" -#include "gvc-stream-status-icon.h" - -#define GVC_APPLET_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GVC_TYPE_APPLET, GvcAppletPrivate)) - -static const gchar *icon_names_output[] = { - "audio-volume-muted", - "audio-volume-low", - "audio-volume-medium", - "audio-volume-high", - NULL -}; - -static const gchar *icon_names_input[] = { - "audio-input-microphone-muted", - "audio-input-microphone-low", - "audio-input-microphone-medium", - "audio-input-microphone-high", - NULL -}; - -struct _GvcAppletPrivate -{ - GvcStreamStatusIcon *icon_input; - GvcStreamStatusIcon *icon_output; - gboolean running; - MateMixerContext *context; - MateMixerStream *input; -}; - -static void gvc_applet_class_init (GvcAppletClass *klass); -static void gvc_applet_init (GvcApplet *applet); - -G_DEFINE_TYPE (GvcApplet, gvc_applet, G_TYPE_OBJECT) - -static void -update_icon_input (GvcApplet *applet) -{ - MateMixerStreamControl *control = NULL; - gboolean show = FALSE; - - /* Enable the input icon in case there is an input stream present and there - * is a non-mixer application using the input */ - if (applet->priv->input != NULL) { - const gchar *app_id; - const GList *inputs = - mate_mixer_stream_list_controls (applet->priv->input); - - control = mate_mixer_stream_get_default_control (applet->priv->input); - - while (inputs != NULL) { - MateMixerStreamControl *input = - MATE_MIXER_STREAM_CONTROL (inputs->data); - MateMixerStreamControlRole role = - mate_mixer_stream_control_get_role (input); - - if (role == MATE_MIXER_STREAM_CONTROL_ROLE_APPLICATION) { - MateMixerAppInfo *app_info = - mate_mixer_stream_control_get_app_info (input); - - app_id = mate_mixer_app_info_get_id (app_info); - if (app_id == NULL) { - /* A recording application which has no - * identifier set */ - g_debug ("Found a recording application control %s", - mate_mixer_stream_control_get_label (input)); - - if G_UNLIKELY (control == NULL) { - /* In the unlikely case when there is no - * default input control, use the application - * control for the icon */ - control = input; - } - show = TRUE; - break; - } - - if (strcmp (app_id, "org.mate.VolumeControl") != 0 && - strcmp (app_id, "org.gnome.VolumeControl") != 0 && - strcmp (app_id, "org.PulseAudio.pavucontrol") != 0) { - g_debug ("Found a recording application %s", app_id); - - if G_UNLIKELY (control == NULL) - control = input; - - show = TRUE; - break; - } - } - inputs = inputs->next; - } - - if (show == TRUE) - g_debug ("Input icon enabled"); - else - g_debug ("There is no recording application, input icon disabled"); - } - - gvc_stream_status_icon_set_control (applet->priv->icon_input, control); - - gtk_status_icon_set_visible (GTK_STATUS_ICON (applet->priv->icon_input), show); -} - -static void -update_icon_output (GvcApplet *applet) -{ - MateMixerStream *stream; - MateMixerStreamControl *control = NULL; - - stream = mate_mixer_context_get_default_output_stream (applet->priv->context); - if (stream != NULL) - control = mate_mixer_stream_get_default_control (stream); - - gvc_stream_status_icon_set_control (applet->priv->icon_output, control); - - if (control != NULL) { - g_debug ("Output icon enabled"); - gtk_status_icon_set_visible (GTK_STATUS_ICON (applet->priv->icon_output), - TRUE); - } - else { - g_debug ("There is no output stream/control, output icon disabled"); - gtk_status_icon_set_visible (GTK_STATUS_ICON (applet->priv->icon_output), - FALSE); - } -} - -static void -on_input_stream_control_added (MateMixerStream *stream, - const gchar *name, - GvcApplet *applet) -{ - MateMixerStreamControl *control; - - control = mate_mixer_stream_get_control (stream, name); - if G_LIKELY (control != NULL) { - MateMixerStreamControlRole role = - mate_mixer_stream_control_get_role (control); - - /* Non-application input control doesn't affect the icon */ - if (role != MATE_MIXER_STREAM_CONTROL_ROLE_APPLICATION) - return; - } - - /* Either an application control has been added or we couldn't - * read the control, this shouldn't happen but let's revalidate the - * icon to be sure if it does */ - update_icon_input (applet); -} - -static void -on_input_stream_control_removed (MateMixerStream *stream, - const gchar *name, - GvcApplet *applet) -{ - /* The removed stream could be an application input, which may cause - * the input status icon to disappear */ - update_icon_input (applet); -} - -static gboolean -update_default_input_stream (GvcApplet *applet) -{ - MateMixerStream *stream; - - stream = mate_mixer_context_get_default_input_stream (applet->priv->context); - if (stream == applet->priv->input) - return FALSE; - - /* The input stream has changed */ - if (applet->priv->input != NULL) { - g_signal_handlers_disconnect_by_data (G_OBJECT (applet->priv->input), - applet); - g_object_unref (applet->priv->input); - } - - applet->priv->input = g_object_ref (stream); - if (applet->priv->input != NULL) { - g_signal_connect (G_OBJECT (applet->priv->input), - "control-added", - G_CALLBACK (on_input_stream_control_added), - applet); - g_signal_connect (G_OBJECT (applet->priv->input), - "control-removed", - G_CALLBACK (on_input_stream_control_removed), - applet); - } - - /* Return TRUE if the default input stream has changed */ - return TRUE; -} - -static void -on_context_state_notify (MateMixerContext *context, - GParamSpec *pspec, - GvcApplet *applet) -{ - MateMixerState state = mate_mixer_context_get_state (context); - - switch (state) { - case MATE_MIXER_STATE_FAILED: - g_warning ("Failed to connect to a sound system"); - break; - - case MATE_MIXER_STATE_READY: - update_default_input_stream (applet); - - /* Each status change may affect the visibility of the icons */ - update_icon_output (applet); - update_icon_input (applet); - break; - default: - break; - } -} - -static void -on_context_default_input_stream_notify (MateMixerContext *context, - GParamSpec *pspec, - GvcApplet *applet) -{ - if (update_default_input_stream (applet) == FALSE) - return; - - update_icon_input (applet); -} - -static void -on_context_default_output_stream_notify (MateMixerContext *control, - GParamSpec *pspec, - GvcApplet *applet) -{ - update_icon_output (applet); -} - -void -gvc_applet_start (GvcApplet *applet) -{ - g_return_if_fail (GVC_IS_APPLET (applet)); - - if G_UNLIKELY (applet->priv->running == TRUE) - return; - - if G_UNLIKELY (mate_mixer_context_open (applet->priv->context) == FALSE) { - /* Normally this should never happen, in the worst case we - * should end up with the Null module */ - g_warning ("Failed to connect to a sound system"); - } - - g_debug ("Applet has been started"); - - applet->priv->running = TRUE; -} - -static void -gvc_applet_dispose (GObject *object) -{ - GvcApplet *applet = GVC_APPLET (object); - - if (applet->priv->input != NULL) { - g_signal_handlers_disconnect_by_data (G_OBJECT (applet->priv->input), - applet); - g_clear_object (&applet->priv->input); - } - - g_clear_object (&applet->priv->context); - g_clear_object (&applet->priv->icon_input); - g_clear_object (&applet->priv->icon_output); - - G_OBJECT_CLASS (gvc_applet_parent_class)->dispose (object); -} - -static void -gvc_applet_class_init (GvcAppletClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - object_class->dispose = gvc_applet_dispose; - - g_type_class_add_private (klass, sizeof (GvcAppletPrivate)); -} - -static void -gvc_applet_init (GvcApplet *applet) -{ - applet->priv = GVC_APPLET_GET_PRIVATE (applet); - - applet->priv->icon_input = gvc_stream_status_icon_new (NULL, icon_names_input); - applet->priv->icon_output = gvc_stream_status_icon_new (NULL, icon_names_output); - - gvc_stream_status_icon_set_display_name (applet->priv->icon_input, _("Input")); - gvc_stream_status_icon_set_display_name (applet->priv->icon_output, _("Output")); - - gtk_status_icon_set_title (GTK_STATUS_ICON (applet->priv->icon_input), - _("Microphone Volume")); - gtk_status_icon_set_title (GTK_STATUS_ICON (applet->priv->icon_output), - _("Sound Output Volume")); - - applet->priv->context = mate_mixer_context_new (); - - mate_mixer_context_set_app_name (applet->priv->context, - _("MATE Volume Control Applet")); - - mate_mixer_context_set_app_id (applet->priv->context, GVC_APPLET_DBUS_NAME); - mate_mixer_context_set_app_version (applet->priv->context, VERSION); - mate_mixer_context_set_app_icon (applet->priv->context, "multimedia-volume-control"); - - g_signal_connect (G_OBJECT (applet->priv->context), - "notify::state", - G_CALLBACK (on_context_state_notify), - applet); - g_signal_connect (G_OBJECT (applet->priv->context), - "notify::default-input-stream", - G_CALLBACK (on_context_default_input_stream_notify), - applet); - g_signal_connect (G_OBJECT (applet->priv->context), - "notify::default-output-stream", - G_CALLBACK (on_context_default_output_stream_notify), - applet); -} - -GvcApplet * -gvc_applet_new (void) -{ - return g_object_new (GVC_TYPE_APPLET, NULL); -} diff --git a/mate-volume-control/src/gvc-applet.h b/mate-volume-control/src/gvc-applet.h deleted file mode 100644 index 991ef6d..0000000 --- a/mate-volume-control/src/gvc-applet.h +++ /dev/null @@ -1,61 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- - * - * Copyright (C) 2008 Red Hat, Inc. - * Copyright (C) 2014 Michal Ratajsky <[email protected]> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ - -#ifndef __GVC_APPLET_H -#define __GVC_APPLET_H - -#include <glib.h> -#include <glib-object.h> - -G_BEGIN_DECLS - -#define GVC_APPLET_DBUS_NAME "org.mate.VolumeControlApplet" - -#define GVC_TYPE_APPLET (gvc_applet_get_type ()) -#define GVC_APPLET(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GVC_TYPE_APPLET, GvcApplet)) -#define GVC_APPLET_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), GVC_TYPE_APPLET, GvcAppletClass)) -#define GVC_IS_APPLET(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GVC_TYPE_APPLET)) -#define GVC_IS_APPLET_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GVC_TYPE_APPLET)) -#define GVC_APPLET_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GVC_TYPE_APPLET, GvcAppletClass)) - -typedef struct _GvcApplet GvcApplet; -typedef struct _GvcAppletClass GvcAppletClass; -typedef struct _GvcAppletPrivate GvcAppletPrivate; - -struct _GvcApplet -{ - GObject parent; - GvcAppletPrivate *priv; -}; - -struct _GvcAppletClass -{ - GObjectClass parent_class; -}; - -GType gvc_applet_get_type (void) G_GNUC_CONST; - -GvcApplet * gvc_applet_new (void); -void gvc_applet_start (GvcApplet *applet); - -G_END_DECLS - -#endif /* __GVC_APPLET_H */ diff --git a/mate-volume-control/src/gvc-balance-bar.c b/mate-volume-control/src/gvc-balance-bar.c deleted file mode 100644 index 7431773..0000000 --- a/mate-volume-control/src/gvc-balance-bar.c +++ /dev/null @@ -1,552 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- - * - * Copyright (C) 2008 William Jon McCann - * Copyright (C) 2014 Michal Ratajsky <[email protected]> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ - -#include <glib.h> -#include <glib/gi18n.h> -#include <glib-object.h> -#include <gtk/gtk.h> - -#include <canberra-gtk.h> -#include <libmatemixer/matemixer.h> - -#include "gvc-balance-bar.h" - -#define BALANCE_BAR_STYLE \ - "style \"balance-bar-scale-style\" {\n" \ - " GtkScale::trough-side-details = 0\n" \ - "}\n" \ - "widget \"*.balance-bar-scale\" style : rc \"balance-bar-scale-style\"\n" - -#define SCALE_SIZE 128 -#define GVC_BALANCE_BAR_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GVC_TYPE_BALANCE_BAR, GvcBalanceBarPrivate)) - -struct _GvcBalanceBarPrivate -{ - GvcBalanceType btype; - GtkWidget *scale_box; - GtkWidget *start_box; - GtkWidget *end_box; - GtkWidget *label; - GtkWidget *scale; - GtkAdjustment *adjustment; - GtkSizeGroup *size_group; - gboolean symmetric; - MateMixerStreamControl *control; - gint lfe_channel; -}; - -enum -{ - PROP_0, - PROP_CONTROL, - PROP_BALANCE_TYPE, - N_PROPERTIES -}; - -static GParamSpec *properties[N_PROPERTIES] = { NULL, }; - -static void gvc_balance_bar_class_init (GvcBalanceBarClass *klass); -static void gvc_balance_bar_init (GvcBalanceBar *balance_bar); -static void gvc_balance_bar_dispose (GObject *object); - -static gboolean on_scale_scroll_event (GtkWidget *widget, - GdkEventScroll *event, - GvcBalanceBar *bar); - -static void on_adjustment_value_changed (GtkAdjustment *adjustment, - GvcBalanceBar *bar); - -#if GTK_CHECK_VERSION (3, 0, 0) -G_DEFINE_TYPE (GvcBalanceBar, gvc_balance_bar, GTK_TYPE_BOX) -#else -G_DEFINE_TYPE (GvcBalanceBar, gvc_balance_bar, GTK_TYPE_HBOX) -#endif - -static void -create_scale_box (GvcBalanceBar *bar) -{ -#if GTK_CHECK_VERSION (3, 0, 0) - bar->priv->scale_box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6); - bar->priv->start_box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6); - bar->priv->end_box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6); - bar->priv->scale = gtk_scale_new (GTK_ORIENTATION_HORIZONTAL, - bar->priv->adjustment); -#if GTK_CHECK_VERSION (3, 4, 0) - /* Balance and fade scales do not have an origin */ - if (bar->priv->btype != BALANCE_TYPE_LFE) - gtk_scale_set_has_origin (GTK_SCALE (bar->priv->scale), FALSE); -#endif -#else - bar->priv->scale_box = gtk_hbox_new (FALSE, 6); - bar->priv->start_box = gtk_hbox_new (FALSE, 6); - bar->priv->end_box = gtk_hbox_new (FALSE, 6); - bar->priv->scale = gtk_hscale_new (bar->priv->adjustment); - - /* GTK2 way to remove the origin */ - if (bar->priv->btype != BALANCE_TYPE_LFE) { - gtk_rc_parse_string (BALANCE_BAR_STYLE); - gtk_widget_set_name (bar->priv->scale, "balance-bar-scale"); - } -#endif - - gtk_widget_set_size_request (bar->priv->scale, SCALE_SIZE, -1); - - gtk_box_pack_start (GTK_BOX (bar->priv->scale_box), - bar->priv->start_box, - FALSE, FALSE, 0); - gtk_box_pack_start (GTK_BOX (bar->priv->start_box), - bar->priv->label, - FALSE, FALSE, 0); - gtk_box_pack_start (GTK_BOX (bar->priv->scale_box), - bar->priv->scale, - TRUE, TRUE, 0); - gtk_box_pack_start (GTK_BOX (bar->priv->scale_box), - bar->priv->end_box, - FALSE, FALSE, 0); - - ca_gtk_widget_disable_sounds (bar->priv->scale, FALSE); - - gtk_widget_add_events (bar->priv->scale, GDK_SCROLL_MASK); - - g_signal_connect (G_OBJECT (bar->priv->scale), - "scroll-event", - G_CALLBACK (on_scale_scroll_event), - bar); - - if (bar->priv->size_group != NULL) { - gtk_size_group_add_widget (bar->priv->size_group, - bar->priv->start_box); - - if (bar->priv->symmetric) - gtk_size_group_add_widget (bar->priv->size_group, - bar->priv->end_box); - } - - gtk_scale_set_draw_value (GTK_SCALE (bar->priv->scale), FALSE); -} - -static void -update_scale_marks (GvcBalanceBar *bar) -{ - gchar *str_lower = NULL, - *str_upper = NULL; - gdouble lower, - upper; - - gtk_scale_clear_marks (GTK_SCALE (bar->priv->scale)); - - switch (bar->priv->btype) { - case BALANCE_TYPE_RL: - str_lower = g_strdup_printf ("<small>%s</small>", C_("balance", "Left")); - str_upper = g_strdup_printf ("<small>%s</small>", C_("balance", "Right")); - break; - case BALANCE_TYPE_FR: - str_lower = g_strdup_printf ("<small>%s</small>", C_("balance", "Rear")); - str_upper = g_strdup_printf ("<small>%s</small>", C_("balance", "Front")); - break; - case BALANCE_TYPE_LFE: - str_lower = g_strdup_printf ("<small>%s</small>", C_("balance", "Minimum")); - str_upper = g_strdup_printf ("<small>%s</small>", C_("balance", "Maximum")); - break; - } - - lower = gtk_adjustment_get_lower (bar->priv->adjustment); - gtk_scale_add_mark (GTK_SCALE (bar->priv->scale), - lower, - GTK_POS_BOTTOM, - str_lower); - upper = gtk_adjustment_get_upper (bar->priv->adjustment); - gtk_scale_add_mark (GTK_SCALE (bar->priv->scale), - upper, - GTK_POS_BOTTOM, - str_upper); - g_free (str_lower); - g_free (str_upper); - - if (bar->priv->btype != BALANCE_TYPE_LFE) - gtk_scale_add_mark (GTK_SCALE (bar->priv->scale), - (upper - lower) / 2 + lower, - GTK_POS_BOTTOM, - NULL); -} - -void -gvc_balance_bar_set_size_group (GvcBalanceBar *bar, - GtkSizeGroup *group, - gboolean symmetric) -{ - g_return_if_fail (GVC_IS_BALANCE_BAR (bar)); - g_return_if_fail (GTK_IS_SIZE_GROUP (group)); - - bar->priv->size_group = group; - bar->priv->symmetric = symmetric; - - if (bar->priv->size_group != NULL) { - gtk_size_group_add_widget (bar->priv->size_group, - bar->priv->start_box); - - if (bar->priv->symmetric) - gtk_size_group_add_widget (bar->priv->size_group, - bar->priv->end_box); - } - gtk_widget_queue_draw (GTK_WIDGET (bar)); -} - -static void -update_balance_value (GvcBalanceBar *bar) -{ - gdouble value = 0; - - switch (bar->priv->btype) { - case BALANCE_TYPE_RL: - value = mate_mixer_stream_control_get_balance (bar->priv->control); - g_debug ("Balance value changed to %.2f", value); - break; - case BALANCE_TYPE_FR: - value = mate_mixer_stream_control_get_fade (bar->priv->control); - g_debug ("Fade value changed to %.2f", value); - break; - case BALANCE_TYPE_LFE: - value = mate_mixer_stream_control_get_channel_volume (bar->priv->control, - bar->priv->lfe_channel); - - g_debug ("Subwoofer volume changed to %.0f", value); - break; - } - - gtk_adjustment_set_value (bar->priv->adjustment, value); -} - -static void -on_balance_value_changed (MateMixerStream *stream, - GParamSpec *pspec, - GvcBalanceBar *bar) -{ - update_balance_value (bar); -} - -static gint -find_stream_lfe_channel (MateMixerStreamControl *control) -{ - guint i; - - for (i = 0; i < mate_mixer_stream_control_get_num_channels (control); i++) { - MateMixerChannelPosition position; - - position = mate_mixer_stream_control_get_channel_position (control, i); - if (position == MATE_MIXER_CHANNEL_LFE) - return i; - } - - return -1; -} - -static void -gvc_balance_bar_set_control (GvcBalanceBar *bar, MateMixerStreamControl *control) -{ - g_return_if_fail (GVC_BALANCE_BAR (bar)); - g_return_if_fail (MATE_MIXER_IS_STREAM_CONTROL (control)); - - if (bar->priv->control != NULL) { - g_signal_handlers_disconnect_by_func (G_OBJECT (bar->priv->control), - on_balance_value_changed, - bar); - g_object_unref (bar->priv->control); - } - - bar->priv->control = g_object_ref (control); - - if (bar->priv->btype == BALANCE_TYPE_LFE) { - gdouble minimum; - gdouble maximum; - - minimum = mate_mixer_stream_control_get_min_volume (bar->priv->control); - maximum = mate_mixer_stream_control_get_normal_volume (bar->priv->control); - - /* Configure the adjustment for the volume limits of the current - * stream. - * Only subwoofer scale uses volume, balance and fade use fixed - * limits which do not need to be updated as balance type is - * only set during construction. */ - gtk_adjustment_configure (GTK_ADJUSTMENT (bar->priv->adjustment), - gtk_adjustment_get_value (bar->priv->adjustment), - minimum, - maximum, - (maximum - minimum) / 100.0, - (maximum - minimum) / 10.0, - 0.0); - - bar->priv->lfe_channel = find_stream_lfe_channel (bar->priv->control); - - if (G_LIKELY (bar->priv->lfe_channel > -1)) - g_debug ("Found LFE channel at position %d", bar->priv->lfe_channel); - else - g_warn_if_reached (); - } else - bar->priv->lfe_channel = -1; - - switch (bar->priv->btype) { - case BALANCE_TYPE_RL: - g_signal_connect (G_OBJECT (bar->priv->control), - "notify::balance", - G_CALLBACK (on_balance_value_changed), - bar); - break; - case BALANCE_TYPE_FR: - g_signal_connect (G_OBJECT (bar->priv->control), - "notify::fade", - G_CALLBACK (on_balance_value_changed), - bar); - break; - case BALANCE_TYPE_LFE: - g_signal_connect (G_OBJECT (bar->priv->control), - "notify::volume", - G_CALLBACK (on_balance_value_changed), - bar); - break; - } - - update_balance_value (bar); - update_scale_marks (bar); - - g_object_notify_by_pspec (G_OBJECT (bar), properties[PROP_CONTROL]); -} - -static void -gvc_balance_bar_set_balance_type (GvcBalanceBar *bar, GvcBalanceType btype) -{ - GtkWidget *frame; - GtkAdjustment *adjustment; - - /* Create adjustment with limits for balance and fade types because - * some limits must be provided. - * If subwoofer type is used instead, the limits will be changed when - * stream is set. */ - adjustment = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, -1.0, 1.0, 0.05, 0.5, 0.0)); - - bar->priv->btype = btype; - bar->priv->adjustment = GTK_ADJUSTMENT (g_object_ref_sink (adjustment)); - - g_signal_connect (G_OBJECT (adjustment), - "value-changed", - G_CALLBACK (on_adjustment_value_changed), - bar); - - switch (btype) { - case BALANCE_TYPE_RL: - bar->priv->label = gtk_label_new_with_mnemonic (_("_Balance:")); - break; - case BALANCE_TYPE_FR: - bar->priv->label = gtk_label_new_with_mnemonic (_("_Fade:")); - break; - case BALANCE_TYPE_LFE: - bar->priv->label = gtk_label_new_with_mnemonic (_("_Subwoofer:")); - break; - } - - gtk_misc_set_alignment (GTK_MISC (bar->priv->label), 0.0, 0.0); - - /* Frame */ - frame = gtk_frame_new (NULL); - gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_NONE); - gtk_box_pack_start (GTK_BOX (bar), frame, TRUE, TRUE, 0); - - /* Box with scale */ - create_scale_box (bar); - gtk_container_add (GTK_CONTAINER (frame), bar->priv->scale_box); - - gtk_label_set_mnemonic_widget (GTK_LABEL (bar->priv->label), - bar->priv->scale); - - gtk_widget_set_direction (bar->priv->scale, GTK_TEXT_DIR_LTR); - gtk_widget_show_all (frame); - - g_object_notify_by_pspec (G_OBJECT (bar), properties[PROP_BALANCE_TYPE]); -} - -static void -gvc_balance_bar_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - GvcBalanceBar *self = GVC_BALANCE_BAR (object); - - switch (prop_id) { - case PROP_CONTROL: - gvc_balance_bar_set_control (self, g_value_get_object (value)); - break; - case PROP_BALANCE_TYPE: - gvc_balance_bar_set_balance_type (self, g_value_get_int (value)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -gvc_balance_bar_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - GvcBalanceBar *self = GVC_BALANCE_BAR (object); - - switch (prop_id) { - case PROP_CONTROL: - g_value_set_object (value, self->priv->control); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -gvc_balance_bar_class_init (GvcBalanceBarClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - object_class->dispose = gvc_balance_bar_dispose; - object_class->set_property = gvc_balance_bar_set_property; - object_class->get_property = gvc_balance_bar_get_property; - - properties[PROP_CONTROL] = - g_param_spec_object ("control", - "Control", - "MateMixer stream control", - MATE_MIXER_TYPE_STREAM_CONTROL, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS); - - properties[PROP_BALANCE_TYPE] = - g_param_spec_int ("balance-type", - "balance type", - "Whether the balance is right-left or front-rear", - BALANCE_TYPE_RL, - NUM_BALANCE_TYPES - 1, - BALANCE_TYPE_RL, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS); - - g_object_class_install_properties (object_class, N_PROPERTIES, properties); - - g_type_class_add_private (klass, sizeof (GvcBalanceBarPrivate)); -} - -static gboolean -on_scale_scroll_event (GtkWidget *widget, - GdkEventScroll *event, - GvcBalanceBar *bar) -{ - gdouble value; - gdouble minimum; - gdouble maximum; - gdouble step; - - value = gtk_adjustment_get_value (bar->priv->adjustment); - minimum = gtk_adjustment_get_lower (bar->priv->adjustment); - maximum = gtk_adjustment_get_upper (bar->priv->adjustment); - - // XXX fix this for GTK3 - - if (bar->priv->btype == BALANCE_TYPE_LFE) - step = (maximum - minimum) / 100.0; - else - step = 0.05; - - if (event->direction == GDK_SCROLL_UP) { - if (value + step > maximum) - value = maximum; - else - value = value + step; - } else if (event->direction == GDK_SCROLL_DOWN) { - if (value - step < minimum) - value = minimum; - else - value = value - step; - } - - gtk_adjustment_set_value (bar->priv->adjustment, value); - return TRUE; -} - -static void -on_adjustment_value_changed (GtkAdjustment *adjustment, GvcBalanceBar *bar) -{ - gdouble value; - - if (bar->priv->control == NULL) - return; - - value = gtk_adjustment_get_value (adjustment); - - switch (bar->priv->btype) { - case BALANCE_TYPE_RL: - mate_mixer_stream_control_set_balance (bar->priv->control, value); - break; - case BALANCE_TYPE_FR: - mate_mixer_stream_control_set_fade (bar->priv->control, value); - break; - case BALANCE_TYPE_LFE: - mate_mixer_stream_control_set_channel_volume (bar->priv->control, - bar->priv->lfe_channel, - value); - break; - } -} - -static void -gvc_balance_bar_init (GvcBalanceBar *bar) -{ - bar->priv = GVC_BALANCE_BAR_GET_PRIVATE (bar); -} - -static void -gvc_balance_bar_dispose (GObject *object) -{ - GvcBalanceBar *bar; - - bar = GVC_BALANCE_BAR (object); - - if (bar->priv->control != NULL) { - g_signal_handlers_disconnect_by_func (G_OBJECT (bar->priv->control), - on_balance_value_changed, - bar); - g_clear_object (&bar->priv->control); - } - - G_OBJECT_CLASS (gvc_balance_bar_parent_class)->dispose (object); -} - -GtkWidget * -gvc_balance_bar_new (MateMixerStreamControl *control, GvcBalanceType btype) -{ - return g_object_new (GVC_TYPE_BALANCE_BAR, - "balance-type", btype, - "control", control, -#if GTK_CHECK_VERSION (3, 0, 0) - "orientation", GTK_ORIENTATION_HORIZONTAL, -#endif - NULL); -} diff --git a/mate-volume-control/src/gvc-balance-bar.h b/mate-volume-control/src/gvc-balance-bar.h deleted file mode 100644 index d5b142d..0000000 --- a/mate-volume-control/src/gvc-balance-bar.h +++ /dev/null @@ -1,82 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- - * - * Copyright (C) 2008 Red Hat, Inc. - * Copyright (C) 2014 Michal Ratajsky <[email protected]> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ - -#ifndef __GVC_BALANCE_BAR_H -#define __GVC_BALANCE_BAR_H - -#include <glib.h> -#include <glib-object.h> -#include <gtk/gtk.h> - -#include <libmatemixer/matemixer.h> - -G_BEGIN_DECLS - -#define GVC_TYPE_BALANCE_BAR (gvc_balance_bar_get_type ()) -#define GVC_BALANCE_BAR(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GVC_TYPE_BALANCE_BAR, GvcBalanceBar)) -#define GVC_BALANCE_BAR_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GVC_TYPE_BALANCE_BAR, GvcBalanceBarClass)) -#define GVC_IS_BALANCE_BAR(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GVC_TYPE_BALANCE_BAR)) -#define GVC_IS_BALANCE_BAR_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GVC_TYPE_BALANCE_BAR)) -#define GVC_BALANCE_BAR_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GVC_TYPE_BALANCE_BAR, GvcBalanceBarClass)) - -typedef enum { - BALANCE_TYPE_RL, - BALANCE_TYPE_FR, - BALANCE_TYPE_LFE, -} GvcBalanceType; - -#define NUM_BALANCE_TYPES BALANCE_TYPE_LFE + 1 - -typedef struct _GvcBalanceBar GvcBalanceBar; -typedef struct _GvcBalanceBarClass GvcBalanceBarClass; -typedef struct _GvcBalanceBarPrivate GvcBalanceBarPrivate; - -struct _GvcBalanceBar -{ -#if GTK_CHECK_VERSION (3, 0, 0) - GtkBox parent; -#else - GtkHBox parent; -#endif - GvcBalanceBarPrivate *priv; -}; - -struct _GvcBalanceBarClass -{ -#if GTK_CHECK_VERSION (3, 0, 0) - GtkBoxClass parent_class; -#else - GtkHBoxClass parent_class; -#endif -}; - -GType gvc_balance_bar_get_type (void) G_GNUC_CONST; - -GtkWidget * gvc_balance_bar_new (MateMixerStreamControl *control, - GvcBalanceType btype); - -void gvc_balance_bar_set_size_group (GvcBalanceBar *bar, - GtkSizeGroup *group, - gboolean symmetric); - -G_END_DECLS - -#endif /* __GVC_BALANCE_BAR_H */ diff --git a/mate-volume-control/src/gvc-channel-bar.c b/mate-volume-control/src/gvc-channel-bar.c deleted file mode 100644 index e431651..0000000 --- a/mate-volume-control/src/gvc-channel-bar.c +++ /dev/null @@ -1,1158 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- - * - * Copyright (C) 2008 William Jon McCann - * Copyright (C) 2014 Michal Ratajsky <[email protected]> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ - -#include "config.h" - -#include <glib.h> -#include <glib/gi18n.h> -#include <glib-object.h> -#include <gtk/gtk.h> - -#include <canberra-gtk.h> -#include <libmatemixer/matemixer.h> - -#include "gvc-channel-bar.h" - -#define SCALE_SIZE 128 -#define GVC_CHANNEL_BAR_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GVC_TYPE_CHANNEL_BAR, GvcChannelBarPrivate)) - -struct _GvcChannelBarPrivate -{ - GtkOrientation orientation; - GtkWidget *scale_box; - GtkWidget *start_box; - GtkWidget *end_box; - GtkWidget *image; - GtkWidget *label; - GtkWidget *low_image; - GtkWidget *scale; - GtkWidget *high_image; - GtkWidget *mute_box; - GtkWidget *mute_button; - GtkAdjustment *adjustment; - gboolean show_icons; - gboolean show_mute; - gboolean show_marks; - gboolean extended; - GtkSizeGroup *size_group; - gboolean symmetric; - gboolean click_lock; - MateMixerStreamControl *control; - MateMixerStreamControlFlags control_flags; -}; - -enum { - PROP_0, - PROP_CONTROL, - PROP_ORIENTATION, - PROP_SHOW_ICONS, - PROP_SHOW_MUTE, - PROP_SHOW_MARKS, - PROP_EXTENDED, - PROP_NAME, - PROP_ICON_NAME, - PROP_LOW_ICON_NAME, - PROP_HIGH_ICON_NAME, - N_PROPERTIES -}; - -static GParamSpec *properties[N_PROPERTIES] = { NULL, }; - -static void gvc_channel_bar_class_init (GvcChannelBarClass *klass); -static void gvc_channel_bar_init (GvcChannelBar *bar); - -static gboolean on_scale_button_press_event (GtkWidget *widget, - GdkEventButton *event, - GvcChannelBar *bar); -static gboolean on_scale_button_release_event (GtkWidget *widget, - GdkEventButton *event, - GvcChannelBar *bar); -static gboolean on_scale_scroll_event (GtkWidget *widget, - GdkEventScroll *event, - GvcChannelBar *bar); - -#if GTK_CHECK_VERSION (3, 0, 0) -G_DEFINE_TYPE (GvcChannelBar, gvc_channel_bar, GTK_TYPE_BOX) -#else -G_DEFINE_TYPE (GvcChannelBar, gvc_channel_bar, GTK_TYPE_HBOX) -#endif - -static void -create_scale_box (GvcChannelBar *bar) -{ -#if GTK_CHECK_VERSION (3, 0, 0) - bar->priv->scale_box = gtk_box_new (bar->priv->orientation, 6); - bar->priv->start_box = gtk_box_new (bar->priv->orientation, 6); - bar->priv->end_box = gtk_box_new (bar->priv->orientation, 6); - bar->priv->scale = gtk_scale_new (bar->priv->orientation, - bar->priv->adjustment); -#else - if (bar->priv->orientation == GTK_ORIENTATION_VERTICAL) { - bar->priv->scale_box = gtk_vbox_new (FALSE, 6); - bar->priv->start_box = gtk_vbox_new (FALSE, 6); - bar->priv->end_box = gtk_vbox_new (FALSE, 6); - bar->priv->scale = gtk_vscale_new (bar->priv->adjustment); - } else { - bar->priv->scale_box = gtk_hbox_new (FALSE, 6); - bar->priv->start_box = gtk_hbox_new (FALSE, 6); - bar->priv->end_box = gtk_hbox_new (FALSE, 6); - bar->priv->scale = gtk_hscale_new (bar->priv->adjustment); - } -#endif - if (bar->priv->orientation == GTK_ORIENTATION_VERTICAL) { - gtk_widget_set_size_request (bar->priv->scale, -1, SCALE_SIZE); - - gtk_range_set_inverted (GTK_RANGE (bar->priv->scale), TRUE); - - gtk_box_pack_start (GTK_BOX (bar->priv->scale_box), - bar->priv->start_box, - FALSE, FALSE, 0); - - gtk_box_pack_start (GTK_BOX (bar->priv->start_box), - bar->priv->image, - FALSE, FALSE, 0); - gtk_box_pack_start (GTK_BOX (bar->priv->start_box), - bar->priv->label, - FALSE, FALSE, 0); - gtk_box_pack_start (GTK_BOX (bar->priv->start_box), - bar->priv->high_image, - FALSE, FALSE, 0); - - gtk_box_pack_start (GTK_BOX (bar->priv->scale_box), - bar->priv->scale, - TRUE, TRUE, 0); - gtk_box_pack_start (GTK_BOX (bar->priv->scale_box), - bar->priv->end_box, - FALSE, FALSE, 0); - - gtk_box_pack_start (GTK_BOX (bar->priv->end_box), - bar->priv->low_image, - FALSE, FALSE, 0); - gtk_box_pack_start (GTK_BOX (bar->priv->end_box), - bar->priv->mute_box, - FALSE, FALSE, 0); - } else { - gtk_widget_set_size_request (bar->priv->scale, SCALE_SIZE, -1); - - gtk_box_pack_start (GTK_BOX (bar->priv->scale_box), - bar->priv->image, - FALSE, FALSE, 0); - gtk_box_pack_start (GTK_BOX (bar->priv->scale_box), - bar->priv->start_box, - FALSE, FALSE, 0); - - gtk_box_pack_end (GTK_BOX (bar->priv->start_box), - bar->priv->low_image, - FALSE, FALSE, 0); - - gtk_box_pack_start (GTK_BOX (bar->priv->start_box), - bar->priv->label, - TRUE, TRUE, 0); - - gtk_box_pack_start (GTK_BOX (bar->priv->scale_box), - bar->priv->scale, - TRUE, TRUE, 0); - gtk_box_pack_start (GTK_BOX (bar->priv->scale_box), - bar->priv->end_box, - FALSE, FALSE, 0); - - gtk_box_pack_start (GTK_BOX (bar->priv->end_box), - bar->priv->high_image, - FALSE, FALSE, 0); - gtk_box_pack_start (GTK_BOX (bar->priv->end_box), - bar->priv->mute_box, - FALSE, FALSE, 0); - } - - if (bar->priv->show_icons) { - gtk_widget_show (bar->priv->low_image); - gtk_widget_show (bar->priv->high_image); - } else { - gtk_widget_hide (bar->priv->low_image); - gtk_widget_hide (bar->priv->high_image); - } - - ca_gtk_widget_disable_sounds (bar->priv->scale, FALSE); - - gtk_widget_add_events (bar->priv->scale, GDK_SCROLL_MASK); - - g_signal_connect (G_OBJECT (bar->priv->scale), - "button-press-event", - G_CALLBACK (on_scale_button_press_event), - bar); - g_signal_connect (G_OBJECT (bar->priv->scale), - "button-release-event", - G_CALLBACK (on_scale_button_release_event), - bar); - g_signal_connect (G_OBJECT (bar->priv->scale), - "scroll-event", - G_CALLBACK (on_scale_scroll_event), - bar); - - if (bar->priv->size_group != NULL) { - gtk_size_group_add_widget (bar->priv->size_group, - bar->priv->start_box); - - if (bar->priv->symmetric) - gtk_size_group_add_widget (bar->priv->size_group, - bar->priv->end_box); - } - - gtk_scale_set_draw_value (GTK_SCALE (bar->priv->scale), FALSE); -} - -static void -on_adjustment_value_changed (GtkAdjustment *adjustment, - GvcChannelBar *bar) -{ - gdouble value; - gdouble lower; - - if (bar->priv->control == NULL || bar->priv->click_lock == TRUE) - return; - - value = gtk_adjustment_get_value (bar->priv->adjustment); - lower = gtk_adjustment_get_lower (bar->priv->adjustment); - - if (bar->priv->control_flags & MATE_MIXER_STREAM_CONTROL_MUTE_WRITABLE) - mate_mixer_stream_control_set_mute (bar->priv->control, (value <= lower)); - - if (bar->priv->control_flags & MATE_MIXER_STREAM_CONTROL_VOLUME_WRITABLE) - mate_mixer_stream_control_set_volume (bar->priv->control, (guint) value); -} - -static void -on_mute_button_toggled (GtkToggleButton *button, GvcChannelBar *bar) -{ - gboolean mute; - - mute = gtk_toggle_button_get_active (button); - - mate_mixer_stream_control_set_mute (bar->priv->control, mute); -} - -static void -update_layout (GvcChannelBar *bar) -{ - GtkWidget *frame; - - if (bar->priv->scale == NULL) - return; - - frame = gtk_widget_get_parent (bar->priv->scale_box); - - g_object_ref (bar->priv->image); - g_object_ref (bar->priv->label); - g_object_ref (bar->priv->mute_box); - g_object_ref (bar->priv->low_image); - g_object_ref (bar->priv->high_image); - - // XXX this is not the opposite of what is done above - gtk_container_remove (GTK_CONTAINER (bar->priv->start_box), - bar->priv->image); - gtk_container_remove (GTK_CONTAINER (bar->priv->start_box), - bar->priv->label); - gtk_container_remove (GTK_CONTAINER (bar->priv->end_box), - bar->priv->mute_box); - - if (bar->priv->orientation == GTK_ORIENTATION_VERTICAL) { - gtk_container_remove (GTK_CONTAINER (bar->priv->start_box), - bar->priv->low_image); - gtk_container_remove (GTK_CONTAINER (bar->priv->end_box), - bar->priv->high_image); - } else { - gtk_container_remove (GTK_CONTAINER (bar->priv->end_box), - bar->priv->low_image); - gtk_container_remove (GTK_CONTAINER (bar->priv->start_box), - bar->priv->high_image); - } - - gtk_container_remove (GTK_CONTAINER (bar->priv->scale_box), - bar->priv->start_box); - gtk_container_remove (GTK_CONTAINER (bar->priv->scale_box), - bar->priv->scale); - gtk_container_remove (GTK_CONTAINER (bar->priv->scale_box), - bar->priv->end_box); - gtk_container_remove (GTK_CONTAINER (frame), - bar->priv->scale_box); - - create_scale_box (bar); - gtk_container_add (GTK_CONTAINER (frame), bar->priv->scale_box); - - g_object_unref (bar->priv->image); - g_object_unref (bar->priv->label); - g_object_unref (bar->priv->mute_box); - g_object_unref (bar->priv->low_image); - g_object_unref (bar->priv->high_image); - - gtk_widget_show_all (frame); -} - -static void -update_marks (GvcChannelBar *bar) -{ - gdouble base; - gdouble normal; - gboolean has_mark = FALSE; - - gtk_scale_clear_marks (GTK_SCALE (bar->priv->scale)); - - if (bar->priv->control == NULL || bar->priv->show_marks == FALSE) - return; - - /* Base volume represents unamplified volume, normal volume is the 100% - * volume, in many cases they are the same as unamplified volume is unknown */ - base = mate_mixer_stream_control_get_base_volume (bar->priv->control); - normal = mate_mixer_stream_control_get_normal_volume (bar->priv->control); - - if (normal <= gtk_adjustment_get_lower (bar->priv->adjustment)) - return; - - if (base < normal) { - gchar *str = g_strdup_printf ("<small>%s</small>", C_("volume", "Unamplified")); - - gtk_scale_add_mark (GTK_SCALE (bar->priv->scale), - base, - GTK_POS_BOTTOM, - str); - has_mark = TRUE; - g_free (str); - } - - /* Only show 100% mark if the scale is extended beyond 100% and - * there is no unamplified mark or it is below the normal volume */ - if (bar->priv->extended && (base == normal || base < normal)) { - gchar *str = g_strdup_printf ("<small>%s</small>", C_("volume", "100%")); - - gtk_scale_add_mark (GTK_SCALE (bar->priv->scale), - normal, - GTK_POS_BOTTOM, - str); - has_mark = TRUE; - g_free (str); - } - - if (has_mark) { - gtk_alignment_set (GTK_ALIGNMENT (bar->priv->mute_box), 0.5, 0, 0, 0); - - gtk_misc_set_alignment (GTK_MISC (bar->priv->low_image), 0.5, 0); - gtk_misc_set_alignment (GTK_MISC (bar->priv->high_image), 0.5, 0); - gtk_misc_set_alignment (GTK_MISC (bar->priv->label), 0, 0); - } else { - gtk_alignment_set (GTK_ALIGNMENT (bar->priv->mute_box), 0.5, 0.5, 0, 0); - - gtk_misc_set_alignment (GTK_MISC (bar->priv->low_image), 0.5, 0.5); - gtk_misc_set_alignment (GTK_MISC (bar->priv->high_image), 0.5, 0.5); - gtk_misc_set_alignment (GTK_MISC (bar->priv->label), 0, 0.5); - } -} - -static void -update_adjustment_value (GvcChannelBar *bar) -{ - gdouble value; - gboolean set_lower = FALSE; - - /* Move the slider to the minimal value if the stream control is muted or - * volume is unavailable */ - if (bar->priv->control == NULL) - set_lower = TRUE; - else if (bar->priv->control_flags & MATE_MIXER_STREAM_CONTROL_MUTE_READABLE) - set_lower = mate_mixer_stream_control_get_mute (bar->priv->control); - - if (set_lower == TRUE) - value = gtk_adjustment_get_lower (bar->priv->adjustment); - else - value = mate_mixer_stream_control_get_volume (bar->priv->control); - - g_signal_handlers_block_by_func (G_OBJECT (bar->priv->adjustment), - on_adjustment_value_changed, - bar); - - gtk_adjustment_set_value (bar->priv->adjustment, value); - - g_signal_handlers_unblock_by_func (G_OBJECT (bar->priv->adjustment), - on_adjustment_value_changed, - bar); -} - -static void -update_adjustment_limits (GvcChannelBar *bar) -{ - gdouble minimum = 0.0; - gdouble maximum = 0.0; - - if (bar->priv->control != NULL) { - minimum = mate_mixer_stream_control_get_min_volume (bar->priv->control); - if (bar->priv->extended) - maximum = mate_mixer_stream_control_get_max_volume (bar->priv->control); - else - maximum = mate_mixer_stream_control_get_normal_volume (bar->priv->control); - } - - gtk_adjustment_configure (bar->priv->adjustment, - gtk_adjustment_get_value (bar->priv->adjustment), - minimum, - maximum, - (maximum - minimum) / 100.0, - (maximum - minimum) / 15.0, - 0.0); -} - -static void -update_mute_button (GvcChannelBar *bar) -{ - if (bar->priv->show_mute == TRUE) { - gboolean enable = FALSE; - - if (bar->priv->control != NULL && - bar->priv->control_flags & MATE_MIXER_STREAM_CONTROL_MUTE_READABLE) - enable = TRUE; - - if (enable == TRUE) { - gboolean mute = mate_mixer_stream_control_get_mute (bar->priv->control); - - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (bar->priv->mute_button), - mute); - } else { - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (bar->priv->mute_button), - FALSE); - } - - gtk_widget_set_sensitive (bar->priv->mute_button, enable); - gtk_widget_show (bar->priv->mute_button); - } else - gtk_widget_hide (bar->priv->mute_button); -} - -static gboolean -on_scale_button_press_event (GtkWidget *widget, - GdkEventButton *event, - GvcChannelBar *bar) -{ - -#if !GTK_CHECK_VERSION (3, 6, 0) - /* Up to GTK 3.4 the slider selection only moves in increments when - * clicking in the slider with the left button and it moves directly - * to the clicked position with the middle mouse button. - * Change this behaviour to also jump to the clicked position with the - * left mouse button. */ - if (event->button == 1) - event->button = 2; -#endif - - /* Muting the stream when volume is non-zero moves the slider to zero, - * but the volume remains the same. In this case delay unmuting and - * changing volume until user releases the mouse button. */ - if (bar->priv->control_flags & MATE_MIXER_STREAM_CONTROL_MUTE_READABLE && - bar->priv->control_flags & MATE_MIXER_STREAM_CONTROL_VOLUME_READABLE) { - if (mate_mixer_stream_control_get_mute (bar->priv->control) == TRUE) { - guint minimum = (guint) gtk_adjustment_get_lower (bar->priv->adjustment); - - if (mate_mixer_stream_control_get_volume (bar->priv->control) > minimum) - bar->priv->click_lock = TRUE; - } - } - return FALSE; -} - -static gboolean -on_scale_button_release_event (GtkWidget *widget, - GdkEventButton *event, - GvcChannelBar *bar) -{ -#if !GTK_CHECK_VERSION (3, 6, 0) - if (event->button == 1) - event->button = 2; -#endif - - if (bar->priv->click_lock == TRUE) { - /* The volume change is not reflected while the lock is - * held, propagate the change now that user has released - * the mouse button */ - bar->priv->click_lock = FALSE; - on_adjustment_value_changed (bar->priv->adjustment, bar); - } - - /* Play a sound */ - ca_gtk_play_for_widget (GTK_WIDGET (bar), 0, - CA_PROP_EVENT_ID, "audio-volume-change", - CA_PROP_EVENT_DESCRIPTION, "Volume change", - CA_PROP_APPLICATION_ID, "org.mate.VolumeControl", - CA_PROP_APPLICATION_NAME, _("Volume Control"), - CA_PROP_APPLICATION_VERSION, VERSION, - CA_PROP_APPLICATION_ICON_NAME, "multimedia-volume-control", - NULL); - return FALSE; -} - -static gboolean -on_scale_scroll_event (GtkWidget *widget, - GdkEventScroll *event, - GvcChannelBar *bar) -{ - GdkScrollDirection direction = event->direction; - -#if GTK_CHECK_VERSION (3, 4, 0) - if (direction == GDK_SCROLL_SMOOTH) { - gdouble dx = 0.0; - gdouble dy = 0.0; - - gdk_event_get_scroll_deltas ((const GdkEvent *) event, &dx, &dy); - if (dy > 0.0) - direction = GDK_SCROLL_DOWN; - else if (dy < 0.0) - direction = GDK_SCROLL_UP; - else - return FALSE; - } -#endif - return gvc_channel_bar_scroll (bar, direction); -} - -static void -on_control_volume_notify (MateMixerStreamControl *control, - GParamSpec *pspec, - GvcChannelBar *bar) -{ - update_adjustment_value (bar); -} - -static void -on_control_mute_notify (MateMixerStreamControl *control, - GParamSpec *pspec, - GvcChannelBar *bar) -{ - if (bar->priv->show_mute == TRUE) { - gboolean mute = mate_mixer_stream_control_get_mute (control); - - g_signal_handlers_block_by_func (G_OBJECT (bar->priv->mute_button), - on_mute_button_toggled, - bar); - - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (bar->priv->mute_button), mute); - - g_signal_handlers_unblock_by_func (G_OBJECT (bar->priv->mute_button), - on_mute_button_toggled, - bar); - } - update_adjustment_value (bar); -} - -MateMixerStreamControl * -gvc_channel_bar_get_control (GvcChannelBar *bar) -{ - g_return_val_if_fail (GVC_IS_CHANNEL_BAR (bar), NULL); - - return bar->priv->control; -} - -void -gvc_channel_bar_set_control (GvcChannelBar *bar, MateMixerStreamControl *control) -{ - g_return_if_fail (GVC_IS_CHANNEL_BAR (bar)); - - if (bar->priv->control == control) - return; - - if (control != NULL) - g_object_ref (control); - - if (bar->priv->control != NULL) { - g_signal_handlers_disconnect_by_func (G_OBJECT (bar->priv->control), - G_CALLBACK (on_control_volume_notify), - bar); - g_signal_handlers_disconnect_by_func (G_OBJECT (bar->priv->control), - G_CALLBACK (on_control_mute_notify), - bar); - g_object_unref (bar->priv->control); - } - - bar->priv->control = control; - - if (control != NULL) - bar->priv->control_flags = mate_mixer_stream_control_get_flags (control); - else - bar->priv->control_flags = MATE_MIXER_STREAM_CONTROL_NO_FLAGS; - - if (bar->priv->control_flags & MATE_MIXER_STREAM_CONTROL_VOLUME_READABLE) - g_signal_connect (G_OBJECT (control), - "notify::volume", - G_CALLBACK (on_control_volume_notify), - bar); - if (bar->priv->control_flags & MATE_MIXER_STREAM_CONTROL_MUTE_READABLE) - g_signal_connect (G_OBJECT (control), - "notify::mute", - G_CALLBACK (on_control_mute_notify), - bar); - - update_marks (bar); - update_mute_button (bar); - update_adjustment_limits (bar); - update_adjustment_value (bar); -} - -GtkOrientation -gvc_channel_bar_get_orientation (GvcChannelBar *bar) -{ - g_return_val_if_fail (GVC_IS_CHANNEL_BAR (bar), 0); - - return bar->priv->orientation; -} - -void -gvc_channel_bar_set_orientation (GvcChannelBar *bar, - GtkOrientation orientation) -{ - g_return_if_fail (GVC_IS_CHANNEL_BAR (bar)); - - if (orientation == bar->priv->orientation) - return; - - bar->priv->orientation = orientation; - update_layout (bar); - - g_object_notify_by_pspec (G_OBJECT (bar), properties[PROP_ORIENTATION]); -} - -gboolean -gvc_channel_bar_get_show_icons (GvcChannelBar *bar) -{ - g_return_val_if_fail (GVC_IS_CHANNEL_BAR (bar), FALSE); - - return bar->priv->show_icons; -} - -void -gvc_channel_bar_set_show_icons (GvcChannelBar *bar, gboolean show_icons) -{ - g_return_if_fail (GVC_IS_CHANNEL_BAR (bar)); - - if (show_icons == bar->priv->show_icons) - return; - - bar->priv->show_icons = show_icons; - - if (bar->priv->show_icons == TRUE) { - gtk_widget_show (bar->priv->low_image); - gtk_widget_show (bar->priv->high_image); - } else { - gtk_widget_hide (bar->priv->low_image); - gtk_widget_hide (bar->priv->high_image); - } - - g_object_notify_by_pspec (G_OBJECT (bar), properties[PROP_SHOW_ICONS]); -} - -gboolean -gvc_channel_bar_get_show_mute (GvcChannelBar *bar) -{ - g_return_val_if_fail (GVC_IS_CHANNEL_BAR (bar), FALSE); - - return bar->priv->show_mute; -} - -void -gvc_channel_bar_set_show_mute (GvcChannelBar *bar, gboolean show_mute) -{ - g_return_if_fail (GVC_IS_CHANNEL_BAR (bar)); - - if (show_mute == bar->priv->show_mute) - return; - - bar->priv->show_mute = show_mute; - update_mute_button (bar); - - g_object_notify_by_pspec (G_OBJECT (bar), properties[PROP_SHOW_MUTE]); -} - -gboolean -gvc_channel_bar_get_show_marks (GvcChannelBar *bar) -{ - g_return_val_if_fail (GVC_IS_CHANNEL_BAR (bar), FALSE); - - return bar->priv->show_marks; -} - -void -gvc_channel_bar_set_show_marks (GvcChannelBar *bar, gboolean show_marks) -{ - g_return_if_fail (GVC_IS_CHANNEL_BAR (bar)); - - if (show_marks == bar->priv->show_marks) - return; - - bar->priv->show_marks = show_marks; - update_marks (bar); - - g_object_notify_by_pspec (G_OBJECT (bar), properties[PROP_SHOW_MARKS]); -} - -gboolean -gvc_channel_bar_get_extended (GvcChannelBar *bar) -{ - g_return_val_if_fail (GVC_IS_CHANNEL_BAR (bar), FALSE); - - return bar->priv->extended; -} - -void -gvc_channel_bar_set_extended (GvcChannelBar *bar, gboolean extended) -{ - g_return_if_fail (GVC_IS_CHANNEL_BAR (bar)); - - if (extended == bar->priv->extended) - return; - - bar->priv->extended = extended; - - /* Update displayed marks as non-extended scales do not show the 100% - * limit at the end of the scale */ - update_marks (bar); - update_adjustment_limits (bar); - - g_object_notify_by_pspec (G_OBJECT (bar), properties[PROP_EXTENDED]); -} - -const gchar * -gvc_channel_bar_get_name (GvcChannelBar *bar) -{ - g_return_val_if_fail (GVC_IS_CHANNEL_BAR (bar), NULL); - - return gtk_label_get_text (GTK_LABEL (bar->priv->label)); -} - -void -gvc_channel_bar_set_name (GvcChannelBar *bar, const gchar *name) -{ - g_return_if_fail (GVC_IS_CHANNEL_BAR (bar)); - - if (name != NULL) { - gtk_label_set_text_with_mnemonic (GTK_LABEL (bar->priv->label), name); - gtk_label_set_mnemonic_widget (GTK_LABEL (bar->priv->label), - bar->priv->scale); - - gtk_widget_show (bar->priv->label); - } else { - gtk_label_set_text (GTK_LABEL (bar->priv->label), NULL); - gtk_widget_hide (bar->priv->label); - } - - g_object_notify_by_pspec (G_OBJECT (bar), properties[PROP_NAME]); -} - -const gchar * -gvc_channel_bar_get_icon_name (GvcChannelBar *bar) -{ - const gchar *name = NULL; - - g_return_val_if_fail (GVC_IS_CHANNEL_BAR (bar), NULL); - - gtk_image_get_icon_name (GTK_IMAGE (bar->priv->image), &name, NULL); - return name; -} - -void -gvc_channel_bar_set_icon_name (GvcChannelBar *bar, const gchar *name) -{ - g_return_if_fail (GVC_IS_CHANNEL_BAR (bar)); - - gtk_image_set_from_icon_name (GTK_IMAGE (bar->priv->image), - name, - GTK_ICON_SIZE_DIALOG); - if (name != NULL) - gtk_widget_show (bar->priv->image); - else - gtk_widget_hide (bar->priv->image); - - g_object_notify_by_pspec (G_OBJECT (bar), properties[PROP_ICON_NAME]); -} - -const gchar * -gvc_channel_bar_get_low_icon_name (GvcChannelBar *bar) -{ - const gchar *name = NULL; - - g_return_val_if_fail (GVC_IS_CHANNEL_BAR (bar), NULL); - - gtk_image_get_icon_name (GTK_IMAGE (bar->priv->low_image), &name, NULL); - return name; -} - -void -gvc_channel_bar_set_low_icon_name (GvcChannelBar *bar, const gchar *name) -{ - g_return_if_fail (GVC_IS_CHANNEL_BAR (bar)); - - gtk_image_set_from_icon_name (GTK_IMAGE (bar->priv->low_image), - name, - GTK_ICON_SIZE_BUTTON); - - g_object_notify_by_pspec (G_OBJECT (bar), properties[PROP_LOW_ICON_NAME]); -} - -const gchar * -gvc_channel_bar_get_high_icon_name (GvcChannelBar *bar) -{ - const gchar *name = NULL; - - g_return_val_if_fail (GVC_IS_CHANNEL_BAR (bar), NULL); - - gtk_image_get_icon_name (GTK_IMAGE (bar->priv->high_image), &name, NULL); - return name; -} - -void -gvc_channel_bar_set_high_icon_name (GvcChannelBar *bar, const gchar *name) -{ - g_return_if_fail (GVC_IS_CHANNEL_BAR (bar)); - - gtk_image_set_from_icon_name (GTK_IMAGE (bar->priv->high_image), - name, - GTK_ICON_SIZE_BUTTON); - - g_object_notify_by_pspec (G_OBJECT (bar), properties[PROP_HIGH_ICON_NAME]); -} - -gboolean -gvc_channel_bar_scroll (GvcChannelBar *bar, GdkScrollDirection direction) -{ - gdouble value; - gdouble minimum; - gdouble maximum; - gdouble scrollstep; - - g_return_val_if_fail (GVC_IS_CHANNEL_BAR (bar), FALSE); - - if (bar->priv->orientation == GTK_ORIENTATION_VERTICAL) { - if (direction != GDK_SCROLL_UP && direction != GDK_SCROLL_DOWN) - return FALSE; - } else { - /* Switch direction for RTL */ - if (gtk_widget_get_direction (GTK_WIDGET (bar)) == GTK_TEXT_DIR_RTL) { - if (direction == GDK_SCROLL_RIGHT) - direction = GDK_SCROLL_LEFT; - else if (direction == GDK_SCROLL_LEFT) - direction = GDK_SCROLL_RIGHT; - } - - /* Switch side scroll to vertical */ - if (direction == GDK_SCROLL_RIGHT) - direction = GDK_SCROLL_UP; - else if (direction == GDK_SCROLL_LEFT) - direction = GDK_SCROLL_DOWN; - } - - value = gtk_adjustment_get_value (bar->priv->adjustment); - minimum = gtk_adjustment_get_lower (bar->priv->adjustment); - maximum = gtk_adjustment_get_upper (bar->priv->adjustment); - - scrollstep = maximum / 100.0 * 5.0; - - if (direction == GDK_SCROLL_UP) { - if (value + scrollstep > maximum) - value = maximum; - else - value = value + scrollstep; - } else if (direction == GDK_SCROLL_DOWN) { - if (value - scrollstep < minimum) - value = minimum; - else - value = value - scrollstep; - } - - gtk_adjustment_set_value (bar->priv->adjustment, value); - return TRUE; -} - -void -gvc_channel_bar_set_size_group (GvcChannelBar *bar, - GtkSizeGroup *group, - gboolean symmetric) -{ - g_return_if_fail (GVC_IS_CHANNEL_BAR (bar)); - g_return_if_fail (GTK_IS_SIZE_GROUP (group)); - - bar->priv->size_group = group; - bar->priv->symmetric = symmetric; - - if (bar->priv->size_group != NULL) { - gtk_size_group_add_widget (bar->priv->size_group, - bar->priv->start_box); - - if (bar->priv->symmetric) - gtk_size_group_add_widget (bar->priv->size_group, - bar->priv->end_box); - } - gtk_widget_queue_draw (GTK_WIDGET (bar)); -} - -static void -gvc_channel_bar_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - GvcChannelBar *self = GVC_CHANNEL_BAR (object); - - switch (prop_id) { - case PROP_CONTROL: - gvc_channel_bar_set_control (self, g_value_get_object (value)); - break; - case PROP_ORIENTATION: - gvc_channel_bar_set_orientation (self, g_value_get_enum (value)); - break; - case PROP_SHOW_MUTE: - gvc_channel_bar_set_show_mute (self, g_value_get_boolean (value)); - break; - case PROP_SHOW_ICONS: - gvc_channel_bar_set_show_icons (self, g_value_get_boolean (value)); - break; - case PROP_SHOW_MARKS: - gvc_channel_bar_set_show_marks (self, g_value_get_boolean (value)); - break; - case PROP_EXTENDED: - gvc_channel_bar_set_extended (self, g_value_get_boolean (value)); - break; - case PROP_NAME: - gvc_channel_bar_set_name (self, g_value_get_string (value)); - break; - case PROP_ICON_NAME: - gvc_channel_bar_set_icon_name (self, g_value_get_string (value)); - break; - case PROP_LOW_ICON_NAME: - gvc_channel_bar_set_low_icon_name (self, g_value_get_string (value)); - break; - case PROP_HIGH_ICON_NAME: - gvc_channel_bar_set_high_icon_name (self, g_value_get_string (value)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -gvc_channel_bar_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - GvcChannelBar *self = GVC_CHANNEL_BAR (object); - - switch (prop_id) { - case PROP_CONTROL: - g_value_set_object (value, self->priv->control); - break; - case PROP_ORIENTATION: - g_value_set_enum (value, self->priv->orientation); - break; - case PROP_SHOW_MUTE: - g_value_set_boolean (value, self->priv->show_mute); - break; - case PROP_SHOW_ICONS: - g_value_set_boolean (value, self->priv->show_icons); - break; - case PROP_SHOW_MARKS: - g_value_set_boolean (value, self->priv->show_marks); - break; - case PROP_EXTENDED: - g_value_set_boolean (value, self->priv->extended); - break; - case PROP_NAME: - g_value_set_string (value, gtk_label_get_text (GTK_LABEL (self->priv->label))); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -gvc_channel_bar_class_init (GvcChannelBarClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - object_class->set_property = gvc_channel_bar_set_property; - object_class->get_property = gvc_channel_bar_get_property; - - properties[PROP_CONTROL] = - g_param_spec_object ("control", - "Control", - "MateMixer stream control", - MATE_MIXER_TYPE_STREAM_CONTROL, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT | - G_PARAM_STATIC_STRINGS); - - properties[PROP_ORIENTATION] = - g_param_spec_enum ("orientation", - "Orientation", - "The orientation of the scale", - GTK_TYPE_ORIENTATION, - GTK_ORIENTATION_VERTICAL, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS); - - properties[PROP_SHOW_MUTE] = - g_param_spec_boolean ("show-mute", - "show mute", - "Whether stream is muted", - FALSE, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT | - G_PARAM_STATIC_STRINGS); - - properties[PROP_SHOW_ICONS] = - g_param_spec_boolean ("show-icons", - "show mute", - "Whether to show low and high icons", - FALSE, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT | - G_PARAM_STATIC_STRINGS); - - properties[PROP_SHOW_MARKS] = - g_param_spec_boolean ("show-marks", - "Show marks", - "Whether to show scale marks", - FALSE, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT | - G_PARAM_STATIC_STRINGS); - - properties[PROP_EXTENDED] = - g_param_spec_boolean ("extended", - "Extended", - "Allow the scale to be extended above normal volume", - FALSE, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS); - - properties[PROP_NAME] = - g_param_spec_string ("name", - "Name", - "Name to display for this stream", - NULL, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT | - G_PARAM_STATIC_STRINGS); - - properties[PROP_ICON_NAME] = - g_param_spec_string ("icon-name", - "Icon name", - "Name of icon to display for this stream", - NULL, - G_PARAM_WRITABLE | - G_PARAM_CONSTRUCT | - G_PARAM_STATIC_STRINGS); - - properties[PROP_LOW_ICON_NAME] = - g_param_spec_string ("low-icon-name", - "Low icon name", - "Name of low volume icon to display for this stream", - "audio-volume-low", - G_PARAM_WRITABLE | - G_PARAM_CONSTRUCT | - G_PARAM_STATIC_STRINGS); - - properties[PROP_HIGH_ICON_NAME] = - g_param_spec_string ("high-icon-name", - "High icon name", - "Name of high volume icon to display for this stream", - "audio-volume-high", - G_PARAM_WRITABLE | - G_PARAM_CONSTRUCT | - G_PARAM_STATIC_STRINGS); - - g_object_class_install_properties (object_class, N_PROPERTIES, properties); - - g_type_class_add_private (klass, sizeof (GvcChannelBarPrivate)); -} - -static void -gvc_channel_bar_init (GvcChannelBar *bar) -{ - GtkWidget *frame; - - bar->priv = GVC_CHANNEL_BAR_GET_PRIVATE (bar); - - /* Mute button */ - bar->priv->mute_button = gtk_check_button_new_with_label (_("Mute")); - gtk_widget_set_no_show_all (bar->priv->mute_button, TRUE); - - g_signal_connect (bar->priv->mute_button, - "toggled", - G_CALLBACK (on_mute_button_toggled), - bar); - - bar->priv->mute_box = gtk_alignment_new (0.5, 0.5, 0, 0); - gtk_container_add (GTK_CONTAINER (bar->priv->mute_box), bar->priv->mute_button); - - bar->priv->image = gtk_image_new (); - gtk_widget_set_no_show_all (bar->priv->image, TRUE); - - /* Low/high icons */ - bar->priv->low_image = gtk_image_new (); - gtk_widget_set_no_show_all (bar->priv->low_image, TRUE); - - bar->priv->high_image = gtk_image_new (); - gtk_widget_set_no_show_all (bar->priv->high_image, TRUE); - - bar->priv->label = gtk_label_new (NULL); - gtk_misc_set_alignment (GTK_MISC (bar->priv->label), 0.0, 0.5); - gtk_widget_set_no_show_all (bar->priv->label, TRUE); - - /* Frame */ - frame = gtk_frame_new (NULL); - gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_NONE); - gtk_box_pack_start (GTK_BOX (bar), frame, TRUE, TRUE, 0); - - gtk_widget_show_all (frame); - - /* Create a default adjustment */ - bar->priv->adjustment = GTK_ADJUSTMENT (gtk_adjustment_new (0, 0, 0, 0, 0, 0)); - - g_object_ref_sink (bar->priv->adjustment); - - g_signal_connect (bar->priv->adjustment, - "value-changed", - G_CALLBACK (on_adjustment_value_changed), - bar); - - /* Initially create a vertical scale box */ - bar->priv->orientation = GTK_ORIENTATION_VERTICAL; - - create_scale_box (bar); - - gtk_container_add (GTK_CONTAINER (frame), bar->priv->scale_box); -} - -GtkWidget * -gvc_channel_bar_new (MateMixerStreamControl *control) -{ - return g_object_new (GVC_TYPE_CHANNEL_BAR, - "control", control, -#if GTK_CHECK_VERSION (3, 0, 0) - "orientation", GTK_ORIENTATION_HORIZONTAL, -#endif - NULL); -} diff --git a/mate-volume-control/src/gvc-channel-bar.h b/mate-volume-control/src/gvc-channel-bar.h deleted file mode 100644 index 1c80be9..0000000 --- a/mate-volume-control/src/gvc-channel-bar.h +++ /dev/null @@ -1,118 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- - * - * Copyright (C) 2008 Red Hat, Inc. - * Copyright (C) 2014 Michal Ratajsky <[email protected]> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ - -#ifndef __GVC_CHANNEL_BAR_H -#define __GVC_CHANNEL_BAR_H - -#include <glib.h> -#include <glib-object.h> -#include <gtk/gtk.h> - -#include <libmatemixer/matemixer.h> - -G_BEGIN_DECLS - -#define GVC_TYPE_CHANNEL_BAR (gvc_channel_bar_get_type ()) -#define GVC_CHANNEL_BAR(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GVC_TYPE_CHANNEL_BAR, GvcChannelBar)) -#define GVC_CHANNEL_BAR_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GVC_TYPE_CHANNEL_BAR, GvcChannelBarClass)) -#define GVC_IS_CHANNEL_BAR(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GVC_TYPE_CHANNEL_BAR)) -#define GVC_IS_CHANNEL_BAR_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GVC_TYPE_CHANNEL_BAR)) -#define GVC_CHANNEL_BAR_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GVC_TYPE_CHANNEL_BAR, GvcChannelBarClass)) - -typedef struct _GvcChannelBar GvcChannelBar; -typedef struct _GvcChannelBarClass GvcChannelBarClass; -typedef struct _GvcChannelBarPrivate GvcChannelBarPrivate; - -struct _GvcChannelBar -{ -#if GTK_CHECK_VERSION (3, 0, 0) - GtkBox parent; -#else - GtkHBox parent; -#endif - GvcChannelBarPrivate *priv; -}; - -struct _GvcChannelBarClass -{ -#if GTK_CHECK_VERSION (3, 0, 0) - GtkBoxClass parent_class; -#else - GtkHBoxClass parent_class; -#endif - - void (* changed) (GvcChannelBar *bar); -}; - -GType gvc_channel_bar_get_type (void); - -GtkWidget * gvc_channel_bar_new (MateMixerStreamControl *control); - -MateMixerStreamControl *gvc_channel_bar_get_control (GvcChannelBar *bar); -void gvc_channel_bar_set_control (GvcChannelBar *bar, - MateMixerStreamControl *control); - -const gchar * gvc_channel_bar_get_name (GvcChannelBar *bar); -void gvc_channel_bar_set_name (GvcChannelBar *bar, - const gchar *name); - -const gchar * gvc_channel_bar_get_icon_name (GvcChannelBar *bar); -void gvc_channel_bar_set_icon_name (GvcChannelBar *bar, - const gchar *icon_name); - -const gchar * gvc_channel_bar_get_low_icon_name (GvcChannelBar *bar); -void gvc_channel_bar_set_low_icon_name (GvcChannelBar *bar, - const gchar *icon_name); - -const gchar * gvc_channel_bar_get_high_icon_name (GvcChannelBar *bar); -void gvc_channel_bar_set_high_icon_name (GvcChannelBar *bar, - const gchar *icon_name); - -GtkOrientation gvc_channel_bar_get_orientation (GvcChannelBar *bar); -void gvc_channel_bar_set_orientation (GvcChannelBar *bar, - GtkOrientation orientation); - -gboolean gvc_channel_bar_get_show_icons (GvcChannelBar *bar); -void gvc_channel_bar_set_show_icons (GvcChannelBar *bar, - gboolean show_mute); - -gboolean gvc_channel_bar_get_show_mute (GvcChannelBar *bar); -void gvc_channel_bar_set_show_mute (GvcChannelBar *bar, - gboolean show_mute); - -gboolean gvc_channel_bar_get_show_marks (GvcChannelBar *bar); -void gvc_channel_bar_set_show_marks (GvcChannelBar *bar, - gboolean show_marks); - -gboolean gvc_channel_bar_get_extended (GvcChannelBar *bar); -void gvc_channel_bar_set_extended (GvcChannelBar *bar, - gboolean extended); - -void gvc_channel_bar_set_size_group (GvcChannelBar *bar, - GtkSizeGroup *group, - gboolean symmetric); - -gboolean gvc_channel_bar_scroll (GvcChannelBar *bar, - GdkScrollDirection direction); - -G_END_DECLS - -#endif /* __GVC_CHANNEL_BAR_H */ diff --git a/mate-volume-control/src/gvc-combo-box.c b/mate-volume-control/src/gvc-combo-box.c deleted file mode 100644 index b2a273f..0000000 --- a/mate-volume-control/src/gvc-combo-box.c +++ /dev/null @@ -1,397 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- - * - * Copyright (C) 2009 Bastien Nocera - * Copyright (C) 2014 Michal Ratajsky <[email protected]> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ - -#include <glib.h> -#include <glib/gi18n.h> -#include <glib-object.h> -#include <gtk/gtk.h> - -#include <libmatemixer/matemixer.h> - -#include "gvc-combo-box.h" - -#define GVC_COMBO_BOX_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GVC_TYPE_COMBO_BOX, GvcComboBoxPrivate)) - -struct _GvcComboBoxPrivate -{ - GtkWidget *drop_box; - GtkWidget *start_box; - GtkWidget *end_box; - GtkWidget *label; - GtkWidget *button; - GtkTreeModel *model; - GtkWidget *combobox; - gboolean set_called; - GtkSizeGroup *size_group; - gboolean symmetric; -}; - -enum { - COL_NAME, - COL_HUMAN_NAME, - NUM_COLS -}; - -enum { - CHANGED, - BUTTON_CLICKED, - LAST_SIGNAL -}; - -static guint signals[LAST_SIGNAL] = { 0, }; - -enum { - PROP_0, - PROP_LABEL, - PROP_SHOW_BUTTON, - PROP_BUTTON_LABEL, - N_PROPERTIES -}; - -static GParamSpec *properties[N_PROPERTIES] = { NULL, }; - -static void gvc_combo_box_class_init (GvcComboBoxClass *klass); -static void gvc_combo_box_init (GvcComboBox *combo); -static void gvc_combo_box_dispose (GObject *object); - -#if GTK_CHECK_VERSION (3, 0, 0) -G_DEFINE_TYPE (GvcComboBox, gvc_combo_box, GTK_TYPE_BOX) -#else -G_DEFINE_TYPE (GvcComboBox, gvc_combo_box, GTK_TYPE_HBOX) -#endif - -void -gvc_combo_box_set_size_group (GvcComboBox *combobox, - GtkSizeGroup *group, - gboolean symmetric) -{ - g_return_if_fail (GVC_IS_COMBO_BOX (combobox)); - g_return_if_fail (GTK_IS_SIZE_GROUP (group)); - - combobox->priv->size_group = group; - combobox->priv->symmetric = symmetric; - - if (combobox->priv->size_group != NULL) { - gtk_size_group_add_widget (combobox->priv->size_group, - combobox->priv->start_box); - - if (combobox->priv->symmetric) - gtk_size_group_add_widget (combobox->priv->size_group, - combobox->priv->end_box); - } - gtk_widget_queue_draw (GTK_WIDGET (combobox)); -} - -static void -gvc_combo_box_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - GvcComboBox *self = GVC_COMBO_BOX (object); - - switch (prop_id) { - case PROP_LABEL: - gtk_label_set_text_with_mnemonic (GTK_LABEL (self->priv->label), g_value_get_string (value)); - break; - case PROP_BUTTON_LABEL: - gtk_button_set_label (GTK_BUTTON (self->priv->button), g_value_get_string (value)); - break; - case PROP_SHOW_BUTTON: - gtk_widget_set_visible (self->priv->button, g_value_get_boolean (value)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -gvc_combo_box_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - GvcComboBox *self = GVC_COMBO_BOX (object); - - switch (prop_id) { - case PROP_LABEL: - g_value_set_string (value, gtk_label_get_text (GTK_LABEL (self->priv->label))); - break; - case PROP_BUTTON_LABEL: - g_value_set_string (value, gtk_button_get_label (GTK_BUTTON (self->priv->button))); - break; - case PROP_SHOW_BUTTON: - g_value_set_boolean (value, gtk_widget_get_visible (self->priv->button)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -gvc_combo_box_class_init (GvcComboBoxClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - object_class->dispose = gvc_combo_box_dispose; - object_class->set_property = gvc_combo_box_set_property; - object_class->get_property = gvc_combo_box_get_property; - - properties[PROP_LABEL] = - g_param_spec_string ("label", - "label", - "The combo box label", - _("_Profile:"), - G_PARAM_READWRITE | G_PARAM_CONSTRUCT); - - properties[PROP_SHOW_BUTTON] = - g_param_spec_boolean ("show-button", - "show-button", - "Whether to show the button", - FALSE, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT); - - properties[PROP_BUTTON_LABEL] = - g_param_spec_string ("button-label", - "button-label", - "The button's label", - "", - G_PARAM_READWRITE | G_PARAM_CONSTRUCT); - - g_object_class_install_properties (object_class, N_PROPERTIES, properties); - - signals[CHANGED] = - g_signal_new ("changed", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (GvcComboBoxClass, changed), - NULL, NULL, - g_cclosure_marshal_VOID__STRING, - G_TYPE_NONE, 1, G_TYPE_STRING); - - signals[BUTTON_CLICKED] = - g_signal_new ("button-clicked", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (GvcComboBoxClass, button_clicked), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0, G_TYPE_NONE); - - g_type_class_add_private (klass, sizeof (GvcComboBoxPrivate)); -} - -void -gvc_combo_box_set_options (GvcComboBox *combobox, const GList *options) -{ - const GList *l; - - g_return_if_fail (GVC_IS_COMBO_BOX (combobox)); - g_return_if_fail (combobox->priv->set_called == FALSE); - - for (l = options; l != NULL; l = l->next) { - MateMixerSwitchOption *option = MATE_MIXER_SWITCH_OPTION (l->data); - - gtk_list_store_insert_with_values (GTK_LIST_STORE (combobox->priv->model), - NULL, - G_MAXINT, - COL_NAME, - mate_mixer_switch_option_get_name (option), - COL_HUMAN_NAME, - mate_mixer_switch_option_get_label (option), - -1); - } - combobox->priv->set_called = TRUE; -} - -void -gvc_combo_box_set_active (GvcComboBox *combobox, const gchar *id) -{ - GtkTreeIter iter; - gboolean cont; - - g_return_if_fail (GVC_IS_COMBO_BOX (combobox)); - g_return_if_fail (id != NULL); - - cont = gtk_tree_model_get_iter_first (combobox->priv->model, &iter); - while (cont != FALSE) { - gchar *name; - - gtk_tree_model_get (combobox->priv->model, &iter, - COL_NAME, &name, - -1); - if (g_strcmp0 (name, id) == 0) { - gtk_combo_box_set_active_iter (GTK_COMBO_BOX (combobox->priv->combobox), &iter); - g_free (name); - return; - } - g_free (name); - - gtk_tree_model_iter_next (combobox->priv->model, &iter); - } - g_warning ("Could not find id '%s' in combo box", id); -} - -static void -on_combo_box_changed (GtkComboBox *widget, GvcComboBox *combobox) -{ - GtkTreeIter iter; - gchar *profile; - - if (gtk_combo_box_get_active_iter (GTK_COMBO_BOX (widget), &iter) == FALSE) { - g_warning ("Could not find an active profile or port"); - return; - } - - gtk_tree_model_get (combobox->priv->model, &iter, - COL_NAME, &profile, - -1); - - g_signal_emit (combobox, signals[CHANGED], 0, profile); - g_free (profile); -} - -static void -on_combo_box_button_clicked (GtkButton *button, GvcComboBox *combobox) -{ - g_signal_emit (combobox, signals[BUTTON_CLICKED], 0); -} - -static void -gvc_combo_box_init (GvcComboBox *combobox) -{ - GtkWidget *frame; - GtkCellRenderer *renderer; - - combobox->priv = GVC_COMBO_BOX_GET_PRIVATE (combobox); - - combobox->priv->model = GTK_TREE_MODEL (gtk_list_store_new (NUM_COLS, - G_TYPE_STRING, - G_TYPE_STRING)); - combobox->priv->label = gtk_label_new (NULL); - - gtk_misc_set_alignment (GTK_MISC (combobox->priv->label), 0.0, 0.5); - - /* Frame */ - frame = gtk_frame_new (NULL); - gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_NONE); - gtk_box_pack_start (GTK_BOX (combobox), frame, TRUE, TRUE, 0); - -#if GTK_CHECK_VERSION (3, 0, 0) - combobox->priv->drop_box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6); - combobox->priv->start_box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6); - combobox->priv->end_box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6); -#else - combobox->priv->drop_box = gtk_hbox_new (FALSE, 6); - combobox->priv->start_box = gtk_hbox_new (FALSE, 6); - combobox->priv->end_box = gtk_hbox_new (FALSE, 6); -#endif - combobox->priv->combobox = gtk_combo_box_new_with_model (combobox->priv->model); - - renderer = gtk_cell_renderer_text_new (); - gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combobox->priv->combobox), - renderer, - FALSE); - gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (combobox->priv->combobox), - renderer, - "text", - COL_HUMAN_NAME); - -#if GTK_CHECK_VERSION (3, 0, 0) - /* Make sure the combo box does not get too long on long profile names */ - g_object_set (G_OBJECT (renderer), - "ellipsize", - PANGO_ELLIPSIZE_END, - NULL); - - gtk_combo_box_set_popup_fixed_width (GTK_COMBO_BOX (combobox->priv->combobox), FALSE); -#endif - - gtk_box_pack_start (GTK_BOX (combobox->priv->drop_box), - combobox->priv->start_box, - FALSE, FALSE, 0); - gtk_box_pack_start (GTK_BOX (combobox->priv->start_box), - combobox->priv->label, - FALSE, FALSE, 0); - gtk_box_pack_start (GTK_BOX (combobox->priv->drop_box), - combobox->priv->combobox, - TRUE, TRUE, 0); - - combobox->priv->button = gtk_button_new_with_label (""); - - gtk_box_pack_start (GTK_BOX (combobox->priv->drop_box), - combobox->priv->button, - FALSE, FALSE, 0); - gtk_box_pack_start (GTK_BOX (combobox->priv->drop_box), - combobox->priv->end_box, - FALSE, FALSE, 0); - - gtk_widget_set_no_show_all (combobox->priv->button, TRUE); - - if (combobox->priv->size_group != NULL) { - gtk_size_group_add_widget (combobox->priv->size_group, - combobox->priv->start_box); - - if (combobox->priv->symmetric) - gtk_size_group_add_widget (combobox->priv->size_group, - combobox->priv->end_box); - } - - gtk_label_set_mnemonic_widget (GTK_LABEL (combobox->priv->label), - combobox->priv->combobox); - - gtk_container_add (GTK_CONTAINER (frame), combobox->priv->drop_box); - gtk_widget_show_all (frame); - - g_signal_connect (G_OBJECT (combobox->priv->combobox), - "changed", - G_CALLBACK (on_combo_box_changed), - combobox); - g_signal_connect (G_OBJECT (combobox->priv->button), - "clicked", - G_CALLBACK (on_combo_box_button_clicked), - combobox); -} - -static void -gvc_combo_box_dispose (GObject *object) -{ - GvcComboBox *combobox; - - combobox = GVC_COMBO_BOX (object); - - g_clear_object (&combobox->priv->model); - - G_OBJECT_CLASS (gvc_combo_box_parent_class)->dispose (object); -} - -GtkWidget * -gvc_combo_box_new (const gchar *label) -{ - return g_object_new (GVC_TYPE_COMBO_BOX, - "label", label, -#if GTK_CHECK_VERSION (3, 0, 0) - "orientation", GTK_ORIENTATION_HORIZONTAL, -#endif - NULL); -} diff --git a/mate-volume-control/src/gvc-combo-box.h b/mate-volume-control/src/gvc-combo-box.h deleted file mode 100644 index 9a2f425..0000000 --- a/mate-volume-control/src/gvc-combo-box.h +++ /dev/null @@ -1,79 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- - * - * Copyright (C) 2009 Red Hat, Inc. - * Copyright (C) 2014 Michal Ratajsky <[email protected]> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ - -#ifndef __GVC_COMBO_BOX_H -#define __GVC_COMBO_BOX_H - -#include <glib.h> -#include <glib-object.h> -#include <gtk/gtk.h> - -G_BEGIN_DECLS - -#define GVC_TYPE_COMBO_BOX (gvc_combo_box_get_type ()) -#define GVC_COMBO_BOX(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GVC_TYPE_COMBO_BOX, GvcComboBox)) -#define GVC_COMBO_BOX_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GVC_TYPE_COMBO_BOX, GvcComboBoxClass)) -#define GVC_IS_COMBO_BOX(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GVC_TYPE_COMBO_BOX)) -#define GVC_IS_COMBO_BOX_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GVC_TYPE_COMBO_BOX)) -#define GVC_COMBO_BOX_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GVC_TYPE_COMBO_BOX, GvcComboBoxClass)) - -typedef struct _GvcComboBox GvcComboBox; -typedef struct _GvcComboBoxClass GvcComboBoxClass; -typedef struct _GvcComboBoxPrivate GvcComboBoxPrivate; - -struct _GvcComboBox -{ -#if GTK_CHECK_VERSION (3, 0, 0) - GtkBox parent; -#else - GtkHBox parent; -#endif - GvcComboBoxPrivate *priv; -}; - -struct _GvcComboBoxClass -{ -#if GTK_CHECK_VERSION (3, 0, 0) - GtkBoxClass parent_class; -#else - GtkHBoxClass parent_class; -#endif - void (* changed) (GvcComboBox *combobox, - const gchar *name); - void (* button_clicked) (GvcComboBox *combobox); -}; - -GType gvc_combo_box_get_type (void) G_GNUC_CONST; - -GtkWidget * gvc_combo_box_new (const gchar *label); - -void gvc_combo_box_set_size_group (GvcComboBox *combobox, - GtkSizeGroup *group, - gboolean symmetric); - -void gvc_combo_box_set_options (GvcComboBox *combobox, - const GList *options); -void gvc_combo_box_set_active (GvcComboBox *combobox, - const gchar *id); - -G_END_DECLS - -#endif /* __GVC_COMBO_BOX_H */ diff --git a/mate-volume-control/src/gvc-level-bar.c b/mate-volume-control/src/gvc-level-bar.c deleted file mode 100644 index 029b346..0000000 --- a/mate-volume-control/src/gvc-level-bar.c +++ /dev/null @@ -1,876 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- - * - * Copyright (C) 2008 William Jon McCann <[email protected]> - * Copyright (C) 2014 Michal Ratajsky <[email protected]> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ - -// XXX on gtk3 the last two squares don't get filled - -#include <math.h> -#include <glib.h> -#include <glib/gi18n.h> -#include <glib-object.h> -#include <gtk/gtk.h> - -#include "gvc-level-bar.h" -#include "gvc-utils.h" - -#define GVC_LEVEL_BAR_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GVC_TYPE_LEVEL_BAR, GvcLevelBarPrivate)) - -#define NUM_BOXES 15 -#define MIN_HORIZONTAL_BAR_WIDTH 150 -#define HORIZONTAL_BAR_HEIGHT 6 -#define VERTICAL_BAR_WIDTH 6 -#define MIN_VERTICAL_BAR_HEIGHT 400 - -typedef struct { - int peak_num; - int max_peak_num; - GdkRectangle area; - int delta; - int box_width; - int box_height; - int box_radius; -#if GTK_CHECK_VERSION (3, 0, 0) - GdkRGBA color_bg; - GdkRGBA color_fg; - GdkRGBA color_dark; -#else - GdkColor color_bg; - GdkColor color_fg; - GdkColor color_dark; -#endif -} LevelBarLayout; - -struct _GvcLevelBarPrivate -{ - GtkOrientation orientation; - GtkAdjustment *peak_adjustment; - GtkAdjustment *rms_adjustment; - GvcLevelScale scale; - gdouble peak_fraction; - gdouble rms_fraction; - gdouble max_peak; - guint max_peak_id; - LevelBarLayout layout; -}; - -enum -{ - PROP_0, - PROP_PEAK_ADJUSTMENT, - PROP_RMS_ADJUSTMENT, - PROP_SCALE, - PROP_ORIENTATION, - N_PROPERTIES -}; - -static GParamSpec *properties[N_PROPERTIES] = { NULL, }; - -static void gvc_level_bar_class_init (GvcLevelBarClass *klass); -static void gvc_level_bar_init (GvcLevelBar *bar); -static void gvc_level_bar_finalize (GObject *object); - -G_DEFINE_TYPE (GvcLevelBar, gvc_level_bar, GTK_TYPE_WIDGET) - -static gboolean -layout_changed (LevelBarLayout *layout1, LevelBarLayout *layout2) -{ - if (layout1->area.x != layout2->area.x) - return TRUE; - if (layout1->area.y != layout2->area.y) - return TRUE; - if (layout1->area.width != layout2->area.width) - return TRUE; - if (layout1->area.height != layout2->area.height) - return TRUE; - - if (layout1->delta != layout2->delta) - return TRUE; - if (layout1->peak_num != layout2->peak_num) - return TRUE; - if (layout1->max_peak_num != layout2->max_peak_num) - return TRUE; - -#if GTK_CHECK_VERSION (3, 0, 0) - if (!gdk_rgba_equal (&layout1->color_fg, &layout2->color_fg)) - return TRUE; - if (!gdk_rgba_equal (&layout1->color_bg, &layout2->color_bg)) - return TRUE; - if (!gdk_rgba_equal (&layout1->color_dark, &layout2->color_dark)) - return TRUE; -#else - if (!gdk_color_equal (&layout1->color_fg, &layout2->color_fg)) - return TRUE; - if (!gdk_color_equal (&layout1->color_bg, &layout2->color_bg)) - return TRUE; - if (!gdk_color_equal (&layout1->color_dark, &layout2->color_dark)) - return TRUE; -#endif - return FALSE; -} - -static gdouble -fraction_from_adjustment (GvcLevelBar *bar, - GtkAdjustment *adjustment) -{ - gdouble level; - gdouble fraction = 0.0; - gdouble min; - gdouble max; - - level = gtk_adjustment_get_value (adjustment); - min = gtk_adjustment_get_lower (adjustment); - max = gtk_adjustment_get_upper (adjustment); - - switch (bar->priv->scale) { - case GVC_LEVEL_SCALE_LINEAR: - fraction = (level - min) / (max - min); - break; - case GVC_LEVEL_SCALE_LOG: - fraction = log10 ((level - min + 1) / (max - min + 1)); - break; - } - - return fraction; -} - -static gboolean -reset_max_peak (GvcLevelBar *bar) -{ - bar->priv->max_peak = gtk_adjustment_get_lower (bar->priv->peak_adjustment); - - bar->priv->layout.max_peak_num = 0; - - gtk_widget_queue_draw (GTK_WIDGET (bar)); - - bar->priv->max_peak_id = 0; - return FALSE; -} - -static void -bar_calc_layout (GvcLevelBar *bar) -{ - int peak_level; - int max_peak_level; - GtkAllocation allocation; - -#if GTK_CHECK_VERSION (3, 0, 0) - GtkStyleContext *context; - - context = gtk_widget_get_style_context (GTK_WIDGET (bar)); - - gtk_style_context_get_background_color (context, - GTK_STATE_FLAG_NORMAL, - &bar->priv->layout.color_bg); - gtk_style_context_get_background_color (context, - GTK_STATE_FLAG_SELECTED, - &bar->priv->layout.color_fg); - gtk_style_context_get_color (context, - GTK_STATE_FLAG_NORMAL, - &bar->priv->layout.color_dark); - - gvc_color_shade (&bar->priv->layout.color_dark, - &bar->priv->layout.color_dark, - 0.7); -#else - GtkStyle *style; - - style = gtk_widget_get_style (GTK_WIDGET (bar)); - - bar->priv->layout.color_bg = style->bg[GTK_STATE_NORMAL]; - bar->priv->layout.color_fg = style->bg[GTK_STATE_SELECTED]; - bar->priv->layout.color_dark = style->dark[GTK_STATE_NORMAL]; -#endif - - gtk_widget_get_allocation (GTK_WIDGET (bar), &allocation); - - bar->priv->layout.area.width = allocation.width - 2; - bar->priv->layout.area.height = allocation.height - 2; - - if (bar->priv->orientation == GTK_ORIENTATION_VERTICAL) { - peak_level = bar->priv->peak_fraction * bar->priv->layout.area.height; - max_peak_level = bar->priv->max_peak * bar->priv->layout.area.height; - - bar->priv->layout.delta = bar->priv->layout.area.height / NUM_BOXES; - bar->priv->layout.area.x = 0; - bar->priv->layout.area.y = 0; - bar->priv->layout.box_height = bar->priv->layout.delta / 2; - bar->priv->layout.box_width = bar->priv->layout.area.width; - bar->priv->layout.box_radius = bar->priv->layout.box_width / 2; - } else { - peak_level = bar->priv->peak_fraction * bar->priv->layout.area.width; - max_peak_level = bar->priv->max_peak * bar->priv->layout.area.width; - - bar->priv->layout.delta = bar->priv->layout.area.width / NUM_BOXES; - bar->priv->layout.area.x = 0; - bar->priv->layout.area.y = 0; - bar->priv->layout.box_width = bar->priv->layout.delta / 2; - bar->priv->layout.box_height = bar->priv->layout.area.height; - bar->priv->layout.box_radius = bar->priv->layout.box_height / 2; - } - - bar->priv->layout.peak_num = peak_level / bar->priv->layout.delta; - bar->priv->layout.max_peak_num = max_peak_level / bar->priv->layout.delta; -} - -static void -update_peak_value (GvcLevelBar *bar) -{ - gdouble value; - LevelBarLayout layout; - - value = fraction_from_adjustment (bar, bar->priv->peak_adjustment); - - bar->priv->peak_fraction = value; - - if (value > bar->priv->max_peak) { - if (bar->priv->max_peak_id > 0) - g_source_remove (bar->priv->max_peak_id); - - bar->priv->max_peak_id = - g_timeout_add_seconds (1, (GSourceFunc) reset_max_peak, bar); - bar->priv->max_peak = value; - } - - layout = bar->priv->layout; - - bar_calc_layout (bar); - - if (layout_changed (&bar->priv->layout, &layout)) - gtk_widget_queue_draw (GTK_WIDGET (bar)); -} - -static void -update_rms_value (GvcLevelBar *bar) -{ - bar->priv->rms_fraction = fraction_from_adjustment (bar, bar->priv->rms_adjustment); -} - -GtkOrientation -gvc_level_bar_get_orientation (GvcLevelBar *bar) -{ - g_return_val_if_fail (GVC_IS_LEVEL_BAR (bar), 0); - - return bar->priv->orientation; -} - -void -gvc_level_bar_set_orientation (GvcLevelBar *bar, - GtkOrientation orientation) -{ - g_return_if_fail (GVC_IS_LEVEL_BAR (bar)); - - if (orientation != bar->priv->orientation) { - if (G_UNLIKELY (orientation != GTK_ORIENTATION_VERTICAL && - orientation != GTK_ORIENTATION_HORIZONTAL)) { - g_warn_if_reached (); - return; - } - - bar->priv->orientation = orientation; - - gtk_widget_queue_draw (GTK_WIDGET (bar)); - - g_object_notify_by_pspec (G_OBJECT (bar), properties[PROP_ORIENTATION]); - } -} - -static void -on_peak_adjustment_value_changed (GtkAdjustment *adjustment, - GvcLevelBar *bar) -{ - update_peak_value (bar); -} - -static void -on_rms_adjustment_value_changed (GtkAdjustment *adjustment, - GvcLevelBar *bar) -{ - update_rms_value (bar); -} - -void -gvc_level_bar_set_peak_adjustment (GvcLevelBar *bar, - GtkAdjustment *adjustment) -{ - g_return_if_fail (GVC_LEVEL_BAR (bar)); - g_return_if_fail (GTK_IS_ADJUSTMENT (adjustment)); - - if (bar->priv->peak_adjustment != NULL) { - g_signal_handlers_disconnect_by_func (G_OBJECT (bar->priv->peak_adjustment), - G_CALLBACK (on_peak_adjustment_value_changed), - bar); - g_object_unref (bar->priv->peak_adjustment); - } - - bar->priv->peak_adjustment = g_object_ref_sink (adjustment); - - g_signal_connect (G_OBJECT (bar->priv->peak_adjustment), - "value-changed", - G_CALLBACK (on_peak_adjustment_value_changed), - bar); - - update_peak_value (bar); - - g_object_notify_by_pspec (G_OBJECT (bar), properties[PROP_PEAK_ADJUSTMENT]); -} - -void -gvc_level_bar_set_rms_adjustment (GvcLevelBar *bar, - GtkAdjustment *adjustment) -{ - g_return_if_fail (GVC_LEVEL_BAR (bar)); - g_return_if_fail (GTK_IS_ADJUSTMENT (adjustment)); - - if (bar->priv->rms_adjustment != NULL) { - g_signal_handlers_disconnect_by_func (G_OBJECT (bar->priv->rms_adjustment), - G_CALLBACK (on_rms_adjustment_value_changed), - bar); - g_object_unref (bar->priv->rms_adjustment); - } - - bar->priv->rms_adjustment = g_object_ref_sink (adjustment); - - g_signal_connect (G_OBJECT (bar->priv->rms_adjustment), - "value-changed", - G_CALLBACK (on_rms_adjustment_value_changed), - bar); - - update_rms_value (bar); - - g_object_notify_by_pspec (G_OBJECT (bar), properties[PROP_RMS_ADJUSTMENT]); -} - -GtkAdjustment * -gvc_level_bar_get_peak_adjustment (GvcLevelBar *bar) -{ - g_return_val_if_fail (GVC_IS_LEVEL_BAR (bar), NULL); - - return bar->priv->peak_adjustment; -} - -GtkAdjustment * -gvc_level_bar_get_rms_adjustment (GvcLevelBar *bar) -{ - g_return_val_if_fail (GVC_IS_LEVEL_BAR (bar), NULL); - - return bar->priv->rms_adjustment; -} - -void -gvc_level_bar_set_scale (GvcLevelBar *bar, GvcLevelScale scale) -{ - g_return_if_fail (GVC_IS_LEVEL_BAR (bar)); - - if (scale != bar->priv->scale) { - if (G_UNLIKELY (scale != GVC_LEVEL_SCALE_LINEAR && - scale != GVC_LEVEL_SCALE_LOG)) { - g_warn_if_reached (); - return; - } - bar->priv->scale = scale; - - update_peak_value (bar); - update_rms_value (bar); - - g_object_notify_by_pspec (G_OBJECT (bar), properties[PROP_SCALE]); - } -} - -static void -gvc_level_bar_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - GvcLevelBar *self = GVC_LEVEL_BAR (object); - - switch (prop_id) { - case PROP_SCALE: - gvc_level_bar_set_scale (self, g_value_get_int (value)); - break; - case PROP_ORIENTATION: - gvc_level_bar_set_orientation (self, g_value_get_enum (value)); - break; - case PROP_PEAK_ADJUSTMENT: - gvc_level_bar_set_peak_adjustment (self, g_value_get_object (value)); - break; - case PROP_RMS_ADJUSTMENT: - gvc_level_bar_set_rms_adjustment (self, g_value_get_object (value)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -gvc_level_bar_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - GvcLevelBar *self = GVC_LEVEL_BAR (object); - - switch (prop_id) { - case PROP_SCALE: - g_value_set_int (value, self->priv->scale); - break; - case PROP_ORIENTATION: - g_value_set_enum (value, self->priv->orientation); - break; - case PROP_PEAK_ADJUSTMENT: - g_value_set_object (value, self->priv->peak_adjustment); - break; - case PROP_RMS_ADJUSTMENT: - g_value_set_object (value, self->priv->rms_adjustment); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -gvc_level_bar_size_request (GtkWidget *widget, - GtkRequisition *requisition) -{ - GvcLevelBar *bar; - - g_return_if_fail (GVC_IS_LEVEL_BAR (widget)); - g_return_if_fail (requisition != NULL); - - bar = GVC_LEVEL_BAR (widget); - - switch (bar->priv->orientation) { - case GTK_ORIENTATION_VERTICAL: - requisition->width = VERTICAL_BAR_WIDTH; - requisition->height = MIN_VERTICAL_BAR_HEIGHT; - break; - case GTK_ORIENTATION_HORIZONTAL: - requisition->width = MIN_HORIZONTAL_BAR_WIDTH; - requisition->height = HORIZONTAL_BAR_HEIGHT; - break; - } -} - -#if GTK_CHECK_VERSION (3, 0, 0) -static void -gvc_level_bar_get_preferred_width (GtkWidget *widget, - gint *minimum, - gint *natural) -{ - GtkRequisition requisition; - - gvc_level_bar_size_request (widget, &requisition); - - if (minimum != NULL) - *minimum = requisition.width; - if (natural != NULL) - *natural = requisition.width; -} - -static void -gvc_level_bar_get_preferred_height (GtkWidget *widget, - gint *minimum, - gint *natural) -{ - GtkRequisition requisition; - - gvc_level_bar_size_request (widget, &requisition); - - if (minimum != NULL) - *minimum = requisition.height; - if (natural != NULL) - *natural = requisition.height; -} -#endif - -static void -gvc_level_bar_size_allocate (GtkWidget *widget, GtkAllocation *allocation) -{ - GvcLevelBar *bar; - - bar = GVC_LEVEL_BAR (widget); - - /* FIXME: add height property, labels, etc */ - GTK_WIDGET_CLASS (gvc_level_bar_parent_class)->size_allocate (widget, allocation); - - gtk_widget_set_allocation (widget, allocation); - gtk_widget_get_allocation (widget, allocation); - - if (bar->priv->orientation == GTK_ORIENTATION_VERTICAL) { - allocation->height = MIN (allocation->height, MIN_VERTICAL_BAR_HEIGHT); - allocation->width = MAX (allocation->width, VERTICAL_BAR_WIDTH); - } else { - allocation->width = MIN (allocation->width, MIN_HORIZONTAL_BAR_WIDTH); - allocation->height = MAX (allocation->height, HORIZONTAL_BAR_HEIGHT); - } - - bar_calc_layout (bar); -} - -static void -curved_rectangle (cairo_t *cr, - double x0, - double y0, - double width, - double height, - double radius) -{ - double x1; - double y1; - - x1 = x0 + width; - y1 = y0 + height; - - if (!width || !height) - return; - - if (width / 2 < radius) { - if (height / 2 < radius) { - cairo_move_to (cr, x0, (y0 + y1) / 2); - cairo_curve_to (cr, x0 ,y0, x0, y0, (x0 + x1) / 2, y0); - cairo_curve_to (cr, x1, y0, x1, y0, x1, (y0 + y1) / 2); - cairo_curve_to (cr, x1, y1, x1, y1, (x1 + x0) / 2, y1); - cairo_curve_to (cr, x0, y1, x0, y1, x0, (y0 + y1) / 2); - } else { - cairo_move_to (cr, x0, y0 + radius); - cairo_curve_to (cr, x0, y0, x0, y0, (x0 + x1) / 2, y0); - cairo_curve_to (cr, x1, y0, x1, y0, x1, y0 + radius); - cairo_line_to (cr, x1, y1 - radius); - cairo_curve_to (cr, x1, y1, x1, y1, (x1 + x0) / 2, y1); - cairo_curve_to (cr, x0, y1, x0, y1, x0, y1 - radius); - } - } else { - if (height / 2 < radius) { - cairo_move_to (cr, x0, (y0 + y1) / 2); - cairo_curve_to (cr, x0, y0, x0 , y0, x0 + radius, y0); - cairo_line_to (cr, x1 - radius, y0); - cairo_curve_to (cr, x1, y0, x1, y0, x1, (y0 + y1) / 2); - cairo_curve_to (cr, x1, y1, x1, y1, x1 - radius, y1); - cairo_line_to (cr, x0 + radius, y1); - cairo_curve_to (cr, x0, y1, x0, y1, x0, (y0 + y1) / 2); - } else { - cairo_move_to (cr, x0, y0 + radius); - cairo_curve_to (cr, x0 , y0, x0 , y0, x0 + radius, y0); - cairo_line_to (cr, x1 - radius, y0); - cairo_curve_to (cr, x1, y0, x1, y0, x1, y0 + radius); - cairo_line_to (cr, x1, y1 - radius); - cairo_curve_to (cr, x1, y1, x1, y1, x1 - radius, y1); - cairo_line_to (cr, x0 + radius, y1); - cairo_curve_to (cr, x0, y1, x0, y1, x0, y1 - radius); - } - } - - cairo_close_path (cr); -} - -static int -gvc_level_bar_draw (GtkWidget *widget, cairo_t *cr) -{ - GvcLevelBar *bar; - - bar = GVC_LEVEL_BAR (widget); - - cairo_save (cr); - - if (bar->priv->orientation == GTK_ORIENTATION_VERTICAL) { - int i; - int by; - - for (i = 0; i < NUM_BOXES; i++) { - by = i * bar->priv->layout.delta; - curved_rectangle (cr, - bar->priv->layout.area.x + 0.5, - by + 0.5, - bar->priv->layout.box_width - 1, - bar->priv->layout.box_height - 1, - bar->priv->layout.box_radius); - if ((bar->priv->layout.max_peak_num - 1) == i) { - /* fill peak foreground */ -#if GTK_CHECK_VERSION (3, 0, 0) - gdk_cairo_set_source_rgba (cr, &bar->priv->layout.color_fg); -#else - gdk_cairo_set_source_color (cr, &bar->priv->layout.color_fg); -#endif - cairo_fill_preserve (cr); - } else if ((bar->priv->layout.peak_num - 1) >= i) { - /* fill background */ -#if GTK_CHECK_VERSION (3, 0, 0) - gdk_cairo_set_source_rgba (cr, &bar->priv->layout.color_bg); -#else - gdk_cairo_set_source_color (cr, &bar->priv->layout.color_bg); -#endif - cairo_fill_preserve (cr); - - /* fill foreground */ -#if GTK_CHECK_VERSION (3, 0, 0) - cairo_set_source_rgba (cr, - bar->priv->layout.color_fg.red, - bar->priv->layout.color_fg.green, - bar->priv->layout.color_fg.blue, - 0.5); -#else - cairo_set_source_rgba (cr, - bar->priv->layout.color_fg.red / 65535.0, - bar->priv->layout.color_fg.green / 65535.0, - bar->priv->layout.color_fg.blue / 65535.0, - 0.5); -#endif - cairo_fill_preserve (cr); - } else { - /* fill background */ -#if GTK_CHECK_VERSION (3, 0, 0) - gdk_cairo_set_source_rgba (cr, &bar->priv->layout.color_bg); -#else - gdk_cairo_set_source_color (cr, &bar->priv->layout.color_bg); -#endif - cairo_fill_preserve (cr); - } - - /* stroke border */ -#if GTK_CHECK_VERSION (3, 0, 0) - gdk_cairo_set_source_rgba (cr, &bar->priv->layout.color_dark); -#else - gdk_cairo_set_source_color (cr, &bar->priv->layout.color_dark); -#endif - cairo_set_line_width (cr, 1); - cairo_stroke (cr); - } - } else { - int i; - int bx; - - if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL) { - GtkAllocation allocation; - - gtk_widget_get_allocation (widget, &allocation); - - cairo_scale (cr, -1, 1); - cairo_translate (cr, -allocation.width, 0); - } - - for (i = 0; i < NUM_BOXES; i++) { - bx = i * bar->priv->layout.delta; - curved_rectangle (cr, - bx + 0.5, - bar->priv->layout.area.y + 0.5, - bar->priv->layout.box_width - 1, - bar->priv->layout.box_height - 1, - bar->priv->layout.box_radius); - - if ((bar->priv->layout.max_peak_num - 1) == i) { - /* fill peak foreground */ -#if GTK_CHECK_VERSION (3, 0, 0) - gdk_cairo_set_source_rgba (cr, &bar->priv->layout.color_fg); -#else - gdk_cairo_set_source_color (cr, &bar->priv->layout.color_fg); -#endif - cairo_fill_preserve (cr); - } else if ((bar->priv->layout.peak_num - 1) >= i) { - /* fill background */ -#if GTK_CHECK_VERSION (3, 0, 0) - gdk_cairo_set_source_rgba (cr, &bar->priv->layout.color_bg); -#else - gdk_cairo_set_source_color (cr, &bar->priv->layout.color_bg); -#endif - cairo_fill_preserve (cr); - - /* fill foreground */ -#if GTK_CHECK_VERSION (3, 0, 0) - cairo_set_source_rgba (cr, - bar->priv->layout.color_fg.red, - bar->priv->layout.color_fg.green, - bar->priv->layout.color_fg.blue, - 0.5); -#else - cairo_set_source_rgba (cr, - bar->priv->layout.color_fg.red / 65535.0, - bar->priv->layout.color_fg.green / 65535.0, - bar->priv->layout.color_fg.blue / 65535.0, - 0.5); -#endif - cairo_fill_preserve (cr); - } else { - /* fill background */ -#if GTK_CHECK_VERSION (3, 0, 0) - gdk_cairo_set_source_rgba (cr, &bar->priv->layout.color_bg); -#else - gdk_cairo_set_source_color (cr, &bar->priv->layout.color_bg); -#endif - cairo_fill_preserve (cr); - } - - /* stroke border */ -#if GTK_CHECK_VERSION (3, 0, 0) - gdk_cairo_set_source_rgba (cr, &bar->priv->layout.color_dark); -#else - gdk_cairo_set_source_color (cr, &bar->priv->layout.color_dark); -#endif - cairo_set_line_width (cr, 1); - cairo_stroke (cr); - } - } - - cairo_restore (cr); - - return FALSE; -} - -#if !GTK_CHECK_VERSION (3, 0, 0) -static int -gvc_level_bar_expose (GtkWidget *widget, GdkEventExpose *event) -{ - cairo_t *cr; - GtkAllocation allocation; - - g_return_val_if_fail (event != NULL, FALSE); - - /* Event queue compression */ - if (event->count > 0) - return FALSE; - - gtk_widget_get_allocation (widget, &allocation); - - cr = gdk_cairo_create (gtk_widget_get_window (widget)); - cairo_translate (cr, - allocation.x, - allocation.y); - - gvc_level_bar_draw (widget, cr); - - cairo_destroy (cr); - return FALSE; -} -#endif - -static void -gvc_level_bar_class_init (GvcLevelBarClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); - - object_class->finalize = gvc_level_bar_finalize; - object_class->set_property = gvc_level_bar_set_property; - object_class->get_property = gvc_level_bar_get_property; - -#if GTK_CHECK_VERSION (3, 0, 0) - widget_class->draw = gvc_level_bar_draw; - widget_class->get_preferred_width = gvc_level_bar_get_preferred_width; - widget_class->get_preferred_height = gvc_level_bar_get_preferred_height; -#else - widget_class->expose_event = gvc_level_bar_expose; - widget_class->size_request = gvc_level_bar_size_request; -#endif - widget_class->size_allocate = gvc_level_bar_size_allocate; - - properties[PROP_ORIENTATION] = - g_param_spec_enum ("orientation", - "Orientation", - "The orientation of the bar", - GTK_TYPE_ORIENTATION, - GTK_ORIENTATION_HORIZONTAL, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS); - - properties[PROP_PEAK_ADJUSTMENT] = - g_param_spec_object ("peak-adjustment", - "Peak Adjustment", - "The GtkAdjustment that contains the current peak value", - GTK_TYPE_ADJUSTMENT, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS); - - properties[PROP_RMS_ADJUSTMENT] = - g_param_spec_object ("rms-adjustment", - "RMS Adjustment", - "The GtkAdjustment that contains the current rms value", - GTK_TYPE_ADJUSTMENT, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS); - - properties[PROP_SCALE] = - g_param_spec_int ("scale", - "Scale", - "Scale", - 0, - G_MAXINT, - GVC_LEVEL_SCALE_LINEAR, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT | - G_PARAM_STATIC_STRINGS); - - g_object_class_install_properties (object_class, N_PROPERTIES, properties); - - g_type_class_add_private (klass, sizeof (GvcLevelBarPrivate)); -} - -static void -gvc_level_bar_init (GvcLevelBar *bar) -{ - bar->priv = GVC_LEVEL_BAR_GET_PRIVATE (bar); - - bar->priv->peak_adjustment = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, - 0.0, - 1.0, - 0.05, - 0.1, - 0.1)); - g_object_ref_sink (bar->priv->peak_adjustment); - - g_signal_connect (bar->priv->peak_adjustment, - "value-changed", - G_CALLBACK (on_peak_adjustment_value_changed), - bar); - - bar->priv->rms_adjustment = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, - 0.0, - 1.0, - 0.05, - 0.1, - 0.1)); - g_object_ref_sink (bar->priv->rms_adjustment); - - g_signal_connect (bar->priv->rms_adjustment, - "value-changed", - G_CALLBACK (on_rms_adjustment_value_changed), - bar); - - gtk_widget_set_has_window (GTK_WIDGET (bar), FALSE); -} - -static void -gvc_level_bar_finalize (GObject *object) -{ - GvcLevelBar *bar; - - bar = GVC_LEVEL_BAR (object); - - if (bar->priv->max_peak_id > 0) - g_source_remove (bar->priv->max_peak_id); - - G_OBJECT_CLASS (gvc_level_bar_parent_class)->finalize (object); -} - -GtkWidget * -gvc_level_bar_new (void) -{ - return g_object_new (GVC_TYPE_LEVEL_BAR, NULL); -} diff --git a/mate-volume-control/src/gvc-level-bar.h b/mate-volume-control/src/gvc-level-bar.h deleted file mode 100644 index ef9ae7e..0000000 --- a/mate-volume-control/src/gvc-level-bar.h +++ /dev/null @@ -1,79 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- - * - * Copyright (C) 2008 William Jon McCann <[email protected]> - * Copyright (C) 2014 Michal Ratajsky <[email protected]> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ - -#ifndef __GVC_LEVEL_BAR_H -#define __GVC_LEVEL_BAR_H - -#include <glib.h> -#include <glib-object.h> -#include <gtk/gtk.h> - -G_BEGIN_DECLS - -#define GVC_TYPE_LEVEL_BAR (gvc_level_bar_get_type ()) -#define GVC_LEVEL_BAR(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GVC_TYPE_LEVEL_BAR, GvcLevelBar)) -#define GVC_LEVEL_BAR_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GVC_TYPE_LEVEL_BAR, GvcLevelBarClass)) -#define GVC_IS_LEVEL_BAR(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GVC_TYPE_LEVEL_BAR)) -#define GVC_IS_LEVEL_BAR_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GVC_TYPE_LEVEL_BAR)) -#define GVC_LEVEL_BAR_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GVC_TYPE_LEVEL_BAR, GvcLevelBarClass)) - -typedef struct _GvcLevelBar GvcLevelBar; -typedef struct _GvcLevelBarClass GvcLevelBarClass; -typedef struct _GvcLevelBarPrivate GvcLevelBarPrivate; - -struct _GvcLevelBar -{ - GtkWidget parent; - GvcLevelBarPrivate *priv; -}; - -struct _GvcLevelBarClass -{ - GtkWidgetClass parent_class; -}; - -typedef enum -{ - GVC_LEVEL_SCALE_LINEAR, - GVC_LEVEL_SCALE_LOG -} GvcLevelScale; - -GType gvc_level_bar_get_type (void) G_GNUC_CONST; - -GtkWidget * gvc_level_bar_new (void); -void gvc_level_bar_set_orientation (GvcLevelBar *bar, - GtkOrientation orientation); -GtkOrientation gvc_level_bar_get_orientation (GvcLevelBar *bar); - -void gvc_level_bar_set_peak_adjustment (GvcLevelBar *bar, - GtkAdjustment *adjustment); -GtkAdjustment * gvc_level_bar_get_peak_adjustment (GvcLevelBar *bar); - -void gvc_level_bar_set_rms_adjustment (GvcLevelBar *bar, - GtkAdjustment *adjustment); -GtkAdjustment * gvc_level_bar_get_rms_adjustment (GvcLevelBar *bar); - -void gvc_level_bar_set_scale (GvcLevelBar *bar, - GvcLevelScale scale); - -G_END_DECLS - -#endif /* __GVC_LEVEL_BAR_H */ diff --git a/mate-volume-control/src/gvc-mixer-dialog.c b/mate-volume-control/src/gvc-mixer-dialog.c deleted file mode 100644 index b6525fb..0000000 --- a/mate-volume-control/src/gvc-mixer-dialog.c +++ /dev/null @@ -1,2606 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- - * - * Copyright (C) 2008 William Jon McCann - * Copyright (C) 2014 Michal Ratajsky <[email protected]> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ - -#include "config.h" - -#include <glib.h> -#include <glib/gi18n.h> -#include <glib-object.h> -#include <gdk/gdk.h> -#include <gdk/gdkkeysyms.h> -#include <gtk/gtk.h> -#include <libmatemixer/matemixer.h> - -#include "gvc-channel-bar.h" -#include "gvc-balance-bar.h" -#include "gvc-combo-box.h" -#include "gvc-mixer-dialog.h" -#include "gvc-sound-theme-chooser.h" -#include "gvc-level-bar.h" -#include "gvc-speaker-test.h" -#include "gvc-utils.h" - -#define GVC_MIXER_DIALOG_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GVC_TYPE_MIXER_DIALOG, GvcMixerDialogPrivate)) - -struct _GvcMixerDialogPrivate -{ - MateMixerContext *context; - GHashTable *bars; - GtkWidget *notebook; - GtkWidget *output_bar; - GtkWidget *input_bar; - GtkWidget *input_level_bar; - GtkWidget *effects_bar; - GtkWidget *output_stream_box; - GtkWidget *sound_effects_box; - GtkWidget *hw_box; - GtkWidget *hw_treeview; - GtkWidget *hw_settings_box; - GtkWidget *hw_profile_combo; - GtkWidget *input_box; - GtkWidget *output_box; - GtkWidget *applications_box; - GtkWidget *applications_window; - GtkWidget *no_apps_label; - GtkWidget *output_treeview; - GtkWidget *output_settings_frame; - GtkWidget *output_settings_box; - GtkWidget *output_balance_bar; - GtkWidget *output_fade_bar; - GtkWidget *output_lfe_bar; - GtkWidget *output_port_combo; - GtkWidget *input_treeview; - GtkWidget *input_port_combo; - GtkWidget *input_settings_box; - GtkWidget *sound_theme_chooser; - GtkSizeGroup *size_group; - gdouble last_input_peak; - guint num_apps; -}; - -enum { - ICON_COLUMN, - NAME_COLUMN, - LABEL_COLUMN, - ACTIVE_COLUMN, - SPEAKERS_COLUMN, - NUM_COLUMNS -}; - -enum { - HW_ICON_COLUMN, - HW_NAME_COLUMN, - HW_LABEL_COLUMN, - HW_STATUS_COLUMN, - HW_PROFILE_COLUMN, - HW_NUM_COLUMNS -}; - -enum { - PAGE_EFFECTS, - PAGE_HARDWARE, - PAGE_INPUT, - PAGE_OUTPUT, - PAGE_APPLICATIONS -}; - -enum { - PROP_0, - PROP_CONTEXT -}; - -static const guint tab_accel_keys[] = { - GDK_KEY_1, GDK_KEY_2, GDK_KEY_3, GDK_KEY_4, GDK_KEY_5 -}; - -static void gvc_mixer_dialog_class_init (GvcMixerDialogClass *klass); -static void gvc_mixer_dialog_init (GvcMixerDialog *dialog); -static void gvc_mixer_dialog_finalize (GObject *object); - -static void add_stream (GvcMixerDialog *dialog, - MateMixerStream *stream); -static void add_application_control (GvcMixerDialog *dialog, - MateMixerStreamControl *control); -static void add_effects_control (GvcMixerDialog *dialog, - MateMixerStreamControl *control); - -static void remove_stream (GvcMixerDialog *dialog, - const gchar *name); -static void remove_application_control (GvcMixerDialog *dialog, - const gchar *name); - -static void bar_set_stream (GvcMixerDialog *dialog, - GtkWidget *bar, - MateMixerStream *stream); -static void bar_set_stream_control (GvcMixerDialog *dialog, - GtkWidget *bar, - MateMixerStreamControl *control); - -G_DEFINE_TYPE (GvcMixerDialog, gvc_mixer_dialog, GTK_TYPE_DIALOG) - -static MateMixerSwitch * -find_stream_port_switch (MateMixerStream *stream) -{ - const GList *switches; - - switches = mate_mixer_stream_list_switches (stream); - while (switches != NULL) { - MateMixerSwitch *swtch = MATE_MIXER_SWITCH (switches->data); - MateMixerSwitchFlags flags; - - flags = mate_mixer_switch_get_flags (swtch); - if ((flags & MATE_MIXER_SWITCH_TOGGLE) == 0 && - mate_mixer_switch_get_role (swtch) == MATE_MIXER_SWITCH_ROLE_PORT) - return swtch; - - switches = switches->next; - } - return NULL; -} - -static MateMixerSwitch * -find_device_profile_switch (MateMixerDevice *device) -{ - const GList *switches; - - switches = mate_mixer_device_list_switches (device); - while (switches != NULL) { - MateMixerSwitch *swtch = MATE_MIXER_SWITCH (switches->data); - - if (mate_mixer_switch_get_role (swtch) == MATE_MIXER_SWITCH_ROLE_DEVICE_PROFILE) - return swtch; - - switches = switches->next; - } - return NULL; -} - -static MateMixerStream * -find_device_test_stream (GvcMixerDialog *dialog, MateMixerDevice *device) -{ - const GList *streams; - - streams = mate_mixer_device_list_streams (device); - while (streams != NULL) { - MateMixerStream *stream; - MateMixerDirection direction; - - stream = MATE_MIXER_STREAM (streams->data); - direction = mate_mixer_stream_get_direction (stream); - - if (direction == MATE_MIXER_DIRECTION_OUTPUT) { - MateMixerStreamControl *control; - - control = mate_mixer_stream_get_default_control (stream); - if (mate_mixer_stream_control_get_num_channels (control) > 0) - return stream; - } - streams = streams->next; - } - return FALSE; -} - -static gboolean -find_tree_item_by_name (GtkTreeModel *model, - const gchar *name, - guint column, - GtkTreeIter *iter) -{ - gboolean found = FALSE; - - if (!gtk_tree_model_get_iter_first (model, iter)) - return FALSE; - - do { - gchar *n; - gtk_tree_model_get (model, iter, column, &n, -1); - - if (!g_strcmp0 (name, n)) - found = TRUE; - - g_free (n); - } while (!found && gtk_tree_model_iter_next (model, iter)); - - return found; -} - -static void -update_default_tree_item (GvcMixerDialog *dialog, - GtkTreeModel *model, - MateMixerStream *stream) -{ - GtkTreeIter iter; - const gchar *name = NULL; - - if (gtk_tree_model_get_iter_first (model, &iter) == FALSE) - return; - - /* The supplied stream is the default, or the selected item. Traverse - * the item list and mark each item as being selected or not. Also do not - * presume some known stream is selected and allow NULL here. */ - if (stream != NULL) - name = mate_mixer_stream_get_name (stream); - - do { - gchar *n; - gtk_tree_model_get (model, &iter, - NAME_COLUMN, &n, - -1); - gtk_list_store_set (GTK_LIST_STORE (model), - &iter, - ACTIVE_COLUMN, !g_strcmp0 (name, n), - -1); - g_free (n); - } while (gtk_tree_model_iter_next (model, &iter)); -} - -static void -on_combobox_option_changed (GvcComboBox *combo, - const gchar *name, - GvcMixerDialog *dialog) -{ - MateMixerSwitch *swtch; - MateMixerSwitchOption *option; - const GList *options; - - swtch = g_object_get_data (G_OBJECT (combo), "switch"); - if (G_UNLIKELY (swtch == NULL)) { - g_warn_if_reached (); - return; - } - - options = mate_mixer_switch_list_options (swtch); - while (options != NULL) { - option = MATE_MIXER_SWITCH_OPTION (options->data); - - if (g_strcmp0 (mate_mixer_switch_option_get_name (option), name) == 0) - break; - - option = NULL; - options = options->next; - } - - if (G_UNLIKELY (option == NULL)) { - g_warn_if_reached (); - return; - } - - mate_mixer_switch_set_active_option (swtch, option); -} - -static GtkWidget * -create_port_combo_box (GvcMixerDialog *dialog, - MateMixerSwitch *swtch, - const gchar *name, - const GList *items, - const gchar *active) -{ - GtkWidget *combobox; - - combobox = gvc_combo_box_new (name); - - gvc_combo_box_set_options (GVC_COMBO_BOX (combobox), items); - gvc_combo_box_set_active (GVC_COMBO_BOX (combobox), active); - - gvc_combo_box_set_size_group (GVC_COMBO_BOX (combobox), - dialog->priv->size_group, - FALSE); - - g_object_set_data_full (G_OBJECT (combobox), - "switch", - g_object_ref (swtch), - g_object_unref); - - g_signal_connect (G_OBJECT (combobox), - "changed", - G_CALLBACK (on_combobox_option_changed), - dialog); - return combobox; -} - -static void -update_output_settings (GvcMixerDialog *dialog) -{ - MateMixerStream *stream; - MateMixerStreamControl *control; - MateMixerStreamControlFlags flags; - MateMixerSwitch *port_switch; - gboolean has_settings = FALSE; - - g_debug ("Updating output settings"); - - if (dialog->priv->output_balance_bar != NULL) { - gtk_container_remove (GTK_CONTAINER (dialog->priv->output_settings_box), - dialog->priv->output_balance_bar); - - dialog->priv->output_balance_bar = NULL; - } - if (dialog->priv->output_fade_bar != NULL) { - gtk_container_remove (GTK_CONTAINER (dialog->priv->output_settings_box), - dialog->priv->output_fade_bar); - - dialog->priv->output_fade_bar = NULL; - } - if (dialog->priv->output_lfe_bar != NULL) { - gtk_container_remove (GTK_CONTAINER (dialog->priv->output_settings_box), - dialog->priv->output_lfe_bar); - - dialog->priv->output_lfe_bar = NULL; - } - if (dialog->priv->output_port_combo != NULL) { - gtk_container_remove (GTK_CONTAINER (dialog->priv->output_settings_box), - dialog->priv->output_port_combo); - - dialog->priv->output_port_combo = NULL; - } - - /* Get the control currently associated with the output slider */ - control = gvc_channel_bar_get_control (GVC_CHANNEL_BAR (dialog->priv->output_bar)); - if (control == NULL) { - g_debug ("There is no control for the default output stream"); - gtk_widget_hide (dialog->priv->output_settings_frame); - return; - } - flags = mate_mixer_stream_control_get_flags (control); - - /* Enable balance bar if it is available */ - if (flags & MATE_MIXER_STREAM_CONTROL_CAN_BALANCE) { - dialog->priv->output_balance_bar = - gvc_balance_bar_new (control, BALANCE_TYPE_RL); - - gvc_balance_bar_set_size_group (GVC_BALANCE_BAR (dialog->priv->output_balance_bar), - dialog->priv->size_group, - TRUE); - - gtk_box_pack_start (GTK_BOX (dialog->priv->output_settings_box), - dialog->priv->output_balance_bar, - FALSE, FALSE, 6); - - gtk_widget_show (dialog->priv->output_balance_bar); - has_settings = TRUE; - } - - /* Enable fade bar if it is available */ - if (flags & MATE_MIXER_STREAM_CONTROL_CAN_FADE) { - dialog->priv->output_fade_bar = - gvc_balance_bar_new (control, BALANCE_TYPE_FR); - - gvc_balance_bar_set_size_group (GVC_BALANCE_BAR (dialog->priv->output_fade_bar), - dialog->priv->size_group, - TRUE); - - gtk_box_pack_start (GTK_BOX (dialog->priv->output_settings_box), - dialog->priv->output_fade_bar, - FALSE, FALSE, 6); - - gtk_widget_show (dialog->priv->output_fade_bar); - has_settings = TRUE; - } - - /* Enable subwoofer volume bar if subwoofer is available */ - if (mate_mixer_stream_control_has_channel_position (control, MATE_MIXER_CHANNEL_LFE)) { - dialog->priv->output_lfe_bar = - gvc_balance_bar_new (control, BALANCE_TYPE_LFE); - - gvc_balance_bar_set_size_group (GVC_BALANCE_BAR (dialog->priv->output_lfe_bar), - dialog->priv->size_group, - TRUE); - - gtk_box_pack_start (GTK_BOX (dialog->priv->output_settings_box), - dialog->priv->output_lfe_bar, - FALSE, FALSE, 6); - - gtk_widget_show (dialog->priv->output_lfe_bar); - has_settings = TRUE; - } - - /* Get owning stream of the control */ - stream = mate_mixer_stream_control_get_stream (control); - if (G_UNLIKELY (stream == NULL)) - return; - - /* Enable the port selector if the stream has one */ - port_switch = find_stream_port_switch (stream); - if (port_switch != NULL) { - const GList *options; - const gchar *active_name = NULL; - MateMixerSwitchOption *active; - - options = mate_mixer_switch_list_options (port_switch); - active = mate_mixer_switch_get_active_option (port_switch); - if (active != NULL) - active_name = mate_mixer_switch_option_get_name (active); - - dialog->priv->output_port_combo = - create_port_combo_box (dialog, - port_switch, - _("Co_nnector:"), - options, - active_name); - - gtk_box_pack_start (GTK_BOX (dialog->priv->output_settings_box), - dialog->priv->output_port_combo, - TRUE, FALSE, 6); - - gtk_widget_show (dialog->priv->output_port_combo); - has_settings = TRUE; - } - - if (has_settings == TRUE) - gtk_widget_show (dialog->priv->output_settings_frame); - else - gtk_widget_hide (dialog->priv->output_settings_frame); -} - -static void -set_output_stream (GvcMixerDialog *dialog, MateMixerStream *stream) -{ - GtkTreeModel *model; - MateMixerSwitch *swtch; - MateMixerStreamControl *control; - - control = gvc_channel_bar_get_control (GVC_CHANNEL_BAR (dialog->priv->output_bar)); - if (control != NULL) { - /* Disconnect port switch of the previous stream */ - if (dialog->priv->output_port_combo != NULL) { - swtch = g_object_get_data (G_OBJECT (dialog->priv->output_port_combo), - "switch"); - if (swtch != NULL) - g_signal_handlers_disconnect_by_data (G_OBJECT (swtch), - dialog); - } - } - - bar_set_stream (dialog, dialog->priv->output_bar, stream); - - if (stream != NULL) { - const GList *controls; - - controls = mate_mixer_context_list_stored_controls (dialog->priv->context); - - /* Move all stored controls to the newly selected default stream */ - while (controls != NULL) { - MateMixerStream *parent; - MateMixerStreamControl *control; - - control = MATE_MIXER_STREAM_CONTROL (controls->data); - parent = mate_mixer_stream_control_get_stream (control); - - /* Prefer streamless controls to stay the way they are, forcing them to - * a particular owning stream would be wrong for eg. event controls */ - if (parent != NULL && parent != stream) { - MateMixerDirection direction = - mate_mixer_stream_get_direction (parent); - - if (direction == MATE_MIXER_DIRECTION_OUTPUT) - mate_mixer_stream_control_set_stream (control, stream); - } - controls = controls->next; - } - } - - model = gtk_tree_view_get_model (GTK_TREE_VIEW (dialog->priv->output_treeview)); - update_default_tree_item (dialog, model, stream); - - update_output_settings (dialog); -} - -static void -on_context_default_output_stream_notify (MateMixerContext *context, - GParamSpec *pspec, - GvcMixerDialog *dialog) -{ - MateMixerStream *stream; - - stream = mate_mixer_context_get_default_output_stream (context); - - set_output_stream (dialog, stream); -} - -#define DECAY_STEP .15 - -static void -on_stream_control_monitor_value (MateMixerStream *stream, - gdouble value, - GvcMixerDialog *dialog) -{ - GtkAdjustment *adj; - - if (dialog->priv->last_input_peak >= DECAY_STEP) { - if (value < dialog->priv->last_input_peak - DECAY_STEP) { - value = dialog->priv->last_input_peak - DECAY_STEP; - } - } - - dialog->priv->last_input_peak = value; - - adj = gvc_level_bar_get_peak_adjustment (GVC_LEVEL_BAR (dialog->priv->input_level_bar)); - if (value >= 0) - gtk_adjustment_set_value (adj, value); - else - gtk_adjustment_set_value (adj, 0.0); -} - -static void -update_input_settings (GvcMixerDialog *dialog) -{ - MateMixerStream *stream; - MateMixerStreamControl *control; - MateMixerStreamControlFlags flags; - MateMixerSwitch *port_switch; - - g_debug ("Updating input settings"); - - if (dialog->priv->input_port_combo != NULL) { - gtk_container_remove (GTK_CONTAINER (dialog->priv->input_settings_box), - dialog->priv->input_port_combo); - - dialog->priv->input_port_combo = NULL; - } - - /* Get the control currently associated with the input slider */ - control = gvc_channel_bar_get_control (GVC_CHANNEL_BAR (dialog->priv->input_bar)); - if (control == NULL) - return; - - flags = mate_mixer_stream_control_get_flags (control); - - /* Enable level bar only if supported by the control */ - if (flags & MATE_MIXER_STREAM_CONTROL_HAS_MONITOR) - g_signal_connect (G_OBJECT (control), - "monitor-value", - G_CALLBACK (on_stream_control_monitor_value), - dialog); - - /* Get owning stream of the control */ - stream = mate_mixer_stream_control_get_stream (control); - if (G_UNLIKELY (stream == NULL)) - return; - - /* Enable the port selector if the stream has one */ - port_switch = find_stream_port_switch (stream); - if (port_switch != NULL) { - const GList *options; - const gchar *active_name = NULL; - MateMixerSwitchOption *active; - - options = mate_mixer_switch_list_options (port_switch); - active = mate_mixer_switch_get_active_option (port_switch); - if (active != NULL) - active_name = mate_mixer_switch_option_get_name (active); - - dialog->priv->input_port_combo = - create_port_combo_box (dialog, - port_switch, - _("Co_nnector:"), - options, - active_name); - - gtk_box_pack_start (GTK_BOX (dialog->priv->input_settings_box), - dialog->priv->input_port_combo, - TRUE, TRUE, 0); - - gtk_widget_show (dialog->priv->input_port_combo); - } -} - -static void -on_stream_control_mute_notify (MateMixerStreamControl *control, - GParamSpec *pspec, - GvcMixerDialog *dialog) -{ - /* Stop monitoring the input stream when it gets muted */ - if (mate_mixer_stream_control_get_mute (control) == TRUE) - mate_mixer_stream_control_set_monitor_enabled (control, FALSE); - else - mate_mixer_stream_control_set_monitor_enabled (control, TRUE); -} - -static void -set_input_stream (GvcMixerDialog *dialog, MateMixerStream *stream) -{ - GtkTreeModel *model; - MateMixerSwitch *swtch; - MateMixerStreamControl *control; - - control = gvc_channel_bar_get_control (GVC_CHANNEL_BAR (dialog->priv->input_bar)); - if (control != NULL) { - /* Disconnect port switch of the previous stream */ - if (dialog->priv->input_port_combo != NULL) { - swtch = g_object_get_data (G_OBJECT (dialog->priv->input_port_combo), - "switch"); - if (swtch != NULL) - g_signal_handlers_disconnect_by_data (G_OBJECT (swtch), - dialog); - } - - /* Disable monitoring of the previous control */ - g_signal_handlers_disconnect_by_func (G_OBJECT (control), - G_CALLBACK (on_stream_control_monitor_value), - dialog); - - mate_mixer_stream_control_set_monitor_enabled (control, FALSE); - } - - bar_set_stream (dialog, dialog->priv->input_bar, stream); - - if (stream != NULL) { - const GList *controls; - guint page = gtk_notebook_get_current_page (GTK_NOTEBOOK (dialog->priv->notebook)); - - controls = mate_mixer_context_list_stored_controls (dialog->priv->context); - - /* Move all stored controls to the newly selected default stream */ - while (controls != NULL) { - MateMixerStream *parent; - - control = MATE_MIXER_STREAM_CONTROL (controls->data); - parent = mate_mixer_stream_control_get_stream (control); - - /* Prefer streamless controls to stay the way they are, forcing them to - * a particular owning stream would be wrong for eg. event controls */ - if (parent != NULL && parent != stream) { - MateMixerDirection direction = - mate_mixer_stream_get_direction (parent); - - if (direction == MATE_MIXER_DIRECTION_INPUT) - mate_mixer_stream_control_set_stream (control, stream); - } - controls = controls->next; - } - - if (page == PAGE_INPUT) { - MateMixerStreamControl *control = - gvc_channel_bar_get_control (GVC_CHANNEL_BAR (dialog->priv->input_bar)); - - if (G_LIKELY (control != NULL)) - mate_mixer_stream_control_set_monitor_enabled (control, TRUE); - } - - /* Enable/disable the peak level monitor according to mute state */ - g_signal_connect (G_OBJECT (stream), - "notify::mute", - G_CALLBACK (on_stream_control_mute_notify), - dialog); - } - - model = gtk_tree_view_get_model (GTK_TREE_VIEW (dialog->priv->input_treeview)); - update_default_tree_item (dialog, model, stream); - - update_input_settings (dialog); -} - -static void -on_context_default_input_stream_notify (MateMixerContext *context, - GParamSpec *pspec, - GvcMixerDialog *dialog) -{ - MateMixerStream *stream; - - g_debug ("Default input stream has changed"); - - stream = mate_mixer_context_get_default_input_stream (context); - - set_input_stream (dialog, stream); -} - -static GvcComboBox * -find_combo_box_by_switch (GvcMixerDialog *dialog, MateMixerSwitch *swtch) -{ - MateMixerSwitch *combo_switch; - - if (dialog->priv->output_port_combo != NULL) { - combo_switch = g_object_get_data (G_OBJECT (dialog->priv->output_port_combo), - "switch"); - if (combo_switch == swtch) - return GVC_COMBO_BOX (dialog->priv->output_port_combo); - } - - if (dialog->priv->input_port_combo != NULL) { - combo_switch = g_object_get_data (G_OBJECT (dialog->priv->input_port_combo), - "switch"); - if (combo_switch == swtch) - return GVC_COMBO_BOX (dialog->priv->input_port_combo); - } - return NULL; -} - -static void -on_switch_option_notify (MateMixerSwitch *swtch, - GParamSpec *pspec, - GvcMixerDialog *dialog) -{ - GvcComboBox *combobox; - MateMixerSwitchOption *port; - - combobox = find_combo_box_by_switch (dialog, swtch); - if (G_UNLIKELY (combobox == NULL)) { - g_warn_if_reached (); - return; - } - - g_signal_handlers_block_by_func (G_OBJECT (combobox), - on_combobox_option_changed, - dialog); - - port = mate_mixer_switch_get_active_option (swtch); - if (G_LIKELY (port != NULL)) - gvc_combo_box_set_active (GVC_COMBO_BOX (combobox), - mate_mixer_switch_option_get_name (port)); - - g_signal_handlers_unblock_by_func (G_OBJECT (combobox), - on_combobox_option_changed, - dialog); -} - -static GtkWidget * -create_bar (GvcMixerDialog *dialog, gboolean use_size_group, gboolean symmetric) -{ - GtkWidget *bar; - - bar = gvc_channel_bar_new (NULL); - - if (use_size_group == TRUE) - gvc_channel_bar_set_size_group (GVC_CHANNEL_BAR (bar), - dialog->priv->size_group, - symmetric); - - g_object_set (G_OBJECT (bar), - "orientation", GTK_ORIENTATION_HORIZONTAL, - "show-mute", TRUE, - "show-icons", TRUE, - "show-marks", TRUE, - "extended", TRUE, NULL); - return bar; -} - -static void -bar_set_stream (GvcMixerDialog *dialog, - GtkWidget *bar, - MateMixerStream *stream) -{ - MateMixerStreamControl *control = NULL; - - if (stream != NULL) { - MateMixerSwitch *port_switch; - - control = mate_mixer_stream_get_default_control (stream); - - port_switch = find_stream_port_switch (stream); - if (port_switch != NULL) - g_signal_connect (G_OBJECT (port_switch), - "notify::active-option", - G_CALLBACK (on_switch_option_notify), - dialog); - } - - bar_set_stream_control (dialog, bar, control); -} - -static void -bar_set_stream_control (GvcMixerDialog *dialog, - GtkWidget *bar, - MateMixerStreamControl *control) -{ - MateMixerStreamControl *previous; - - previous = gvc_channel_bar_get_control (GVC_CHANNEL_BAR (bar)); - if (previous != NULL) { - const gchar *name = mate_mixer_stream_control_get_name (previous); - - g_debug ("Disconnecting old stream control %s", name); - - g_signal_handlers_disconnect_by_data (G_OBJECT (previous), dialog); - - /* This may not do anything because we no longer have the information - * about the owning stream, in case it was an input stream, make - * sure to disconnected from the peak level monitor */ - mate_mixer_stream_control_set_monitor_enabled (previous, FALSE); - - g_hash_table_remove (dialog->priv->bars, name); - } - - gvc_channel_bar_set_control (GVC_CHANNEL_BAR (bar), control); - - if (control != NULL) { - const gchar *name = mate_mixer_stream_control_get_name (control); - - g_hash_table_insert (dialog->priv->bars, - (gpointer) name, - bar); - - gtk_widget_set_sensitive (GTK_WIDGET (bar), TRUE); - } else - gtk_widget_set_sensitive (GTK_WIDGET (bar), TRUE); -} - -static void -add_application_control (GvcMixerDialog *dialog, MateMixerStreamControl *control) -{ - MateMixerStream *stream; - MateMixerStreamControlMediaRole media_role; - MateMixerAppInfo *info; - MateMixerDirection direction = MATE_MIXER_DIRECTION_UNKNOWN; - GtkWidget *bar; - const gchar *app_id; - const gchar *app_name; - const gchar *app_icon; - - media_role = mate_mixer_stream_control_get_media_role (control); - - /* Add stream to the applications page, but make sure the stream qualifies - * for the inclusion */ - info = mate_mixer_stream_control_get_app_info (control); - if (info == NULL) - return; - - /* Skip streams with roles we don't care about */ - if (media_role == MATE_MIXER_STREAM_CONTROL_MEDIA_ROLE_EVENT || - media_role == MATE_MIXER_STREAM_CONTROL_MEDIA_ROLE_TEST || - media_role == MATE_MIXER_STREAM_CONTROL_MEDIA_ROLE_ABSTRACT || - media_role == MATE_MIXER_STREAM_CONTROL_MEDIA_ROLE_FILTER) - return; - - app_id = mate_mixer_app_info_get_id (info); - - /* These applications may have associated streams because they do peak - * level monitoring, skip these too */ - if (!g_strcmp0 (app_id, "org.mate.VolumeControl") || - !g_strcmp0 (app_id, "org.gnome.VolumeControl") || - !g_strcmp0 (app_id, "org.PulseAudio.pavucontrol")) - return; - - app_name = mate_mixer_app_info_get_name (info); - if (app_name == NULL) - app_name = mate_mixer_stream_control_get_label (control); - if (app_name == NULL) - app_name = mate_mixer_stream_control_get_name (control); - if (G_UNLIKELY (app_name == NULL)) - return; - - bar = create_bar (dialog, FALSE, FALSE); - - g_object_set (G_OBJECT (bar), - "show-marks", FALSE, - "extended", FALSE, - NULL); - - /* By default channel bars use speaker icons, use microphone icons - * instead for recording applications */ - stream = mate_mixer_stream_control_get_stream (control); - if (stream != NULL) - direction = mate_mixer_stream_get_direction (stream); - - if (direction == MATE_MIXER_DIRECTION_INPUT) - g_object_set (G_OBJECT (bar), - "low-icon-name", "audio-input-microphone-low", - "high-icon-name", "audio-input-microphone-high", - NULL); - - app_icon = mate_mixer_app_info_get_icon (info); - if (app_icon == NULL) { - if (direction == MATE_MIXER_DIRECTION_INPUT) - app_icon = "audio-input-microphone"; - else - app_icon = "applications-multimedia"; - } - - gvc_channel_bar_set_name (GVC_CHANNEL_BAR (bar), app_name); - gvc_channel_bar_set_icon_name (GVC_CHANNEL_BAR (bar), app_icon); - - gtk_box_pack_start (GTK_BOX (dialog->priv->applications_box), - bar, - FALSE, FALSE, 12); - - bar_set_stream_control (dialog, bar, control); - dialog->priv->num_apps++; - - gtk_widget_hide (dialog->priv->no_apps_label); - gtk_widget_show (bar); -} - -static void -add_effects_control (GvcMixerDialog *dialog, MateMixerStreamControl *control) -{ - MateMixerStreamControl *previous; - const gchar *name; - - /* We use a stored event control for the effects volume slider, - * because regular streams are only created when an event sound - * is played and then immediately destroyed. - * The stored event control should exist all the time. */ - previous = gvc_channel_bar_get_control (GVC_CHANNEL_BAR (dialog->priv->effects_bar)); - if (previous != NULL) { - name = mate_mixer_stream_control_get_name (previous); - - g_signal_handlers_disconnect_by_data (G_OBJECT (previous), dialog); - g_hash_table_remove (dialog->priv->bars, name); - } - - gvc_channel_bar_set_control (GVC_CHANNEL_BAR (dialog->priv->effects_bar), control); - - if (control != NULL) { - name = mate_mixer_stream_control_get_name (control); - g_hash_table_insert (dialog->priv->bars, - (gpointer) name, - dialog->priv->effects_bar); - - gtk_widget_set_sensitive (GTK_WIDGET (dialog->priv->effects_bar), TRUE); - } else - gtk_widget_set_sensitive (GTK_WIDGET (dialog->priv->effects_bar), FALSE); -} - -static void -on_stream_control_added (MateMixerStream *stream, - const gchar *name, - GvcMixerDialog *dialog) -{ - MateMixerStreamControl *control; - MateMixerStreamControlRole role; - - control = mate_mixer_stream_get_control (stream, name); - if G_UNLIKELY (control == NULL) - return; - - role = mate_mixer_stream_control_get_role (control); - - if (role == MATE_MIXER_STREAM_CONTROL_ROLE_APPLICATION) - add_application_control (dialog, control); -} - -static void -on_stream_control_removed (MateMixerStream *stream, - const gchar *name, - GvcMixerDialog *dialog) -{ - MateMixerStreamControl *control; - - control = gvc_channel_bar_get_control (GVC_CHANNEL_BAR (dialog->priv->input_bar)); - if (control != NULL) { - const gchar *input_name = mate_mixer_stream_control_get_name (control); - - if (strcmp (name, input_name) == 0) { - // XXX probably can't even happen, but handle it somehow - return; - } - } - - control = gvc_channel_bar_get_control (GVC_CHANNEL_BAR (dialog->priv->output_bar)); - if (control != NULL) { - const gchar *input_name = mate_mixer_stream_control_get_name (control); - - if (strcmp (name, input_name) == 0) { - // XXX probably can't even happen, but handle it somehow - return; - } - } - - /* No way to be sure that it is an application control, but we don't have - * any other than application bars that could match the name */ - remove_application_control (dialog, name); -} - -static void -add_stream (GvcMixerDialog *dialog, MateMixerStream *stream) -{ - GtkTreeModel *model = NULL; - GtkTreeIter iter; - const gchar *speakers = NULL; - const GList *controls; - gboolean is_default = FALSE; - MateMixerDirection direction; - - direction = mate_mixer_stream_get_direction (stream); - - if (direction == MATE_MIXER_DIRECTION_INPUT) { - MateMixerStream *input; - - input = mate_mixer_context_get_default_input_stream (dialog->priv->context); - if (stream == input) { - bar_set_stream (dialog, dialog->priv->input_bar, stream); - - update_input_settings (dialog); - is_default = TRUE; - } - model = gtk_tree_view_get_model (GTK_TREE_VIEW (dialog->priv->input_treeview)); - } - else if (direction == MATE_MIXER_DIRECTION_OUTPUT) { - MateMixerStream *output; - MateMixerStreamControl *control; - - output = mate_mixer_context_get_default_output_stream (dialog->priv->context); - if (stream == output) { - bar_set_stream (dialog, dialog->priv->output_bar, stream); - - update_output_settings (dialog); - is_default = TRUE; - } - model = gtk_tree_view_get_model (GTK_TREE_VIEW (dialog->priv->output_treeview)); - - control = mate_mixer_stream_get_default_control (stream); - if (G_LIKELY (control != NULL)) - speakers = gvc_channel_map_to_pretty_string (control); - } - - controls = mate_mixer_stream_list_controls (stream); - while (controls != NULL) { - MateMixerStreamControl *control = MATE_MIXER_STREAM_CONTROL (controls->data); - MateMixerStreamControlRole role; - - role = mate_mixer_stream_control_get_role (control); - - if (role == MATE_MIXER_STREAM_CONTROL_ROLE_APPLICATION) - add_application_control (dialog, control); - - controls = controls->next; - } - - if (model != NULL) { - const gchar *name; - const gchar *label; - - name = mate_mixer_stream_get_name (stream); - label = mate_mixer_stream_get_label (stream); - - gtk_list_store_append (GTK_LIST_STORE (model), &iter); - gtk_list_store_set (GTK_LIST_STORE (model), - &iter, - NAME_COLUMN, name, - LABEL_COLUMN, label, - ACTIVE_COLUMN, is_default, - SPEAKERS_COLUMN, speakers, - -1); - } - - // XXX find a way to disconnect when removed - g_signal_connect (G_OBJECT (stream), - "control-added", - G_CALLBACK (on_stream_control_added), - dialog); - g_signal_connect (G_OBJECT (stream), - "control-removed", - G_CALLBACK (on_stream_control_removed), - dialog); -} - -static void -update_device_test_visibility (GvcMixerDialog *dialog) -{ - MateMixerDevice *device; - MateMixerStream *stream; - - device = g_object_get_data (G_OBJECT (dialog->priv->hw_profile_combo), "device"); - if (G_UNLIKELY (device == NULL)) { - return; - } - - stream = find_device_test_stream (dialog, device); - - g_object_set (G_OBJECT (dialog->priv->hw_profile_combo), - "show-button", (stream != NULL), - NULL); -} - -static void -on_context_stream_added (MateMixerContext *context, - const gchar *name, - GvcMixerDialog *dialog) -{ - MateMixerStream *stream; - MateMixerDirection direction; - GtkWidget *bar; - - stream = mate_mixer_context_get_stream (context, name); - if (G_UNLIKELY (stream == NULL)) - return; - - direction = mate_mixer_stream_get_direction (stream); - - /* If the newly added stream belongs to the currently selected device and - * the test button is hidden, this stream may be the one to allow the - * sound test and therefore we may need to enable the button */ - if (dialog->priv->hw_profile_combo != NULL && direction == MATE_MIXER_DIRECTION_OUTPUT) { - MateMixerDevice *device1; - MateMixerDevice *device2; - - device1 = mate_mixer_stream_get_device (stream); - device2 = g_object_get_data (G_OBJECT (dialog->priv->hw_profile_combo), - "device"); - - if (device1 == device2) { - gboolean show_button; - - g_object_get (G_OBJECT (dialog->priv->hw_profile_combo), - "show-button", &show_button, - NULL); - - if (show_button == FALSE) - update_device_test_visibility (dialog); - } - } - - bar = g_hash_table_lookup (dialog->priv->bars, name); - if (G_UNLIKELY (bar != NULL)) - return; - - add_stream (dialog, stream); -} - -static void -remove_stream (GvcMixerDialog *dialog, const gchar *name) -{ - GtkWidget *bar; - GtkTreeIter iter; - GtkTreeModel *model; - - bar = g_hash_table_lookup (dialog->priv->bars, name); - - if (bar != NULL) { - g_debug ("Removing stream %s from bar %s", - name, - gvc_channel_bar_get_name (GVC_CHANNEL_BAR (bar))); - - bar_set_stream (dialog, bar, NULL); - } - - /* Remove from any models */ - model = gtk_tree_view_get_model (GTK_TREE_VIEW (dialog->priv->output_treeview)); - if (find_tree_item_by_name (GTK_TREE_MODEL (model), - name, - NAME_COLUMN, - &iter) == TRUE) - gtk_list_store_remove (GTK_LIST_STORE (model), &iter); - - model = gtk_tree_view_get_model (GTK_TREE_VIEW (dialog->priv->input_treeview)); - if (find_tree_item_by_name (GTK_TREE_MODEL (model), - name, - NAME_COLUMN, - &iter) == TRUE) - gtk_list_store_remove (GTK_LIST_STORE (model), &iter); -} - -static void -remove_application_control (GvcMixerDialog *dialog, const gchar *name) -{ - GtkWidget *bar; - - bar = g_hash_table_lookup (dialog->priv->bars, name); - if (G_UNLIKELY (bar == NULL)) - return; - - g_debug ("Removing application stream %s", name); - - /* We could call bar_set_stream_control here, but that would pointlessly - * invalidate the channel bar, so just remove it ourselves */ - g_hash_table_remove (dialog->priv->bars, name); - - gtk_container_remove (GTK_CONTAINER (gtk_widget_get_parent (bar)), bar); - - if (G_UNLIKELY (dialog->priv->num_apps <= 0)) { - g_warn_if_reached (); - dialog->priv->num_apps = 1; - } - - dialog->priv->num_apps--; - - if (dialog->priv->num_apps == 0) - gtk_widget_show (dialog->priv->no_apps_label); -} - -static void -on_context_stream_removed (MateMixerContext *context, - const gchar *name, - GvcMixerDialog *dialog) -{ - if (dialog->priv->hw_profile_combo != NULL) { - gboolean show_button; - - g_object_get (G_OBJECT (dialog->priv->hw_profile_combo), - "show-button", &show_button, - NULL); - - if (show_button == TRUE) - update_device_test_visibility (dialog); - } - - remove_stream (dialog, name); -} - -static void -on_context_stored_control_added (MateMixerContext *context, - const gchar *name, - GvcMixerDialog *dialog) -{ - MateMixerStreamControl *control; - MateMixerStreamControlMediaRole media_role; - - control = MATE_MIXER_STREAM_CONTROL (mate_mixer_context_get_stored_control (context, name)); - if (G_UNLIKELY (control == NULL)) - return; - - media_role = mate_mixer_stream_control_get_media_role (control); - - if (media_role == MATE_MIXER_STREAM_CONTROL_MEDIA_ROLE_EVENT) - add_effects_control (dialog, control); -} - -static void -on_context_stored_control_removed (MateMixerContext *context, - const gchar *name, - GvcMixerDialog *dialog) -{ - GtkWidget *bar; - - bar = g_hash_table_lookup (dialog->priv->bars, name); - - if (bar != NULL) { - /* We only use a stored control in the effects bar */ - if (G_UNLIKELY (bar != dialog->priv->effects_bar)) { - g_warn_if_reached (); - return; - } - - bar_set_stream (dialog, bar, NULL); - } -} - -static gchar * -device_status (MateMixerDevice *device) -{ - guint inputs = 0; - guint outputs = 0; - gchar *inputs_str = NULL; - gchar *outputs_str = NULL; - const GList *streams; - - /* Get number of input and output streams in the device */ - streams = mate_mixer_device_list_streams (device); - while (streams != NULL) { - MateMixerStream *stream = MATE_MIXER_STREAM (streams->data); - MateMixerDirection direction; - - direction = mate_mixer_stream_get_direction (stream); - - if (direction == MATE_MIXER_DIRECTION_INPUT) - inputs++; - else if (direction == MATE_MIXER_DIRECTION_OUTPUT) - outputs++; - - streams = streams->next; - } - - if (inputs == 0 && outputs == 0) { - /* translators: - * The device has been disabled */ - return g_strdup (_("Disabled")); - } - - if (outputs > 0) { - /* translators: - * The number of sound outputs on a particular device */ - outputs_str = g_strdup_printf (ngettext ("%u Output", - "%u Outputs", - outputs), - outputs); - } - - if (inputs > 0) { - /* translators: - * The number of sound inputs on a particular device */ - inputs_str = g_strdup_printf (ngettext ("%u Input", - "%u Inputs", - inputs), - inputs); - } - - if (inputs_str != NULL && outputs_str != NULL) { - gchar *ret = g_strdup_printf ("%s / %s", - outputs_str, - inputs_str); - g_free (outputs_str); - g_free (inputs_str); - return ret; - } - - if (inputs_str != NULL) - return inputs_str; - - return outputs_str; -} - -static void -update_device_info (GvcMixerDialog *dialog, MateMixerDevice *device) -{ - GtkTreeModel *model = NULL; - GtkTreeIter iter; - const gchar *label; - const gchar *profile_label = NULL; - gchar *status; - MateMixerSwitch *profile_switch; - - model = gtk_tree_view_get_model (GTK_TREE_VIEW (dialog->priv->hw_treeview)); - - if (find_tree_item_by_name (model, - mate_mixer_device_get_name (device), - HW_NAME_COLUMN, - &iter) == FALSE) - return; - - label = mate_mixer_device_get_label (device); - - profile_switch = find_device_profile_switch (device); - if (profile_switch != NULL) { - MateMixerSwitchOption *active; - - active = mate_mixer_switch_get_active_option (profile_switch); - if (G_LIKELY (active != NULL)) - profile_label = mate_mixer_switch_option_get_label (active); - } - - status = device_status (device); - - gtk_list_store_set (GTK_LIST_STORE (model), - &iter, - HW_LABEL_COLUMN, label, - HW_PROFILE_COLUMN, profile_label, - HW_STATUS_COLUMN, status, - -1); - g_free (status); -} - -static void -on_device_profile_notify (MateMixerSwitch *swtch, - GParamSpec *pspec, - GvcMixerDialog *dialog) -{ - MateMixerSwitchOption *active; - - g_signal_handlers_block_by_func (G_OBJECT (dialog->priv->hw_profile_combo), - G_CALLBACK (on_combobox_option_changed), - dialog); - - active = mate_mixer_switch_get_active_option (swtch); - if (G_LIKELY (active != NULL)) { - const gchar *name = mate_mixer_switch_option_get_name (active); - - gvc_combo_box_set_active (GVC_COMBO_BOX (dialog->priv->hw_profile_combo), - name); - } - - g_signal_handlers_unblock_by_func (G_OBJECT (dialog->priv->hw_profile_combo), - G_CALLBACK (on_combobox_option_changed), - dialog); - - // XXX find device - // update_device_info (dialog, device); -} - -static void -add_device (GvcMixerDialog *dialog, MateMixerDevice *device) -{ - GtkTreeModel *model; - GtkTreeIter iter; - GIcon *icon; - const gchar *name; - const gchar *label; - gchar *status; - const gchar *profile_label = NULL; - MateMixerSwitch *profile_switch; - - model = gtk_tree_view_get_model (GTK_TREE_VIEW (dialog->priv->hw_treeview)); - - name = mate_mixer_device_get_name (device); - label = mate_mixer_device_get_label (device); - - if (find_tree_item_by_name (GTK_TREE_MODEL (model), - name, - HW_NAME_COLUMN, - &iter) == FALSE) - gtk_list_store_append (GTK_LIST_STORE (model), &iter); - - icon = g_themed_icon_new_with_default_fallbacks (mate_mixer_device_get_icon (device)); - - profile_switch = find_device_profile_switch (device); - if (profile_switch != NULL) { - MateMixerSwitchOption *active; - - active = mate_mixer_switch_get_active_option (profile_switch); - if (G_LIKELY (active != NULL)) - profile_label = mate_mixer_switch_option_get_label (active); - - g_signal_connect (G_OBJECT (device), - "notify::active-option", - G_CALLBACK (on_device_profile_notify), - dialog); - } - - status = device_status (device); - - gtk_list_store_set (GTK_LIST_STORE (model), - &iter, - HW_NAME_COLUMN, name, - HW_LABEL_COLUMN, label, - HW_ICON_COLUMN, icon, - HW_PROFILE_COLUMN, profile_label, - HW_STATUS_COLUMN, status, - -1); - g_free (status); - -} - -static void -on_context_device_added (MateMixerContext *context, const gchar *name, GvcMixerDialog *dialog) -{ - MateMixerDevice *device; - - device = mate_mixer_context_get_device (context, name); - if (G_UNLIKELY (device == NULL)) - return; - - add_device (dialog, device); -} - -static void -on_context_device_removed (MateMixerContext *context, - const gchar *name, - GvcMixerDialog *dialog) -{ - GtkTreeIter iter; - GtkTreeModel *model; - - /* Remove from the device model */ - model = gtk_tree_view_get_model (GTK_TREE_VIEW (dialog->priv->hw_treeview)); - - if (find_tree_item_by_name (GTK_TREE_MODEL (model), - name, - HW_NAME_COLUMN, - &iter) == TRUE) - gtk_list_store_remove (GTK_LIST_STORE (model), &iter); -} - -static void -make_label_bold (GtkLabel *label) -{ - PangoFontDescription *font_desc; - - font_desc = pango_font_description_new (); - - pango_font_description_set_weight (font_desc, PANGO_WEIGHT_BOLD); - - /* This will only affect the weight of the font, the rest is - * from the current state of the widget, which comes from the - * theme or user prefs, since the font desc only has the - * weight flag turned on. */ -#if GTK_CHECK_VERSION (3, 0, 0) - gtk_widget_override_font (GTK_WIDGET (label), font_desc); -#else - gtk_widget_modify_font (GTK_WIDGET (label), font_desc); -#endif - pango_font_description_free (font_desc); -} - -static void -on_input_radio_toggled (GtkCellRendererToggle *renderer, - gchar *path_str, - GvcMixerDialog *dialog) -{ - GtkTreeModel *model; - GtkTreeIter iter; - GtkTreePath *path; - gboolean toggled = FALSE; - gchar *name = NULL; - - model = gtk_tree_view_get_model (GTK_TREE_VIEW (dialog->priv->input_treeview)); - path = gtk_tree_path_new_from_string (path_str); - - gtk_tree_model_get_iter (model, &iter, path); - gtk_tree_path_free (path); - - gtk_tree_model_get (model, &iter, - NAME_COLUMN, &name, - ACTIVE_COLUMN, &toggled, - -1); - if (toggled ^ 1) { - MateMixerStream *stream; - MateMixerBackendFlags flags; - - stream = mate_mixer_context_get_stream (dialog->priv->context, name); - if (G_UNLIKELY (stream == NULL)) { - g_warn_if_reached (); - g_free (name); - return; - } - - g_debug ("Default input stream selection changed to %s", name); - - // XXX cache this - flags = mate_mixer_context_get_backend_flags (dialog->priv->context); - - if (flags & MATE_MIXER_BACKEND_CAN_SET_DEFAULT_INPUT_STREAM) - mate_mixer_context_set_default_input_stream (dialog->priv->context, stream); - else - set_input_stream (dialog, stream); - } - g_free (name); -} - -static void -on_output_radio_toggled (GtkCellRendererToggle *renderer, - gchar *path_str, - GvcMixerDialog *dialog) -{ - GtkTreeModel *model; - GtkTreeIter iter; - GtkTreePath *path; - gboolean toggled = FALSE; - gchar *name = NULL; - - model = gtk_tree_view_get_model (GTK_TREE_VIEW (dialog->priv->output_treeview)); - path = gtk_tree_path_new_from_string (path_str); - - gtk_tree_model_get_iter (model, &iter, path); - gtk_tree_path_free (path); - - gtk_tree_model_get (model, &iter, - NAME_COLUMN, &name, - ACTIVE_COLUMN, &toggled, - -1); - if (toggled ^ 1) { - MateMixerStream *stream; - MateMixerBackendFlags flags; - - stream = mate_mixer_context_get_stream (dialog->priv->context, name); - if (G_UNLIKELY (stream == NULL)) { - g_warn_if_reached (); - g_free (name); - return; - } - - g_debug ("Default output stream selection changed to %s", name); - - // XXX cache this - flags = mate_mixer_context_get_backend_flags (dialog->priv->context); - - if (flags & MATE_MIXER_BACKEND_CAN_SET_DEFAULT_OUTPUT_STREAM) - mate_mixer_context_set_default_output_stream (dialog->priv->context, stream); - else - set_output_stream (dialog, stream); - } - g_free (name); -} - -static void -stream_name_to_text (GtkTreeViewColumn *column, - GtkCellRenderer *cell, - GtkTreeModel *model, - GtkTreeIter *iter, - gpointer user_data) -{ - gchar *label; - gchar *speakers; - - gtk_tree_model_get (model, iter, - LABEL_COLUMN, &label, - SPEAKERS_COLUMN, &speakers, - -1); - - if (speakers != NULL) { - gchar *str = g_strdup_printf ("%s\n<i>%s</i>", - label, - speakers); - - g_object_set (cell, "markup", str, NULL); - g_free (str); - g_free (speakers); - } else { - g_object_set (cell, "text", label, NULL); - } - - g_free (label); -} - -static gint -compare_stream_treeview_items (GtkTreeModel *model, - GtkTreeIter *a, - GtkTreeIter *b, - gpointer user_data) -{ - gchar *desc_a = NULL; - gchar *desc_b = NULL; - gint result; - - gtk_tree_model_get (model, a, - LABEL_COLUMN, &desc_a, - -1); - gtk_tree_model_get (model, b, - LABEL_COLUMN, &desc_b, - -1); - - if (desc_a == NULL) { - g_free (desc_b); - return -1; - } - if (desc_b == NULL) { - g_free (desc_a); - return 1; - } - - result = g_ascii_strcasecmp (desc_a, desc_b); - - g_free (desc_a); - g_free (desc_b); - return result; -} - -static GtkWidget * -create_stream_treeview (GvcMixerDialog *dialog, GCallback on_toggled) -{ - GtkWidget *treeview; - GtkListStore *store; - GtkCellRenderer *renderer; - GtkTreeViewColumn *column; - - treeview = gtk_tree_view_new (); - gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (treeview), FALSE); - - store = gtk_list_store_new (NUM_COLUMNS, - G_TYPE_ICON, - G_TYPE_STRING, - G_TYPE_STRING, - G_TYPE_BOOLEAN, - G_TYPE_STRING); - - gtk_tree_view_set_model (GTK_TREE_VIEW (treeview), - GTK_TREE_MODEL (store)); - - renderer = gtk_cell_renderer_toggle_new (); - gtk_cell_renderer_toggle_set_radio (GTK_CELL_RENDERER_TOGGLE (renderer), TRUE); - - column = gtk_tree_view_column_new_with_attributes (NULL, - renderer, - "active", ACTIVE_COLUMN, - NULL); - - gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column); - - g_signal_connect (G_OBJECT (renderer), - "toggled", - G_CALLBACK (on_toggled), - dialog); - - gtk_tree_view_insert_column_with_data_func (GTK_TREE_VIEW (treeview), -1, - _("Name"), - gtk_cell_renderer_text_new (), - stream_name_to_text, - NULL, NULL); - - /* Keep the list of streams sorted by the name */ - gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (store), - LABEL_COLUMN, - GTK_SORT_ASCENDING); - - gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (store), - LABEL_COLUMN, - compare_stream_treeview_items, - NULL, NULL); - return treeview; -} - -static void -on_test_speakers_clicked (GvcComboBox *widget, GvcMixerDialog *dialog) -{ - GtkWidget *d, - *test, - *container; - gchar *title; - MateMixerDevice *device; - MateMixerStream *stream; - - device = g_object_get_data (G_OBJECT (widget), "device"); - if (G_UNLIKELY (device == NULL)) { - g_warn_if_reached (); - return; - } - - stream = find_device_test_stream (dialog, device); - if (G_UNLIKELY (stream == NULL)) { - g_warn_if_reached (); - return; - } - - title = g_strdup_printf (_("Speaker Testing for %s"), - mate_mixer_device_get_label (device)); - - d = gtk_dialog_new_with_buttons (title, - GTK_WINDOW (dialog), - GTK_DIALOG_MODAL | - GTK_DIALOG_DESTROY_WITH_PARENT, - "gtk-close", - GTK_RESPONSE_CLOSE, - NULL); - g_free (title); - - gtk_window_set_resizable (GTK_WINDOW (d), FALSE); - - test = gvc_speaker_test_new (stream); - gtk_widget_show (test); - - container = gtk_dialog_get_content_area (GTK_DIALOG (d)); - gtk_container_add (GTK_CONTAINER (container), test); - - gtk_dialog_run (GTK_DIALOG (d)); - gtk_widget_destroy (d); -} - -static GtkWidget * -create_profile_combo_box (GvcMixerDialog *dialog, - MateMixerSwitch *swtch, - const gchar *name, - const GList *items, - const gchar *active) -{ - GtkWidget *combobox; - - combobox = gvc_combo_box_new (name); - - gvc_combo_box_set_options (GVC_COMBO_BOX (combobox), items); - gvc_combo_box_set_active (GVC_COMBO_BOX (combobox), active); - - gvc_combo_box_set_size_group (GVC_COMBO_BOX (combobox), - dialog->priv->size_group, - FALSE); - - g_object_set (G_OBJECT (combobox), - "button-label", _("Test Speakers"), - NULL); - - g_object_set_data_full (G_OBJECT (combobox), - "switch", - g_object_ref (swtch), - g_object_unref); - - g_signal_connect (G_OBJECT (combobox), - "changed", - G_CALLBACK (on_combobox_option_changed), - dialog); - - g_signal_connect (G_OBJECT (combobox), - "button-clicked", - G_CALLBACK (on_test_speakers_clicked), - dialog); - - return combobox; -} - -static void -on_device_selection_changed (GtkTreeSelection *selection, GvcMixerDialog *dialog) -{ - GtkTreeIter iter; - gchar *name; - MateMixerDevice *device; - MateMixerSwitch *profile_switch; - - g_debug ("Device selection changed"); - - if (dialog->priv->hw_profile_combo != NULL) { - gtk_container_remove (GTK_CONTAINER (dialog->priv->hw_settings_box), - dialog->priv->hw_profile_combo); - - dialog->priv->hw_profile_combo = NULL; - } - - if (gtk_tree_selection_get_selected (selection, NULL, &iter) == FALSE) - return; - - gtk_tree_model_get (gtk_tree_view_get_model (GTK_TREE_VIEW (dialog->priv->hw_treeview)), - &iter, - HW_NAME_COLUMN, &name, - -1); - - device = mate_mixer_context_get_device (dialog->priv->context, name); - if (G_UNLIKELY (device == NULL)) { - g_warn_if_reached (); - g_free (name); - return; - } - g_free (name); - - /* Profile/speaker test combo */ - profile_switch = find_device_profile_switch (device); - if (profile_switch != NULL) { - const GList *options; - const gchar *active_name = NULL; - MateMixerSwitchOption *active; - - options = mate_mixer_switch_list_options (profile_switch); - active = mate_mixer_switch_get_active_option (profile_switch); - if (active != NULL) - active_name = mate_mixer_switch_option_get_name (active); - - dialog->priv->hw_profile_combo = - create_profile_combo_box (dialog, - profile_switch, - _("_Profile:"), - options, - active_name); - - g_object_set_data_full (G_OBJECT (dialog->priv->hw_profile_combo), - "device", - g_object_ref (device), - g_object_unref); - - gtk_box_pack_start (GTK_BOX (dialog->priv->hw_settings_box), - dialog->priv->hw_profile_combo, - TRUE, TRUE, 6); - - /* Enable the speaker test button if the selected device - * is capable of sound output */ - update_device_test_visibility (dialog); - - gtk_widget_show (dialog->priv->hw_profile_combo); - } -} - -static void -on_notebook_switch_page (GtkNotebook *notebook, - GtkWidget *page, - guint page_num, - GvcMixerDialog *dialog) -{ - MateMixerStreamControl *control; - - // XXX because this is called too early in constructor - if (G_UNLIKELY (dialog->priv->input_bar == NULL)) - return; - - control = gvc_channel_bar_get_control (GVC_CHANNEL_BAR (dialog->priv->input_bar)); - if (control == NULL) - return; - - if (page_num == PAGE_INPUT) - mate_mixer_stream_control_set_monitor_enabled (control, TRUE); - else - mate_mixer_stream_control_set_monitor_enabled (control, FALSE); -} - -static void -device_name_to_text (GtkTreeViewColumn *column, - GtkCellRenderer *cell, - GtkTreeModel *model, - GtkTreeIter *iter, - gpointer user_data) -{ - gchar *label = NULL; - gchar *profile = NULL; - gchar *status = NULL; - - gtk_tree_model_get (model, iter, - HW_LABEL_COLUMN, &label, - HW_PROFILE_COLUMN, &profile, - HW_STATUS_COLUMN, &status, - -1); - - if (G_LIKELY (status != NULL)) { - gchar *str; - - if (profile != NULL) - str = g_strdup_printf ("%s\n<i>%s</i>\n<i>%s</i>", - label, - status, - profile); - else - str = g_strdup_printf ("%s\n<i>%s</i>", - label, - status); - - g_object_set (cell, "markup", str, NULL); - g_free (str); - g_free (profile); - g_free (status); - } else - g_object_set (cell, "text", label, NULL); - - g_free (label); -} - -static gint -compare_device_treeview_items (GtkTreeModel *model, - GtkTreeIter *a, - GtkTreeIter *b, - gpointer user_data) -{ - gchar *desc_a = NULL; - gchar *desc_b = NULL; - gint result; - - gtk_tree_model_get (model, a, - HW_LABEL_COLUMN, &desc_a, - -1); - gtk_tree_model_get (model, b, - HW_LABEL_COLUMN, &desc_b, - -1); - - result = g_ascii_strcasecmp (desc_a, desc_b); - - g_free (desc_a); - g_free (desc_b); - return result; -} - -static GtkWidget * -create_device_treeview (GvcMixerDialog *dialog, GCallback on_changed) -{ - GtkWidget *treeview; - GtkListStore *store; - GtkCellRenderer *renderer; - GtkTreeViewColumn *column; - GtkTreeSelection *selection; - - treeview = gtk_tree_view_new (); - gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (treeview), FALSE); - - selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview)); - g_signal_connect (G_OBJECT (selection), - "changed", - on_changed, - dialog); - - store = gtk_list_store_new (HW_NUM_COLUMNS, - G_TYPE_ICON, - G_TYPE_STRING, - G_TYPE_STRING, - G_TYPE_STRING, - G_TYPE_STRING); - - gtk_tree_view_set_model (GTK_TREE_VIEW (treeview), - GTK_TREE_MODEL (store)); - - renderer = gtk_cell_renderer_pixbuf_new (); - g_object_set (G_OBJECT (renderer), - "stock-size", - GTK_ICON_SIZE_DIALOG, - NULL); - - column = gtk_tree_view_column_new_with_attributes (NULL, - renderer, - "gicon", HW_ICON_COLUMN, - NULL); - - gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column); - gtk_tree_view_insert_column_with_data_func (GTK_TREE_VIEW (treeview), -1, - _("Name"), - gtk_cell_renderer_text_new (), - device_name_to_text, - NULL, NULL); - - /* Keep the list of streams sorted by the name */ - gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (store), - HW_LABEL_COLUMN, - GTK_SORT_ASCENDING); - - gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (store), - HW_LABEL_COLUMN, - compare_device_treeview_items, - NULL, NULL); - return treeview; -} - -static void -dialog_accel_cb (GtkAccelGroup *accelgroup, - GObject *object, - guint key, - GdkModifierType mod, - GvcMixerDialog *self) -{ - gint num = -1; - gint i; - - for (i = 0; i < G_N_ELEMENTS (tab_accel_keys); i++) { - if (tab_accel_keys[i] == key) { - num = i; - break; - } - } - - if (num != -1) - gtk_notebook_set_current_page (GTK_NOTEBOOK (self->priv->notebook), num); -} - -static GObject * -gvc_mixer_dialog_constructor (GType type, - guint n_construct_properties, - GObjectConstructParam *construct_params) -{ - GObject *object; - GvcMixerDialog *self; - GtkWidget *main_vbox; - GtkWidget *label; - GtkWidget *alignment; - GtkWidget *box; - GtkWidget *sbox; - GtkWidget *ebox; - GtkTreeSelection *selection; - GtkAccelGroup *accel_group; - GClosure *closure; - GtkTreeIter iter; - gint i; - const GList *list; - - object = G_OBJECT_CLASS (gvc_mixer_dialog_parent_class)->constructor (type, - n_construct_properties, - construct_params); - - self = GVC_MIXER_DIALOG (object); - - gtk_dialog_add_button (GTK_DIALOG (self), "gtk-close", GTK_RESPONSE_OK); - - main_vbox = gtk_dialog_get_content_area (GTK_DIALOG (self)); - gtk_box_set_spacing (GTK_BOX (main_vbox), 2); - - gtk_container_set_border_width (GTK_CONTAINER (self), 6); - -#if GTK_CHECK_VERSION (3, 0, 0) - self->priv->output_stream_box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12); -#else - self->priv->output_stream_box = gtk_hbox_new (FALSE, 12); -#endif - - alignment = gtk_alignment_new (0, 0, 1, 1); - gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 12, 0, 0, 0); - gtk_container_add (GTK_CONTAINER (alignment), self->priv->output_stream_box); - gtk_box_pack_start (GTK_BOX (main_vbox), - alignment, - FALSE, FALSE, 0); - - self->priv->output_bar = create_bar (self, TRUE, TRUE); - gvc_channel_bar_set_name (GVC_CHANNEL_BAR (self->priv->output_bar), - _("_Output volume: ")); - - gtk_widget_show (self->priv->output_bar); - gtk_widget_set_sensitive (self->priv->output_bar, FALSE); - - gtk_box_pack_start (GTK_BOX (self->priv->output_stream_box), - self->priv->output_bar, TRUE, TRUE, 12); - - self->priv->notebook = gtk_notebook_new (); - gtk_box_pack_start (GTK_BOX (main_vbox), - self->priv->notebook, - TRUE, TRUE, 0); - - g_signal_connect (G_OBJECT (self->priv->notebook), - "switch-page", - G_CALLBACK (on_notebook_switch_page), - self); - - gtk_container_set_border_width (GTK_CONTAINER (self->priv->notebook), 5); - - /* Set up accels (borrowed from Empathy) */ - accel_group = gtk_accel_group_new (); - gtk_window_add_accel_group (GTK_WINDOW (self), accel_group); - - for (i = 0; i < G_N_ELEMENTS (tab_accel_keys); i++) { - closure = g_cclosure_new (G_CALLBACK (dialog_accel_cb), - self, - NULL); - gtk_accel_group_connect (accel_group, - tab_accel_keys[i], - GDK_MOD1_MASK, - 0, - closure); - } - - g_object_unref (accel_group); - - /* Create notebook pages */ -#if GTK_CHECK_VERSION (3, 0, 0) - self->priv->sound_effects_box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6); -#else - self->priv->sound_effects_box = gtk_vbox_new (FALSE, 6); -#endif - gtk_container_set_border_width (GTK_CONTAINER (self->priv->sound_effects_box), 12); - - label = gtk_label_new (_("Sound Effects")); - gtk_notebook_append_page (GTK_NOTEBOOK (self->priv->notebook), - self->priv->sound_effects_box, - label); - - self->priv->effects_bar = create_bar (self, TRUE, TRUE); - gtk_box_pack_start (GTK_BOX (self->priv->sound_effects_box), - self->priv->effects_bar, FALSE, FALSE, 0); - - gvc_channel_bar_set_show_marks (GVC_CHANNEL_BAR (self->priv->effects_bar), FALSE); - gvc_channel_bar_set_extended (GVC_CHANNEL_BAR (self->priv->effects_bar), FALSE); - - gvc_channel_bar_set_name (GVC_CHANNEL_BAR (self->priv->effects_bar), - _("_Alert volume: ")); - - gtk_widget_show (self->priv->effects_bar); - gtk_widget_set_sensitive (self->priv->effects_bar, FALSE); - - self->priv->sound_theme_chooser = gvc_sound_theme_chooser_new (); - - gtk_box_pack_start (GTK_BOX (self->priv->sound_effects_box), - self->priv->sound_theme_chooser, - TRUE, TRUE, 6); - -#if GTK_CHECK_VERSION (3, 0, 0) - self->priv->hw_box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12); -#else - self->priv->hw_box = gtk_vbox_new (FALSE, 12); -#endif - gtk_container_set_border_width (GTK_CONTAINER (self->priv->hw_box), 12); - - label = gtk_label_new (_("Hardware")); - gtk_notebook_append_page (GTK_NOTEBOOK (self->priv->notebook), - self->priv->hw_box, - label); - - box = gtk_frame_new (_("C_hoose a device to configure:")); - label = gtk_frame_get_label_widget (GTK_FRAME (box)); - make_label_bold (GTK_LABEL (label)); - gtk_label_set_use_underline (GTK_LABEL (label), TRUE); - gtk_frame_set_shadow_type (GTK_FRAME (box), GTK_SHADOW_NONE); - gtk_box_pack_start (GTK_BOX (self->priv->hw_box), box, TRUE, TRUE, 0); - - alignment = gtk_alignment_new (0, 0, 1, 1); - gtk_container_add (GTK_CONTAINER (box), alignment); - gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 6, 0, 0, 0); - - self->priv->hw_treeview = create_device_treeview (self, - G_CALLBACK (on_device_selection_changed)); - gtk_label_set_mnemonic_widget (GTK_LABEL (label), self->priv->hw_treeview); - - box = gtk_scrolled_window_new (NULL, NULL); - gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (box), - GTK_POLICY_NEVER, - GTK_POLICY_AUTOMATIC); - gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (box), - GTK_SHADOW_IN); - gtk_container_add (GTK_CONTAINER (box), self->priv->hw_treeview); - gtk_container_add (GTK_CONTAINER (alignment), box); - - selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (self->priv->hw_treeview)); - gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE); - - box = gtk_frame_new (_("Settings for the selected device:")); - label = gtk_frame_get_label_widget (GTK_FRAME (box)); - make_label_bold (GTK_LABEL (label)); - gtk_frame_set_shadow_type (GTK_FRAME (box), GTK_SHADOW_NONE); - gtk_box_pack_start (GTK_BOX (self->priv->hw_box), box, FALSE, TRUE, 12); - -#if GTK_CHECK_VERSION (3, 0, 0) - self->priv->hw_settings_box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12); -#else - self->priv->hw_settings_box = gtk_vbox_new (FALSE, 12); -#endif - - gtk_container_add (GTK_CONTAINER (box), self->priv->hw_settings_box); - -#if GTK_CHECK_VERSION (3, 0, 0) - self->priv->input_box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12); -#else - self->priv->input_box = gtk_vbox_new (FALSE, 12); -#endif - - gtk_container_set_border_width (GTK_CONTAINER (self->priv->input_box), 12); - - label = gtk_label_new (_("Input")); - gtk_notebook_append_page (GTK_NOTEBOOK (self->priv->notebook), - self->priv->input_box, - label); - - self->priv->input_bar = create_bar (self, TRUE, TRUE); - - gvc_channel_bar_set_name (GVC_CHANNEL_BAR (self->priv->input_bar), - _("_Input volume: ")); - - gvc_channel_bar_set_low_icon_name (GVC_CHANNEL_BAR (self->priv->input_bar), - "audio-input-microphone-low"); - gvc_channel_bar_set_high_icon_name (GVC_CHANNEL_BAR (self->priv->input_bar), - "audio-input-microphone-high"); - - gtk_widget_show (self->priv->input_bar); - gtk_widget_set_sensitive (self->priv->input_bar, FALSE); - - alignment = gtk_alignment_new (0, 0, 1, 1); - gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 6, 0, 0, 0); - gtk_container_add (GTK_CONTAINER (alignment), self->priv->input_bar); - gtk_box_pack_start (GTK_BOX (self->priv->input_box), - alignment, - FALSE, FALSE, 0); - -#if GTK_CHECK_VERSION (3, 0, 0) - box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6); - sbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6); - ebox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6); -#else - box = gtk_hbox_new (FALSE, 6); - sbox = gtk_hbox_new (FALSE, 6); - ebox = gtk_hbox_new (FALSE, 6); -#endif - - gtk_box_pack_start (GTK_BOX (self->priv->input_box), - box, - FALSE, FALSE, 6); - gtk_box_pack_start (GTK_BOX (box), - sbox, - FALSE, FALSE, 0); - - label = gtk_label_new (_("Input level:")); - gtk_box_pack_start (GTK_BOX (sbox), - label, - FALSE, FALSE, 0); - gtk_size_group_add_widget (self->priv->size_group, sbox); - - self->priv->input_level_bar = gvc_level_bar_new (); - gvc_level_bar_set_orientation (GVC_LEVEL_BAR (self->priv->input_level_bar), - GTK_ORIENTATION_HORIZONTAL); - gvc_level_bar_set_scale (GVC_LEVEL_BAR (self->priv->input_level_bar), - GVC_LEVEL_SCALE_LINEAR); - gtk_box_pack_start (GTK_BOX (box), - self->priv->input_level_bar, - TRUE, TRUE, 6); - - gtk_box_pack_start (GTK_BOX (box), - ebox, - FALSE, FALSE, 0); - gtk_size_group_add_widget (self->priv->size_group, ebox); - -#if GTK_CHECK_VERSION (3, 0, 0) - self->priv->input_settings_box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6); -#else - self->priv->input_settings_box = gtk_hbox_new (FALSE, 6); -#endif - gtk_box_pack_start (GTK_BOX (self->priv->input_box), - self->priv->input_settings_box, - FALSE, FALSE, 0); - - box = gtk_frame_new (_("C_hoose a device for sound input:")); - label = gtk_frame_get_label_widget (GTK_FRAME (box)); - make_label_bold (GTK_LABEL (label)); - gtk_label_set_use_underline (GTK_LABEL (label), TRUE); - gtk_frame_set_shadow_type (GTK_FRAME (box), GTK_SHADOW_NONE); - gtk_box_pack_start (GTK_BOX (self->priv->input_box), box, TRUE, TRUE, 0); - - alignment = gtk_alignment_new (0, 0, 1, 1); - gtk_container_add (GTK_CONTAINER (box), alignment); - gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 6, 0, 0, 0); - - self->priv->input_treeview = - create_stream_treeview (self, G_CALLBACK (on_input_radio_toggled)); - - gtk_label_set_mnemonic_widget (GTK_LABEL (label), self->priv->input_treeview); - - box = gtk_scrolled_window_new (NULL, NULL); - gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (box), - GTK_POLICY_NEVER, - GTK_POLICY_AUTOMATIC); - gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (box), - GTK_SHADOW_IN); - gtk_container_add (GTK_CONTAINER (box), self->priv->input_treeview); - gtk_container_add (GTK_CONTAINER (alignment), box); - - selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (self->priv->input_treeview)); - gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE); - - /* Output page */ - self->priv->output_box = gtk_vbox_new (FALSE, 12); - gtk_container_set_border_width (GTK_CONTAINER (self->priv->output_box), 12); - label = gtk_label_new (_("Output")); - gtk_notebook_append_page (GTK_NOTEBOOK (self->priv->notebook), - self->priv->output_box, - label); - - box = gtk_frame_new (_("C_hoose a device for sound output:")); - label = gtk_frame_get_label_widget (GTK_FRAME (box)); - make_label_bold (GTK_LABEL (label)); - gtk_label_set_use_underline (GTK_LABEL (label), TRUE); - gtk_frame_set_shadow_type (GTK_FRAME (box), GTK_SHADOW_NONE); - gtk_box_pack_start (GTK_BOX (self->priv->output_box), box, TRUE, TRUE, 0); - - alignment = gtk_alignment_new (0, 0, 1, 1); - gtk_container_add (GTK_CONTAINER (box), alignment); - gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 6, 0, 0, 0); - - self->priv->output_treeview = create_stream_treeview (self, - G_CALLBACK (on_output_radio_toggled)); - gtk_label_set_mnemonic_widget (GTK_LABEL (label), self->priv->output_treeview); - - box = gtk_scrolled_window_new (NULL, NULL); - gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (box), - GTK_POLICY_NEVER, - GTK_POLICY_AUTOMATIC); - gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (box), - GTK_SHADOW_IN); - gtk_container_add (GTK_CONTAINER (box), self->priv->output_treeview); - gtk_container_add (GTK_CONTAINER (alignment), box); - - selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (self->priv->output_treeview)); - gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE); - - box = gtk_frame_new (_("Settings for the selected device:")); - label = gtk_frame_get_label_widget (GTK_FRAME (box)); - make_label_bold (GTK_LABEL (label)); - gtk_frame_set_shadow_type (GTK_FRAME (box), GTK_SHADOW_NONE); - gtk_box_pack_start (GTK_BOX (self->priv->output_box), box, FALSE, FALSE, 12); - self->priv->output_settings_box = gtk_vbox_new (FALSE, 0); - gtk_container_add (GTK_CONTAINER (box), self->priv->output_settings_box); - - self->priv->output_settings_frame = box; - - /* Applications */ - self->priv->applications_window = gtk_scrolled_window_new (NULL, NULL); - gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (self->priv->applications_window), - GTK_POLICY_NEVER, - GTK_POLICY_AUTOMATIC); - - gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (self->priv->applications_window), - GTK_SHADOW_IN); - -#if GTK_CHECK_VERSION (3, 0, 0) - self->priv->applications_box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12); -#else - self->priv->applications_box = gtk_vbox_new (FALSE, 12); -#endif - gtk_container_set_border_width (GTK_CONTAINER (self->priv->applications_box), 12); - -#if GTK_CHECK_VERSION (3, 8, 0) - gtk_container_add (GTK_CONTAINER (self->priv->applications_window), - self->priv->applications_box); -#else - gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (self->priv->applications_window), - self->priv->applications_box); -#endif - - label = gtk_label_new (_("Applications")); - gtk_notebook_append_page (GTK_NOTEBOOK (self->priv->notebook), - self->priv->applications_window, - label); - - self->priv->no_apps_label = gtk_label_new (_("No application is currently playing or recording audio.")); - gtk_box_pack_start (GTK_BOX (self->priv->applications_box), - self->priv->no_apps_label, - TRUE, TRUE, 0); - - gtk_widget_show_all (main_vbox); - - list = mate_mixer_context_list_streams (self->priv->context); - while (list != NULL) { - add_stream (self, MATE_MIXER_STREAM (list->data)); - list = list->next; - } - - list = mate_mixer_context_list_devices (self->priv->context); - while (list != NULL) { - add_device (self, MATE_MIXER_DEVICE (list->data)); - list = list->next; - } - - /* Find an event role stream */ - list = mate_mixer_context_list_stored_controls (self->priv->context); - while (list != NULL) { - MateMixerStreamControl *control = MATE_MIXER_STREAM_CONTROL (list->data); - MateMixerStreamControlMediaRole media_role; - - media_role = mate_mixer_stream_control_get_media_role (control); - - if (media_role == MATE_MIXER_STREAM_CONTROL_MEDIA_ROLE_EVENT) { - add_effects_control (self, control); - break; - } - list = list->next; - } - - selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (self->priv->hw_treeview)); - - /* Select the first device in the list */ - // XXX handle no devices - if (gtk_tree_selection_get_selected (selection, NULL, NULL) == FALSE) { - GtkTreeModel *model = - gtk_tree_view_get_model (GTK_TREE_VIEW (self->priv->hw_treeview)); - - if (gtk_tree_model_get_iter_first (model, &iter)) - gtk_tree_selection_select_iter (selection, &iter); - } - - return object; -} - -static MateMixerContext * -gvc_mixer_dialog_get_context (GvcMixerDialog *dialog) -{ - return dialog->priv->context; -} - -static void -gvc_mixer_dialog_set_context (GvcMixerDialog *dialog, MateMixerContext *context) -{ - dialog->priv->context = g_object_ref (context); - - g_signal_connect (G_OBJECT (dialog->priv->context), - "stream-added", - G_CALLBACK (on_context_stream_added), - dialog); - g_signal_connect (G_OBJECT (dialog->priv->context), - "stream-removed", - G_CALLBACK (on_context_stream_removed), - dialog); - - g_signal_connect (G_OBJECT (dialog->priv->context), - "device-added", - G_CALLBACK (on_context_device_added), - dialog); - g_signal_connect (G_OBJECT (dialog->priv->context), - "device-removed", - G_CALLBACK (on_context_device_removed), - dialog); - - g_signal_connect (G_OBJECT (dialog->priv->context), - "notify::default-input-stream", - G_CALLBACK (on_context_default_input_stream_notify), - dialog); - g_signal_connect (G_OBJECT (dialog->priv->context), - "notify::default-output-stream", - G_CALLBACK (on_context_default_output_stream_notify), - dialog); - - g_signal_connect (G_OBJECT (dialog->priv->context), - "stored-control-added", - G_CALLBACK (on_context_stored_control_added), - dialog); - g_signal_connect (G_OBJECT (dialog->priv->context), - "stored-control-removed", - G_CALLBACK (on_context_stored_control_removed), - dialog); - - g_object_notify (G_OBJECT (dialog), "context"); -} - -static void -gvc_mixer_dialog_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - GvcMixerDialog *self = GVC_MIXER_DIALOG (object); - - switch (prop_id) { - case PROP_CONTEXT: - gvc_mixer_dialog_set_context (self, g_value_get_object (value)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -gvc_mixer_dialog_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - GvcMixerDialog *self = GVC_MIXER_DIALOG (object); - - switch (prop_id) { - case PROP_CONTEXT: - g_value_set_object (value, gvc_mixer_dialog_get_context (self)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -gvc_mixer_dialog_dispose (GObject *object) -{ - GvcMixerDialog *dialog = GVC_MIXER_DIALOG (object); - - if (dialog->priv->context != NULL) { - g_signal_handlers_disconnect_by_data (G_OBJECT (dialog->priv->context), - dialog); - - g_clear_object (&dialog->priv->context); - } - - G_OBJECT_CLASS (gvc_mixer_dialog_parent_class)->dispose (object); -} - -static void -gvc_mixer_dialog_class_init (GvcMixerDialogClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - object_class->constructor = gvc_mixer_dialog_constructor; - object_class->dispose = gvc_mixer_dialog_dispose; - object_class->finalize = gvc_mixer_dialog_finalize; - object_class->set_property = gvc_mixer_dialog_set_property; - object_class->get_property = gvc_mixer_dialog_get_property; - - g_object_class_install_property (object_class, - PROP_CONTEXT, - g_param_spec_object ("context", - "Context", - "MateMixer context", - MATE_MIXER_TYPE_CONTEXT, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS)); - - g_type_class_add_private (klass, sizeof (GvcMixerDialogPrivate)); -} - -static void -gvc_mixer_dialog_init (GvcMixerDialog *dialog) -{ - dialog->priv = GVC_MIXER_DIALOG_GET_PRIVATE (dialog); - - dialog->priv->bars = g_hash_table_new (g_str_hash, g_str_equal); - dialog->priv->size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL); -} - -static void -gvc_mixer_dialog_finalize (GObject *object) -{ - GvcMixerDialog *dialog; - - dialog = GVC_MIXER_DIALOG (object); - - g_hash_table_destroy (dialog->priv->bars); - - G_OBJECT_CLASS (gvc_mixer_dialog_parent_class)->finalize (object); -} - -GvcMixerDialog * -gvc_mixer_dialog_new (MateMixerContext *context) -{ - return g_object_new (GVC_TYPE_MIXER_DIALOG, - "icon-name", "multimedia-volume-control", - "title", _("Sound Preferences"), - "context", context, - NULL); -} - -gboolean -gvc_mixer_dialog_set_page (GvcMixerDialog *self, const gchar *page) -{ - guint num = 0; - - g_return_val_if_fail (GVC_IS_MIXER_DIALOG (self), FALSE); - - if (page != NULL) { - if (g_str_equal (page, "effects")) - num = PAGE_EFFECTS; - else if (g_str_equal (page, "hardware")) - num = PAGE_HARDWARE; - else if (g_str_equal (page, "input")) - num = PAGE_INPUT; - else if (g_str_equal (page, "output")) - num = PAGE_OUTPUT; - else if (g_str_equal (page, "applications")) - num = PAGE_APPLICATIONS; - } - - gtk_notebook_set_current_page (GTK_NOTEBOOK (self->priv->notebook), num); - - return TRUE; -} diff --git a/mate-volume-control/src/gvc-mixer-dialog.h b/mate-volume-control/src/gvc-mixer-dialog.h deleted file mode 100644 index 22e522d..0000000 --- a/mate-volume-control/src/gvc-mixer-dialog.h +++ /dev/null @@ -1,65 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- - * - * Copyright (C) 2008 Red Hat, Inc. - * Copyright (C) 2014 Michal Ratajsky <[email protected]> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ - -#ifndef __GVC_MIXER_DIALOG_H -#define __GVC_MIXER_DIALOG_H - -#include <glib.h> -#include <glib-object.h> - -#include <libmatemixer/matemixer.h> - -G_BEGIN_DECLS - -#define GVC_DIALOG_DBUS_NAME "org.mate.VolumeControl" - -#define GVC_TYPE_MIXER_DIALOG (gvc_mixer_dialog_get_type ()) -#define GVC_MIXER_DIALOG(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GVC_TYPE_MIXER_DIALOG, GvcMixerDialog)) -#define GVC_MIXER_DIALOG_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GVC_TYPE_MIXER_DIALOG, GvcMixerDialogClass)) -#define GVC_IS_MIXER_DIALOG(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GVC_TYPE_MIXER_DIALOG)) -#define GVC_IS_MIXER_DIALOG_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GVC_TYPE_MIXER_DIALOG)) -#define GVC_MIXER_DIALOG_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GVC_TYPE_MIXER_DIALOG, GvcMixerDialogClass)) - -typedef struct _GvcMixerDialog GvcMixerDialog; -typedef struct _GvcMixerDialogClass GvcMixerDialogClass; -typedef struct _GvcMixerDialogPrivate GvcMixerDialogPrivate; - -struct _GvcMixerDialog -{ - GtkDialog parent; - GvcMixerDialogPrivate *priv; -}; - -struct _GvcMixerDialogClass -{ - GtkDialogClass parent_class; -}; - -GType gvc_mixer_dialog_get_type (void) G_GNUC_CONST; - -GvcMixerDialog * gvc_mixer_dialog_new (MateMixerContext *context); - -gboolean gvc_mixer_dialog_set_page (GvcMixerDialog *dialog, - const gchar *page); - -G_END_DECLS - -#endif /* __GVC_MIXER_DIALOG_H */ diff --git a/mate-volume-control/src/gvc-speaker-test.c b/mate-volume-control/src/gvc-speaker-test.c deleted file mode 100644 index e638413..0000000 --- a/mate-volume-control/src/gvc-speaker-test.c +++ /dev/null @@ -1,517 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- - * - * Copyright (C) 2009 Bastien Nocera - * Copyright (C) 2014 Michal Ratajsky <[email protected]> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ - -#include "config.h" - -#include <glib.h> -#include <glib/gi18n.h> -#include <glib-object.h> -#include <gtk/gtk.h> - -#include <canberra.h> -#include <libmatemixer/matemixer.h> - -#include "gvc-speaker-test.h" -#include "gvc-utils.h" - -#define GVC_SPEAKER_TEST_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GVC_TYPE_SPEAKER_TEST, GvcSpeakerTestPrivate)) - -struct _GvcSpeakerTestPrivate -{ - GArray *controls; - ca_context *canberra; - MateMixerStream *stream; -}; - -enum { - PROP_0, - PROP_STREAM, - N_PROPERTIES -}; - -static GParamSpec *properties[N_PROPERTIES] = { NULL, }; - -static void gvc_speaker_test_class_init (GvcSpeakerTestClass *klass); -static void gvc_speaker_test_init (GvcSpeakerTest *test); -static void gvc_speaker_test_dispose (GObject *object); -static void gvc_speaker_test_finalize (GObject *object); - -#if GTK_CHECK_VERSION (3, 4, 0) -G_DEFINE_TYPE (GvcSpeakerTest, gvc_speaker_test, GTK_TYPE_GRID) -#else -G_DEFINE_TYPE (GvcSpeakerTest, gvc_speaker_test, GTK_TYPE_TABLE) -#endif - -typedef struct { - MateMixerChannelPosition position; - guint left; - guint top; -} TablePosition; - -static const TablePosition positions[] = { - /* Position, X, Y */ - { MATE_MIXER_CHANNEL_FRONT_LEFT, 0, 0, }, - { MATE_MIXER_CHANNEL_FRONT_LEFT_CENTER, 1, 0, }, - { MATE_MIXER_CHANNEL_FRONT_CENTER, 2, 0, }, - { MATE_MIXER_CHANNEL_MONO, 2, 0, }, - { MATE_MIXER_CHANNEL_FRONT_RIGHT_CENTER, 3, 0, }, - { MATE_MIXER_CHANNEL_FRONT_RIGHT, 4, 0, }, - { MATE_MIXER_CHANNEL_SIDE_LEFT, 0, 1, }, - { MATE_MIXER_CHANNEL_SIDE_RIGHT, 4, 1, }, - { MATE_MIXER_CHANNEL_BACK_LEFT, 0, 2, }, - { MATE_MIXER_CHANNEL_BACK_CENTER, 2, 2, }, - { MATE_MIXER_CHANNEL_BACK_RIGHT, 4, 2, }, - { MATE_MIXER_CHANNEL_LFE, 3, 2 } -}; - -MateMixerStream * -gvc_speaker_test_get_stream (GvcSpeakerTest *test) -{ - g_return_val_if_fail (GVC_IS_SPEAKER_TEST (test), NULL); - - return test->priv->stream; -} - -static void -gvc_speaker_test_set_stream (GvcSpeakerTest *test, MateMixerStream *stream) -{ - MateMixerStreamControl *control; - const gchar *name; - guint i; - - name = mate_mixer_stream_get_name (stream); - control = mate_mixer_stream_get_default_control (stream); - - ca_context_change_device (test->priv->canberra, name); - - for (i = 0; i < G_N_ELEMENTS (positions); i++) { - gboolean has_position = - mate_mixer_stream_control_has_channel_position (control, positions[i].position); - - gtk_widget_set_visible (g_array_index (test->priv->controls, GtkWidget *, i), - has_position); - } - - test->priv->stream = g_object_ref (stream); -} - -static void -gvc_speaker_test_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - GvcSpeakerTest *self = GVC_SPEAKER_TEST (object); - - switch (prop_id) { - case PROP_STREAM: - gvc_speaker_test_set_stream (self, g_value_get_object (value)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -gvc_speaker_test_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - GvcSpeakerTest *self = GVC_SPEAKER_TEST (object); - - switch (prop_id) { - case PROP_STREAM: - g_value_set_object (value, self->priv->stream); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -gvc_speaker_test_class_init (GvcSpeakerTestClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - object_class->dispose = gvc_speaker_test_dispose; - object_class->finalize = gvc_speaker_test_finalize; - object_class->set_property = gvc_speaker_test_set_property; - object_class->get_property = gvc_speaker_test_get_property; - - properties[PROP_STREAM] = - g_param_spec_object ("stream", - "Stream", - "MateMixer stream", - MATE_MIXER_TYPE_STREAM, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS); - - g_object_class_install_properties (object_class, N_PROPERTIES, properties); - - g_type_class_add_private (klass, sizeof (GvcSpeakerTestPrivate)); -} - -static const gchar * -sound_name (MateMixerChannelPosition position) -{ - switch (position) { - case MATE_MIXER_CHANNEL_FRONT_LEFT: - return "audio-channel-front-left"; - case MATE_MIXER_CHANNEL_FRONT_RIGHT: - return "audio-channel-front-right"; - case MATE_MIXER_CHANNEL_FRONT_CENTER: - return "audio-channel-front-center"; - case MATE_MIXER_CHANNEL_BACK_LEFT: - return "audio-channel-rear-left"; - case MATE_MIXER_CHANNEL_BACK_RIGHT: - return "audio-channel-rear-right"; - case MATE_MIXER_CHANNEL_BACK_CENTER: - return "audio-channel-rear-center"; - case MATE_MIXER_CHANNEL_LFE: - return "audio-channel-lfe"; - case MATE_MIXER_CHANNEL_SIDE_LEFT: - return "audio-channel-side-left"; - case MATE_MIXER_CHANNEL_SIDE_RIGHT: - return "audio-channel-side-right"; - default: - return NULL; - } -} - -static const gchar * -icon_name (MateMixerChannelPosition position, gboolean playing) -{ - switch (position) { - case MATE_MIXER_CHANNEL_FRONT_LEFT: - return playing - ? "audio-speaker-left-testing" - : "audio-speaker-left"; - case MATE_MIXER_CHANNEL_FRONT_RIGHT: - return playing - ? "audio-speaker-right-testing" - : "audio-speaker-right"; - case MATE_MIXER_CHANNEL_FRONT_CENTER: - return playing - ? "audio-speaker-center-testing" - : "audio-speaker-center"; - case MATE_MIXER_CHANNEL_BACK_LEFT: - return playing - ? "audio-speaker-left-back-testing" - : "audio-speaker-left-back"; - case MATE_MIXER_CHANNEL_BACK_RIGHT: - return playing - ? "audio-speaker-right-back-testing" - : "audio-speaker-right-back"; - case MATE_MIXER_CHANNEL_BACK_CENTER: - return playing - ? "audio-speaker-center-back-testing" - : "audio-speaker-center-back"; - case MATE_MIXER_CHANNEL_LFE: - return playing - ? "audio-subwoofer-testing" - : "audio-subwoofer"; - case MATE_MIXER_CHANNEL_SIDE_LEFT: - return playing - ? "audio-speaker-left-side-testing" - : "audio-speaker-left-side"; - case MATE_MIXER_CHANNEL_SIDE_RIGHT: - return playing - ? "audio-speaker-right-side-testing" - : "audio-speaker-right-side"; - default: - return NULL; - } -} - -static void -update_button (GtkWidget *control) -{ - GtkWidget *button; - GtkWidget *image; - gboolean playing; - MateMixerChannelPosition position; - - button = g_object_get_data (G_OBJECT (control), "button"); - image = g_object_get_data (G_OBJECT (control), "image"); - - position = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (control), "position")); - playing = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (control), "playing")); - - gtk_button_set_label (GTK_BUTTON (button), playing ? _("Stop") : _("Test")); - - gtk_image_set_from_icon_name (GTK_IMAGE (image), - icon_name (position, playing), - GTK_ICON_SIZE_DIALOG); -} - -static gboolean -idle_cb (GtkWidget *control) -{ - if (control != NULL) { - /* This is called in the background thread, hence forward to main thread - * via idle callback */ - g_object_set_data (G_OBJECT (control), "playing", GINT_TO_POINTER (FALSE)); - - update_button (control); - } - return FALSE; -} - -static void -finish_cb (ca_context *c, uint32_t id, int error_code, void *userdata) -{ - GtkWidget *control = (GtkWidget *) userdata; - - if (error_code == CA_ERROR_DESTROYED || control == NULL) - return; - - g_idle_add ((GSourceFunc) idle_cb, control); -} - -static void -on_test_button_clicked (GtkButton *button, GtkWidget *control) -{ - gboolean playing; - ca_context *canberra; - - canberra = g_object_get_data (G_OBJECT (control), "canberra"); - - ca_context_cancel (canberra, 1); - - playing = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (control), "playing")); - - if (playing) { - g_object_set_data (G_OBJECT (control), "playing", GINT_TO_POINTER (FALSE)); - } else { - MateMixerChannelPosition position; - const gchar *name; - ca_proplist *proplist; - - position = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (control), "position")); - - ca_proplist_create (&proplist); - ca_proplist_sets (proplist, - CA_PROP_MEDIA_ROLE, "test"); - ca_proplist_sets (proplist, - CA_PROP_MEDIA_NAME, - gvc_channel_position_to_pretty_string (position)); - ca_proplist_sets (proplist, - CA_PROP_CANBERRA_FORCE_CHANNEL, - gvc_channel_position_to_pulse_string (position)); - - ca_proplist_sets (proplist, CA_PROP_CANBERRA_ENABLE, "1"); - - name = sound_name (position); - if (name != NULL) { - ca_proplist_sets (proplist, CA_PROP_EVENT_ID, name); - playing = ca_context_play_full (canberra, 1, proplist, finish_cb, control) >= 0; - } - - if (!playing) { - ca_proplist_sets (proplist, CA_PROP_EVENT_ID, "audio-test-signal"); - playing = ca_context_play_full (canberra, 1, proplist, finish_cb, control) >= 0; - } - - if (!playing) { - ca_proplist_sets(proplist, CA_PROP_EVENT_ID, "bell-window-system"); - playing = ca_context_play_full (canberra, 1, proplist, finish_cb, control) >= 0; - } - - g_object_set_data (G_OBJECT (control), "playing", GINT_TO_POINTER (playing)); - } - - update_button (control); -} - -static GtkWidget * -create_control (ca_context *canberra, MateMixerChannelPosition position) -{ - GtkWidget *control; - GtkWidget *box; - GtkWidget *label; - GtkWidget *image; - GtkWidget *test_button; - const gchar *name; - -#if GTK_CHECK_VERSION (3, 0, 0) - control = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6); - box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0); -#else - control = gtk_vbox_new (FALSE, 6); - box = gtk_hbox_new (FALSE, 0); -#endif - g_object_set_data (G_OBJECT (control), "playing", GINT_TO_POINTER (FALSE)); - g_object_set_data (G_OBJECT (control), "position", GINT_TO_POINTER (position)); - g_object_set_data (G_OBJECT (control), "canberra", canberra); - - name = icon_name (position, FALSE); - if (name == NULL) - name = "audio-volume-medium"; - - image = gtk_image_new_from_icon_name (name, GTK_ICON_SIZE_DIALOG); - g_object_set_data (G_OBJECT (control), "image", image); - gtk_box_pack_start (GTK_BOX (control), image, FALSE, FALSE, 0); - - label = gtk_label_new (gvc_channel_position_to_pretty_string (position)); - gtk_box_pack_start (GTK_BOX (control), label, FALSE, FALSE, 0); - - test_button = gtk_button_new_with_label (_("Test")); - g_signal_connect (G_OBJECT (test_button), - "clicked", - G_CALLBACK (on_test_button_clicked), - control); - - g_object_set_data (G_OBJECT (control), "button", test_button); - - gtk_box_pack_start (GTK_BOX (box), test_button, TRUE, FALSE, 0); - gtk_box_pack_start (GTK_BOX (control), box, FALSE, FALSE, 0); - - gtk_widget_show_all (control); - - return control; -} - -static void -create_controls (GvcSpeakerTest *test) -{ - guint i; - - for (i = 0; i < G_N_ELEMENTS (positions); i++) { - GtkWidget *control = create_control (test->priv->canberra, positions[i].position); - -#if GTK_CHECK_VERSION (3, 4, 0) - gtk_grid_attach (GTK_GRID (test), - control, - positions[i].left, - positions[i].top, - 1, 1); -#else - gtk_table_attach (GTK_TABLE (test), - control, - positions[i].left, - positions[i].left + 1, - positions[i].top, - positions[i].top + 1, - GTK_EXPAND, GTK_EXPAND, 0, 0); -#endif - g_array_insert_val (test->priv->controls, i, control); - } -} - -static void -gvc_speaker_test_init (GvcSpeakerTest *test) -{ - GtkWidget *face; - - test->priv = GVC_SPEAKER_TEST_GET_PRIVATE (test); - - gtk_container_set_border_width (GTK_CONTAINER (test), 12); - - face = gtk_image_new_from_icon_name ("face-smile", GTK_ICON_SIZE_DIALOG); - -#if GTK_CHECK_VERSION (3, 4, 0) - gtk_grid_attach (GTK_GRID (test), - face, - 1, 1, - 3, 1); - - - gtk_grid_set_baseline_row (GTK_GRID (test), 1); -#else - gtk_table_attach (GTK_TABLE (test), - face, - 2, 3, 1, 2, - GTK_EXPAND, - GTK_EXPAND, - 0, 0); -#endif - gtk_widget_show (face); - - ca_context_create (&test->priv->canberra); - - /* The test sounds are played for a single channel, set up using the - * FORCE_CHANNEL property of libcanberra; this property is only supported - * in the PulseAudio backend, so avoid other backends completely */ - ca_context_set_driver (test->priv->canberra, "pulse"); - - ca_context_change_props (test->priv->canberra, - CA_PROP_APPLICATION_ID, "org.mate.VolumeControl", - CA_PROP_APPLICATION_NAME, _("Volume Control"), - CA_PROP_APPLICATION_VERSION, VERSION, - CA_PROP_APPLICATION_ICON_NAME, "multimedia-volume-control", - NULL); - - test->priv->controls = g_array_new (FALSE, FALSE, sizeof (GtkWidget *)); - - create_controls (test); -} - -static void -gvc_speaker_test_dispose (GObject *object) -{ - GvcSpeakerTest *test; - - test = GVC_SPEAKER_TEST (object); - - g_clear_object (&test->priv->stream); - - G_OBJECT_CLASS (gvc_speaker_test_parent_class)->dispose (object); -} - -static void -gvc_speaker_test_finalize (GObject *object) -{ - GvcSpeakerTest *test; - - test = GVC_SPEAKER_TEST (object); - - ca_context_destroy (test->priv->canberra); - - G_OBJECT_CLASS (gvc_speaker_test_parent_class)->finalize (object); -} - -GtkWidget * -gvc_speaker_test_new (MateMixerStream *stream) -{ - GObject *test; - - g_return_val_if_fail (MATE_MIXER_IS_STREAM (stream), NULL); - - test = g_object_new (GVC_TYPE_SPEAKER_TEST, - "row-spacing", 6, - "column-spacing", 6, -#if GTK_CHECK_VERSION (3, 4, 0) - "row-homogeneous", TRUE, - "column-homogeneous", TRUE, -#else - "homogeneous", TRUE, - "n-rows", 3, - "n-columns", 5, -#endif - "stream", stream, - NULL); - - return GTK_WIDGET (test); -} diff --git a/mate-volume-control/src/gvc-speaker-test.h b/mate-volume-control/src/gvc-speaker-test.h deleted file mode 100644 index 1c1546d..0000000 --- a/mate-volume-control/src/gvc-speaker-test.h +++ /dev/null @@ -1,71 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- - * - * Copyright (C) 2009 Red Hat, Inc. - * Copyright (C) 2014 Michal Ratajsky <[email protected]> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ - -#ifndef __GVC_SPEAKER_TEST_H -#define __GVC_SPEAKER_TEST_H - -#include <glib.h> -#include <glib-object.h> -#include <gtk/gtk.h> - -#include <libmatemixer/matemixer.h> - -G_BEGIN_DECLS - -#define GVC_TYPE_SPEAKER_TEST (gvc_speaker_test_get_type ()) -#define GVC_SPEAKER_TEST(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GVC_TYPE_SPEAKER_TEST, GvcSpeakerTest)) -#define GVC_SPEAKER_TEST_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GVC_TYPE_SPEAKER_TEST, GvcSpeakerTestClass)) -#define GVC_IS_SPEAKER_TEST(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GVC_TYPE_SPEAKER_TEST)) -#define GVC_IS_SPEAKER_TEST_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GVC_TYPE_SPEAKER_TEST)) -#define GVC_SPEAKER_TEST_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GVC_TYPE_SPEAKER_TEST, GvcSpeakerTestClass)) - -typedef struct _GvcSpeakerTest GvcSpeakerTest; -typedef struct _GvcSpeakerTestClass GvcSpeakerTestClass; -typedef struct _GvcSpeakerTestPrivate GvcSpeakerTestPrivate; - -struct _GvcSpeakerTest -{ -#if GTK_CHECK_VERSION (3, 4, 0) - GtkGrid parent; -#else - GtkTable parent; -#endif - GvcSpeakerTestPrivate *priv; -}; - -struct _GvcSpeakerTestClass -{ -#if GTK_CHECK_VERSION (3, 4, 0) - GtkGridClass parent_class; -#else - GtkTableClass parent_class; -#endif -}; - -GType gvc_speaker_test_get_type (void) G_GNUC_CONST; - -GtkWidget * gvc_speaker_test_new (MateMixerStream *stream); - -MateMixerStream * gvc_speaker_test_get_stream (GvcSpeakerTest *test); - -G_END_DECLS - -#endif /* __GVC_SPEAKER_TEST_H */ diff --git a/mate-volume-control/src/gvc-stream-status-icon.c b/mate-volume-control/src/gvc-stream-status-icon.c deleted file mode 100644 index 3ede4b1..0000000 --- a/mate-volume-control/src/gvc-stream-status-icon.c +++ /dev/null @@ -1,805 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- - * - * Copyright (C) 2008 William Jon McCann - * Copyright (C) 2014 Michal Ratajsky <[email protected]> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ - -#include <glib.h> -#include <glib/gi18n.h> -#include <gtk/gtk.h> -#include <gdk/gdkkeysyms.h> - -#include <libmatemixer/matemixer.h> - -#define MATE_DESKTOP_USE_UNSTABLE_API -#include <libmate-desktop/mate-desktop-utils.h> - -#include "gvc-channel-bar.h" -#include "gvc-stream-status-icon.h" - -#define GVC_STREAM_STATUS_ICON_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GVC_TYPE_STREAM_STATUS_ICON, GvcStreamStatusIconPrivate)) - -struct _GvcStreamStatusIconPrivate -{ - gchar **icon_names; - GtkWidget *dock; - GtkWidget *bar; - guint current_icon; - gchar *display_name; - MateMixerStreamControl *control; -}; - -enum -{ - PROP_0, - PROP_CONTROL, - PROP_DISPLAY_NAME, - PROP_ICON_NAMES, - N_PROPERTIES -}; - -static GParamSpec *properties[N_PROPERTIES] = { NULL, }; - -static void gvc_stream_status_icon_class_init (GvcStreamStatusIconClass *klass); -static void gvc_stream_status_icon_init (GvcStreamStatusIcon *stream_status_icon); -static void gvc_stream_status_icon_finalize (GObject *object); - -G_DEFINE_TYPE (GvcStreamStatusIcon, gvc_stream_status_icon, GTK_TYPE_STATUS_ICON) - -static gboolean -popup_dock (GvcStreamStatusIcon *icon, guint time) -{ - GdkRectangle area; - GtkOrientation orientation; - GdkDisplay *display; - GdkScreen *screen; - int x; - int y; - int monitor_num; - GdkRectangle monitor; - GtkRequisition dock_req; - - screen = gtk_status_icon_get_screen (GTK_STATUS_ICON (icon)); - - if (gtk_status_icon_get_geometry (GTK_STATUS_ICON (icon), - &screen, - &area, - &orientation) == FALSE) { - g_warning ("Unable to determine geometry of status icon"); - return FALSE; - } - - /* position roughly */ - gtk_window_set_screen (GTK_WINDOW (icon->priv->dock), screen); - gvc_channel_bar_set_orientation (GVC_CHANNEL_BAR (icon->priv->bar), - 1 - orientation); - - monitor_num = gdk_screen_get_monitor_at_point (screen, area.x, area.y); - gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor); - - gtk_container_foreach (GTK_CONTAINER (icon->priv->dock), - (GtkCallback) gtk_widget_show_all, NULL); -#if GTK_CHECK_VERSION (3, 0, 0) - gtk_widget_get_preferred_size (icon->priv->dock, &dock_req, NULL); -#else - gtk_widget_size_request (icon->priv->dock, &dock_req); -#endif - - if (orientation == GTK_ORIENTATION_VERTICAL) { - if (area.x + area.width + dock_req.width <= monitor.x + monitor.width) - x = area.x + area.width; - else - x = area.x - dock_req.width; - - if (area.y + dock_req.height <= monitor.y + monitor.height) - y = area.y; - else - y = monitor.y + monitor.height - dock_req.height; - } else { - if (area.y + area.height + dock_req.height <= monitor.y + monitor.height) - y = area.y + area.height; - else - y = area.y - dock_req.height; - - if (area.x + dock_req.width <= monitor.x + monitor.width) - x = area.x; - else - x = monitor.x + monitor.width - dock_req.width; - } - - gtk_window_move (GTK_WINDOW (icon->priv->dock), x, y); - - /* Without this, the popup window appears as a square after changing - * the orientation */ - gtk_window_resize (GTK_WINDOW (icon->priv->dock), 1, 1); - - gtk_widget_show_all (icon->priv->dock); - - /* Grab focus */ - gtk_grab_add (icon->priv->dock); - - display = gtk_widget_get_display (icon->priv->dock); - -#if GTK_CHECK_VERSION (3, 0, 0) - do { - GdkDeviceManager *manager = gdk_display_get_device_manager (display); - - if (gdk_device_grab (gdk_device_manager_get_client_pointer (manager), - gtk_widget_get_window (icon->priv->dock), - GDK_OWNERSHIP_NONE, - TRUE, - GDK_BUTTON_PRESS_MASK | - GDK_BUTTON_RELEASE_MASK | - GDK_POINTER_MOTION_MASK | - GDK_SCROLL_MASK, - NULL, - time) != GDK_GRAB_SUCCESS) { - gtk_grab_remove (icon->priv->dock); - gtk_widget_hide (icon->priv->dock); - } - } while (0); -#else - if (gdk_pointer_grab (gtk_widget_get_window (icon->priv->dock), - TRUE, - GDK_BUTTON_PRESS_MASK | - GDK_BUTTON_RELEASE_MASK | - GDK_POINTER_MOTION_MASK | - GDK_SCROLL_MASK, - NULL, NULL, - time) != GDK_GRAB_SUCCESS) { - gtk_grab_remove (icon->priv->dock); - gtk_widget_hide (icon->priv->dock); - return FALSE; - } - - if (gdk_keyboard_grab (gtk_widget_get_window (icon->priv->dock), - TRUE, - time) != GDK_GRAB_SUCCESS) { - gdk_display_pointer_ungrab (display, time); - gtk_grab_remove (icon->priv->dock); - gtk_widget_hide (icon->priv->dock); - return FALSE; - } -#endif - gtk_widget_grab_focus (icon->priv->dock); - - return TRUE; -} - -static void -on_status_icon_activate (GtkStatusIcon *status_icon, GvcStreamStatusIcon *icon) -{ - popup_dock (icon, GDK_CURRENT_TIME); -} - -static gboolean -on_status_icon_button_press (GtkStatusIcon *status_icon, - GdkEventButton *event, - GvcStreamStatusIcon *icon) -{ - /* Middle click acts as mute/unmute */ - if (event->button == 2) { - gboolean is_muted = mate_mixer_stream_control_get_mute (icon->priv->control); - - mate_mixer_stream_control_set_mute (icon->priv->control, !is_muted); - return TRUE; - } - return FALSE; -} - -static void -on_menu_mute_toggled (GtkMenuItem *item, GvcStreamStatusIcon *icon) -{ - gboolean is_muted; - - is_muted = gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (item)); - - mate_mixer_stream_control_set_mute (icon->priv->control, is_muted); -} - -static void -on_menu_activate_open_volume_control (GtkMenuItem *item, - GvcStreamStatusIcon *icon) -{ - GError *error = NULL; - - mate_gdk_spawn_command_line_on_screen (gtk_widget_get_screen (icon->priv->dock), - "mate-volume-control", - &error); - - if (error != NULL) { - GtkWidget *dialog; - - dialog = gtk_message_dialog_new (NULL, - 0, - GTK_MESSAGE_ERROR, - GTK_BUTTONS_CLOSE, - _("Failed to start Sound Preferences: %s"), - error->message); - g_signal_connect (G_OBJECT (dialog), - "response", - G_CALLBACK (gtk_widget_destroy), - NULL); - gtk_widget_show (dialog); - g_error_free (error); - } -} - -static void -on_status_icon_popup_menu (GtkStatusIcon *status_icon, - guint button, - guint activate_time, - GvcStreamStatusIcon *icon) -{ - GtkWidget *menu; - GtkWidget *item; - - menu = gtk_menu_new (); - item = gtk_check_menu_item_new_with_mnemonic (_("_Mute")); - - gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), - mate_mixer_stream_control_get_mute (icon->priv->control)); - g_signal_connect (G_OBJECT (item), - "toggled", - G_CALLBACK (on_menu_mute_toggled), - icon); - - gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); - -#if GTK_CHECK_VERSION (3, 10, 0) - item = gtk_menu_item_new_with_mnemonic (_("_Sound Preferences")); -#else - item = gtk_image_menu_item_new_with_mnemonic (_("_Sound Preferences")); - - do { - GtkWidget *image; - - image = gtk_image_new_from_icon_name ("multimedia-volume-control", - GTK_ICON_SIZE_MENU); - - gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image); - } while (0); -#endif - g_signal_connect (G_OBJECT (item), - "activate", - G_CALLBACK (on_menu_activate_open_volume_control), - icon); - - gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); - - gtk_widget_show_all (menu); - gtk_menu_popup (GTK_MENU (menu), - NULL, - NULL, - gtk_status_icon_position_menu, - status_icon, - button, - activate_time); -} - -static gboolean -on_status_icon_scroll_event (GtkStatusIcon *status_icon, - GdkEventScroll *event, - GvcStreamStatusIcon *icon) -{ - return gvc_channel_bar_scroll (GVC_CHANNEL_BAR (icon->priv->bar), event->direction); -} - -static void -gvc_icon_release_grab (GvcStreamStatusIcon *icon, GdkEventButton *event) -{ -#if GTK_CHECK_VERSION (3, 0, 0) - gdk_device_ungrab (event->device, event->time); -#else - GdkDisplay *display; - - display = gtk_widget_get_display (GTK_WIDGET (icon->priv->dock)); - - gdk_display_keyboard_ungrab (display, event->time); - gdk_display_pointer_ungrab (display, event->time); -#endif - gtk_grab_remove (icon->priv->dock); - - /* Hide again */ - gtk_widget_hide (icon->priv->dock); -} - -static gboolean -on_dock_button_press (GtkWidget *widget, - GdkEventButton *event, - GvcStreamStatusIcon *icon) -{ - if (event->type == GDK_BUTTON_PRESS) { - gvc_icon_release_grab (icon, event); - return TRUE; - } - - return FALSE; -} - -static void -popdown_dock (GvcStreamStatusIcon *icon) -{ - GdkDisplay *display; - - display = gtk_widget_get_display (icon->priv->dock); - -#if GTK_CHECK_VERSION (3, 0, 0) - GdkDeviceManager *manager = gdk_display_get_device_manager (display); - - gdk_device_ungrab (gdk_device_manager_get_client_pointer (manager), - GDK_CURRENT_TIME); -#else - gdk_display_keyboard_ungrab (display, GDK_CURRENT_TIME); - gdk_display_pointer_ungrab (display, GDK_CURRENT_TIME); - gtk_grab_remove (icon->priv->dock); -#endif - /* Hide again */ - gtk_widget_hide (icon->priv->dock); -} - -/* This is called when the grab is broken for either the dock, or the scale */ -static void -gvc_icon_grab_notify (GvcStreamStatusIcon *icon, gboolean was_grabbed) -{ - if (was_grabbed != FALSE) - return; - - if (gtk_widget_has_grab (icon->priv->dock) == FALSE) - return; - - if (gtk_widget_is_ancestor (gtk_grab_get_current (), icon->priv->dock)) - return; - - popdown_dock (icon); -} - -static void -on_dock_grab_notify (GtkWidget *widget, - gboolean was_grabbed, - GvcStreamStatusIcon *icon) -{ - gvc_icon_grab_notify (icon, was_grabbed); -} - -static gboolean -on_dock_grab_broken_event (GtkWidget *widget, - gboolean was_grabbed, - GvcStreamStatusIcon *icon) -{ - gvc_icon_grab_notify (icon, FALSE); - return FALSE; -} - -static gboolean -on_dock_key_release (GtkWidget *widget, - GdkEventKey *event, - GvcStreamStatusIcon *icon) -{ - if (event->keyval == GDK_KEY_Escape) { - popdown_dock (icon); - return TRUE; - } - return TRUE; -} - -static gboolean -on_dock_scroll_event (GtkWidget *widget, - GdkEventScroll *event, - GvcStreamStatusIcon *icon) -{ - /* Forward event to the status icon */ - on_status_icon_scroll_event (NULL, event, icon); - return TRUE; -} - -static void -update_icon (GvcStreamStatusIcon *icon) -{ - guint volume = 0; - gdouble decibel = 0; - guint normal = 0; - gboolean muted = FALSE; - guint n = 0; - gchar *markup; - const gchar *description; - MateMixerStreamControlFlags flags; - - if (icon->priv->control == NULL) { - /* Do not bother creating a tooltip for an unusable icon as it - * has no practical use */ - gtk_status_icon_set_has_tooltip (GTK_STATUS_ICON (icon), FALSE); - return; - } else - gtk_status_icon_set_has_tooltip (GTK_STATUS_ICON (icon), TRUE); - - flags = mate_mixer_stream_control_get_flags (icon->priv->control); - - if (flags & MATE_MIXER_STREAM_CONTROL_MUTE_READABLE) - muted = mate_mixer_stream_control_get_mute (icon->priv->control); - - if (flags & MATE_MIXER_STREAM_CONTROL_VOLUME_READABLE) { - volume = mate_mixer_stream_control_get_volume (icon->priv->control); - normal = mate_mixer_stream_control_get_normal_volume (icon->priv->control); - - /* Select an icon, they are expected to be sorted, the lowest index being - * the mute icon and the rest being volume increments */ - if (volume <= 0 || muted) - n = 0; - else - n = CLAMP (3 * volume / normal + 1, 1, 3); - } - if (flags & MATE_MIXER_STREAM_CONTROL_HAS_DECIBEL) - decibel = mate_mixer_stream_control_get_decibel (icon->priv->control); - - /* Apparently status icon will reset icon even if it doesn't change */ - if (icon->priv->current_icon != n) { - gtk_status_icon_set_from_icon_name (GTK_STATUS_ICON (icon), - icon->priv->icon_names[n]); - icon->priv->current_icon = n; - } - - description = mate_mixer_stream_control_get_label (icon->priv->control); - - if (muted) { - markup = g_strdup_printf ("<b>%s: %s</b>\n<small>%s</small>", - icon->priv->display_name, - _("Muted"), - description); - } else if (flags & MATE_MIXER_STREAM_CONTROL_VOLUME_READABLE) { - gdouble display_volume = 100 * volume / normal; - - if (flags & MATE_MIXER_STREAM_CONTROL_HAS_DECIBEL) { - if (decibel > -MATE_MIXER_INFINITY) { - markup = g_strdup_printf ("<b>%s: %.0f%%</b>\n" - "<small>%0.2f dB\n%s</small>", - icon->priv->display_name, - display_volume, - decibel, - description); - } else { - markup = g_strdup_printf ("<b>%s: %.0f%%</b>\n" - "<small>-∞ dB\n%s</small>", - icon->priv->display_name, - display_volume, - description); - } - } else { - markup = g_strdup_printf ("<b>%s: %.0f%%</b>\n<small>%s</small>", - icon->priv->display_name, - display_volume, - description); - } - } else { - markup = g_strdup_printf ("<b>%s</b>\n<small>%s</small>", - icon->priv->display_name, - description); - } - - gtk_status_icon_set_tooltip_markup (GTK_STATUS_ICON (icon), markup); - - g_free (markup); -} - -void -gvc_stream_status_icon_set_icon_names (GvcStreamStatusIcon *icon, - const gchar **names) -{ - g_return_if_fail (GVC_IS_STREAM_STATUS_ICON (icon)); - g_return_if_fail (names != NULL && *names != NULL); - - if (G_UNLIKELY (g_strv_length ((gchar **) names) != 4)) { - g_warn_if_reached (); - return; - } - - g_strfreev (icon->priv->icon_names); - - icon->priv->icon_names = g_strdupv ((gchar **) names); - - /* Set the first icon as the initial one, the icon may be immediately - * updated or not depending on whether a stream is available */ - gtk_status_icon_set_from_icon_name (GTK_STATUS_ICON (icon), names[0]); - update_icon (icon); - - g_object_notify_by_pspec (G_OBJECT (icon), properties[PROP_ICON_NAMES]); -} - -static void -on_stream_control_volume_notify (MateMixerStreamControl *control, - GParamSpec *pspec, - GvcStreamStatusIcon *icon) -{ - update_icon (icon); -} - -static void -on_stream_control_mute_notify (MateMixerStreamControl *control, - GParamSpec *pspec, - GvcStreamStatusIcon *icon) -{ - update_icon (icon); -} - -void -gvc_stream_status_icon_set_display_name (GvcStreamStatusIcon *icon, - const gchar *name) -{ - g_return_if_fail (GVC_STREAM_STATUS_ICON (icon)); - - g_free (icon->priv->display_name); - - icon->priv->display_name = g_strdup (name); - update_icon (icon); - - g_object_notify_by_pspec (G_OBJECT (icon), properties[PROP_DISPLAY_NAME]); -} - -void -gvc_stream_status_icon_set_control (GvcStreamStatusIcon *icon, - MateMixerStreamControl *control) -{ - g_return_if_fail (GVC_STREAM_STATUS_ICON (icon)); - - if (icon->priv->control == control) - return; - - if (control != NULL) - g_object_ref (control); - - if (icon->priv->control != NULL) { - g_signal_handlers_disconnect_by_func (G_OBJECT (icon->priv->control), - G_CALLBACK (on_stream_control_volume_notify), - icon); - g_signal_handlers_disconnect_by_func (G_OBJECT (icon->priv->control), - G_CALLBACK (on_stream_control_mute_notify), - icon); - - g_object_unref (icon->priv->control); - } - - icon->priv->control = control; - - if (icon->priv->control != NULL) { - g_signal_connect (G_OBJECT (icon->priv->control), - "notify::volume", - G_CALLBACK (on_stream_control_volume_notify), - icon); - g_signal_connect (G_OBJECT (icon->priv->control), - "notify::mute", - G_CALLBACK (on_stream_control_mute_notify), - icon); - - // XXX when no stream set some default icon and "unset" dock - update_icon (icon); - } - - gvc_channel_bar_set_control (GVC_CHANNEL_BAR (icon->priv->bar), icon->priv->control); - - g_object_notify_by_pspec (G_OBJECT (icon), properties[PROP_CONTROL]); -} - -static void -gvc_stream_status_icon_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - GvcStreamStatusIcon *self = GVC_STREAM_STATUS_ICON (object); - - switch (prop_id) { - case PROP_CONTROL: - gvc_stream_status_icon_set_control (self, g_value_get_object (value)); - break; - case PROP_DISPLAY_NAME: - gvc_stream_status_icon_set_display_name (self, g_value_get_string (value)); - break; - case PROP_ICON_NAMES: - gvc_stream_status_icon_set_icon_names (self, g_value_get_boxed (value)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -gvc_stream_status_icon_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - GvcStreamStatusIcon *self = GVC_STREAM_STATUS_ICON (object); - - switch (prop_id) { - case PROP_CONTROL: - g_value_set_object (value, self->priv->control); - break; - case PROP_DISPLAY_NAME: - g_value_set_string (value, self->priv->display_name); - break; - case PROP_ICON_NAMES: - g_value_set_boxed (value, self->priv->icon_names); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -gvc_stream_status_icon_dispose (GObject *object) -{ - GvcStreamStatusIcon *icon = GVC_STREAM_STATUS_ICON (object); - - if (icon->priv->dock != NULL) { - gtk_widget_destroy (icon->priv->dock); - icon->priv->dock = NULL; - } - - g_clear_object (&icon->priv->control); - - G_OBJECT_CLASS (gvc_stream_status_icon_parent_class)->dispose (object); -} - -static void -gvc_stream_status_icon_class_init (GvcStreamStatusIconClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - object_class->finalize = gvc_stream_status_icon_finalize; - object_class->dispose = gvc_stream_status_icon_dispose; - object_class->set_property = gvc_stream_status_icon_set_property; - object_class->get_property = gvc_stream_status_icon_get_property; - - properties[PROP_CONTROL] = - g_param_spec_object ("control", - "Control", - "MateMixer stream control", - MATE_MIXER_TYPE_STREAM_CONTROL, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT | - G_PARAM_STATIC_STRINGS); - - properties[PROP_DISPLAY_NAME] = - g_param_spec_string ("display-name", - "Display name", - "Name to display for this stream", - NULL, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT | - G_PARAM_STATIC_STRINGS); - - properties[PROP_ICON_NAMES] = - g_param_spec_boxed ("icon-names", - "Icon names", - "Name of icon to display for this stream", - G_TYPE_STRV, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT | - G_PARAM_STATIC_STRINGS); - - g_object_class_install_properties (object_class, N_PROPERTIES, properties); - - g_type_class_add_private (klass, sizeof (GvcStreamStatusIconPrivate)); -} - -static void -on_status_icon_visible_notify (GvcStreamStatusIcon *icon) -{ - if (gtk_status_icon_get_visible (GTK_STATUS_ICON (icon)) == FALSE) - gtk_widget_hide (icon->priv->dock); -} - -static void -gvc_stream_status_icon_init (GvcStreamStatusIcon *icon) -{ - GtkWidget *frame; - GtkWidget *box; - - icon->priv = GVC_STREAM_STATUS_ICON_GET_PRIVATE (icon); - - g_signal_connect (G_OBJECT (icon), - "activate", - G_CALLBACK (on_status_icon_activate), - icon); - g_signal_connect (G_OBJECT (icon), - "button-press-event", - G_CALLBACK (on_status_icon_button_press), - icon); - g_signal_connect (G_OBJECT (icon), - "popup-menu", - G_CALLBACK (on_status_icon_popup_menu), - icon); - g_signal_connect (G_OBJECT (icon), - "scroll-event", - G_CALLBACK (on_status_icon_scroll_event), - icon); - g_signal_connect (G_OBJECT (icon), - "notify::visible", - G_CALLBACK (on_status_icon_visible_notify), - NULL); - - /* Create the dock window */ - icon->priv->dock = gtk_window_new (GTK_WINDOW_POPUP); - - gtk_window_set_decorated (GTK_WINDOW (icon->priv->dock), FALSE); - - g_signal_connect (G_OBJECT (icon->priv->dock), - "button-press-event", - G_CALLBACK (on_dock_button_press), - icon); - g_signal_connect (G_OBJECT (icon->priv->dock), - "key-release-event", - G_CALLBACK (on_dock_key_release), - icon); - g_signal_connect (G_OBJECT (icon->priv->dock), - "scroll-event", - G_CALLBACK (on_dock_scroll_event), - icon); - g_signal_connect (G_OBJECT (icon->priv->dock), - "grab-notify", - G_CALLBACK (on_dock_grab_notify), - icon); - g_signal_connect (G_OBJECT (icon->priv->dock), - "grab-broken-event", - G_CALLBACK (on_dock_grab_broken_event), - icon); - - frame = gtk_frame_new (NULL); - gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_OUT); - gtk_container_add (GTK_CONTAINER (icon->priv->dock), frame); - - icon->priv->bar = gvc_channel_bar_new (NULL); - - gvc_channel_bar_set_orientation (GVC_CHANNEL_BAR (icon->priv->bar), - GTK_ORIENTATION_VERTICAL); - -#if GTK_CHECK_VERSION (3, 0, 0) - box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6); -#else - box = gtk_vbox_new (FALSE, 6); -#endif - - gtk_container_set_border_width (GTK_CONTAINER (box), 2); - gtk_container_add (GTK_CONTAINER (frame), box); - - gtk_box_pack_start (GTK_BOX (box), icon->priv->bar, TRUE, FALSE, 0); -} - -static void -gvc_stream_status_icon_finalize (GObject *object) -{ - GvcStreamStatusIcon *icon; - - icon = GVC_STREAM_STATUS_ICON (object); - - g_strfreev (icon->priv->icon_names); - - G_OBJECT_CLASS (gvc_stream_status_icon_parent_class)->finalize (object); -} - -GvcStreamStatusIcon * -gvc_stream_status_icon_new (MateMixerStreamControl *control, - const gchar **icon_names) -{ - return g_object_new (GVC_TYPE_STREAM_STATUS_ICON, - "control", control, - "icon-names", icon_names, - NULL); -} diff --git a/mate-volume-control/src/gvc-stream-status-icon.h b/mate-volume-control/src/gvc-stream-status-icon.h deleted file mode 100644 index 7b51801..0000000 --- a/mate-volume-control/src/gvc-stream-status-icon.h +++ /dev/null @@ -1,68 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- - * - * Copyright (C) 2008 Red Hat, Inc. - * Copyright (C) 2014 Michal Ratajsky <[email protected]> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ - -#ifndef __GVC_STREAM_STATUS_ICON_H -#define __GVC_STREAM_STATUS_ICON_H - -#include <glib.h> -#include <glib-object.h> -#include <libmatemixer/matemixer.h> - -G_BEGIN_DECLS - -#define GVC_TYPE_STREAM_STATUS_ICON (gvc_stream_status_icon_get_type ()) -#define GVC_STREAM_STATUS_ICON(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GVC_TYPE_STREAM_STATUS_ICON, GvcStreamStatusIcon)) -#define GVC_STREAM_STATUS_ICON_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), GVC_TYPE_STREAM_STATUS_ICON, GvcStreamStatusIconClass)) -#define GVC_IS_STREAM_STATUS_ICON(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GVC_TYPE_STREAM_STATUS_ICON)) -#define GVC_IS_STREAM_STATUS_ICON_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GVC_TYPE_STREAM_STATUS_ICON)) -#define GVC_STREAM_STATUS_ICON_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GVC_TYPE_STREAM_STATUS_ICON, GvcStreamStatusIconClass)) - -typedef struct _GvcStreamStatusIcon GvcStreamStatusIcon; -typedef struct _GvcStreamStatusIconClass GvcStreamStatusIconClass; -typedef struct _GvcStreamStatusIconPrivate GvcStreamStatusIconPrivate; - -struct _GvcStreamStatusIcon -{ - GtkStatusIcon parent; - GvcStreamStatusIconPrivate *priv; -}; - -struct _GvcStreamStatusIconClass -{ - GtkStatusIconClass parent_class; -}; - -GType gvc_stream_status_icon_get_type (void) G_GNUC_CONST; - -GvcStreamStatusIcon * gvc_stream_status_icon_new (MateMixerStreamControl *control, - const gchar **icon_names); - -void gvc_stream_status_icon_set_icon_names (GvcStreamStatusIcon *icon, - const gchar **icon_names); -void gvc_stream_status_icon_set_display_name (GvcStreamStatusIcon *icon, - const gchar *display_name); - -void gvc_stream_status_icon_set_control (GvcStreamStatusIcon *icon, - MateMixerStreamControl *control); - -G_END_DECLS - -#endif /* __GVC_STREAM_STATUS_ICON_H */ diff --git a/mate-volume-control/src/gvc-utils.c b/mate-volume-control/src/gvc-utils.c deleted file mode 100644 index d45a217..0000000 --- a/mate-volume-control/src/gvc-utils.c +++ /dev/null @@ -1,335 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- - * - * Copyright (C) 2014 Michal Ratajsky <[email protected]> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ - -#include "config.h" - -#include <glib.h> -#include <glib/gi18n.h> -#include <gtk/gtk.h> - -#include <libmatemixer/matemixer.h> - -#include "gvc-utils.h" - -/* libcanberra requires a PulseAudio channel name to be given to its - * CA_PROP_CANBERRA_FORCE_CHANNEL property. - * - * The strings here are copied from PulseAudio source code to avoid depending - * on libpulse. */ -static const gchar *pulse_position[MATE_MIXER_CHANNEL_MAX] = { - [MATE_MIXER_CHANNEL_MONO] = "mono", - [MATE_MIXER_CHANNEL_FRONT_LEFT] = "front-left", - [MATE_MIXER_CHANNEL_FRONT_RIGHT] = "front-right", - [MATE_MIXER_CHANNEL_FRONT_CENTER] = "front-center", - [MATE_MIXER_CHANNEL_LFE] = "lfe", - [MATE_MIXER_CHANNEL_BACK_LEFT] = "rear-left", - [MATE_MIXER_CHANNEL_BACK_RIGHT] = "rear-right", - [MATE_MIXER_CHANNEL_BACK_CENTER] = "rear-center", - [MATE_MIXER_CHANNEL_FRONT_LEFT_CENTER] = "front-left-of-center", - [MATE_MIXER_CHANNEL_FRONT_RIGHT_CENTER] = "front-right-of-center", - [MATE_MIXER_CHANNEL_SIDE_LEFT] = "side-left", - [MATE_MIXER_CHANNEL_SIDE_RIGHT] = "side-right", - [MATE_MIXER_CHANNEL_TOP_FRONT_LEFT] = "top-front-left", - [MATE_MIXER_CHANNEL_TOP_FRONT_RIGHT] = "top-front-right", - [MATE_MIXER_CHANNEL_TOP_FRONT_CENTER] = "top-front-center", - [MATE_MIXER_CHANNEL_TOP_CENTER] = "top-center", - [MATE_MIXER_CHANNEL_TOP_BACK_LEFT] = "top-rear-left", - [MATE_MIXER_CHANNEL_TOP_BACK_RIGHT] = "top-rear-right", - [MATE_MIXER_CHANNEL_TOP_BACK_CENTER] = "top-rear-center" -}; - -static const gchar *pretty_position[MATE_MIXER_CHANNEL_MAX] = { - [MATE_MIXER_CHANNEL_UNKNOWN] = N_("Unknown"), - /* Speaker channel names */ - [MATE_MIXER_CHANNEL_MONO] = N_("Mono"), - [MATE_MIXER_CHANNEL_FRONT_LEFT] = N_("Front Left"), - [MATE_MIXER_CHANNEL_FRONT_RIGHT] = N_("Front Right"), - [MATE_MIXER_CHANNEL_FRONT_CENTER] = N_("Front Center"), - [MATE_MIXER_CHANNEL_LFE] = N_("LFE"), - [MATE_MIXER_CHANNEL_BACK_LEFT] = N_("Rear Left"), - [MATE_MIXER_CHANNEL_BACK_RIGHT] = N_("Rear Right"), - [MATE_MIXER_CHANNEL_BACK_CENTER] = N_("Rear Center"), - [MATE_MIXER_CHANNEL_FRONT_LEFT_CENTER] = N_("Front Left of Center"), - [MATE_MIXER_CHANNEL_FRONT_RIGHT_CENTER] = N_("Front Right of Center"), - [MATE_MIXER_CHANNEL_SIDE_LEFT] = N_("Side Left"), - [MATE_MIXER_CHANNEL_SIDE_RIGHT] = N_("Side Right"), - [MATE_MIXER_CHANNEL_TOP_FRONT_LEFT] = N_("Top Front Left"), - [MATE_MIXER_CHANNEL_TOP_FRONT_RIGHT] = N_("Top Front Right"), - [MATE_MIXER_CHANNEL_TOP_FRONT_CENTER] = N_("Top Front Center"), - [MATE_MIXER_CHANNEL_TOP_CENTER] = N_("Top Center"), - [MATE_MIXER_CHANNEL_TOP_BACK_LEFT] = N_("Top Rear Left"), - [MATE_MIXER_CHANNEL_TOP_BACK_RIGHT] = N_("Top Rear Right"), - [MATE_MIXER_CHANNEL_TOP_BACK_CENTER] = N_("Top Rear Center") -}; - -const gchar * -gvc_channel_position_to_pulse_string (MateMixerChannelPosition position) -{ - g_return_val_if_fail (position >= 0 && position < MATE_MIXER_CHANNEL_MAX, NULL); - - return pulse_position[position]; -} - -const gchar * -gvc_channel_position_to_pretty_string (MateMixerChannelPosition position) -{ - g_return_val_if_fail (position >= 0 && position < MATE_MIXER_CHANNEL_MAX, NULL); - - return pretty_position[position]; -} - -const gchar * -gvc_channel_map_to_pretty_string (MateMixerStreamControl *control) -{ - g_return_val_if_fail (MATE_MIXER_IS_STREAM_CONTROL (control), NULL); - -#define HAS_POSITION(p) (mate_mixer_stream_control_has_channel_position (control, (p))) - - /* Modeled after PulseAudio 5.0, probably could be extended with other combinations */ - switch (mate_mixer_stream_control_get_num_channels (control)) { - case 1: - if (HAS_POSITION (MATE_MIXER_CHANNEL_MONO)) - return _("Mono"); - break; - case 2: - if (HAS_POSITION (MATE_MIXER_CHANNEL_FRONT_LEFT) && - HAS_POSITION (MATE_MIXER_CHANNEL_FRONT_RIGHT)) - return _("Stereo"); - break; - case 4: - if (HAS_POSITION (MATE_MIXER_CHANNEL_FRONT_LEFT) && - HAS_POSITION (MATE_MIXER_CHANNEL_FRONT_RIGHT) && - HAS_POSITION (MATE_MIXER_CHANNEL_BACK_LEFT) && - HAS_POSITION (MATE_MIXER_CHANNEL_BACK_RIGHT)) - return _("Surround 4.0"); - break; - case 5: - if (HAS_POSITION (MATE_MIXER_CHANNEL_FRONT_LEFT) && - HAS_POSITION (MATE_MIXER_CHANNEL_FRONT_RIGHT) && - HAS_POSITION (MATE_MIXER_CHANNEL_BACK_LEFT) && - HAS_POSITION (MATE_MIXER_CHANNEL_BACK_RIGHT)) - if (HAS_POSITION (MATE_MIXER_CHANNEL_LFE)) - return _("Surround 4.1"); - if (HAS_POSITION (MATE_MIXER_CHANNEL_FRONT_CENTER)) - return _("Surround 5.0"); - break; - case 6: - if (HAS_POSITION (MATE_MIXER_CHANNEL_FRONT_LEFT) && - HAS_POSITION (MATE_MIXER_CHANNEL_FRONT_RIGHT) && - HAS_POSITION (MATE_MIXER_CHANNEL_FRONT_CENTER) && - HAS_POSITION (MATE_MIXER_CHANNEL_BACK_LEFT) && - HAS_POSITION (MATE_MIXER_CHANNEL_BACK_RIGHT) && - HAS_POSITION (MATE_MIXER_CHANNEL_LFE)) - return _("Surround 5.1"); - break; - case 8: - if (HAS_POSITION (MATE_MIXER_CHANNEL_FRONT_LEFT) && - HAS_POSITION (MATE_MIXER_CHANNEL_FRONT_RIGHT) && - HAS_POSITION (MATE_MIXER_CHANNEL_FRONT_CENTER) && - HAS_POSITION (MATE_MIXER_CHANNEL_BACK_LEFT) && - HAS_POSITION (MATE_MIXER_CHANNEL_BACK_RIGHT) && - HAS_POSITION (MATE_MIXER_CHANNEL_SIDE_LEFT) && - HAS_POSITION (MATE_MIXER_CHANNEL_SIDE_RIGHT) && - HAS_POSITION (MATE_MIXER_CHANNEL_LFE)) - return _("Surround 7.1"); - break; - } - -#undef HAS_POSITION - - return NULL; -} - -#if GTK_CHECK_VERSION (3, 0, 0) -/* Taken from gtkstyle.c */ -static void rgb_to_hls (gdouble *r, gdouble *g, gdouble *b); -static void hls_to_rgb (gdouble *h, gdouble *l, gdouble *s); - -void -gvc_color_shade (GdkRGBA *a, GdkRGBA *b, gdouble k) -{ - gdouble red; - gdouble green; - gdouble blue; - - red = (gdouble) a->red / 65535.0; - green = (gdouble) a->green / 65535.0; - blue = (gdouble) a->blue / 65535.0; - - rgb_to_hls (&red, &green, &blue); - - green *= k; - if (green > 1.0) - green = 1.0; - else if (green < 0.0) - green = 0.0; - - blue *= k; - if (blue > 1.0) - blue = 1.0; - else if (blue < 0.0) - blue = 0.0; - - hls_to_rgb (&red, &green, &blue); - - b->red = red * 65535.0; - b->green = green * 65535.0; - b->blue = blue * 65535.0; -} - -static void -rgb_to_hls (gdouble *r, gdouble *g, gdouble *b) -{ - gdouble min; - gdouble max; - gdouble red; - gdouble green; - gdouble blue; - gdouble h, l, s; - gdouble delta; - - red = *r; - green = *g; - blue = *b; - - if (red > green) { - if (red > blue) - max = red; - else - max = blue; - - if (green < blue) - min = green; - else - min = blue; - } else { - if (green > blue) - max = green; - else - max = blue; - - if (red < blue) - min = red; - else - min = blue; - } - - l = (max + min) / 2; - s = 0; - h = 0; - - if (max != min) { - if (l <= 0.5) - s = (max - min) / (max + min); - else - s = (max - min) / (2 - max - min); - - delta = max - min; - if (red == max) - h = (green - blue) / delta; - else if (green == max) - h = 2 + (blue - red) / delta; - else if (blue == max) - h = 4 + (red - green) / delta; - - h *= 60; - if (h < 0.0) - h += 360; - } - - *r = h; - *g = l; - *b = s; -} - -static void -hls_to_rgb (gdouble *h, gdouble *l, gdouble *s) -{ - gdouble hue; - gdouble lightness; - gdouble saturation; - gdouble m1, m2; - gdouble r, g, b; - - lightness = *l; - saturation = *s; - - if (lightness <= 0.5) - m2 = lightness * (1 + saturation); - else - m2 = lightness + saturation - lightness * saturation; - m1 = 2 * lightness - m2; - - if (saturation == 0) { - *h = lightness; - *l = lightness; - *s = lightness; - } else { - hue = *h + 120; - while (hue > 360) - hue -= 360; - while (hue < 0) - hue += 360; - - if (hue < 60) - r = m1 + (m2 - m1) * hue / 60; - else if (hue < 180) - r = m2; - else if (hue < 240) - r = m1 + (m2 - m1) * (240 - hue) / 60; - else - r = m1; - - hue = *h; - while (hue > 360) - hue -= 360; - while (hue < 0) - hue += 360; - - if (hue < 60) - g = m1 + (m2 - m1) * hue / 60; - else if (hue < 180) - g = m2; - else if (hue < 240) - g = m1 + (m2 - m1) * (240 - hue) / 60; - else - g = m1; - - hue = *h - 120; - while (hue > 360) - hue -= 360; - while (hue < 0) - hue += 360; - - if (hue < 60) - b = m1 + (m2 - m1) * hue / 60; - else if (hue < 180) - b = m2; - else if (hue < 240) - b = m1 + (m2 - m1) * (240 - hue) / 60; - else - b = m1; - - *h = r; - *l = g; - *s = b; - } -} -#endif diff --git a/mate-volume-control/src/gvc-utils.h b/mate-volume-control/src/gvc-utils.h deleted file mode 100644 index 4eca7a7..0000000 --- a/mate-volume-control/src/gvc-utils.h +++ /dev/null @@ -1,42 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- - * - * Copyright (C) 2014 Michal Ratajsky <[email protected]> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ - -#ifndef __GVC_HELPERS_H -#define __GVC_HELPERS_H - -#include <glib.h> - -#include <libmatemixer/matemixer.h> - -G_BEGIN_DECLS - -const gchar *gvc_channel_position_to_pulse_string (MateMixerChannelPosition position); -const gchar *gvc_channel_position_to_pretty_string (MateMixerChannelPosition position); -const gchar *gvc_channel_map_to_pretty_string (MateMixerStreamControl *control); - -#if GTK_CHECK_VERSION (3, 0, 0) -void gvc_color_shade (GdkRGBA *a, - GdkRGBA *b, - gdouble k); -#endif - -G_END_DECLS - -#endif /* __GVC_HELPERS_H */ |