xref: /third_party/alsa-utils/alsamixer/cli.c (revision c72fcc34)
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