Remove widgets from struct alsa_elem and add data to callbacks

Rather than having widget/widget2/widget_callback fields in the struct
alsa_elem, have a list of callbacks and allow private data to be
passed to callbacks.
This commit is contained in:
Geoffrey D. Bennett
2023-12-03 04:53:34 +10:30
parent d56a1d34ff
commit 47034d7901
11 changed files with 222 additions and 126 deletions

View File

@@ -116,6 +116,20 @@ int is_elem_routing_snk(struct alsa_elem *elem) {
return 0;
}
// add a callback to the list of callbacks for this element
void alsa_elem_add_callback(
struct alsa_elem *elem,
AlsaElemCallback *callback,
void *data
) {
struct alsa_elem_callback *cb = calloc(1, sizeof(struct alsa_elem_callback));
cb->callback = callback;
cb->data = data;
elem->callbacks = g_list_append(elem->callbacks, cb);
}
//
// alsa snd_ctl_elem_*() mediation functions
// for simulated elements, fake the ALSA element
@@ -401,11 +415,17 @@ static void alsa_get_elem_list(struct alsa_card *card) {
}
static void alsa_elem_change(struct alsa_elem *elem) {
if (!elem->widget)
if (!elem || !elem->callbacks)
return;
if (!elem->widget_callback)
return;
elem->widget_callback(elem);
for (GList *l = elem->callbacks; l; l = l->next) {
struct alsa_elem_callback *cb = (struct alsa_elem_callback *)l->data;
if (!cb || !cb->callback)
continue;
cb->callback(elem, cb->data);
}
}
static gboolean alsa_card_callback(

View File

@@ -17,7 +17,7 @@ struct alsa_card;
// typedef for callbacks to update widgets when the alsa element
// notifies of a change
typedef void (AlsaElemCallback)(struct alsa_elem *);
typedef void (AlsaElemCallback)(struct alsa_elem *, void *);
// port categories for routing_src and routing_snk entries
// must match the level meter ordering from the driver
@@ -92,6 +92,12 @@ struct routing_snk {
// pointer back to the element this entry is associated with
struct alsa_elem *elem;
// box widget on the routing page
GtkWidget *box_widget;
// socket widget on the routing page
GtkWidget *socket_widget;
// PC_DSP, PC_MIX, PC_PCM, or PC_HW
int port_category;
@@ -103,6 +109,12 @@ struct routing_snk {
GtkWidget *mixer_label_bottom;
};
// hold one callback & its data
struct alsa_elem_callback {
AlsaElemCallback *callback;
void *data;
};
// entry in alsa_card elems (ALSA control elements) array
struct alsa_elem {
@@ -125,15 +137,8 @@ struct alsa_elem {
// TODO: move this to struct routing_snk?
int lr_num;
// the primary GTK widget and callback function for this ALSA
// control element
GtkWidget *widget;
AlsaElemCallback *widget_callback;
// text label for volume controls
// handle for routing controls
// second button for dual controls
GtkWidget *widget2;
// the callback functions for this ALSA control element
GList *callbacks;
// for boolean buttons, the two possible texts
// for dual buttons, the four possible texts
@@ -203,6 +208,13 @@ struct alsa_elem *get_elem_by_prefix(GArray *elems, char *prefix);
int get_max_elem_by_name(GArray *elems, char *prefix, char *needle);
int is_elem_routing_snk(struct alsa_elem *elem);
// add callback to alsa_elem callback list
void alsa_elem_add_callback(
struct alsa_elem *elem,
AlsaElemCallback *callback,
void *data
);
// alsa snd_ctl_elem_*() functions
int alsa_get_elem_type(struct alsa_elem *elem);
char *alsa_get_elem_name(struct alsa_elem *elem);

View File

@@ -92,18 +92,19 @@ static void add_speaker_switching_controls(
if (!speaker_switching)
return;
make_dual_boolean_alsa_elems(speaker_switching, "Off", "On", "Main", "Alt");
GtkWidget *b = gtk_box_new(GTK_ORIENTATION_VERTICAL, 5);
GtkWidget *w = make_dual_boolean_alsa_elems(
speaker_switching,
"Speaker Switching",
"Off", "On", "Main", "Alt"
);
gtk_widget_set_tooltip_text(
b,
w,
"Speaker Switching lets you swap between two pairs of "
"monitoring speakers very easily."
);
GtkWidget *l = gtk_label_new("Speaker Switching");
gtk_box_append(GTK_BOX(global_controls), b);
gtk_box_append(GTK_BOX(b), l);
gtk_box_append(GTK_BOX(b), speaker_switching->widget);
gtk_box_append(GTK_BOX(b), speaker_switching->widget2);
gtk_box_append(GTK_BOX(global_controls), w);
}
static void add_talkback_controls(
@@ -119,19 +120,20 @@ static void add_talkback_controls(
if (!talkback)
return;
make_dual_boolean_alsa_elems(talkback, "Disabled", "Enabled", "Off", "On");
GtkWidget *b = gtk_box_new(GTK_ORIENTATION_VERTICAL, 5);
GtkWidget *w = make_dual_boolean_alsa_elems(
talkback,
"Talkback",
"Disabled", "Enabled", "Off", "On"
);
gtk_widget_set_tooltip_text(
b,
w,
"Talkback lets you add another channel (usually the talkback "
"mic) to a mix with a button push, usually to talk to "
"musicians, and without using an additional mic channel."
);
GtkWidget *l = gtk_label_new("Talkback");
gtk_box_append(GTK_BOX(global_controls), b);
gtk_box_append(GTK_BOX(b), l);
gtk_box_append(GTK_BOX(b), talkback->widget);
gtk_box_append(GTK_BOX(b), talkback->widget2);
gtk_box_append(GTK_BOX(global_controls), w);
}
static GtkWidget *create_global_box(GtkWidget *grid, int *x, int orient) {
@@ -502,7 +504,7 @@ static void create_output_controls(
elem, "*audio-volume-high", "*audio-volume-muted"
);
gtk_widget_set_tooltip_text(w, "Mute HW controlled outputs");
gtk_grid_attach(GTK_GRID(output_grid), elem->widget, 0, 2, 1, 1);
gtk_grid_attach(GTK_GRID(output_grid), w, 0, 2, 1, 1);
} else if (strcmp(elem->name, "Dim Playback Switch") == 0) {
w = make_boolean_alsa_elem(
elem, "*audio-volume-medium", "*audio-volume-low"

View File

@@ -258,7 +258,7 @@ static void get_snk_center(
double *x,
double *y
) {
get_widget_center(r_snk->elem->widget2, parent, x, y);
get_widget_center(r_snk->socket_widget, parent, x, y);
if (IS_MIXER(r_snk->port_category))
(*y)++;
}

View File

@@ -3,32 +3,42 @@
#include "widget-boolean.h"
struct boolean {
struct alsa_elem *elem;
GtkWidget *button;
};
static void button_clicked(GtkWidget *widget, struct alsa_elem *elem) {
int value = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
alsa_set_elem_value(elem, value);
}
static void toggle_button_set_text(struct alsa_elem *elem, const char *text) {
static void toggle_button_set_text(GtkWidget *button, const char *text) {
if (!text)
return;
if (*text == '*') {
GtkWidget *icon = gtk_image_new_from_icon_name(text + 1);
gtk_button_set_child(GTK_BUTTON(elem->widget), icon);
gtk_button_set_child(GTK_BUTTON(button), icon);
} else {
gtk_button_set_label(GTK_BUTTON(elem->widget), text);
gtk_button_set_label(GTK_BUTTON(button), text);
}
}
static void toggle_button_updated(struct alsa_elem *elem) {
static void toggle_button_updated(
struct alsa_elem *elem,
void *private
) {
struct boolean *data = private;
int is_writable = alsa_get_elem_writable(elem);
gtk_widget_set_sensitive(elem->widget, is_writable);
gtk_widget_set_sensitive(data->button, is_writable);
int value = !!alsa_get_elem_value(elem);
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(elem->widget), value);
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(data->button), value);
toggle_button_set_text(elem, elem->bool_text[value]);
toggle_button_set_text(data->button, elem->bool_text[value]);
}
GtkWidget *make_boolean_alsa_elem(
@@ -36,23 +46,24 @@ GtkWidget *make_boolean_alsa_elem(
const char *disabled_text,
const char *enabled_text
) {
GtkWidget *button = gtk_toggle_button_new();
struct boolean *data = g_malloc(sizeof(struct boolean));
data->elem = elem;
data->button = gtk_toggle_button_new();
g_signal_connect(
button, "clicked", G_CALLBACK(button_clicked), elem
data->button, "clicked", G_CALLBACK(button_clicked), elem
);
elem->widget = button;
elem->widget_callback = toggle_button_updated;
alsa_elem_add_callback(elem, toggle_button_updated, data);
elem->bool_text[0] = disabled_text;
elem->bool_text[1] = enabled_text;
// find the maximum width and height of both possible labels
int max_width = 0, max_height = 0;
for (int i = 0; i < 2; i++) {
toggle_button_set_text(elem, elem->bool_text[i]);
toggle_button_set_text(data->button, elem->bool_text[i]);
GtkRequisition *size = gtk_requisition_new();
gtk_widget_get_preferred_size(button, size, NULL);
gtk_widget_get_preferred_size(data->button, size, NULL);
if (size->width > max_width)
max_width = size->width;
@@ -62,9 +73,9 @@ GtkWidget *make_boolean_alsa_elem(
// set the widget minimum size to the maximum label size so that the
// widget doesn't change size when the label changes
gtk_widget_set_size_request(button, max_width, max_height);
gtk_widget_set_size_request(data->button, max_width, max_height);
toggle_button_updated(elem);
toggle_button_updated(elem, data);
return button;
return data->button;
}

View File

@@ -3,15 +3,25 @@
#include "widget-combo.h"
static void combo_box_changed(GtkWidget *widget, struct alsa_elem *elem) {
int value = gtk_combo_box_get_active(GTK_COMBO_BOX(widget));
struct combo {
struct alsa_elem *elem;
GtkWidget *combo_box;
};
alsa_set_elem_value(elem, value);
static void combo_box_changed(GtkWidget *widget, struct combo *data) {
int value = gtk_combo_box_get_active(GTK_COMBO_BOX(data->combo_box));
alsa_set_elem_value(data->elem, value);
}
static void combo_box_updated(struct alsa_elem *elem) {
static void combo_box_updated(
struct alsa_elem *elem,
void *private
) {
struct combo *data = private;
int value = alsa_get_elem_value(elem);
gtk_combo_box_set_active(GTK_COMBO_BOX(elem->widget), value);
gtk_combo_box_set_active(GTK_COMBO_BOX(data->combo_box), value);
}
// Center-align text in the combo box
@@ -29,23 +39,26 @@ static void combo_box_center_text(GtkComboBoxText *widget) {
}
GtkWidget *make_combo_box_alsa_elem(struct alsa_elem *elem) {
GtkWidget *combo_box = gtk_combo_box_text_new();
combo_box_center_text(GTK_COMBO_BOX_TEXT(combo_box));
struct combo *data = g_malloc(sizeof(struct combo));
data->elem = elem;
data->combo_box = gtk_combo_box_text_new();
combo_box_center_text(GTK_COMBO_BOX_TEXT(data->combo_box));
int count = alsa_get_item_count(elem);
for (int i = 0; i < count; i++) {
const char *text = alsa_get_item_name(elem, i);
gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(combo_box), NULL, text);
gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(data->combo_box), NULL, text);
}
g_signal_connect(
combo_box, "changed", G_CALLBACK(combo_box_changed), elem
data->combo_box, "changed", G_CALLBACK(combo_box_changed), data
);
elem->widget = combo_box;
elem->widget_callback = combo_box_updated;
combo_box_updated(elem);
alsa_elem_add_callback(elem, combo_box_updated, data);
return combo_box;
combo_box_updated(elem, data);
return data->combo_box;
}

View File

@@ -3,18 +3,28 @@
#include "widget-dual.h"
static void dual_button_clicked(GtkWidget *widget, struct alsa_elem *elem) {
int value1 = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(elem->widget));
int value2 = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(elem->widget2));
struct dual_button {
struct alsa_elem *elem;
GtkWidget *button1;
GtkWidget *button2;
};
static void dual_button_clicked(GtkWidget *widget, struct dual_button *data) {
int value1 = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(data->button1));
int value2 = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(data->button2));
int value = value1 ? value2 + 1 : 0;
alsa_set_elem_value(elem, value);
alsa_set_elem_value(data->elem, value);
gtk_widget_set_sensitive(elem->widget2, value1);
gtk_widget_set_sensitive(data->button2, value1);
}
static void dual_button_updated(struct alsa_elem *elem) {
static void dual_button_updated(
struct alsa_elem *elem,
void *private
) {
struct dual_button *data = private;
// value (from ALSA control) is 0/1/2
// value1 (first button) is 0/1/1
@@ -22,14 +32,14 @@ static void dual_button_updated(struct alsa_elem *elem) {
int value = alsa_get_elem_value(elem);
int value1 = !!value;
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(elem->widget), value1);
gtk_button_set_label(GTK_BUTTON(elem->widget), elem->bool_text[value1]);
gtk_widget_set_sensitive(elem->widget2, value1);
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(data->button1), value1);
gtk_button_set_label(GTK_BUTTON(data->button1), elem->bool_text[value1]);
gtk_widget_set_sensitive(data->button2, value1);
if (value1) {
int value2 = value - 1;
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(elem->widget2), value2);
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(data->button2), value2);
gtk_button_set_label(
GTK_BUTTON(elem->widget2), elem->bool_text[value2 + 2]
GTK_BUTTON(data->button2), elem->bool_text[value2 + 2]
);
}
}
@@ -38,31 +48,40 @@ static void dual_button_updated(struct alsa_elem *elem) {
// buttons:
// first button disables/enables the feature
// second button switches between the two enabled states
void make_dual_boolean_alsa_elems(
GtkWidget *make_dual_boolean_alsa_elems(
struct alsa_elem *elem,
const char *label_text,
const char *disabled_text_1,
const char *enabled_text_1,
const char *disabled_text_2,
const char *enabled_text_2
) {
GtkWidget *button1 = gtk_toggle_button_new();
GtkWidget *button2 = gtk_toggle_button_new();
struct dual_button *data = g_malloc(sizeof(struct dual_button));
data->elem = elem;
data->button1 = gtk_toggle_button_new();
data->button2 = gtk_toggle_button_new();
g_signal_connect(
button1, "clicked", G_CALLBACK(dual_button_clicked), elem
data->button1, "clicked", G_CALLBACK(dual_button_clicked), data
);
g_signal_connect(
button2, "clicked", G_CALLBACK(dual_button_clicked), elem
data->button2, "clicked", G_CALLBACK(dual_button_clicked), data
);
elem->widget = button1;
elem->widget2 = button2;
elem->widget_callback = dual_button_updated;
alsa_elem_add_callback(elem, dual_button_updated, data);
elem->bool_text[0] = disabled_text_1;
elem->bool_text[1] = enabled_text_1;
elem->bool_text[2] = disabled_text_2;
elem->bool_text[3] = enabled_text_2;
gtk_button_set_label(GTK_BUTTON(elem->widget2), disabled_text_2);
gtk_button_set_label(GTK_BUTTON(data->button2), disabled_text_2);
dual_button_updated(elem);
dual_button_updated(elem, data);
GtkWidget *box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 5);
GtkWidget *label = gtk_label_new(label_text);
gtk_box_append(GTK_BOX(box), label);
gtk_box_append(GTK_BOX(box), GTK_WIDGET(data->button1));
gtk_box_append(GTK_BOX(box), GTK_WIDGET(data->button2));
return box;
}

View File

@@ -9,8 +9,9 @@
// buttons:
// first button disables/enables the feature
// second button switches between the two features states
void make_dual_boolean_alsa_elems(
GtkWidget *make_dual_boolean_alsa_elems(
struct alsa_elem *alsa_elem,
const char *label_text,
const char *disabled_text_1,
const char *enabled_text_1,
const char *disabled_text_2,

View File

@@ -4,18 +4,30 @@
#include "gtkdial.h"
#include "widget-gain.h"
static void gain_changed(GtkWidget *widget, struct alsa_elem *elem) {
int value = gtk_dial_get_value(GTK_DIAL(widget));
struct gain {
struct alsa_elem *elem;
GtkWidget *vbox;
GtkWidget *dial;
GtkWidget *label;
};
alsa_set_elem_value(elem, value);
static void gain_changed(GtkWidget *widget, struct gain *data) {
int value = gtk_dial_get_value(GTK_DIAL(data->dial));
alsa_set_elem_value(data->elem, value);
}
static void gain_updated(struct alsa_elem *elem) {
static void gain_updated(
struct alsa_elem *elem,
void *private
) {
struct gain *data = private;
int is_writable = alsa_get_elem_writable(elem);
gtk_widget_set_sensitive(elem->widget, is_writable);
gtk_widget_set_sensitive(data->dial, is_writable);
int alsa_value = alsa_get_elem_value(elem);
gtk_dial_set_value(GTK_DIAL(elem->widget), alsa_value);
gtk_dial_set_value(GTK_DIAL(data->dial), alsa_value);
char s[20];
float scale = (float)(elem->max_dB - elem->min_dB) /
@@ -28,39 +40,38 @@ static void gain_updated(struct alsa_elem *elem) {
else
snprintf(s, 20, "%.0fdB", value);
gtk_label_set_text(GTK_LABEL(elem->widget2), s);
gtk_label_set_text(GTK_LABEL(data->label), s);
}
//GList *make_gain_alsa_elem(struct alsa_elem *elem) {
GtkWidget *make_gain_alsa_elem(struct alsa_elem *elem) {
GtkWidget *vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
gtk_widget_set_hexpand(vbox, TRUE);
struct gain *data = g_malloc(sizeof(struct gain));
data->elem = elem;
data->vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
gtk_widget_set_hexpand(data->vbox, TRUE);
GtkWidget *dial = gtk_dial_new_with_range(
elem->min_val, elem->max_val, 1
);
data->dial = gtk_dial_new_with_range(elem->min_val, elem->max_val, 1);
// calculate 0dB value from min/max dB and min/max value
float scale = (float)(elem->max_dB - elem->min_dB) /
(elem->max_val - elem->min_val);
int zero_db_value = (int)((0 - elem->min_dB) / scale + elem->min_val);
gtk_dial_set_zero_db(GTK_DIAL(dial), zero_db_value);
gtk_dial_set_zero_db(GTK_DIAL(data->dial), zero_db_value);
gtk_widget_set_vexpand(dial, TRUE);
data->label = gtk_label_new(NULL);
gtk_widget_set_vexpand(data->dial, TRUE);
g_signal_connect(
dial, "value-changed", G_CALLBACK(gain_changed), elem
data->dial, "value-changed", G_CALLBACK(gain_changed), data
);
elem->widget = dial;
elem->widget_callback = gain_updated;
GtkWidget *label = gtk_label_new(NULL);
elem->widget2 = label;
alsa_elem_add_callback(elem, gain_updated, data);
gain_updated(elem);
gain_updated(elem, data);
gtk_box_append(GTK_BOX(vbox), dial);
gtk_box_append(GTK_BOX(vbox), label);
gtk_box_append(GTK_BOX(data->vbox), data->dial);
gtk_box_append(GTK_BOX(data->vbox), data->label);
return vbox;
return data->vbox;
}

View File

@@ -3,21 +3,29 @@
#include "widget-label.h"
static void label_updated(struct alsa_elem *elem) {
struct label {
struct alsa_elem *elem;
GtkWidget *label;
};
static void label_updated(struct alsa_elem *elem, void *private) {
struct label *data = private;
const char *text = alsa_get_item_name(elem, alsa_get_elem_value(elem));
gtk_label_set_text(GTK_LABEL(elem->widget), text);
gtk_label_set_text(GTK_LABEL(data->label), text);
}
GtkWidget *make_label_alsa_elem(struct alsa_elem *elem) {
GtkWidget *label = gtk_label_new(NULL);
gtk_widget_set_halign(label, GTK_ALIGN_CENTER);
gtk_widget_set_valign(label, GTK_ALIGN_CENTER);
struct label *data = g_malloc(sizeof(struct label));
data->label = gtk_label_new(NULL);
elem->widget = label;
elem->widget_callback = label_updated;
gtk_widget_set_halign(data->label, GTK_ALIGN_CENTER);
gtk_widget_set_valign(data->label, GTK_ALIGN_CENTER);
label_updated(elem);
alsa_elem_add_callback(elem, label_updated, data);
return label;
label_updated(elem, data);
return data->label;
}

View File

@@ -642,8 +642,7 @@ static void setup_src_drag(struct routing_src *r_src) {
}
static void setup_snk_drag(struct routing_snk *r_snk) {
struct alsa_elem *elem = r_snk->elem;
GtkWidget *box = elem->widget;
GtkWidget *box = r_snk->box_widget;
// handle drags on the box
GtkDragSource *source = gtk_drag_source_new();
@@ -670,7 +669,7 @@ static void setup_snk_drag(struct routing_snk *r_snk) {
// set the box as a drop target
GtkDropTarget *dest = gtk_drop_target_new(G_TYPE_INT, GDK_ACTION_COPY);
gtk_widget_add_controller(box, GTK_EVENT_CONTROLLER(dest));
g_signal_connect(dest, "drop", G_CALLBACK(dropped_on_snk), elem);
g_signal_connect(dest, "drop", G_CALLBACK(dropped_on_snk), r_snk->elem);
g_signal_connect(dest, "accept", G_CALLBACK(snk_drop_accept), r_snk);
g_signal_connect(dest, "enter", G_CALLBACK(snk_drop_enter), r_snk);
g_signal_connect(dest, "leave", G_CALLBACK(snk_drop_leave), r_snk);
@@ -747,11 +746,11 @@ static void make_snk_routing_widget(
struct alsa_elem *elem = r_snk->elem;
// create a box, a "socket", and a label
GtkWidget *box = elem->widget = gtk_box_new(orientation, 5);
GtkWidget *box = r_snk->box_widget = gtk_box_new(orientation, 5);
gtk_widget_add_css_class(box, "route-label");
GtkWidget *label = gtk_label_new(name);
gtk_box_append(GTK_BOX(box), label);
GtkWidget *socket = elem->widget2 = make_socket_widget();
GtkWidget *socket = r_snk->socket_widget = make_socket_widget();
if (orientation == GTK_ORIENTATION_VERTICAL) {
gtk_box_append(GTK_BOX(box), socket);
gtk_widget_set_margin_start(box, 5);
@@ -777,7 +776,7 @@ static void make_snk_routing_widget(
setup_snk_drag(r_snk);
}
static void routing_updated(struct alsa_elem *elem) {
static void routing_updated(struct alsa_elem *elem, void *data) {
struct alsa_card *card = elem->card;
update_mixer_labels(card);
@@ -797,7 +796,7 @@ static void make_routing_alsa_elem(struct routing_snk *r_snk) {
snprintf(name, 10, "%d", elem->lr_num);
make_snk_routing_widget(r_snk, name, GTK_ORIENTATION_VERTICAL);
gtk_grid_attach(
GTK_GRID(card->routing_dsp_in_grid), elem->widget,
GTK_GRID(card->routing_dsp_in_grid), r_snk->box_widget,
r_snk->port_num + 1, 0, 1, 1
);
@@ -810,7 +809,7 @@ static void make_routing_alsa_elem(struct routing_snk *r_snk) {
snprintf(name, 10, "%d", elem->lr_num);
make_snk_routing_widget(r_snk, name, GTK_ORIENTATION_VERTICAL);
gtk_grid_attach(
GTK_GRID(card->routing_mixer_in_grid), elem->widget,
GTK_GRID(card->routing_mixer_in_grid), r_snk->box_widget,
r_snk->port_num + 1, 0, 1, 1
);
@@ -828,7 +827,7 @@ static void make_routing_alsa_elem(struct routing_snk *r_snk) {
free(name);
gtk_grid_attach(
GTK_GRID(card->routing_pcm_out_grid), elem->widget,
GTK_GRID(card->routing_pcm_out_grid), r_snk->box_widget,
0, r_snk->port_num + 1, 1, 1
);
@@ -848,14 +847,14 @@ static void make_routing_alsa_elem(struct routing_snk *r_snk) {
free(name);
gtk_grid_attach(
GTK_GRID(card->routing_hw_out_grid), elem->widget,
GTK_GRID(card->routing_hw_out_grid), r_snk->box_widget,
0, r_snk->port_num + 1, 1, 1
);
} else {
printf("invalid port category %d\n", r_snk->port_category);
}
elem->widget_callback = routing_updated;
alsa_elem_add_callback(elem, routing_updated, NULL);
}
static void add_routing_widgets(