From b35fa3cf5048d2f718739da55c8dc136e57150fb Mon Sep 17 00:00:00 2001 From: "Geoffrey D. Bennett" Date: Mon, 4 Dec 2023 00:49:44 +1030 Subject: [PATCH] Add input select widget for 4th Gen 2i2 and 4i4 --- src/iface-mixer.c | 16 ++++++-- src/widget-input-select.c | 77 +++++++++++++++++++++++++++++++++++++++ src/widget-input-select.h | 13 +++++++ 3 files changed, 103 insertions(+), 3 deletions(-) create mode 100644 src/widget-input-select.c create mode 100644 src/widget-input-select.h diff --git a/src/iface-mixer.c b/src/iface-mixer.c index ded58b8..1eabecf 100644 --- a/src/iface-mixer.c +++ b/src/iface-mixer.c @@ -9,6 +9,7 @@ #include "widget-combo.h" #include "widget-dual.h" #include "widget-gain.h" +#include "widget-input-select.h" #include "widget-label.h" #include "window-helper.h" #include "window-levels.h" @@ -339,6 +340,9 @@ static void create_input_controls( if (!input_count) return; + struct alsa_elem *input_select_elem = + get_elem_by_name(elems, "Input Select Capture Enum"); + GtkWidget *sep = gtk_separator_new(GTK_ORIENTATION_VERTICAL); gtk_widget_set_halign(sep, GTK_ALIGN_CENTER); gtk_grid_attach(GTK_GRID(top), sep, (*x)++, 0, 1, 3); @@ -354,9 +358,15 @@ static void create_input_controls( gtk_grid_attach(GTK_GRID(top), input_grid, *x, 2, 1, 1); for (int i = 1; i <= input_count; i++) { - char s[20]; - snprintf(s, 20, "%d", i); - GtkWidget *label = gtk_label_new(s); + GtkWidget *label; + + if (input_select_elem) { + label = make_input_select_alsa_elem(input_select_elem, i); + } else { + char s[20]; + snprintf(s, 20, "%d", i); + label = gtk_label_new(s); + } gtk_grid_attach(GTK_GRID(input_grid), label, i, 0, 1, 1); } diff --git a/src/widget-input-select.c b/src/widget-input-select.c new file mode 100644 index 0000000..5818967 --- /dev/null +++ b/src/widget-input-select.c @@ -0,0 +1,77 @@ +// SPDX-FileCopyrightText: 2023-2024 Geoffrey D. Bennett +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "stringhelper.h" +#include "widget-input-select.h" + +struct input_select { + struct alsa_elem *elem; + GtkWidget *button; + int line_num; +}; + +static void input_select_clicked( + GtkWidget *widget, + struct input_select *data +) { + int count = alsa_get_item_count(data->elem); + + // select the item that matches the line number that was clicked on + for (int i = 0; i < count; i++) { + const char *text = alsa_get_item_name(data->elem, i); + int a, b; + get_two_num_from_string(text, &a, &b); + + if ((b == -1 && a == data->line_num) || + (a <= data->line_num && b >= data->line_num)) { + alsa_set_elem_value(data->elem, i); + break; + } + } +} + +static void input_select_updated( + struct alsa_elem *elem, + void *private +) { + struct input_select *data = private; + int line_num = data->line_num; + int is_writable = alsa_get_elem_writable(elem); + + int value = alsa_get_elem_value(elem); + const char *text = alsa_get_item_name(elem, value); + + int a, b; + get_two_num_from_string(text, &a, &b); + + // set the button active if it's the selected line number + // (or in the range) + int active = b == -1 + ? a == line_num + : a <= line_num && b >= line_num; + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(data->button), active); + gtk_widget_set_sensitive(data->button, !active && is_writable); +} + +GtkWidget *make_input_select_alsa_elem( + struct alsa_elem *elem, + int line_num +) { + struct input_select *data = malloc(sizeof(struct input_select)); + data->elem = elem; + data->button = gtk_toggle_button_new(); + data->line_num = line_num; + + char s[20]; + snprintf(s, 20, "%d", line_num); + gtk_button_set_label(GTK_BUTTON(data->button), s); + + g_signal_connect( + data->button, "clicked", G_CALLBACK(input_select_clicked), data + ); + alsa_elem_add_callback(elem, input_select_updated, data); + + input_select_updated(elem, data); + + return data->button; +} diff --git a/src/widget-input-select.h b/src/widget-input-select.h new file mode 100644 index 0000000..833862d --- /dev/null +++ b/src/widget-input-select.h @@ -0,0 +1,13 @@ +// SPDX-FileCopyrightText: 2023-2024 Geoffrey D. Bennett +// SPDX-License-Identifier: GPL-3.0-or-later + +#pragma once + +#include + +#include "alsa.h" + +GtkWidget *make_input_select_alsa_elem( + struct alsa_elem *alsa_elem, + int line_num +);