1/* 2 * alsamixer - curses mixer for the ALSA project 3 * Copyright (c) 1998,1999 Tim Janik 4 * Jaroslav Kysela <perex@perex.cz> 5 * Copyright (c) 2009 Clemens Ladisch <clemens@ladisch.de> 6 * 7 * This program is free software: you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation, either version 2 of the License, or 10 * (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program. If not, see <http://www.gnu.org/licenses/>. 19 */ 20 21#include "aconfig.h" 22#include <stdio.h> 23#include <stdlib.h> 24#include <locale.h> 25#include <getopt.h> 26#include <alsa/asoundlib.h> 27#include "gettext_curses.h" 28#include "mixer_widget.h" 29#include "mainloop.h" 30#include "configparser.h" 31#include "colors.h" 32 33static int black_background = 0; 34static int use_color = 1; 35static int use_mouse = 1; 36static const char* config_file = CONFIG_DEFAULT; 37static struct snd_mixer_selem_regopt selem_regopt = { 38 .ver = 1, 39 .abstract = SND_MIXER_SABSTRACT_NONE, 40 .device = "default", 41}; 42 43static void show_help(void) 44{ 45 puts(_("Usage: alsamixer [options]")); 46 puts(_("Useful options:\n" 47 " -h, --help this help\n" 48 " -c, --card=NUMBER sound card number or id\n" 49 " -D, --device=NAME mixer device name\n" 50 " -m, --mouse enable mouse\n" 51 " -M, --no-mouse disable mouse\n" 52 " -f, --config=FILE configuration file\n" 53 " -F, --no-config do not load configuration file\n" 54 " -V, --view=MODE starting view mode: playback/capture/all\n" 55 " -B, --black-background use black background color")); 56 puts(_("Debugging options:\n" 57 " -g, --no-color toggle using of colors\n" 58 " -a, --abstraction=NAME mixer abstraction level: none/basic")); 59} 60 61static void parse_options(int argc, char *argv[]) 62{ 63 static const char short_options[] = "hc:f:FD:mMV:Bga:"; 64 static const struct option long_options[] = { 65 { .name = "help", .val = 'h' }, 66 { .name = "card", .has_arg = 1, .val = 'c' }, 67 { .name = "config", .has_arg = 1, .val = 'f' }, 68 { .name = "no-config", .val = 'F' }, 69 { .name = "device", .has_arg = 1, .val = 'D' }, 70 { .name = "mouse", .val = 'm' }, 71 { .name = "no-mouse", .val = 'M' }, 72 { .name = "view", .has_arg = 1, .val = 'V' }, 73 { .name = "black-background", .val = 'B' }, 74 { .name = "no-color", .val = 'g' }, 75 { .name = "abstraction", .has_arg = 1, .val = 'a' }, 76 { 0 } 77 }; 78 int option; 79 int card_index; 80 static char name_buf[24]; 81 82 while ((option = getopt_long(argc, argv, short_options, 83 long_options, NULL)) != -1) { 84 switch (option) { 85 case '?': 86 case 'h': 87 show_help(); 88 exit(EXIT_SUCCESS); 89 case 'c': 90 card_index = snd_card_get_index(optarg); 91 if (card_index < 0) { 92 fprintf(stderr, _("invalid card index: %s\n"), optarg); 93 goto fail; 94 } 95#if defined(SND_LIB_VER) && SND_LIB_VER(1, 2, 5) <= SND_LIB_VERSION 96 sprintf(name_buf, "sysdefault:%d", card_index); 97#else 98 sprintf(name_buf, "hw:%d", card_index); 99#endif 100 selem_regopt.device = name_buf; 101 break; 102 case 'D': 103 selem_regopt.device = optarg; 104 break; 105 case 'f': 106 config_file = optarg; 107 break; 108 case 'F': 109 config_file = NULL; 110 break; 111 case 'm': 112 use_mouse = 1; 113 break; 114 case 'M': 115 use_mouse = 0; 116 break; 117 case 'V': 118 if (*optarg == 'p' || *optarg == 'P') 119 view_mode = VIEW_MODE_PLAYBACK; 120 else if (*optarg == 'c' || *optarg == 'C') 121 view_mode = VIEW_MODE_CAPTURE; 122 else 123 view_mode = VIEW_MODE_ALL; 124 break; 125 case 'B': 126 black_background = 1; 127 break; 128 case 'g': 129 use_color = !use_color; 130 break; 131 case 'a': 132 if (!strcmp(optarg, "none")) 133 selem_regopt.abstract = SND_MIXER_SABSTRACT_NONE; 134 else if (!strcmp(optarg, "basic")) 135 selem_regopt.abstract = SND_MIXER_SABSTRACT_BASIC; 136 else { 137 fprintf(stderr, _("unknown abstraction level: %s\n"), optarg); 138 goto fail; 139 } 140 break; 141 default: 142 fprintf(stderr, _("unknown option: %c\n"), option); 143fail: 144 fputs(_("try `alsamixer --help' for more information\n"), stderr); 145 exit(EXIT_FAILURE); 146 } 147 } 148} 149 150int main(int argc, char *argv[]) 151{ 152 if (!isatty(fileno(stdin))) 153 return 0; 154 155 setlocale(LC_ALL, ""); 156#ifdef ENABLE_NLS_IN_CURSES 157 textdomain(PACKAGE); 158#endif 159 160 parse_options(argc, argv); 161 162 create_mixer_object(&selem_regopt); 163 164 initialize_curses(use_color, use_mouse); 165 166 if (config_file == CONFIG_DEFAULT) 167 parse_default_config_file(); 168 else if (config_file) 169 parse_config_file(config_file); 170 171 if (black_background) 172 reinit_colors(COLOR_BLACK); 173 174 create_mixer_widget(); 175 176 mainloop(); 177 178 app_shutdown(); 179 return 0; 180} 181