diff options
Diffstat (limited to 'mate-volume-control')
-rw-r--r-- | mate-volume-control/src/Makefile.am | 4 | ||||
-rw-r--r-- | mate-volume-control/src/applet-main.c | 10 | ||||
-rw-r--r-- | mate-volume-control/src/dialog-main.c | 106 | ||||
-rw-r--r-- | mate-volume-control/src/gvc-applet.c | 289 | ||||
-rw-r--r-- | mate-volume-control/src/gvc-balance-bar.c | 93 | ||||
-rw-r--r-- | mate-volume-control/src/gvc-balance-bar.h | 2 | ||||
-rw-r--r-- | mate-volume-control/src/gvc-channel-bar.c | 210 | ||||
-rw-r--r-- | mate-volume-control/src/gvc-channel-bar.h | 8 | ||||
-rw-r--r-- | mate-volume-control/src/gvc-combo-box.c | 33 | ||||
-rw-r--r-- | mate-volume-control/src/gvc-combo-box.h | 6 | ||||
-rw-r--r-- | mate-volume-control/src/gvc-mixer-dialog.c | 1448 | ||||
-rw-r--r-- | mate-volume-control/src/gvc-mixer-dialog.h | 2 | ||||
-rw-r--r-- | mate-volume-control/src/gvc-speaker-test.c | 9 | ||||
-rw-r--r-- | mate-volume-control/src/gvc-stream-status-icon.c | 118 | ||||
-rw-r--r-- | mate-volume-control/src/gvc-stream-status-icon.h | 17 | ||||
-rw-r--r-- | mate-volume-control/src/mvc-helpers.c | 8 | ||||
-rw-r--r-- | mate-volume-control/src/mvc-helpers.h | 2 |
17 files changed, 1233 insertions, 1132 deletions
diff --git a/mate-volume-control/src/Makefile.am b/mate-volume-control/src/Makefile.am index 3ca81f5..50e3c15 100644 --- a/mate-volume-control/src/Makefile.am +++ b/mate-volume-control/src/Makefile.am @@ -51,14 +51,14 @@ mate_volume_control_LDADD = \ mate_volume_control_SOURCES = \ gvc-balance-bar.h \ gvc-balance-bar.c \ - gvc-mixer-dialog.h \ - gvc-mixer-dialog.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) diff --git a/mate-volume-control/src/applet-main.c b/mate-volume-control/src/applet-main.c index 1c260fc..48c41a1 100644 --- a/mate-volume-control/src/applet-main.c +++ b/mate-volume-control/src/applet-main.c @@ -50,7 +50,7 @@ main (int argc, char **argv) textdomain (GETTEXT_PACKAGE); gtk_init_with_args (&argc, &argv, - (char *) _(" — MATE Volume Control Applet"), + _(" — MATE Volume Control Applet"), entries, GETTEXT_PACKAGE, &error); @@ -58,18 +58,18 @@ main (int argc, char **argv) g_warning ("%s", error->message); return 1; } - if (show_version) { + if (show_version == TRUE) { g_print ("%s %s\n", argv[0], VERSION); return 0; } app = unique_app_new (GVC_APPLET_DBUS_NAME, NULL); - if (unique_app_is_running (app)) { + if (unique_app_is_running (app) == TRUE) { g_warning ("Applet is already running, exiting"); return 0; } - if (!mate_mixer_init ()) { + if (mate_mixer_init () == FALSE) { g_warning ("libmatemixer initialization failed, exiting"); return 1; } @@ -85,7 +85,5 @@ main (int argc, char **argv) g_object_unref (applet); g_object_unref (app); - mate_mixer_deinit (); - return 0; } diff --git a/mate-volume-control/src/dialog-main.c b/mate-volume-control/src/dialog-main.c index 9b44d38..c111c26 100644 --- a/mate-volume-control/src/dialog-main.c +++ b/mate-volume-control/src/dialog-main.c @@ -86,14 +86,14 @@ remove_warning_dialog (void) } static void -control_ready (MateMixerControl *control, UniqueApp *app) +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 (control)); + app_dialog = GTK_WIDGET (gvc_mixer_dialog_new (context)); g_signal_connect (G_OBJECT (app_dialog), "response", @@ -115,37 +115,37 @@ control_ready (MateMixerControl *control, UniqueApp *app) } static void -on_control_state_notify (MateMixerControl *control, +on_context_state_notify (MateMixerContext *context, GParamSpec *pspec, UniqueApp *app) { - MateMixerState state = mate_mixer_control_get_state (control); + MateMixerState state = mate_mixer_context_get_state (context); if (state == MATE_MIXER_STATE_READY) { remove_warning_dialog (); - control_ready (control, app); + 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); + 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); } } @@ -160,12 +160,12 @@ dialog_popup_timeout (gpointer data) g_signal_connect (G_OBJECT (warning_dialog), "response", - G_CALLBACK (on_dialog_response), - GINT_TO_POINTER (TRUE)); + 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)); + G_CALLBACK (on_dialog_close), + GINT_TO_POINTER (TRUE)); gtk_widget_show (warning_dialog); @@ -177,10 +177,10 @@ main (int argc, char **argv) { GError *error = NULL; gchar *backend = NULL; - MateMixerControl *control; + MateMixerContext *context; UniqueApp *app; GOptionEntry entries[] = { - { "backend", 'b', 0, G_OPTION_ARG_STRING, &backend, N_("Sound system backend"), "pulse|null" }, + { "backend", 'b', 0, G_OPTION_ARG_STRING, &backend, N_("Sound system backend"), "pulse|alsa|oss|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 } @@ -191,7 +191,7 @@ main (int argc, char **argv) textdomain (GETTEXT_PACKAGE); gtk_init_with_args (&argc, &argv, - (char *) _(" — MATE Volume Control"), + _(" — MATE Volume Control"), entries, GETTEXT_PACKAGE, &error); @@ -199,58 +199,60 @@ main (int argc, char **argv) g_warning ("%s", error->message); return 1; } - if (show_version) { + if (show_version == TRUE) { g_print ("%s %s\n", argv[0], VERSION); return 0; } app = unique_app_new (GVC_DIALOG_DBUS_NAME, NULL); - if (unique_app_is_running (app)) { - unique_app_send_message (app, UNIQUE_ACTIVATE, NULL); - return 0; + if (unique_app_is_running (app) == TRUE) { + unique_app_send_message (app, UNIQUE_ACTIVATE, NULL); + return 0; } - if (!mate_mixer_init ()) { + if (mate_mixer_init () == FALSE) { g_warning ("libmatemixer initialization failed, exiting"); return 1; } - control = mate_mixer_control_new (); + context = mate_mixer_context_new (); if (backend != NULL) { if (strcmp (backend, "pulse") == 0) - mate_mixer_control_set_backend_type (control, MATE_MIXER_BACKEND_PULSEAUDIO); + 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_control_set_backend_type (control, MATE_MIXER_BACKEND_NULL); + mate_mixer_context_set_backend_type (context, MATE_MIXER_BACKEND_NULL); else { g_warning ("Invalid backend: %s", backend); - g_object_unref (control); + g_object_unref (context); g_object_unref (app); g_free (backend); - - mate_mixer_deinit (); return 1; } g_free (backend); } - mate_mixer_control_set_app_name (control, _("Volume Control")); - mate_mixer_control_set_app_id (control, GVC_DIALOG_DBUS_NAME); - mate_mixer_control_set_app_version (control, VERSION); - mate_mixer_control_set_app_icon (control, "multimedia-volume-control"); + 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 (control), + g_signal_connect (G_OBJECT (context), "notify::state", - G_CALLBACK (on_control_state_notify), + G_CALLBACK (on_context_state_notify), app); - mate_mixer_control_open (control); + mate_mixer_context_open (context); - if (mate_mixer_control_get_state (control) == MATE_MIXER_STATE_CONNECTING) { - popup_id = g_timeout_add_seconds (DIALOG_POPUP_TIMEOUT, - dialog_popup_timeout, - NULL); + 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 (), @@ -260,10 +262,8 @@ main (int argc, char **argv) gtk_main (); - g_object_unref (control); + g_object_unref (context); g_object_unref (app); - mate_mixer_deinit (); - return 0; } diff --git a/mate-volume-control/src/gvc-applet.c b/mate-volume-control/src/gvc-applet.c index b2f40a1..fd5affc 100644 --- a/mate-volume-control/src/gvc-applet.c +++ b/mate-volume-control/src/gvc-applet.c @@ -55,7 +55,8 @@ struct _GvcAppletPrivate GvcStreamStatusIcon *icon_input; GvcStreamStatusIcon *icon_output; gboolean running; - MateMixerControl *control; + MateMixerContext *context; + MateMixerStream *input; }; static void gvc_applet_class_init (GvcAppletClass *klass); @@ -66,48 +67,41 @@ G_DEFINE_TYPE (GvcApplet, gvc_applet, G_TYPE_OBJECT) static void update_icon_input (GvcApplet *applet) { - MateMixerStream *stream; - gboolean show = FALSE; + 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 */ - stream = mate_mixer_control_get_default_input_stream (applet->priv->control); - if (stream != NULL) { + if (applet->priv->input != NULL) { const gchar *app_id; const GList *inputs = - mate_mixer_control_list_streams (applet->priv->control); + mate_mixer_stream_list_controls (applet->priv->input); + + control = mate_mixer_stream_get_default_control (applet->priv->input); while (inputs != NULL) { - MateMixerStream *input = MATE_MIXER_STREAM (inputs->data); - MateMixerStreamFlags flags = mate_mixer_stream_get_flags (input); - - if (flags & MATE_MIXER_STREAM_INPUT && flags & MATE_MIXER_STREAM_CLIENT) { - MateMixerClientStream *client = - MATE_MIXER_CLIENT_STREAM (input); - - MateMixerClientStreamRole client_role = - mate_mixer_client_stream_get_role (client); - MateMixerClientStreamFlags client_flags = - mate_mixer_client_stream_get_flags (client); - - if (!(client_flags & MATE_MIXER_CLIENT_STREAM_APPLICATION) || - client_role == MATE_MIXER_CLIENT_STREAM_ROLE_EVENT || - client_role == MATE_MIXER_CLIENT_STREAM_ROLE_TEST || - client_role == MATE_MIXER_CLIENT_STREAM_ROLE_ABSTRACT || - client_role == MATE_MIXER_CLIENT_STREAM_ROLE_FILTER) { - /* Skip roles we don't care about and non-application - * client streams */ - inputs = inputs->next; - continue; - } + MateMixerStreamControl *input = + MATE_MIXER_STREAM_CONTROL (inputs->data); + MateMixerStreamControlRole role = + mate_mixer_stream_control_get_role (input); - app_id = mate_mixer_client_stream_get_app_id (client); + 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 %s (%s)", - mate_mixer_stream_get_name (input), - mate_mixer_stream_get_description (input)); + 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 output control, use the application + * control for the icon */ + control = input; + } show = TRUE; break; } @@ -116,6 +110,10 @@ update_icon_input (GvcApplet *applet) 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; } @@ -123,19 +121,13 @@ update_icon_input (GvcApplet *applet) inputs = inputs->next; } - g_debug ("Current default input stream is %s (%s)", - mate_mixer_stream_get_name (stream), - mate_mixer_stream_get_description (stream)); - - if (show) + if (show == TRUE) g_debug ("Input icon enabled"); else g_debug ("There is no recording application, input icon disabled"); - } else { - g_debug ("There is no default input stream, input icon disabled"); } - gvc_stream_status_icon_set_stream (applet->priv->icon_input, stream); + gvc_stream_status_icon_set_control (applet->priv->icon_input, control); gtk_status_icon_set_visible (GTK_STATUS_ICON (applet->priv->icon_input), show); } @@ -143,35 +135,94 @@ update_icon_input (GvcApplet *applet) static void update_icon_output (GvcApplet *applet) { - MateMixerStream *stream; - - stream = mate_mixer_control_get_default_output_stream (applet->priv->control); + MateMixerStream *stream; + MateMixerStreamControl *control = NULL; - gvc_stream_status_icon_set_stream (applet->priv->icon_output, stream); + stream = mate_mixer_context_get_default_output_stream (applet->priv->context); + if (stream != NULL) + control = mate_mixer_stream_get_default_control (stream); - if (stream != NULL) { - g_debug ("Current default output stream is %s (%s)", - mate_mixer_stream_get_name (stream), - mate_mixer_stream_get_description (stream)); + gvc_stream_status_icon_set_control (applet->priv->icon_output, control); + if (control != NULL) gtk_status_icon_set_visible (GTK_STATUS_ICON (applet->priv->icon_output), TRUE); - - g_debug ("Output icon enabled"); - } else { + else 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; - g_debug ("There is no default output stream, output icon disabled"); + 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_control_state_notify (MateMixerControl *control, +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 = mate_mixer_context_get_default_input_stream (applet->priv->context); + 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_control_get_state (control); + MateMixerState state = mate_mixer_context_get_state (context); switch (state) { case MATE_MIXER_STATE_FAILED: @@ -180,6 +231,8 @@ on_control_state_notify (MateMixerControl *control, case MATE_MIXER_STATE_READY: case MATE_MIXER_STATE_CONNECTING: + update_default_input_stream (applet); + /* Each status change may affect the visibility of the icons */ update_icon_output (applet); update_icon_input (applet); @@ -190,93 +243,41 @@ on_control_state_notify (MateMixerControl *control, } static void -on_control_default_input_notify (MateMixerControl *control, - GParamSpec *pspec, - GvcApplet *applet) +on_context_default_input_stream_notify (MateMixerContext *context, + GParamSpec *pspec, + GvcApplet *applet) { - update_icon_input (applet); -} - -static void -on_control_default_output_notify (MateMixerControl *control, - GParamSpec *pspec, - GvcApplet *applet) -{ - update_icon_output (applet); -} - -static void -on_control_stream_added (MateMixerControl *control, - const gchar *name, - GvcApplet *applet) -{ - MateMixerStream *stream; - MateMixerStreamFlags flags; - - stream = mate_mixer_control_get_stream (control, name); - if (G_UNLIKELY (stream == NULL)) + if (update_default_input_stream (applet) == FALSE) return; - flags = mate_mixer_stream_get_flags (stream); - - /* Newly added input application stream may cause the input status - * icon to change visibility */ - if (flags & MATE_MIXER_STREAM_CLIENT && flags & MATE_MIXER_STREAM_INPUT) { - MateMixerClientStreamFlags client_flags = - mate_mixer_client_stream_get_flags (MATE_MIXER_CLIENT_STREAM (stream)); - - if (client_flags & MATE_MIXER_CLIENT_STREAM_APPLICATION) { - g_debug ("Added input application stream %s (%s)", - mate_mixer_stream_get_name (stream), - mate_mixer_stream_get_description (stream)); - - update_icon_input (applet); - } - } else - g_debug ("Ignoring new stream %s (%s)", - mate_mixer_stream_get_name (stream), - mate_mixer_stream_get_description (stream)); + update_icon_input (applet); } static void -on_control_stream_removed (MateMixerControl *control, - const gchar *name, - GvcApplet *applet) +on_context_default_output_stream_notify (MateMixerContext *control, + GParamSpec *pspec, + GvcApplet *applet) { - g_debug ("Removed stream %s", name); - - /* The removed stream could be an application input, which may cause - * the input status icon to disappear */ - update_icon_input (applet); + update_icon_output (applet); } void gvc_applet_start (GvcApplet *applet) { - MateMixerState state; - g_return_if_fail (GVC_IS_APPLET (applet)); - if (G_UNLIKELY (applet->priv->running == TRUE)) + if G_UNLIKELY (applet->priv->running == TRUE) return; - state = mate_mixer_control_get_state (applet->priv->control); - - if (G_UNLIKELY (state != MATE_MIXER_STATE_IDLE)) { - g_warn_if_reached (); - } else { - if (mate_mixer_control_open (applet->priv->control) == 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"); - } - - gtk_status_icon_set_visible (GTK_STATUS_ICON (applet->priv->icon_output), - FALSE); - gtk_status_icon_set_visible (GTK_STATUS_ICON (applet->priv->icon_input), - FALSE); + 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"); } + gtk_status_icon_set_visible (GTK_STATUS_ICON (applet->priv->icon_output), FALSE); + gtk_status_icon_set_visible (GTK_STATUS_ICON (applet->priv->icon_input), FALSE); + g_debug ("Applet has been started"); applet->priv->running = TRUE; @@ -287,7 +288,13 @@ gvc_applet_dispose (GObject *object) { GvcApplet *applet = GVC_APPLET (object); - g_clear_object (&applet->priv->control); + 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); @@ -320,34 +327,26 @@ gvc_applet_init (GvcApplet *applet) gtk_status_icon_set_title (GTK_STATUS_ICON (applet->priv->icon_output), _("Sound Output Volume")); - applet->priv->control = mate_mixer_control_new (); + applet->priv->context = mate_mixer_context_new (); - mate_mixer_control_set_app_name (applet->priv->control, + mate_mixer_context_set_app_name (applet->priv->context, _("MATE Volume Control Applet")); - mate_mixer_control_set_app_id (applet->priv->control, GVC_APPLET_DBUS_NAME); - mate_mixer_control_set_app_version (applet->priv->control, VERSION); - mate_mixer_control_set_app_icon (applet->priv->control, "multimedia-volume-control"); + 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->control), + g_signal_connect (G_OBJECT (applet->priv->context), "notify::state", - G_CALLBACK (on_control_state_notify), - applet); - g_signal_connect (G_OBJECT (applet->priv->control), - "notify::default-input", - G_CALLBACK (on_control_default_input_notify), - applet); - g_signal_connect (G_OBJECT (applet->priv->control), - "notify::default-output", - G_CALLBACK (on_control_default_output_notify), + G_CALLBACK (on_context_state_notify), applet); - g_signal_connect (G_OBJECT (applet->priv->control), - "stream-added", - G_CALLBACK (on_control_stream_added), + 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->control), - "stream-removed", - G_CALLBACK (on_control_stream_removed), + g_signal_connect (G_OBJECT (applet->priv->context), + "notify::default-output-stream", + G_CALLBACK (on_context_default_output_stream_notify), applet); } diff --git a/mate-volume-control/src/gvc-balance-bar.c b/mate-volume-control/src/gvc-balance-bar.c index f31d136..7431773 100644 --- a/mate-volume-control/src/gvc-balance-bar.c +++ b/mate-volume-control/src/gvc-balance-bar.c @@ -49,14 +49,14 @@ struct _GvcBalanceBarPrivate GtkAdjustment *adjustment; GtkSizeGroup *size_group; gboolean symmetric; - MateMixerStream *stream; + MateMixerStreamControl *control; gint lfe_channel; }; enum { PROP_0, - PROP_STREAM, + PROP_CONTROL, PROP_BALANCE_TYPE, N_PROPERTIES }; @@ -217,16 +217,16 @@ update_balance_value (GvcBalanceBar *bar) switch (bar->priv->btype) { case BALANCE_TYPE_RL: - value = mate_mixer_stream_get_balance (bar->priv->stream); + 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_get_fade (bar->priv->stream); + 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_get_channel_volume (bar->priv->stream, - bar->priv->lfe_channel); + value = mate_mixer_stream_control_get_channel_volume (bar->priv->control, + bar->priv->lfe_channel); g_debug ("Subwoofer volume changed to %.0f", value); break; @@ -244,14 +244,14 @@ on_balance_value_changed (MateMixerStream *stream, } static gint -find_stream_lfe_channel (MateMixerStream *stream) +find_stream_lfe_channel (MateMixerStreamControl *control) { guint i; - for (i = 0; i < mate_mixer_stream_get_num_channels (stream); i++) { + for (i = 0; i < mate_mixer_stream_control_get_num_channels (control); i++) { MateMixerChannelPosition position; - position = mate_mixer_stream_get_channel_position (stream, i); + position = mate_mixer_stream_control_get_channel_position (control, i); if (position == MATE_MIXER_CHANNEL_LFE) return i; } @@ -260,28 +260,26 @@ find_stream_lfe_channel (MateMixerStream *stream) } static void -gvc_balance_bar_set_stream (GvcBalanceBar *bar, MateMixerStream *stream) +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 (stream)); + g_return_if_fail (MATE_MIXER_IS_STREAM_CONTROL (control)); - if (bar->priv->stream != NULL) { - g_signal_handlers_disconnect_by_func (G_OBJECT (bar->priv->stream), + 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->stream); + g_object_unref (bar->priv->control); } - bar->priv->stream = g_object_ref (stream); + bar->priv->control = g_object_ref (control); if (bar->priv->btype == BALANCE_TYPE_LFE) { - gdouble minimum = 0.0; - gdouble maximum = 0.0; + gdouble minimum; + gdouble maximum; - if (mate_mixer_stream_get_flags (stream) & MATE_MIXER_STREAM_HAS_VOLUME) { - minimum = mate_mixer_stream_get_min_volume (stream); - maximum = mate_mixer_stream_get_normal_volume (stream); - } + 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. @@ -296,7 +294,7 @@ gvc_balance_bar_set_stream (GvcBalanceBar *bar, MateMixerStream *stream) (maximum - minimum) / 10.0, 0.0); - bar->priv->lfe_channel = find_stream_lfe_channel (stream); + 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); @@ -307,19 +305,19 @@ gvc_balance_bar_set_stream (GvcBalanceBar *bar, MateMixerStream *stream) switch (bar->priv->btype) { case BALANCE_TYPE_RL: - g_signal_connect (G_OBJECT (stream), + 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 (stream), + 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 (stream), + g_signal_connect (G_OBJECT (bar->priv->control), "notify::volume", G_CALLBACK (on_balance_value_changed), bar); @@ -329,7 +327,7 @@ gvc_balance_bar_set_stream (GvcBalanceBar *bar, MateMixerStream *stream) update_balance_value (bar); update_scale_marks (bar); - g_object_notify_by_pspec (G_OBJECT (bar), properties[PROP_STREAM]); + g_object_notify_by_pspec (G_OBJECT (bar), properties[PROP_CONTROL]); } static void @@ -393,8 +391,8 @@ gvc_balance_bar_set_property (GObject *object, GvcBalanceBar *self = GVC_BALANCE_BAR (object); switch (prop_id) { - case PROP_STREAM: - gvc_balance_bar_set_stream (self, g_value_get_object (value)); + 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)); @@ -414,8 +412,8 @@ gvc_balance_bar_get_property (GObject *object, GvcBalanceBar *self = GVC_BALANCE_BAR (object); switch (prop_id) { - case PROP_STREAM: - g_value_set_object (value, self->priv->stream); + case PROP_CONTROL: + g_value_set_object (value, self->priv->control); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -432,12 +430,13 @@ gvc_balance_bar_class_init (GvcBalanceBarClass *klass) object_class->set_property = gvc_balance_bar_set_property; object_class->get_property = gvc_balance_bar_get_property; - properties[PROP_STREAM] = - g_param_spec_object ("stream", - "Stream", - "Libmatemixer stream", - MATE_MIXER_TYPE_STREAM, - G_PARAM_READWRITE); + 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", @@ -446,7 +445,9 @@ gvc_balance_bar_class_init (GvcBalanceBarClass *klass) BALANCE_TYPE_RL, NUM_BALANCE_TYPES - 1, BALANCE_TYPE_RL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS); g_object_class_install_properties (object_class, N_PROPERTIES, properties); @@ -495,20 +496,20 @@ on_adjustment_value_changed (GtkAdjustment *adjustment, GvcBalanceBar *bar) { gdouble value; - if (bar->priv->stream == NULL) + if (bar->priv->control == NULL) return; value = gtk_adjustment_get_value (adjustment); switch (bar->priv->btype) { case BALANCE_TYPE_RL: - mate_mixer_stream_set_balance (bar->priv->stream, value); + mate_mixer_stream_control_set_balance (bar->priv->control, value); break; case BALANCE_TYPE_FR: - mate_mixer_stream_set_fade (bar->priv->stream, value); + mate_mixer_stream_control_set_fade (bar->priv->control, value); break; case BALANCE_TYPE_LFE: - mate_mixer_stream_set_channel_volume (bar->priv->stream, + mate_mixer_stream_control_set_channel_volume (bar->priv->control, bar->priv->lfe_channel, value); break; @@ -528,22 +529,22 @@ gvc_balance_bar_dispose (GObject *object) bar = GVC_BALANCE_BAR (object); - if (bar->priv->stream != NULL) { - g_signal_handlers_disconnect_by_func (G_OBJECT (bar->priv->stream), + 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->stream); + g_clear_object (&bar->priv->control); } G_OBJECT_CLASS (gvc_balance_bar_parent_class)->dispose (object); } GtkWidget * -gvc_balance_bar_new (MateMixerStream *stream, GvcBalanceType btype) +gvc_balance_bar_new (MateMixerStreamControl *control, GvcBalanceType btype) { return g_object_new (GVC_TYPE_BALANCE_BAR, "balance-type", btype, - "stream", stream, + "control", control, #if GTK_CHECK_VERSION (3, 0, 0) "orientation", GTK_ORIENTATION_HORIZONTAL, #endif diff --git a/mate-volume-control/src/gvc-balance-bar.h b/mate-volume-control/src/gvc-balance-bar.h index 32602ae..d5b142d 100644 --- a/mate-volume-control/src/gvc-balance-bar.h +++ b/mate-volume-control/src/gvc-balance-bar.h @@ -70,7 +70,7 @@ struct _GvcBalanceBarClass GType gvc_balance_bar_get_type (void) G_GNUC_CONST; -GtkWidget * gvc_balance_bar_new (MateMixerStream *stream, +GtkWidget * gvc_balance_bar_new (MateMixerStreamControl *control, GvcBalanceType btype); void gvc_balance_bar_set_size_group (GvcBalanceBar *bar, diff --git a/mate-volume-control/src/gvc-channel-bar.c b/mate-volume-control/src/gvc-channel-bar.c index 9a2c765..e431651 100644 --- a/mate-volume-control/src/gvc-channel-bar.c +++ b/mate-volume-control/src/gvc-channel-bar.c @@ -36,32 +36,32 @@ 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; - MateMixerStream *stream; - MateMixerStreamFlags stream_flags; + 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_STREAM, + PROP_CONTROL, PROP_ORIENTATION, PROP_SHOW_ICONS, PROP_SHOW_MUTE, @@ -226,17 +226,27 @@ on_adjustment_value_changed (GtkAdjustment *adjustment, gdouble value; gdouble lower; - if (bar->priv->stream == NULL || bar->priv->click_lock == TRUE) + 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->stream_flags & MATE_MIXER_STREAM_HAS_MUTE) - mate_mixer_stream_set_mute (bar->priv->stream, (value <= lower)); + 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->stream_flags & MATE_MIXER_STREAM_CAN_SET_VOLUME) - mate_mixer_stream_set_volume (bar->priv->stream, (guint) value); + 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 @@ -305,15 +315,13 @@ update_marks (GvcChannelBar *bar) gtk_scale_clear_marks (GTK_SCALE (bar->priv->scale)); - if (bar->priv->stream == NULL || bar->priv->show_marks == FALSE) - return; - if (!(bar->priv->stream_flags & MATE_MIXER_STREAM_HAS_VOLUME)) + 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_get_base_volume (bar->priv->stream); - normal = mate_mixer_stream_get_normal_volume (bar->priv->stream); + 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; @@ -363,18 +371,17 @@ update_adjustment_value (GvcChannelBar *bar) gdouble value; gboolean set_lower = FALSE; - /* Move the slider to the minimal value if the stream is muted or + /* Move the slider to the minimal value if the stream control is muted or * volume is unavailable */ - if (!(bar->priv->stream_flags & MATE_MIXER_STREAM_HAS_VOLUME)) + if (bar->priv->control == NULL) set_lower = TRUE; - else if (bar->priv->stream == NULL || - bar->priv->stream_flags & MATE_MIXER_STREAM_HAS_MUTE) - set_lower = mate_mixer_stream_get_mute (bar->priv->stream); + 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) + if (set_lower == TRUE) value = gtk_adjustment_get_lower (bar->priv->adjustment); else - value = mate_mixer_stream_get_volume (bar->priv->stream); + 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, @@ -393,12 +400,12 @@ update_adjustment_limits (GvcChannelBar *bar) gdouble minimum = 0.0; gdouble maximum = 0.0; - if (bar->priv->stream_flags & MATE_MIXER_STREAM_HAS_VOLUME) { - minimum = mate_mixer_stream_get_min_volume (bar->priv->stream); + if (bar->priv->control != NULL) { + minimum = mate_mixer_stream_control_get_min_volume (bar->priv->control); if (bar->priv->extended) - maximum = mate_mixer_stream_get_max_volume (bar->priv->stream); + maximum = mate_mixer_stream_control_get_max_volume (bar->priv->control); else - maximum = mate_mixer_stream_get_normal_volume (bar->priv->stream); + maximum = mate_mixer_stream_control_get_normal_volume (bar->priv->control); } gtk_adjustment_configure (bar->priv->adjustment, @@ -416,12 +423,12 @@ update_mute_button (GvcChannelBar *bar) if (bar->priv->show_mute == TRUE) { gboolean enable = FALSE; - if (bar->priv->stream != NULL && - bar->priv->stream_flags & MATE_MIXER_STREAM_HAS_MUTE) + 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_get_mute (bar->priv->stream); + gboolean mute = mate_mixer_stream_control_get_mute (bar->priv->control); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (bar->priv->mute_button), mute); @@ -455,12 +462,12 @@ on_scale_button_press_event (GtkWidget *widget, /* 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->stream_flags & MATE_MIXER_STREAM_HAS_MUTE && - bar->priv->stream_flags & MATE_MIXER_STREAM_HAS_VOLUME) { - if (mate_mixer_stream_get_mute (bar->priv->stream) == TRUE) { + 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_get_volume (bar->priv->stream) > minimum) + if (mate_mixer_stream_control_get_volume (bar->priv->control) > minimum) bar->priv->click_lock = TRUE; } } @@ -522,71 +529,79 @@ on_scale_scroll_event (GtkWidget *widget, } static void -on_stream_volume_notify (MateMixerStream *stream, - GParamSpec *pspec, - GvcChannelBar *bar) +on_control_volume_notify (MateMixerStreamControl *control, + GParamSpec *pspec, + GvcChannelBar *bar) { update_adjustment_value (bar); } static void -on_stream_mute_notify (MateMixerStream *stream, - GParamSpec *pspec, - GvcChannelBar *bar) +on_control_mute_notify (MateMixerStreamControl *control, + GParamSpec *pspec, + GvcChannelBar *bar) { if (bar->priv->show_mute == TRUE) { - gboolean mute = mate_mixer_stream_get_mute (stream); + 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); } -MateMixerStream * -gvc_channel_bar_get_stream (GvcChannelBar *bar) +MateMixerStreamControl * +gvc_channel_bar_get_control (GvcChannelBar *bar) { g_return_val_if_fail (GVC_IS_CHANNEL_BAR (bar), NULL); - return bar->priv->stream; + return bar->priv->control; } void -gvc_channel_bar_set_stream (GvcChannelBar *bar, MateMixerStream *stream) +gvc_channel_bar_set_control (GvcChannelBar *bar, MateMixerStreamControl *control) { g_return_if_fail (GVC_IS_CHANNEL_BAR (bar)); - if (bar->priv->stream == stream) + if (bar->priv->control == control) return; - if (stream != NULL) - g_object_ref (stream); + if (control != NULL) + g_object_ref (control); - if (bar->priv->stream != NULL) { - g_signal_handlers_disconnect_by_func (G_OBJECT (bar->priv->stream), - G_CALLBACK (on_stream_volume_notify), + 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->stream), - G_CALLBACK (on_stream_mute_notify), + g_signal_handlers_disconnect_by_func (G_OBJECT (bar->priv->control), + G_CALLBACK (on_control_mute_notify), bar); - g_object_unref (bar->priv->stream); + g_object_unref (bar->priv->control); } - bar->priv->stream = stream; + bar->priv->control = control; - if (stream != NULL) - bar->priv->stream_flags = mate_mixer_stream_get_flags (stream); + if (control != NULL) + bar->priv->control_flags = mate_mixer_stream_control_get_flags (control); else - bar->priv->stream_flags = MATE_MIXER_STREAM_NO_FLAGS; + bar->priv->control_flags = MATE_MIXER_STREAM_CONTROL_NO_FLAGS; - if (bar->priv->stream_flags & MATE_MIXER_STREAM_HAS_VOLUME) - g_signal_connect (G_OBJECT (stream), + if (bar->priv->control_flags & MATE_MIXER_STREAM_CONTROL_VOLUME_READABLE) + g_signal_connect (G_OBJECT (control), "notify::volume", - G_CALLBACK (on_stream_volume_notify), + G_CALLBACK (on_control_volume_notify), bar); - if (bar->priv->stream_flags & MATE_MIXER_STREAM_HAS_MUTE) - g_signal_connect (G_OBJECT (stream), + if (bar->priv->control_flags & MATE_MIXER_STREAM_CONTROL_MUTE_READABLE) + g_signal_connect (G_OBJECT (control), "notify::mute", - G_CALLBACK (on_stream_mute_notify), + G_CALLBACK (on_control_mute_notify), bar); update_marks (bar); @@ -899,8 +914,8 @@ gvc_channel_bar_set_property (GObject *object, GvcChannelBar *self = GVC_CHANNEL_BAR (object); switch (prop_id) { - case PROP_STREAM: - gvc_channel_bar_set_stream (self, g_value_get_object (value)); + 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)); @@ -944,8 +959,8 @@ gvc_channel_bar_get_property (GObject *object, GvcChannelBar *self = GVC_CHANNEL_BAR (object); switch (prop_id) { - case PROP_STREAM: - g_value_set_object (value, self->priv->stream); + case PROP_CONTROL: + g_value_set_object (value, self->priv->control); break; case PROP_ORIENTATION: g_value_set_enum (value, self->priv->orientation); @@ -979,11 +994,11 @@ gvc_channel_bar_class_init (GvcChannelBarClass *klass) object_class->set_property = gvc_channel_bar_set_property; object_class->get_property = gvc_channel_bar_get_property; - properties[PROP_STREAM] = - g_param_spec_object ("stream", - "Stream", - "MateMixer stream", - MATE_MIXER_TYPE_STREAM, + 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); @@ -1074,19 +1089,6 @@ gvc_channel_bar_class_init (GvcChannelBarClass *klass) } static void -on_mute_button_toggled (GtkToggleButton *button, GvcChannelBar *bar) -{ - gboolean mute; - - if (G_UNLIKELY (bar->priv->stream == NULL)) - g_warn_if_reached (); - - mute = gtk_toggle_button_get_active (button); - - mate_mixer_stream_set_mute (bar->priv->stream, mute); -} - -static void gvc_channel_bar_init (GvcChannelBar *bar) { GtkWidget *frame; @@ -1145,10 +1147,10 @@ gvc_channel_bar_init (GvcChannelBar *bar) } GtkWidget * -gvc_channel_bar_new (MateMixerStream *stream) +gvc_channel_bar_new (MateMixerStreamControl *control) { return g_object_new (GVC_TYPE_CHANNEL_BAR, - "stream", stream, + "control", control, #if GTK_CHECK_VERSION (3, 0, 0) "orientation", GTK_ORIENTATION_HORIZONTAL, #endif diff --git a/mate-volume-control/src/gvc-channel-bar.h b/mate-volume-control/src/gvc-channel-bar.h index 16d6257..1c80be9 100644 --- a/mate-volume-control/src/gvc-channel-bar.h +++ b/mate-volume-control/src/gvc-channel-bar.h @@ -64,11 +64,11 @@ struct _GvcChannelBarClass GType gvc_channel_bar_get_type (void); -GtkWidget * gvc_channel_bar_new (MateMixerStream *stream); +GtkWidget * gvc_channel_bar_new (MateMixerStreamControl *control); -MateMixerStream * gvc_channel_bar_get_stream (GvcChannelBar *bar); -void gvc_channel_bar_set_stream (GvcChannelBar *bar, - MateMixerStream *stream); +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, diff --git a/mate-volume-control/src/gvc-combo-box.c b/mate-volume-control/src/gvc-combo-box.c index 524e1b0..b2a273f 100644 --- a/mate-volume-control/src/gvc-combo-box.c +++ b/mate-volume-control/src/gvc-combo-box.c @@ -202,46 +202,23 @@ gvc_combo_box_class_init (GvcComboBoxClass *klass) } void -gvc_combo_box_set_profiles (GvcComboBox *combobox, const GList *profiles) +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 = profiles; l != NULL; l = l->next) { - MateMixerDeviceProfile *p = MATE_MIXER_DEVICE_PROFILE (l->data); + 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_device_profile_get_name (p), + mate_mixer_switch_option_get_name (option), COL_HUMAN_NAME, - mate_mixer_device_profile_get_description (p), - -1); - } - combobox->priv->set_called = TRUE; -} - -void -gvc_combo_box_set_ports (GvcComboBox *combobox, const GList *ports) -{ - const GList *l; - - g_return_if_fail (GVC_IS_COMBO_BOX (combobox)); - g_return_if_fail (combobox->priv->set_called == FALSE); - - for (l = ports; l != NULL; l = l->next) { - MateMixerPort *p = MATE_MIXER_PORT (l->data); - - gtk_list_store_insert_with_values (GTK_LIST_STORE (combobox->priv->model), - NULL, - G_MAXINT, - COL_NAME, - mate_mixer_port_get_name (p), - COL_HUMAN_NAME, - mate_mixer_port_get_description (p), + mate_mixer_switch_option_get_label (option), -1); } combobox->priv->set_called = TRUE; diff --git a/mate-volume-control/src/gvc-combo-box.h b/mate-volume-control/src/gvc-combo-box.h index 4cd8511..9a2f425 100644 --- a/mate-volume-control/src/gvc-combo-box.h +++ b/mate-volume-control/src/gvc-combo-box.h @@ -69,10 +69,8 @@ void gvc_combo_box_set_size_group (GvcComboBox *combobox, GtkSizeGroup *group, gboolean symmetric); -void gvc_combo_box_set_profiles (GvcComboBox *combobox, - const GList *profiles); -void gvc_combo_box_set_ports (GvcComboBox *combobox, - const GList *ports); +void gvc_combo_box_set_options (GvcComboBox *combobox, + const GList *options); void gvc_combo_box_set_active (GvcComboBox *combobox, const gchar *id); diff --git a/mate-volume-control/src/gvc-mixer-dialog.c b/mate-volume-control/src/gvc-mixer-dialog.c index 5087bae..bbad904 100644 --- a/mate-volume-control/src/gvc-mixer-dialog.c +++ b/mate-volume-control/src/gvc-mixer-dialog.c @@ -42,7 +42,7 @@ struct _GvcMixerDialogPrivate { - MateMixerControl *control; + MateMixerContext *context; GHashTable *bars; GtkWidget *notebook; GtkWidget *output_bar; @@ -79,7 +79,7 @@ struct _GvcMixerDialogPrivate enum { ICON_COLUMN, NAME_COLUMN, - DESCRIPTION_COLUMN, + LABEL_COLUMN, ACTIVE_COLUMN, SPEAKERS_COLUMN, NUM_COLUMNS @@ -88,7 +88,7 @@ enum { enum { HW_ICON_COLUMN, HW_NAME_COLUMN, - HW_DESCRIPTION_COLUMN, + HW_LABEL_COLUMN, HW_STATUS_COLUMN, HW_PROFILE_COLUMN, HW_NUM_COLUMNS @@ -104,7 +104,7 @@ enum { enum { PROP_0, - PROP_CONTROL + PROP_CONTEXT }; static const guint tab_accel_keys[] = { @@ -121,6 +121,65 @@ static void bar_set_stream (GvcMixerDialog *dialog, 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); + + if (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, @@ -134,7 +193,6 @@ find_tree_item_by_name (GtkTreeModel *model, do { gchar *n; - gtk_tree_model_get (model, iter, column, &n, -1); if (!g_strcmp0 (name, n)) @@ -147,9 +205,9 @@ find_tree_item_by_name (GtkTreeModel *model, } static void -update_default_item (GvcMixerDialog *dialog, - GtkTreeModel *model, - MateMixerStream *stream) +update_default_tree_item (GvcMixerDialog *dialog, + GtkTreeModel *model, + MateMixerStream *stream) { GtkTreeIter iter; const gchar *name = NULL; @@ -165,7 +223,6 @@ update_default_item (GvcMixerDialog *dialog, do { gchar *n; - gtk_tree_model_get (model, &iter, NAME_COLUMN, &n, -1); @@ -178,84 +235,42 @@ update_default_item (GvcMixerDialog *dialog, } static void -on_combo_box_port_changed (GvcComboBox *combo, - const gchar *name, - GvcMixerDialog *dialog) +on_combobox_option_changed (GvcComboBox *combo, + const gchar *name, + GvcMixerDialog *dialog) { - MateMixerStream *stream; - MateMixerPort *port = NULL; - GList *ports; + MateMixerSwitch *swtch; + MateMixerSwitchOption *option; + const GList *options; - stream = g_object_get_data (G_OBJECT (combo), "stream"); - if (G_UNLIKELY (stream == NULL)) { + swtch = g_object_get_data (G_OBJECT (combo), "switch"); + if (G_UNLIKELY (swtch == NULL)) { g_warn_if_reached (); return; } - ports = (GList *) mate_mixer_stream_list_ports (stream); - while (ports) { - port = MATE_MIXER_PORT (ports->data); + options = mate_mixer_switch_list_options (swtch); + while (options != NULL) { + option = MATE_MIXER_SWITCH_OPTION (options->data); - if (!g_strcmp0 (mate_mixer_port_get_name (port), name)) + if (g_strcmp0 (mate_mixer_switch_option_get_name (option), name) == 0) break; - port = NULL; - ports = ports->next; + option = NULL; + options = options->next; } - if (G_UNLIKELY (port == NULL)) { + if (G_UNLIKELY (option == NULL)) { g_warn_if_reached (); return; } - g_debug ("Stream port changed to %s for stream %s", - name, - mate_mixer_stream_get_name (stream)); - - mate_mixer_stream_set_active_port (stream, port); -} - -static void -on_combo_box_profile_changed (GvcComboBox *combo, - const gchar *name, - GvcMixerDialog *dialog) -{ - MateMixerDevice *device; - MateMixerDeviceProfile *profile = NULL; - GList *profiles; - - device = g_object_get_data (G_OBJECT (combo), "device"); - if (G_UNLIKELY (device == NULL)) { - g_warn_if_reached (); - return; - } - - profiles = (GList *) mate_mixer_device_list_profiles (device); - while (profiles) { - profile = MATE_MIXER_DEVICE_PROFILE (profiles->data); - - if (!g_strcmp0 (mate_mixer_device_profile_get_name (profile), name)) - break; - - profile = NULL; - profiles = profiles->next; - } - - if (G_UNLIKELY (profile == NULL)) { - g_warn_if_reached (); - return; - } - - g_debug ("Device profile changed to %s for device %s", - name, - mate_mixer_device_get_name (device)); - - mate_mixer_device_set_active_profile (device, profile); + mate_mixer_switch_set_active_option (swtch, option); } static GtkWidget * create_port_combo_box (GvcMixerDialog *dialog, - MateMixerStream *stream, + MateMixerSwitch *swtch, const gchar *name, const GList *items, const gchar *active) @@ -264,7 +279,7 @@ create_port_combo_box (GvcMixerDialog *dialog, combobox = gvc_combo_box_new (name); - gvc_combo_box_set_ports (GVC_COMBO_BOX (combobox), items); + 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), @@ -272,25 +287,25 @@ create_port_combo_box (GvcMixerDialog *dialog, FALSE); g_object_set_data_full (G_OBJECT (combobox), - "stream", - g_object_ref (stream), + "switch", + g_object_ref (swtch), g_object_unref); g_signal_connect (G_OBJECT (combobox), "changed", - G_CALLBACK (on_combo_box_port_changed), + G_CALLBACK (on_combobox_option_changed), dialog); - return combobox; } static void update_output_settings (GvcMixerDialog *dialog) { - MateMixerStream *stream; - MateMixerStreamFlags flags; - const GList *ports; - gboolean has_settings = FALSE; + MateMixerStream *stream; + MateMixerStreamControl *control = NULL; + MateMixerStreamControlFlags flags; + MateMixerSwitch *port_switch; + gboolean has_settings = FALSE; g_debug ("Updating output settings"); @@ -319,19 +334,25 @@ update_output_settings (GvcMixerDialog *dialog) dialog->priv->output_port_combo = NULL; } - stream = mate_mixer_control_get_default_output_stream (dialog->priv->control); + stream = mate_mixer_context_get_default_output_stream (dialog->priv->context); if (stream == NULL) { - g_debug ("There is no default output stream - output settings disabled"); + g_debug ("There is no default output stream"); + gtk_widget_hide (dialog->priv->output_settings_frame); + return; + } + control = mate_mixer_stream_get_default_control (stream); + 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_get_flags (stream); + flags = mate_mixer_stream_control_get_flags (control); - /* Enable balance bar if stream feature is available */ - if (flags & MATE_MIXER_STREAM_CAN_BALANCE) { + /* Enable balance bar if it is available */ + if (flags & MATE_MIXER_STREAM_CONTROL_CAN_BALANCE) { dialog->priv->output_balance_bar = - gvc_balance_bar_new (stream, BALANCE_TYPE_RL); + 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, @@ -345,10 +366,10 @@ update_output_settings (GvcMixerDialog *dialog) has_settings = TRUE; } - /* Enable fade bar if stream feature is available */ - if (flags & MATE_MIXER_STREAM_CAN_FADE) { + /* Enable fade bar if it is available */ + if (flags & MATE_MIXER_STREAM_CONTROL_CAN_FADE) { dialog->priv->output_fade_bar = - gvc_balance_bar_new (stream, BALANCE_TYPE_FR); + 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, @@ -363,9 +384,9 @@ update_output_settings (GvcMixerDialog *dialog) } /* Enable subwoofer volume bar if subwoofer is available */ - if (mate_mixer_stream_has_channel_position (stream, MATE_MIXER_CHANNEL_LFE)) { + if (mate_mixer_stream_control_has_channel_position (control, MATE_MIXER_CHANNEL_LFE)) { dialog->priv->output_lfe_bar = - gvc_balance_bar_new (stream, BALANCE_TYPE_LFE); + 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, @@ -379,23 +400,24 @@ update_output_settings (GvcMixerDialog *dialog) has_settings = TRUE; } - ports = mate_mixer_stream_list_ports (stream); - if (ports != NULL) { - MateMixerPort *port; + /* 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; - port = mate_mixer_stream_get_active_port (stream); - if (G_UNLIKELY (port == NULL)) { - /* Select the first port if none is selected at the moment */ - port = MATE_MIXER_PORT (ports->data); - mate_mixer_stream_set_active_port (stream, port); - } + 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, - stream, + port_switch, _("Co_nnector:"), - ports, - mate_mixer_port_get_name (port)); + options, + active_name); gtk_box_pack_start (GTK_BOX (dialog->priv->output_settings_box), dialog->priv->output_port_combo, @@ -412,52 +434,68 @@ update_output_settings (GvcMixerDialog *dialog) } static void -on_control_default_output_notify (MateMixerControl *control, - GParamSpec *pspec, - GvcMixerDialog *dialog) +set_output_stream (GvcMixerDialog *dialog, MateMixerStream *stream) { GtkTreeModel *model; - MateMixerStream *stream; + MateMixerSwitch *swtch; - stream = mate_mixer_control_get_default_output_stream (control); - if (stream != NULL) { - GList *streams; + if (0 && stream != NULL) { + const GList *controls; - streams = (GList *) mate_mixer_control_list_cached_streams (dialog->priv->control); + controls = mate_mixer_context_list_stored_controls (dialog->priv->context); - /* Move all cached stream to the newly selected default stream */ - while (streams) { - MateMixerStream *parent; - MateMixerClientStream *client = MATE_MIXER_CLIENT_STREAM (streams->data); + /* Move all stored controls to the newly selected default stream */ + while (controls != NULL) { + MateMixerStream *parent; + MateMixerStreamControl *control; - parent = mate_mixer_client_stream_get_parent (client); + control = MATE_MIXER_STREAM_CONTROL (controls->data); + parent = mate_mixer_stream_control_get_stream (control); if (parent != stream) { - MateMixerStreamFlags flags; - - flags = mate_mixer_stream_get_flags (MATE_MIXER_STREAM (client)); + MateMixerDirection direction = + mate_mixer_stream_get_direction (parent); - if (flags & MATE_MIXER_STREAM_OUTPUT) - mate_mixer_client_stream_set_parent (client, stream); + if (direction == MATE_MIXER_DIRECTION_OUTPUT) + mate_mixer_stream_control_set_stream (control, stream); } - streams = streams->next; + controls = controls->next; } } + /* Changing the default input stream, disconnect the port switch */ + 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); model = gtk_tree_view_get_model (GTK_TREE_VIEW (dialog->priv->output_treeview)); - update_default_item (dialog, model, stream); + 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_monitor_value (MateMixerStream *stream, - gdouble value, - GvcMixerDialog *dialog) +on_stream_control_monitor_value (MateMixerStream *stream, + gdouble value, + GvcMixerDialog *dialog) { GtkAdjustment *adj; @@ -479,9 +517,10 @@ on_stream_monitor_value (MateMixerStream *stream, static void update_input_settings (GvcMixerDialog *dialog) { - MateMixerStream *stream; - MateMixerStreamFlags flags; - const GList *ports; + MateMixerStream *stream; + MateMixerStreamControl *control; + MateMixerStreamControlFlags flags; + MateMixerSwitch *port_switch; g_debug ("Updating input settings"); @@ -492,41 +531,44 @@ update_input_settings (GvcMixerDialog *dialog) dialog->priv->input_port_combo = NULL; } - stream = mate_mixer_control_get_default_input_stream (dialog->priv->control); + stream = mate_mixer_context_get_default_input_stream (dialog->priv->context); if (stream == NULL) { g_debug ("There is no default input stream"); return; } + control = mate_mixer_stream_get_default_control (stream); + if (control == NULL) { + g_debug ("There is no control for the default input stream"); + return; + } - flags = mate_mixer_stream_get_flags (stream); - - /* Enable level bar only if supported by the stream */ - if (flags & MATE_MIXER_STREAM_HAS_MONITOR) { - mate_mixer_stream_monitor_set_name (stream, _("Peak detect")); + flags = mate_mixer_stream_control_get_flags (control); - g_signal_connect (G_OBJECT (stream), + /* 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_monitor_value), + G_CALLBACK (on_stream_control_monitor_value), dialog); - } - ports = mate_mixer_stream_list_ports (stream); - if (ports != NULL) { - MateMixerPort *port; + /* 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; - port = mate_mixer_stream_get_active_port (stream); - if (G_UNLIKELY (port == NULL)) { - /* Select the first port if none is selected at the moment */ - port = MATE_MIXER_PORT (ports->data); - mate_mixer_stream_set_active_port (stream, port); - } + 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, - stream, + port_switch, _("Co_nnector:"), - ports, - mate_mixer_port_get_name (port)); + options, + active_name); gtk_box_pack_start (GTK_BOX (dialog->priv->input_settings_box), dialog->priv->input_port_combo, @@ -537,167 +579,147 @@ update_input_settings (GvcMixerDialog *dialog) } static void -on_control_default_input_notify (MateMixerControl *control, - GParamSpec *pspec, - GvcMixerDialog *dialog) +on_stream_control_mute_notify (MateMixerStreamControl *control, + GParamSpec *pspec, + GvcMixerDialog *dialog) { - GtkTreeModel *model; - MateMixerStream *stream; - MateMixerStream *current; + /* 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); +} - g_debug ("Default input stream has changed"); +static void +set_input_stream (GvcMixerDialog *dialog, MateMixerStream *stream) +{ + GtkTreeModel *model; + MateMixerSwitch *swtch; + MateMixerStreamControl *control; - current = gvc_channel_bar_get_stream (GVC_CHANNEL_BAR (dialog->priv->input_bar)); - if (current != NULL) { + control = gvc_channel_bar_get_control (GVC_CHANNEL_BAR (dialog->priv->input_bar)); + if (control != NULL) { /* Make sure to disable monitoring of the removed stream */ - g_signal_handlers_disconnect_by_func (G_OBJECT (current), - G_CALLBACK (on_stream_monitor_value), + g_signal_handlers_disconnect_by_func (G_OBJECT (control), + G_CALLBACK (on_stream_control_monitor_value), dialog); - mate_mixer_stream_monitor_stop (current); + mate_mixer_stream_control_set_monitor_enabled (control, FALSE); } - stream = mate_mixer_control_get_default_input_stream (control); if (stream != NULL) { - GList *streams; - guint page = gtk_notebook_get_current_page (GTK_NOTEBOOK (dialog->priv->notebook)); + const GList *controls; + guint page = gtk_notebook_get_current_page (GTK_NOTEBOOK (dialog->priv->notebook)); - streams = (GList *) mate_mixer_control_list_cached_streams (dialog->priv->control); + controls = mate_mixer_context_list_stored_controls (dialog->priv->context); - /* Move all cached stream to the newly selected default stream */ - while (streams) { - MateMixerStream *parent; - MateMixerClientStream *client = MATE_MIXER_CLIENT_STREAM (streams->data); + /* Move all stored controls to the newly selected default stream */ + while (controls != NULL) { + MateMixerStream *parent; - parent = mate_mixer_client_stream_get_parent (client); + control = MATE_MIXER_STREAM_CONTROL (controls->data); + parent = mate_mixer_stream_control_get_stream (control); if (parent != stream) { - MateMixerStreamFlags flags; - - flags = mate_mixer_stream_get_flags (MATE_MIXER_STREAM (client)); + MateMixerDirection direction = + mate_mixer_stream_get_direction (parent); - if (flags & MATE_MIXER_STREAM_INPUT) - mate_mixer_client_stream_set_parent (client, stream); + if (direction == MATE_MIXER_DIRECTION_INPUT) + mate_mixer_stream_control_set_stream (control, stream); } - streams = streams->next; + controls = controls->next; } if (page == PAGE_INPUT) - mate_mixer_stream_monitor_start (stream); + mate_mixer_stream_control_set_monitor_enabled (control, TRUE); + } + + /* Changing the default input stream, disconnect the port switch */ + 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); } bar_set_stream (dialog, dialog->priv->input_bar, stream); + if (stream != NULL) { + /* 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_item (dialog, model, stream); + 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_stream (GvcMixerDialog *dialog, MateMixerStream *stream) +find_combo_box_by_switch (GvcMixerDialog *dialog, MateMixerSwitch *swtch) { - MateMixerStream *combo_stream; + MateMixerSwitch *combo_switch; if (dialog->priv->output_port_combo != NULL) { - combo_stream = g_object_get_data (G_OBJECT (dialog->priv->output_port_combo), - "stream"); - if (combo_stream == stream) + 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_stream = g_object_get_data (G_OBJECT (dialog->priv->input_port_combo), - "stream"); - if (combo_stream == stream) + 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_stream_description_notify (MateMixerStream *stream, - GParamSpec *pspec, - GvcMixerDialog *dialog) -{ - GtkTreeModel *model; - GtkTreeIter iter; - MateMixerStreamFlags flags; - - flags = mate_mixer_stream_get_flags (stream); - - if (flags & MATE_MIXER_STREAM_INPUT) - model = gtk_tree_view_get_model (GTK_TREE_VIEW (dialog->priv->input_treeview)); - else - model = gtk_tree_view_get_model (GTK_TREE_VIEW (dialog->priv->output_treeview)); - - if (find_tree_item_by_name (model, - mate_mixer_stream_get_name (stream), - NAME_COLUMN, - &iter) == TRUE) { - const gchar *description; - - description = mate_mixer_stream_get_description (stream); - gtk_list_store_set (GTK_LIST_STORE (model), - &iter, - DESCRIPTION_COLUMN, description, - -1); - } -} - -static void -on_stream_port_notify (MateMixerStream *stream, - GParamSpec *pspec, - GvcMixerDialog *dialog) +on_switch_option_notify (MateMixerSwitch *swtch, + GParamSpec *pspec, + GvcMixerDialog *dialog) { - GvcComboBox *combobox; - MateMixerPort *port; + GvcComboBox *combobox; + MateMixerSwitchOption *port; - combobox = find_combo_box_by_stream (dialog, stream); + combobox = find_combo_box_by_switch (dialog, swtch); if (G_UNLIKELY (combobox == NULL)) { g_warn_if_reached (); return; } - g_debug ("Stream %s port has changed", - mate_mixer_stream_get_name (stream)); - g_signal_handlers_block_by_func (G_OBJECT (combobox), - on_combo_box_port_changed, + on_combobox_option_changed, dialog); - port = mate_mixer_stream_get_active_port (stream); - if (G_LIKELY (port != NULL)) { - const gchar *name = mate_mixer_port_get_name (port); - - g_debug ("The current port is %s", name); - - gvc_combo_box_set_active (GVC_COMBO_BOX (combobox), name); - } + 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_combo_box_port_changed, + on_combobox_option_changed, dialog); } -static void -on_stream_mute_notify (MateMixerStream *stream, - GParamSpec *pspec, - GvcMixerDialog *dialog) -{ - MateMixerStream *input; - - input = mate_mixer_control_get_default_input_stream (dialog->priv->control); - - /* Stop monitoring the input stream when it gets muted */ - if (stream == input) { - if (mate_mixer_stream_get_mute (stream)) - mate_mixer_stream_monitor_stop (stream); - else - mate_mixer_stream_monitor_start (stream); - } -} - static GtkWidget * create_bar (GvcMixerDialog *dialog, gboolean use_size_group, gboolean symmetric) { @@ -724,228 +746,241 @@ bar_set_stream (GvcMixerDialog *dialog, GtkWidget *bar, MateMixerStream *stream) { - MateMixerStream *previous; + MateMixerStreamControl *control = NULL; + MateMixerStreamControl *previous; - previous = gvc_channel_bar_get_stream (GVC_CHANNEL_BAR (bar)); + previous = gvc_channel_bar_get_control (GVC_CHANNEL_BAR (bar)); if (previous != NULL) { - const gchar *name = mate_mixer_stream_get_name (previous); + const gchar *name = mate_mixer_stream_control_get_name (previous); - g_debug ("Disconnecting old stream %s", name); + g_debug ("Disconnecting old stream control %s", name); - g_signal_handlers_disconnect_by_func (previous, - on_stream_mute_notify, - dialog); - g_signal_handlers_disconnect_by_func (previous, - on_stream_port_notify, - dialog); + g_signal_handlers_disconnect_by_data (G_OBJECT (previous), dialog); - if (mate_mixer_stream_get_flags (previous) & MATE_MIXER_STREAM_INPUT) - mate_mixer_stream_monitor_stop (previous); + /* 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_stream (GVC_CHANNEL_BAR (bar), stream); - if (stream != NULL) { - const gchar *name = mate_mixer_stream_get_name (stream); + MateMixerSwitch *port_switch; - g_debug ("Connecting new stream %s", name); + control = mate_mixer_stream_get_default_control (stream); - g_signal_connect (stream, - "notify::mute", - G_CALLBACK (on_stream_mute_notify), - dialog); - g_signal_connect (stream, - "notify::active-port", - G_CALLBACK (on_stream_port_notify), - dialog); + 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); - g_hash_table_insert (dialog->priv->bars, (gpointer) name, bar); + if (G_LIKELY (control != NULL)) + g_hash_table_insert (dialog->priv->bars, + (gpointer) mate_mixer_stream_control_get_name (control), + bar); } + gvc_channel_bar_set_control (GVC_CHANNEL_BAR (bar), control); + gtk_widget_set_sensitive (GTK_WIDGET (bar), (stream != NULL)); } static void -add_stream (GvcMixerDialog *dialog, MateMixerStream *stream) +add_application_control (GvcMixerDialog *dialog, MateMixerStreamControl *control) { - GtkWidget *bar = NULL; - MateMixerStreamFlags flags; + 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; - flags = mate_mixer_stream_get_flags (stream); + /* 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; - if (MATE_MIXER_IS_CLIENT_STREAM (stream)) { - MateMixerClientStream *client ; - MateMixerClientStreamFlags client_flags; - MateMixerClientStreamRole client_role; - const gchar *name; - const gchar *icon; - - client = MATE_MIXER_CLIENT_STREAM (stream); - client_flags = mate_mixer_client_stream_get_flags (client); - client_role = mate_mixer_client_stream_get_role (client); - - /* We use a cached event stream for the effects volume slider, - * because regular streams are only created when an event sound - * is played and then immediately destroyed. - * The cached event stream should exist all the time. */ - if (client_flags & MATE_MIXER_CLIENT_STREAM_CACHED && - client_role == MATE_MIXER_CLIENT_STREAM_ROLE_EVENT) { - g_debug ("Found cached event role stream %s", - mate_mixer_stream_get_name (stream)); - - bar = dialog->priv->effects_bar; - } + app_id = mate_mixer_app_info_get_id (info); - /* Add stream to the applications page, but make sure the stream - * qualifies for the inclusion */ - if (client_flags & MATE_MIXER_CLIENT_STREAM_APPLICATION) { - const gchar *app_id; - - /* Skip streams with roles we don't care about */ - if (client_role == MATE_MIXER_CLIENT_STREAM_ROLE_EVENT || - client_role == MATE_MIXER_CLIENT_STREAM_ROLE_TEST || - client_role == MATE_MIXER_CLIENT_STREAM_ROLE_ABSTRACT || - client_role == MATE_MIXER_CLIENT_STREAM_ROLE_FILTER) - return; - - app_id = mate_mixer_client_stream_get_app_id (client); - - /* 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; - - name = mate_mixer_client_stream_get_app_name (client); - if (name == NULL) - name = mate_mixer_stream_get_description (stream); - if (name == NULL) - name = mate_mixer_stream_get_name (stream); - if (G_UNLIKELY (name == NULL)) - return; - - bar = create_bar (dialog, FALSE, FALSE); - - g_object_set (G_OBJECT (bar), - "show-marks", FALSE, - "extended", FALSE, - NULL); + /* 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; - /* By default channel bars use speaker icons, use microphone - * icons instead for recording applications */ - if (flags & MATE_MIXER_STREAM_INPUT) - g_object_set (G_OBJECT (bar), - "low-icon-name", "audio-input-microphone-low", - "high-icon-name", "audio-input-microphone-high", - NULL); - - icon = mate_mixer_client_stream_get_app_icon (client); - if (icon == NULL) { - if (flags & MATE_MIXER_STREAM_INPUT) - icon = "audio-input-microphone"; - else - icon = "applications-multimedia"; - } + 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; - gvc_channel_bar_set_name (GVC_CHANNEL_BAR (bar), name); - gvc_channel_bar_set_icon_name (GVC_CHANNEL_BAR (bar), icon); + bar = create_bar (dialog, FALSE, FALSE); - gtk_box_pack_start (GTK_BOX (dialog->priv->applications_box), - bar, - FALSE, FALSE, 12); + g_object_set (G_OBJECT (bar), + "show-marks", FALSE, + "extended", FALSE, + NULL); - gtk_widget_hide (dialog->priv->no_apps_label); - dialog->priv->num_apps++; - } - } else { - GtkTreeModel *model = NULL; - GtkTreeIter iter; - MateMixerStream *input; - MateMixerStream *output; - const gchar *speakers = NULL; - gboolean is_default = FALSE; + /* 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); - input = mate_mixer_control_get_default_input_stream (dialog->priv->control); - output = mate_mixer_control_get_default_output_stream (dialog->priv->control); + 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); - if (flags & MATE_MIXER_STREAM_INPUT) { - if (stream == input) { - bar = dialog->priv->input_bar; + 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"; + } - update_input_settings (dialog); - is_default = TRUE; - } + gvc_channel_bar_set_name (GVC_CHANNEL_BAR (bar), app_name); + gvc_channel_bar_set_icon_name (GVC_CHANNEL_BAR (bar), app_icon); - model = gtk_tree_view_get_model (GTK_TREE_VIEW (dialog->priv->input_treeview)); - } - else if (flags & MATE_MIXER_STREAM_OUTPUT) { - if (stream == output) { - bar = dialog->priv->output_bar; + gtk_box_pack_start (GTK_BOX (dialog->priv->applications_box), + bar, + FALSE, FALSE, 12); - update_output_settings (dialog); - is_default = TRUE; - } + bar_set_stream (dialog, bar, stream); + dialog->priv->num_apps++; - model = gtk_tree_view_get_model (GTK_TREE_VIEW (dialog->priv->output_treeview)); - speakers = mvc_channel_map_to_pretty_string (stream); - } + gtk_widget_hide (dialog->priv->no_apps_label); + gtk_widget_show (bar); +} - if (model != NULL) { - const gchar *name; - const gchar *description; - - name = mate_mixer_stream_get_name (stream); - description = mate_mixer_stream_get_description (stream); - - gtk_list_store_append (GTK_LIST_STORE (model), &iter); - gtk_list_store_set (GTK_LIST_STORE (model), - &iter, - NAME_COLUMN, name, - DESCRIPTION_COLUMN, description, - ACTIVE_COLUMN, is_default, - SPEAKERS_COLUMN, speakers, - -1); - - g_signal_connect (stream, - "notify::description", - G_CALLBACK (on_stream_description_notify), - dialog); - } - } +static void +add_effects_control (GvcMixerDialog *dialog, MateMixerStreamControl *control) +{ + MateMixerStreamControl *previous; + const gchar *name; - if (bar != NULL) { - bar_set_stream (dialog, bar, stream); - gtk_widget_show (bar); + /* 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 MateMixerStream * -find_device_test_stream (GvcMixerDialog *dialog, MateMixerDevice *device) +static void +add_stream (GvcMixerDialog *dialog, MateMixerStream *stream) { - GList *streams; + GtkWidget *bar = NULL; + GtkTreeModel *model = NULL; + GtkTreeIter iter; + const gchar *speakers = NULL; + const GList *controls; + gboolean is_default = FALSE; + MateMixerDirection direction; - streams = (GList *) mate_mixer_control_list_streams (dialog->priv->control); - while (streams) { - MateMixerStream *stream; + direction = mate_mixer_stream_get_direction (stream); - stream = MATE_MIXER_STREAM (streams->data); + if (direction == MATE_MIXER_DIRECTION_INPUT) { + MateMixerStream *input; - if (mate_mixer_stream_get_device (stream) == device && - mate_mixer_stream_get_num_channels (stream) >= 1) { - MateMixerStreamFlags flags; + input = mate_mixer_context_get_default_input_stream (dialog->priv->context); + if (stream == input) { + bar = dialog->priv->input_bar; - flags = mate_mixer_stream_get_flags (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; - if ((flags & (MATE_MIXER_STREAM_OUTPUT | - MATE_MIXER_STREAM_CLIENT)) == MATE_MIXER_STREAM_OUTPUT) - return stream; + output = mate_mixer_context_get_default_output_stream (dialog->priv->context); + if (stream == output) { + bar = dialog->priv->output_bar; + + update_output_settings (dialog); + is_default = TRUE; } - streams = streams->next; + model = gtk_tree_view_get_model (GTK_TREE_VIEW (dialog->priv->output_treeview)); + + control = mate_mixer_stream_get_default_control (output); + if (G_LIKELY (control != NULL)) + speakers = mvc_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); + } + + if (bar != NULL) { + bar_set_stream (dialog, bar, stream); + gtk_widget_show (bar); } - return FALSE; } static void @@ -956,7 +991,6 @@ update_device_test_visibility (GvcMixerDialog *dialog) device = g_object_get_data (G_OBJECT (dialog->priv->hw_profile_combo), "device"); if (G_UNLIKELY (device == NULL)) { - g_warn_if_reached (); return; } @@ -968,26 +1002,49 @@ update_device_test_visibility (GvcMixerDialog *dialog) } static void -on_control_stream_added (MateMixerControl *control, +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) +{ +} + +static void +on_context_stream_added (MateMixerContext *context, const gchar *name, GvcMixerDialog *dialog) { - MateMixerStream *stream; - MateMixerStreamFlags flags; - GtkWidget *bar; + MateMixerStream *stream; + MateMixerDirection direction; + GtkWidget *bar; - stream = mate_mixer_control_get_stream (control, name); + stream = mate_mixer_context_get_stream (context, name); if (G_UNLIKELY (stream == NULL)) return; - flags = mate_mixer_stream_get_flags (stream); + 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 && - ((flags & (MATE_MIXER_STREAM_OUTPUT | - MATE_MIXER_STREAM_CLIENT)) == MATE_MIXER_STREAM_OUTPUT)) { + if (dialog->priv->hw_profile_combo != NULL && direction == MATE_MIXER_DIRECTION_OUTPUT) { MateMixerDevice *device1; MateMixerDevice *device2; @@ -1012,6 +1069,16 @@ on_control_stream_added (MateMixerControl *control, return; add_stream (dialog, stream); + + // XXX broken in libmatemixer? + 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 @@ -1024,26 +1091,14 @@ remove_stream (GvcMixerDialog *dialog, const gchar *name) /* Remove bars for applications and reset fixed bars */ bar = g_hash_table_lookup (dialog->priv->bars, name); - if (bar == dialog->priv->input_bar || bar == dialog->priv->output_bar) { - g_debug ("Removing stream %s from bar %s", - name, - gvc_channel_bar_get_name (GVC_CHANNEL_BAR (bar))); - - bar_set_stream (dialog, bar, NULL); - } else if (bar != NULL) { - g_debug ("Removing application stream %s", name); - - g_hash_table_remove (dialog->priv->bars, name); - gtk_container_remove (GTK_CONTAINER (gtk_widget_get_parent (bar)), bar); + if (bar != dialog->priv->input_bar && bar != dialog->priv->output_bar) + return; - if (G_UNLIKELY (dialog->priv->num_apps <= 0)) { - g_warn_if_reached (); - dialog->priv->num_apps = 1; - } + g_debug ("Removing stream %s from bar %s", + name, + gvc_channel_bar_get_name (GVC_CHANNEL_BAR (bar))); - if (--dialog->priv->num_apps == 0) - gtk_widget_show (dialog->priv->no_apps_label); - } + bar_set_stream (dialog, bar, NULL); /* Remove from any models */ model = gtk_tree_view_get_model (GTK_TREE_VIEW (dialog->priv->output_treeview)); @@ -1062,7 +1117,28 @@ remove_stream (GvcMixerDialog *dialog, const gchar *name) } static void -on_control_stream_removed (MateMixerControl *control, +remove_application_control (GvcMixerDialog *dialog, const gchar *name) +{ + GtkWidget *bar; + + bar = g_hash_table_lookup (dialog->priv->bars, name); + + g_debug ("Removing application stream %s", name); + + 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; + } + + 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) { @@ -1082,16 +1158,34 @@ on_control_stream_removed (MateMixerControl *control, } static void -on_control_cached_stream_removed (MateMixerControl *control, - const gchar *name, - GvcMixerDialog *dialog) +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 cached stream in the effects bar */ + /* We only use a stored control in the effects bar */ if (G_UNLIKELY (bar != dialog->priv->effects_bar)) { g_warn_if_reached (); return; @@ -1102,15 +1196,29 @@ on_control_cached_stream_removed (MateMixerControl *control, } static gchar * -device_profile_status (MateMixerDeviceProfile *profile) +device_status (MateMixerDevice *device) { - guint inputs; - guint outputs; - gchar *inputs_str = NULL; - gchar *outputs_str = NULL; + guint inputs = 0; + guint outputs = 0; + gchar *inputs_str = NULL; + gchar *outputs_str = NULL; + const GList *streams; - inputs = mate_mixer_device_profile_get_num_input_streams (profile); - outputs = mate_mixer_device_profile_get_num_output_streams (profile); + /* 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: @@ -1154,12 +1262,12 @@ device_profile_status (MateMixerDeviceProfile *profile) static void update_device_info (GvcMixerDialog *dialog, MateMixerDevice *device) { - GtkTreeModel *model = NULL; - GtkTreeIter iter; - MateMixerDeviceProfile *profile; - const gchar *description; - const gchar *profile_description = NULL; - gchar *profile_status = NULL; + 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)); @@ -1169,70 +1277,71 @@ update_device_info (GvcMixerDialog *dialog, MateMixerDevice *device) &iter) == FALSE) return; - description = mate_mixer_device_get_description (device); + label = mate_mixer_device_get_label (device); - profile = mate_mixer_device_get_active_profile (device); - if (profile != NULL) { - profile_description = mate_mixer_device_profile_get_description (profile); - profile_status = device_profile_status (profile); + 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_DESCRIPTION_COLUMN, description, - HW_PROFILE_COLUMN, profile_description, - HW_STATUS_COLUMN, profile_status, + HW_LABEL_COLUMN, label, + HW_PROFILE_COLUMN, profile_label, + HW_STATUS_COLUMN, status, -1); - - g_free (profile_status); + g_free (status); } static void -on_device_profile_notify (MateMixerDevice *device, +on_device_profile_notify (MateMixerSwitch *swtch, GParamSpec *pspec, GvcMixerDialog *dialog) { - MateMixerDeviceProfile *profile; - - g_debug ("Device profile has changed"); + MateMixerSwitchOption *active; g_signal_handlers_block_by_func (G_OBJECT (dialog->priv->hw_profile_combo), - G_CALLBACK (on_combo_box_profile_changed), + G_CALLBACK (on_combobox_option_changed), dialog); - profile = mate_mixer_device_get_active_profile (device); - if (G_LIKELY (profile != NULL)) { - const gchar *name = mate_mixer_device_profile_get_name (profile); - - g_debug ("The current profile is %s", name); + 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_combo_box_profile_changed), + G_CALLBACK (on_combobox_option_changed), dialog); - update_device_info (dialog, device); + // XXX find device + // update_device_info (dialog, device); } static void add_device (GvcMixerDialog *dialog, MateMixerDevice *device) { - GtkTreeModel *model; - GtkTreeIter iter; - MateMixerDeviceProfile *profile; - GIcon *icon; - const gchar *name; - const gchar *description; - const gchar *profile_description = NULL; - gchar *profile_status = NULL; + 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); - description = mate_mixer_device_get_description (device); + 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, @@ -1242,35 +1351,40 @@ add_device (GvcMixerDialog *dialog, MateMixerDevice *device) icon = g_themed_icon_new_with_default_fallbacks (mate_mixer_device_get_icon (device)); - profile = mate_mixer_device_get_active_profile (device); - if (profile != NULL) { - profile_description = mate_mixer_device_profile_get_description (profile); - profile_status = device_profile_status (profile); + 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_DESCRIPTION_COLUMN, description, + HW_LABEL_COLUMN, label, HW_ICON_COLUMN, icon, - HW_PROFILE_COLUMN, profile_description, - HW_STATUS_COLUMN, profile_status, + HW_PROFILE_COLUMN, profile_label, + HW_STATUS_COLUMN, status, -1); + g_free (status); - g_free (profile_status); - - g_signal_connect (device, - "notify::active-profile", - G_CALLBACK (on_device_profile_notify), - dialog); } static void -on_control_device_added (MateMixerControl *control, const gchar *name, GvcMixerDialog *dialog) +on_context_device_added (MateMixerContext *context, const gchar *name, GvcMixerDialog *dialog) { MateMixerDevice *device; - device = mate_mixer_control_get_device (control, name); + device = mate_mixer_context_get_device (context, name); if (G_UNLIKELY (device == NULL)) return; @@ -1278,14 +1392,14 @@ on_control_device_added (MateMixerControl *control, const gchar *name, GvcMixerD } static void -on_control_device_removed (MateMixerControl *control, +on_context_device_removed (MateMixerContext *context, const gchar *name, GvcMixerDialog *dialog) { GtkTreeIter iter; GtkTreeModel *model; - /* Remove from any models */ + /* 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), @@ -1338,9 +1452,10 @@ on_input_radio_toggled (GtkCellRendererToggle *renderer, ACTIVE_COLUMN, &toggled, -1); if (toggled ^ 1) { - MateMixerStream *stream; + MateMixerStream *stream; + MateMixerBackendFlags flags; - stream = mate_mixer_control_get_stream (dialog->priv->control, name); + stream = mate_mixer_context_get_stream (dialog->priv->context, name); if (G_UNLIKELY (stream == NULL)) { g_warn_if_reached (); g_free (name); @@ -1348,7 +1463,14 @@ on_input_radio_toggled (GtkCellRendererToggle *renderer, } g_debug ("Default input stream selection changed to %s", name); - mate_mixer_control_set_default_input_stream (dialog->priv->control, stream); + + // 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); } @@ -1375,9 +1497,10 @@ on_output_radio_toggled (GtkCellRendererToggle *renderer, ACTIVE_COLUMN, &toggled, -1); if (toggled ^ 1) { - MateMixerStream *stream; + MateMixerStream *stream; + MateMixerBackendFlags flags; - stream = mate_mixer_control_get_stream (dialog->priv->control, name); + stream = mate_mixer_context_get_stream (dialog->priv->context, name); if (G_UNLIKELY (stream == NULL)) { g_warn_if_reached (); g_free (name); @@ -1385,7 +1508,14 @@ on_output_radio_toggled (GtkCellRendererToggle *renderer, } g_debug ("Default output stream selection changed to %s", name); - mate_mixer_control_set_default_output_stream (dialog->priv->control, stream); + + // 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); } @@ -1397,27 +1527,27 @@ stream_name_to_text (GtkTreeViewColumn *column, GtkTreeIter *iter, gpointer user_data) { - gchar *description; + gchar *label; gchar *speakers; gtk_tree_model_get (model, iter, - DESCRIPTION_COLUMN, &description, + LABEL_COLUMN, &label, SPEAKERS_COLUMN, &speakers, -1); if (speakers != NULL) { gchar *str = g_strdup_printf ("%s\n<i>%s</i>", - description, + label, speakers); g_object_set (cell, "markup", str, NULL); g_free (str); g_free (speakers); } else { - g_object_set (cell, "text", description, NULL); + g_object_set (cell, "text", label, NULL); } - g_free (description); + g_free (label); } static gint @@ -1431,12 +1561,21 @@ compare_stream_treeview_items (GtkTreeModel *model, gint result; gtk_tree_model_get (model, a, - DESCRIPTION_COLUMN, &desc_a, + LABEL_COLUMN, &desc_a, -1); gtk_tree_model_get (model, b, - DESCRIPTION_COLUMN, &desc_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); @@ -1488,11 +1627,11 @@ create_stream_treeview (GvcMixerDialog *dialog, GCallback on_toggled) /* Keep the list of streams sorted by the name */ gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (store), - DESCRIPTION_COLUMN, + LABEL_COLUMN, GTK_SORT_ASCENDING); gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (store), - DESCRIPTION_COLUMN, + LABEL_COLUMN, compare_stream_treeview_items, NULL, NULL); return treeview; @@ -1521,7 +1660,7 @@ on_test_speakers_clicked (GvcComboBox *widget, GvcMixerDialog *dialog) } title = g_strdup_printf (_("Speaker Testing for %s"), - mate_mixer_device_get_description (device)); + mate_mixer_device_get_label (device)); d = gtk_dialog_new_with_buttons (title, GTK_WINDOW (dialog), @@ -1546,7 +1685,7 @@ on_test_speakers_clicked (GvcComboBox *widget, GvcMixerDialog *dialog) static GtkWidget * create_profile_combo_box (GvcMixerDialog *dialog, - MateMixerDevice *device, + MateMixerSwitch *swtch, const gchar *name, const GList *items, const gchar *active) @@ -1555,7 +1694,7 @@ create_profile_combo_box (GvcMixerDialog *dialog, combobox = gvc_combo_box_new (name); - gvc_combo_box_set_profiles (GVC_COMBO_BOX (combobox), items); + 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), @@ -1567,13 +1706,13 @@ create_profile_combo_box (GvcMixerDialog *dialog, NULL); g_object_set_data_full (G_OBJECT (combobox), - "device", - g_object_ref (device), + "switch", + g_object_ref (swtch), g_object_unref); g_signal_connect (G_OBJECT (combobox), "changed", - G_CALLBACK (on_combo_box_profile_changed), + G_CALLBACK (on_combobox_option_changed), dialog); g_signal_connect (G_OBJECT (combobox), @@ -1590,7 +1729,7 @@ on_device_selection_changed (GtkTreeSelection *selection, GvcMixerDialog *dialog GtkTreeIter iter; gchar *name; MateMixerDevice *device; - MateMixerBackendType backend; + MateMixerSwitch *profile_switch; g_debug ("Device selection changed"); @@ -1609,7 +1748,7 @@ on_device_selection_changed (GtkTreeSelection *selection, GvcMixerDialog *dialog HW_NAME_COLUMN, &name, -1); - device = mate_mixer_control_get_device (dialog->priv->control, name); + device = mate_mixer_context_get_device (dialog->priv->context, name); if (G_UNLIKELY (device == NULL)) { g_warn_if_reached (); g_free (name); @@ -1617,35 +1756,24 @@ on_device_selection_changed (GtkTreeSelection *selection, GvcMixerDialog *dialog } g_free (name); - backend = mate_mixer_control_get_backend_type (dialog->priv->control); - - /* Speaker test is only possible on PulseAudio and profile changing is - * not supported on other backends by libmatemixer, so avoid displaying - * the combo box on other backends */ - if (backend == MATE_MIXER_BACKEND_PULSEAUDIO) { - const GList *profiles; - const gchar *profile_name = NULL; + /* 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; - profiles = mate_mixer_device_list_profiles (device); - if (profiles != NULL) { - MateMixerDeviceProfile *profile; - - profile = mate_mixer_device_get_active_profile (device); - if (G_UNLIKELY (profile == NULL)) { - /* Select the first profile if none is selected */ - profile = MATE_MIXER_DEVICE_PROFILE (profiles->data); - mate_mixer_device_set_active_profile (device, profile); - } - - profile_name = mate_mixer_device_profile_get_name (profile); - } + 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, - device, + profile_switch, _("_Profile:"), - profiles, - profile_name); + options, + active_name); gtk_box_pack_start (GTK_BOX (dialog->priv->hw_settings_box), dialog->priv->hw_profile_combo, @@ -1665,16 +1793,20 @@ on_notebook_switch_page (GtkNotebook *notebook, guint page_num, GvcMixerDialog *dialog) { - MateMixerStream *stream; + MateMixerStreamControl *control; - stream = mate_mixer_control_get_default_input_stream (dialog->priv->control); - if (stream == NULL) + // 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_monitor_start (stream); + mate_mixer_stream_control_set_monitor_enabled (control, TRUE); else - mate_mixer_stream_monitor_stop (stream); + mate_mixer_stream_control_set_monitor_enabled (control, FALSE); } static void @@ -1684,37 +1816,37 @@ device_name_to_text (GtkTreeViewColumn *column, GtkTreeIter *iter, gpointer user_data) { - gchar *description = NULL; + gchar *label = NULL; gchar *profile = NULL; - gchar *profile_status = NULL; + gchar *status = NULL; gtk_tree_model_get (model, iter, - HW_DESCRIPTION_COLUMN, &description, + HW_LABEL_COLUMN, &label, HW_PROFILE_COLUMN, &profile, - HW_STATUS_COLUMN, &profile_status, + HW_STATUS_COLUMN, &status, -1); - if (profile != NULL) { + if (G_LIKELY (status != NULL)) { gchar *str; - if (G_LIKELY (profile_status != NULL)) + if (profile != NULL) str = g_strdup_printf ("%s\n<i>%s</i>\n<i>%s</i>", - description, - profile_status, + label, + status, profile); else str = g_strdup_printf ("%s\n<i>%s</i>", - description, - profile); + label, + status); g_object_set (cell, "markup", str, NULL); g_free (str); g_free (profile); - g_free (profile_status); + g_free (status); } else - g_object_set (cell, "text", description, NULL); + g_object_set (cell, "text", label, NULL); - g_free (description); + g_free (label); } static gint @@ -1728,10 +1860,10 @@ compare_device_treeview_items (GtkTreeModel *model, gint result; gtk_tree_model_get (model, a, - HW_DESCRIPTION_COLUMN, &desc_a, + HW_LABEL_COLUMN, &desc_a, -1); gtk_tree_model_get (model, b, - HW_DESCRIPTION_COLUMN, &desc_b, + HW_LABEL_COLUMN, &desc_b, -1); result = g_ascii_strcasecmp (desc_a, desc_b); @@ -1789,11 +1921,11 @@ create_device_treeview (GvcMixerDialog *dialog, GCallback on_changed) /* Keep the list of streams sorted by the name */ gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (store), - HW_DESCRIPTION_COLUMN, + HW_LABEL_COLUMN, GTK_SORT_ASCENDING); gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (store), - HW_DESCRIPTION_COLUMN, + HW_LABEL_COLUMN, compare_device_treeview_items, NULL, NULL); return treeview; @@ -1838,7 +1970,7 @@ gvc_mixer_dialog_constructor (GType type, GClosure *closure; GtkTreeIter iter; gint i; - GList *list; + const GList *list; object = G_OBJECT_CLASS (gvc_mixer_dialog_parent_class)->constructor (type, n_construct_properties, @@ -2172,30 +2304,30 @@ gvc_mixer_dialog_constructor (GType type, gtk_widget_show_all (main_vbox); - // XXX subscribe to cached stream stuff, in case event stream is not found - - list = (GList *) mate_mixer_control_list_streams (self->priv->control); - while (list) { + list = mate_mixer_context_list_streams (self->priv->context); + while (list != NULL) { add_stream (self, MATE_MIXER_STREAM (list->data)); list = list->next; } - list = (GList *) mate_mixer_control_list_devices (self->priv->control); - while (list) { + 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 = (GList *) mate_mixer_control_list_cached_streams (self->priv->control); - while (list) { - MateMixerClientStreamRole role; - - role = mate_mixer_client_stream_get_role (MATE_MIXER_CLIENT_STREAM (list->data)); + list = mate_mixer_context_list_stored_controls (self->priv->context); + while (list != NULL) { + MateMixerStreamControl *control = MATE_MIXER_STREAM_CONTROL (list->data); + MateMixerStreamControlMediaRole media_role; - if (role == MATE_MIXER_CLIENT_STREAM_ROLE_EVENT) - add_stream (self, MATE_MIXER_STREAM (list->data)); + 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; } @@ -2214,59 +2346,54 @@ gvc_mixer_dialog_constructor (GType type, return object; } -static MateMixerControl * -gvc_mixer_dialog_get_control (GvcMixerDialog *dialog) +static MateMixerContext * +gvc_mixer_dialog_get_context (GvcMixerDialog *dialog) { - return dialog->priv->control; + return dialog->priv->context; } static void -gvc_mixer_dialog_set_control (GvcMixerDialog *dialog, MateMixerControl *control) +gvc_mixer_dialog_set_context (GvcMixerDialog *dialog, MateMixerContext *context) { - MateMixerState state; - - state = mate_mixer_control_get_state (control); - - if (G_UNLIKELY (state != MATE_MIXER_STATE_READY)) - g_warn_if_reached (); + dialog->priv->context = g_object_ref (context); - dialog->priv->control = g_object_ref (control); - - g_signal_connect (G_OBJECT (dialog->priv->control), + g_signal_connect (G_OBJECT (dialog->priv->context), "stream-added", - G_CALLBACK (on_control_stream_added), - dialog); - g_signal_connect (G_OBJECT (dialog->priv->control), - "cached-stream-added", - G_CALLBACK (on_control_stream_added), + G_CALLBACK (on_context_stream_added), dialog); - g_signal_connect (G_OBJECT (dialog->priv->control), + g_signal_connect (G_OBJECT (dialog->priv->context), "stream-removed", - G_CALLBACK (on_control_stream_removed), - dialog); - g_signal_connect (G_OBJECT (dialog->priv->control), - "cached-stream-removed", - G_CALLBACK (on_control_cached_stream_removed), + G_CALLBACK (on_context_stream_removed), dialog); - g_signal_connect (G_OBJECT (dialog->priv->control), + + g_signal_connect (G_OBJECT (dialog->priv->context), "device-added", - G_CALLBACK (on_control_device_added), + G_CALLBACK (on_context_device_added), dialog); - g_signal_connect (G_OBJECT (dialog->priv->control), + g_signal_connect (G_OBJECT (dialog->priv->context), "device-removed", - G_CALLBACK (on_control_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->control), - "notify::default-output", - G_CALLBACK (on_control_default_output_notify), + 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->control), - "notify::default-input", - G_CALLBACK (on_control_default_input_notify), + 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), "control"); + g_object_notify (G_OBJECT (dialog), "context"); } static void @@ -2278,8 +2405,8 @@ gvc_mixer_dialog_set_property (GObject *object, GvcMixerDialog *self = GVC_MIXER_DIALOG (object); switch (prop_id) { - case PROP_CONTROL: - gvc_mixer_dialog_set_control (self, g_value_get_object (value)); + 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); @@ -2296,8 +2423,8 @@ gvc_mixer_dialog_get_property (GObject *object, GvcMixerDialog *self = GVC_MIXER_DIALOG (object); switch (prop_id) { - case PROP_CONTROL: - g_value_set_object (value, gvc_mixer_dialog_get_control (self)); + 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); @@ -2310,21 +2437,11 @@ gvc_mixer_dialog_dispose (GObject *object) { GvcMixerDialog *dialog = GVC_MIXER_DIALOG (object); - if (dialog->priv->control != NULL) { - g_signal_handlers_disconnect_by_func (dialog->priv->control, - on_control_stream_added, - dialog); - g_signal_handlers_disconnect_by_func (dialog->priv->control, - on_control_stream_removed, - dialog); - g_signal_handlers_disconnect_by_func (dialog->priv->control, - on_control_device_added, - dialog); - g_signal_handlers_disconnect_by_func (dialog->priv->control, - on_control_device_removed, + if (dialog->priv->context != NULL) { + g_signal_handlers_disconnect_by_data (G_OBJECT (dialog->priv->context), dialog); - g_clear_object (&dialog->priv->control); + g_clear_object (&dialog->priv->context); } G_OBJECT_CLASS (gvc_mixer_dialog_parent_class)->dispose (object); @@ -2342,13 +2459,14 @@ gvc_mixer_dialog_class_init (GvcMixerDialogClass *klass) object_class->get_property = gvc_mixer_dialog_get_property; g_object_class_install_property (object_class, - PROP_CONTROL, - g_param_spec_object ("control", - "Control", - "MateMixer control", - MATE_MIXER_TYPE_CONTROL, + PROP_CONTEXT, + g_param_spec_object ("context", + "Context", + "MateMixer context", + MATE_MIXER_TYPE_CONTEXT, G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY)); + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); g_type_class_add_private (klass, sizeof (GvcMixerDialogPrivate)); } @@ -2375,12 +2493,12 @@ gvc_mixer_dialog_finalize (GObject *object) } GvcMixerDialog * -gvc_mixer_dialog_new (MateMixerControl *control) +gvc_mixer_dialog_new (MateMixerContext *context) { return g_object_new (GVC_TYPE_MIXER_DIALOG, "icon-name", "multimedia-volume-control", "title", _("Sound Preferences"), - "control", control, + "context", context, NULL); } diff --git a/mate-volume-control/src/gvc-mixer-dialog.h b/mate-volume-control/src/gvc-mixer-dialog.h index c494c1a..22e522d 100644 --- a/mate-volume-control/src/gvc-mixer-dialog.h +++ b/mate-volume-control/src/gvc-mixer-dialog.h @@ -55,7 +55,7 @@ struct _GvcMixerDialogClass GType gvc_mixer_dialog_get_type (void) G_GNUC_CONST; -GvcMixerDialog * gvc_mixer_dialog_new (MateMixerControl *control); +GvcMixerDialog * gvc_mixer_dialog_new (MateMixerContext *context); gboolean gvc_mixer_dialog_set_page (GvcMixerDialog *dialog, const gchar *page); diff --git a/mate-volume-control/src/gvc-speaker-test.c b/mate-volume-control/src/gvc-speaker-test.c index 61fd510..d43b6cf 100644 --- a/mate-volume-control/src/gvc-speaker-test.c +++ b/mate-volume-control/src/gvc-speaker-test.c @@ -42,7 +42,6 @@ struct _GvcSpeakerTestPrivate { GArray *controls; ca_context *canberra; - MateMixerControl *control; MateMixerStream *stream; }; @@ -98,16 +97,18 @@ gvc_speaker_test_get_stream (GvcSpeakerTest *test) static void gvc_speaker_test_set_stream (GvcSpeakerTest *test, MateMixerStream *stream) { - guint i; - const gchar *name; + 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_has_channel_position (stream, positions[i].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); diff --git a/mate-volume-control/src/gvc-stream-status-icon.c b/mate-volume-control/src/gvc-stream-status-icon.c index c85df0c..b7c1b73 100644 --- a/mate-volume-control/src/gvc-stream-status-icon.c +++ b/mate-volume-control/src/gvc-stream-status-icon.c @@ -42,13 +42,13 @@ struct _GvcStreamStatusIconPrivate GtkWidget *bar; guint current_icon; gchar *display_name; - MateMixerStream *stream; + MateMixerStreamControl *control; }; enum { PROP_0, - PROP_STREAM, + PROP_CONTROL, PROP_DISPLAY_NAME, PROP_ICON_NAMES, N_PROPERTIES @@ -195,9 +195,9 @@ on_status_icon_button_press (GtkStatusIcon *status_icon, { /* Middle click acts as mute/unmute */ if (event->button == 2) { - gboolean is_muted = mate_mixer_stream_get_mute (icon->priv->stream); + gboolean is_muted = mate_mixer_stream_control_get_mute (icon->priv->control); - mate_mixer_stream_set_mute (icon->priv->stream, !is_muted); + mate_mixer_stream_control_set_mute (icon->priv->control, !is_muted); return TRUE; } return FALSE; @@ -210,7 +210,7 @@ on_menu_mute_toggled (GtkMenuItem *item, GvcStreamStatusIcon *icon) is_muted = gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (item)); - mate_mixer_stream_set_mute (icon->priv->stream, is_muted); + mate_mixer_stream_control_set_mute (icon->priv->control, is_muted); } static void @@ -255,7 +255,7 @@ on_status_icon_popup_menu (GtkStatusIcon *status_icon, item = gtk_check_menu_item_new_with_mnemonic (_("_Mute")); gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), - mate_mixer_stream_get_mute (icon->priv->stream)); + mate_mixer_stream_control_get_mute (icon->priv->control)); g_signal_connect (G_OBJECT (item), "toggled", G_CALLBACK (on_menu_mute_toggled), @@ -420,9 +420,9 @@ update_icon (GvcStreamStatusIcon *icon) guint n = 0; gchar *markup; const gchar *description; - MateMixerStreamFlags flags; + MateMixerStreamControlFlags flags; - if (icon->priv->stream == NULL) { + 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); @@ -430,14 +430,14 @@ update_icon (GvcStreamStatusIcon *icon) } else gtk_status_icon_set_has_tooltip (GTK_STATUS_ICON (icon), TRUE); - flags = mate_mixer_stream_get_flags (icon->priv->stream); + flags = mate_mixer_stream_control_get_flags (icon->priv->control); - if (flags & MATE_MIXER_STREAM_HAS_MUTE) - muted = mate_mixer_stream_get_mute (icon->priv->stream); + if (flags & MATE_MIXER_STREAM_CONTROL_MUTE_READABLE) + muted = mate_mixer_stream_control_get_mute (icon->priv->control); - if (flags & MATE_MIXER_STREAM_HAS_VOLUME) { - volume = mate_mixer_stream_get_volume (icon->priv->stream); - normal = mate_mixer_stream_get_normal_volume (icon->priv->stream); + 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 */ @@ -446,8 +446,8 @@ update_icon (GvcStreamStatusIcon *icon) else n = CLAMP (3 * volume / normal + 1, 1, 3); } - if (flags & MATE_MIXER_STREAM_HAS_DECIBEL_VOLUME) - decibel = mate_mixer_stream_get_decibel (icon->priv->stream); + 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) { @@ -456,17 +456,17 @@ update_icon (GvcStreamStatusIcon *icon) icon->priv->current_icon = n; } - description = mate_mixer_stream_get_description (icon->priv->stream); + 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_HAS_VOLUME) { + } else if (flags & MATE_MIXER_STREAM_CONTROL_VOLUME_READABLE) { gdouble display_volume = 100 * volume / normal; - if (flags & MATE_MIXER_STREAM_HAS_DECIBEL_VOLUME) { + 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>", @@ -523,7 +523,7 @@ gvc_stream_status_icon_set_icon_names (GvcStreamStatusIcon *icon, } static void -on_stream_volume_notify (MateMixerStream *stream, +on_stream_control_volume_notify (MateMixerStreamControl *control, GParamSpec *pspec, GvcStreamStatusIcon *icon) { @@ -531,7 +531,7 @@ on_stream_volume_notify (MateMixerStream *stream, } static void -on_stream_mute_notify (MateMixerStream *stream, +on_stream_control_mute_notify (MateMixerStreamControl *control, GParamSpec *pspec, GvcStreamStatusIcon *icon) { @@ -553,47 +553,47 @@ gvc_stream_status_icon_set_display_name (GvcStreamStatusIcon *icon, } void -gvc_stream_status_icon_set_stream (GvcStreamStatusIcon *icon, - MateMixerStream *stream) +gvc_stream_status_icon_set_control (GvcStreamStatusIcon *icon, + MateMixerStreamControl *control) { g_return_if_fail (GVC_STREAM_STATUS_ICON (icon)); - if (icon->priv->stream == stream) + if (icon->priv->control == control) return; - if (stream != NULL) - g_object_ref (stream); + if (control != NULL) + g_object_ref (control); - if (icon->priv->stream != NULL) { - g_signal_handlers_disconnect_by_func (icon->priv->stream, - G_CALLBACK (on_stream_volume_notify), + 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 (icon->priv->stream, - G_CALLBACK (on_stream_mute_notify), + g_signal_handlers_disconnect_by_func (G_OBJECT (icon->priv->control), + G_CALLBACK (on_stream_control_mute_notify), icon); - g_object_unref (icon->priv->stream); + g_object_unref (icon->priv->control); } - icon->priv->stream = stream; + icon->priv->control = control; - if (icon->priv->stream != NULL) { - g_signal_connect (icon->priv->stream, + if (icon->priv->control != NULL) { + g_signal_connect (G_OBJECT (icon->priv->control), "notify::volume", - G_CALLBACK (on_stream_volume_notify), + G_CALLBACK (on_stream_control_volume_notify), icon); - g_signal_connect (icon->priv->stream, + g_signal_connect (G_OBJECT (icon->priv->control), "notify::mute", - G_CALLBACK (on_stream_mute_notify), + 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_stream (GVC_CHANNEL_BAR (icon->priv->bar), stream); + gvc_channel_bar_set_control (GVC_CHANNEL_BAR (icon->priv->bar), icon->priv->control); - g_object_notify_by_pspec (G_OBJECT (icon), properties[PROP_STREAM]); + g_object_notify_by_pspec (G_OBJECT (icon), properties[PROP_CONTROL]); } static void @@ -605,8 +605,8 @@ gvc_stream_status_icon_set_property (GObject *object, GvcStreamStatusIcon *self = GVC_STREAM_STATUS_ICON (object); switch (prop_id) { - case PROP_STREAM: - gvc_stream_status_icon_set_stream (self, g_value_get_object (value)); + 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)); @@ -629,8 +629,8 @@ gvc_stream_status_icon_get_property (GObject *object, GvcStreamStatusIcon *self = GVC_STREAM_STATUS_ICON (object); switch (prop_id) { - case PROP_STREAM: - g_value_set_object (value, self->priv->stream); + 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); @@ -654,7 +654,7 @@ gvc_stream_status_icon_dispose (GObject *object) icon->priv->dock = NULL; } - g_clear_object (&icon->priv->stream); + g_clear_object (&icon->priv->control); G_OBJECT_CLASS (gvc_stream_status_icon_parent_class)->dispose (object); } @@ -669,26 +669,32 @@ gvc_stream_status_icon_class_init (GvcStreamStatusIconClass *klass) object_class->set_property = gvc_stream_status_icon_set_property; object_class->get_property = gvc_stream_status_icon_get_property; - properties[PROP_STREAM] = - g_param_spec_object ("stream", - "Stream", - "MateMixer stream", - MATE_MIXER_TYPE_STREAM, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT); + 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_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_READWRITE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS); g_object_class_install_properties (object_class, N_PROPERTIES, properties); @@ -791,11 +797,11 @@ gvc_stream_status_icon_finalize (GObject *object) } GvcStreamStatusIcon * -gvc_stream_status_icon_new (MateMixerStream *stream, - const gchar **icon_names) +gvc_stream_status_icon_new (MateMixerStreamControl *control, + const gchar **icon_names) { return g_object_new (GVC_TYPE_STREAM_STATUS_ICON, - "stream", stream, + "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 index 9b61898..7b51801 100644 --- a/mate-volume-control/src/gvc-stream-status-icon.h +++ b/mate-volume-control/src/gvc-stream-status-icon.h @@ -50,17 +50,18 @@ struct _GvcStreamStatusIconClass GtkStatusIconClass parent_class; }; -GType gvc_stream_status_icon_get_type (void) G_GNUC_CONST; +GType gvc_stream_status_icon_get_type (void) G_GNUC_CONST; -GvcStreamStatusIcon * gvc_stream_status_icon_new (MateMixerStream *stream, - const gchar **icon_names); +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, +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_stream (GvcStreamStatusIcon *icon, - MateMixerStream *stream); + +void gvc_stream_status_icon_set_control (GvcStreamStatusIcon *icon, + MateMixerStreamControl *control); G_END_DECLS diff --git a/mate-volume-control/src/mvc-helpers.c b/mate-volume-control/src/mvc-helpers.c index b82d6c8..7488743 100644 --- a/mate-volume-control/src/mvc-helpers.c +++ b/mate-volume-control/src/mvc-helpers.c @@ -100,14 +100,14 @@ mvc_channel_position_to_pretty_string (MateMixerChannelPosition position) } const gchar * -mvc_channel_map_to_pretty_string (MateMixerStream *stream) +mvc_channel_map_to_pretty_string (MateMixerStreamControl *control) { - g_return_val_if_fail (MATE_MIXER_IS_STREAM (stream), NULL); + g_return_val_if_fail (MATE_MIXER_IS_STREAM_CONTROL (control), NULL); -#define HAS_POSITION(p) (mate_mixer_stream_has_channel_position (stream, (p))) +#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_get_num_channels (stream)) { + switch (mate_mixer_stream_control_get_num_channels (control)) { case 1: if (HAS_POSITION (MATE_MIXER_CHANNEL_MONO)) return _("Mono"); diff --git a/mate-volume-control/src/mvc-helpers.h b/mate-volume-control/src/mvc-helpers.h index 16e48db..050e66b 100644 --- a/mate-volume-control/src/mvc-helpers.h +++ b/mate-volume-control/src/mvc-helpers.h @@ -29,7 +29,7 @@ G_BEGIN_DECLS const gchar *mvc_channel_position_to_string (MateMixerChannelPosition position); const gchar *mvc_channel_position_to_pretty_string (MateMixerChannelPosition position); -const gchar *mvc_channel_map_to_pretty_string (MateMixerStream *stream); +const gchar *mvc_channel_map_to_pretty_string (MateMixerStreamControl *control); #if GTK_CHECK_VERSION (3, 0, 0) void mvc_color_shade (GdkRGBA *a, |