mirror of
https://github.com/alsa-project/alsa-utils
synced 2024-11-14 05:45:41 +01:00
5b6b5fd14b
For multichannel mixer controls, add the channel name to each screen control. Also make some other small changes. Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
197 lines
4.4 KiB
C
197 lines
4.4 KiB
C
/*
|
|
* device_name_form.c - ask for sound control device name
|
|
* Copyright (c) Clemens Ladisch <clemens@ladisch.de>
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include "aconfig.h"
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include CURSESINC
|
|
#include <form.h>
|
|
#include "gettext_curses.h"
|
|
#include "die.h"
|
|
#include "mem.h"
|
|
#include "utils.h"
|
|
#include "colors.h"
|
|
#include "widget.h"
|
|
#include "mixer_widget.h"
|
|
#include "card_select.h"
|
|
#include "device_name.h"
|
|
|
|
static struct widget form_widget;
|
|
static FIELD *fields[3];
|
|
static FORM *form;
|
|
|
|
static char *dup_current_name(void)
|
|
{
|
|
int rows, cols, max, i;
|
|
char *s;
|
|
|
|
if (form_driver(form, REQ_VALIDATION) == E_OK) {
|
|
dynamic_field_info(fields[1], &rows, &cols, &max);
|
|
s = ccalloc(1, cols + 1);
|
|
memcpy(s, field_buffer(fields[1], 0), cols);
|
|
for (i = strlen(s) - 1; i >= 0 && s[i] == ' '; --i)
|
|
s[i] = '\0';
|
|
return s;
|
|
} else {
|
|
return cstrdup("");
|
|
}
|
|
}
|
|
|
|
static void on_key_enter(void)
|
|
{
|
|
char *s;
|
|
bool ok;
|
|
|
|
s = dup_current_name();
|
|
ok = select_card_by_name(s);
|
|
free(s);
|
|
if (ok) {
|
|
form_widget.close();
|
|
close_card_select_list();
|
|
}
|
|
}
|
|
|
|
static void on_form_key(int key)
|
|
{
|
|
static const struct {
|
|
int key;
|
|
int request;
|
|
} key_map[] = {
|
|
{ KEY_LEFT, REQ_PREV_CHAR },
|
|
{ KEY_RIGHT, REQ_NEXT_CHAR },
|
|
{ KEY_HOME, REQ_BEG_FIELD },
|
|
{ KEY_BACKSPACE, REQ_DEL_PREV },
|
|
{ KEY_DC, REQ_DEL_CHAR },
|
|
{ KEY_BEG, REQ_BEG_FIELD },
|
|
{ KEY_END, REQ_END_FIELD },
|
|
};
|
|
unsigned int i;
|
|
|
|
if (key >= 32 && key < 256) {
|
|
form_driver(form, key);
|
|
return;
|
|
}
|
|
for (i = 0; i < ARRAY_SIZE(key_map); ++i)
|
|
if (key_map[i].key == key) {
|
|
form_driver(form, key_map[i].request);
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void on_handle_key(int key)
|
|
{
|
|
switch (key) {
|
|
case 27:
|
|
case KEY_CANCEL:
|
|
form_widget.close();
|
|
break;
|
|
case 10:
|
|
case 13:
|
|
case KEY_ENTER:
|
|
on_key_enter();
|
|
break;
|
|
default:
|
|
on_form_key(key);
|
|
break;
|
|
}
|
|
}
|
|
|
|
static bool create(void)
|
|
{
|
|
const char *title;
|
|
|
|
if (screen_lines < 6 || screen_cols < 36) {
|
|
form_widget.close();
|
|
beep();
|
|
return FALSE;
|
|
}
|
|
widget_init(&form_widget,
|
|
6, 36, SCREEN_CENTER, SCREEN_CENTER,
|
|
attr_textbox, WIDGET_BORDER | WIDGET_SUBWINDOW | WIDGET_CURSOR_VISIBLE);
|
|
title = _("Sound Card");
|
|
mvwprintw(form_widget.window, 0, (36 - 2 - get_mbs_width(title)) / 2, " %s ", title);
|
|
|
|
set_form_win(form, form_widget.window);
|
|
set_form_sub(form, form_widget.subwindow);
|
|
return TRUE;
|
|
}
|
|
|
|
static void on_window_size_changed(void)
|
|
{
|
|
form_driver(form, REQ_VALIDATION); /* save field value */
|
|
unpost_form(form);
|
|
|
|
if (!create())
|
|
return;
|
|
|
|
/*
|
|
* This call fails because ncurses does not allow changing options of
|
|
* the current field, and we cannot change the current field because
|
|
* there is only one. The only way to make this work would be to throw
|
|
* away and recreate all fields.
|
|
*/
|
|
field_opts_off(fields[1], O_BLANK);
|
|
|
|
post_form(form);
|
|
}
|
|
|
|
static void on_close(void)
|
|
{
|
|
unpost_form(form);
|
|
free_form(form);
|
|
free_field(fields[0]);
|
|
free_field(fields[1]);
|
|
widget_free(&form_widget);
|
|
}
|
|
|
|
static struct widget form_widget = {
|
|
.handle_key = on_handle_key,
|
|
.window_size_changed = on_window_size_changed,
|
|
.close = on_close,
|
|
};
|
|
|
|
void create_device_name_form(void)
|
|
{
|
|
fields[0] = new_field(1, 32, 1, 1, 0, 0);
|
|
if (!fields[0])
|
|
fatal_error("cannot create field");
|
|
field_opts_off(fields[0], O_ACTIVE);
|
|
field_opts_off(fields[0], O_EDIT);
|
|
set_field_fore(fields[0], attr_textbox);
|
|
set_field_back(fields[0], attr_textbox);
|
|
set_field_buffer(fields[0], 0, _("Device name:"));
|
|
|
|
fields[1] = new_field(1, 32, 2, 1, 0, 0);
|
|
if (!fields[1])
|
|
fatal_error("cannot create field");
|
|
field_opts_off(fields[1], O_AUTOSKIP);
|
|
field_opts_off(fields[1], O_NULLOK);
|
|
field_opts_off(fields[1], O_STATIC);
|
|
set_field_fore(fields[1], attr_textfield);
|
|
set_field_back(fields[1], attr_textfield);
|
|
set_field_buffer(fields[1], 0, mixer_device_name);
|
|
|
|
form = new_form(fields);
|
|
if (!form)
|
|
fatal_error("cannot create form");
|
|
|
|
if (!create())
|
|
return;
|
|
|
|
post_form(form);
|
|
}
|