device_name.c (4553B)
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 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 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 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 { KEY_DC, REQ_DEL_CHAR }, 80 { KEY_BEG, REQ_BEG_FIELD }, 81 { KEY_END, REQ_END_FIELD }, 82 }; 83 unsigned int i; 84 85 if (key >= 32 && key < 256) { 86 form_driver(form, key); 87 return; 88 } 89 for (i = 0; i < ARRAY_SIZE(key_map); ++i) 90 if (key_map[i].key == key) { 91 form_driver(form, key_map[i].request); 92 break; 93 } 94 } 95 96 static void on_handle_key(int key) 97 { 98 switch (key) { 99 case 27: 100 case KEY_CANCEL: 101 form_widget.close(); 102 break; 103 case 10: 104 case 13: 105 case KEY_ENTER: 106 on_key_enter(); 107 break; 108 default: 109 on_form_key(key); 110 break; 111 } 112 } 113 114 static bool create(void) 115 { 116 const char *title; 117 118 if (screen_lines < 6 || screen_cols < 36) { 119 form_widget.close(); 120 beep(); 121 return FALSE; 122 } 123 widget_init(&form_widget, 124 6, 36, SCREEN_CENTER, SCREEN_CENTER, 125 attr_textbox, WIDGET_BORDER | WIDGET_SUBWINDOW | WIDGET_CURSOR_VISIBLE); 126 title = _("Sound Card"); 127 mvwprintw(form_widget.window, 0, (36 - 2 - get_mbs_width(title)) / 2, " %s ", title); 128 129 set_form_win(form, form_widget.window); 130 set_form_sub(form, form_widget.subwindow); 131 return TRUE; 132 } 133 134 static void on_window_size_changed(void) 135 { 136 form_driver(form, REQ_VALIDATION); /* save field value */ 137 unpost_form(form); 138 139 if (!create()) 140 return; 141 142 /* 143 * This call fails because ncurses does not allow changing options of 144 * the current field, and we cannot change the current field because 145 * there is only one. The only way to make this work would be to throw 146 * away and recreate all fields. 147 */ 148 field_opts_off(fields[1], O_BLANK); 149 150 post_form(form); 151 } 152 153 static void on_close(void) 154 { 155 unpost_form(form); 156 free_form(form); 157 free_field(fields[0]); 158 free_field(fields[1]); 159 widget_free(&form_widget); 160 } 161 162 static struct widget form_widget = { 163 .handle_key = on_handle_key, 164 .window_size_changed = on_window_size_changed, 165 .close = on_close, 166 }; 167 168 void create_device_name_form(void) 169 { 170 fields[0] = new_field(1, 32, 1, 1, 0, 0); 171 if (!fields[0]) 172 fatal_error("cannot create field"); 173 field_opts_off(fields[0], O_ACTIVE); 174 field_opts_off(fields[0], O_EDIT); 175 set_field_fore(fields[0], attr_textbox); 176 set_field_back(fields[0], attr_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); 183 field_opts_off(fields[1], O_NULLOK); 184 field_opts_off(fields[1], O_STATIC); 185 set_field_fore(fields[1], attr_textfield); 186 set_field_back(fields[1], attr_textfield); 187 set_field_buffer(fields[1], 0, mixer_device_name); 188 189 form = new_form(fields); 190 if (!form) 191 fatal_error("cannot create form"); 192 193 if (!create()) 194 return; 195 196 post_form(form); 197 }