• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * device_name_form.c - ask for sound control device name
3  * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
4  *
5  * This program is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation, either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
17  */
18 
19 #include "aconfig.h"
20 #include <stdlib.h>
21 #include <string.h>
22 #include CURSESINC
23 #include <form.h>
24 #include "gettext_curses.h"
25 #include "die.h"
26 #include "mem.h"
27 #include "utils.h"
28 #include "colors.h"
29 #include "widget.h"
30 #include "mixer_widget.h"
31 #include "card_select.h"
32 #include "device_name.h"
33 
34 static struct widget form_widget;
35 static FIELD *fields[3];
36 static FORM *form;
37 
dup_current_name(void)38 static char *dup_current_name(void)
39 {
40 	int rows, cols, max, i;
41 	char *s;
42 
43 	if (form_driver(form, REQ_VALIDATION) == E_OK) {
44 		dynamic_field_info(fields[1], &rows, &cols, &max);
45 		s = ccalloc(1, cols + 1);
46 		memcpy(s, field_buffer(fields[1], 0), cols);
47 		for (i = strlen(s) - 1; i >= 0 && s[i] == ' '; --i)
48 			s[i] = '\0';
49 		return s;
50 	} else {
51 		return cstrdup("");
52 	}
53 }
54 
on_key_enter(void)55 static void on_key_enter(void)
56 {
57 	char *s;
58 	bool ok;
59 
60 	s = dup_current_name();
61 	ok = select_card_by_name(s);
62 	free(s);
63 	if (ok) {
64 		form_widget.close();
65 		close_card_select_list();
66 	}
67 }
68 
on_form_key(int key)69 static void on_form_key(int key)
70 {
71 	static const struct {
72 		int key;
73 		int request;
74 	} key_map[] = {
75 		{ KEY_LEFT, REQ_PREV_CHAR },
76 		{ KEY_RIGHT, REQ_NEXT_CHAR },
77 		{ KEY_HOME, REQ_BEG_FIELD },
78 		{ KEY_BACKSPACE, REQ_DEL_PREV },
79 		{ 127, REQ_DEL_PREV },
80 		{ KEY_DC, REQ_DEL_CHAR },
81 		{ KEY_BEG, REQ_BEG_FIELD },
82 		{ KEY_END, REQ_END_FIELD },
83 	};
84 	unsigned int i;
85 
86 	if (key >= 32 && key < 256 && key != 127) {
87 		form_driver(form, key);
88 		return;
89 	}
90 	for (i = 0; i < ARRAY_SIZE(key_map); ++i)
91 		if (key_map[i].key == key) {
92 			form_driver(form, key_map[i].request);
93 			break;
94 		}
95 }
96 
on_handle_key(int key)97 static void on_handle_key(int key)
98 {
99 	switch (key) {
100 	case 27:
101 	case KEY_CANCEL:
102 		form_widget.close();
103 		break;
104 	case 10:
105 	case 13:
106 	case KEY_ENTER:
107 		on_key_enter();
108 		break;
109 	default:
110 		on_form_key(key);
111 		break;
112 	}
113 }
114 
create(void)115 static bool create(void)
116 {
117 	const char *title;
118 
119 	if (screen_lines < 6 || screen_cols < 36) {
120 		form_widget.close();
121 		beep();
122 		return FALSE;
123 	}
124 	widget_init(&form_widget,
125 		    6, 36, SCREEN_CENTER, SCREEN_CENTER,
126 		    attrs.textbox, WIDGET_BORDER | WIDGET_SUBWINDOW | WIDGET_CURSOR_VISIBLE);
127 	title = _("Sound Card");
128 	mvwprintw(form_widget.window, 0, (36 - 2 - get_mbs_width(title)) / 2, " %s ", title);
129 
130 	set_form_win(form, form_widget.window);
131 	set_form_sub(form, form_widget.subwindow);
132 	return TRUE;
133 }
134 
on_window_size_changed(void)135 static void on_window_size_changed(void)
136 {
137 	form_driver(form, REQ_VALIDATION); /* save field value */
138 	unpost_form(form);
139 
140 	if (!create())
141 		return;
142 
143 	/*
144 	 * This call fails because ncurses does not allow changing options of
145 	 * the current field, and we cannot change the current field because
146 	 * there is only one.  The only way to make this work would be to throw
147 	 * away and recreate all fields.
148 	 */
149 	field_opts_off(fields[1], O_BLANK);
150 
151 	post_form(form);
152 }
153 
on_close(void)154 static void on_close(void)
155 {
156 	unpost_form(form);
157 	free_form(form);
158 	free_field(fields[0]);
159 	free_field(fields[1]);
160 	widget_free(&form_widget);
161 }
162 
163 static struct widget form_widget = {
164 	.handle_key = on_handle_key,
165 	.window_size_changed = on_window_size_changed,
166 	.close = on_close,
167 };
168 
create_device_name_form(void)169 void create_device_name_form(void)
170 {
171 	fields[0] = new_field(1, 32, 1, 1, 0, 0);
172 	if (!fields[0])
173 		fatal_error("cannot create field");
174 	field_opts_off(fields[0], O_ACTIVE|O_EDIT);
175 	set_field_fore(fields[0], attrs.textbox);
176 	set_field_back(fields[0], attrs.textbox);
177 	set_field_buffer(fields[0], 0, _("Device name:"));
178 
179 	fields[1] = new_field(1, 32, 2, 1, 0, 0);
180 	if (!fields[1])
181 		fatal_error("cannot create field");
182 	field_opts_off(fields[1], O_AUTOSKIP|O_NULLOK|O_STATIC);
183 	set_field_fore(fields[1], attrs.textfield);
184 	set_field_back(fields[1], attrs.textfield);
185 	set_field_buffer(fields[1], 0, mixer_device_name);
186 
187 	form = new_form(fields);
188 	if (!form)
189 		fatal_error("cannot create form");
190 
191 	if (!create())
192 		return;
193 
194 	post_form(form);
195 }
196