wmix: added appropriate message and fall back if user's color for OSD failed
[dockapps.git] / wmix / config.c
blobf335df9063506424cb98ab93a19c2b562b3b2f3f
1 /* WMix -- a mixer using the OSS mixer API.
2 * Copyright (C) 2014 Christophe CURIS for the WindowMaker Team
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 * config.c: functions related to loading the configuration, both from
20 * command line options and from file
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <ctype.h>
27 #include <getopt.h>
29 #include <sys/soundcard.h>
31 #include "include/common.h"
32 #include "include/config.h"
35 #define HELP_TEXT \
36 "WMixer " VERSION " by timecop@japan.co.jp + skunk@mit.edu\n" \
37 "usage:\n" \
38 " -d <dsp> connect to remote X display\n" \
39 " -e <name> exclude channel, can be used many times\n" \
40 " -f <file> parse this config [~/.wmixrc]\n" \
41 " -h print this help\n" \
42 " -m <dev> mixer device [/dev/mixer]\n" \
43 " -v verbose -> id, long name, name\n" \
45 /* The global configuration */
46 struct _Config config;
48 /* Default color for OSD */
49 const char default_osd_color[] = "green";
53 * Sets the default values in configuration
55 void config_init(void)
57 memset(&config, 0, sizeof(config));
59 config.mousewheel = 1;
60 config.scrolltext = 1;
61 config.wheel_button_up = 4;
62 config.wheel_button_down = 5;
63 config.scrollstep = 0.03;
64 config.osd = 1;
65 config.osd_color = (char *) default_osd_color;
69 * Parse Command-Line options
71 * Supposed to be called before reading config file, as there's an
72 * option to change its name
74 void parse_cli_options(int argc, char **argv)
76 int opt;
77 int count_exclude = 0;
78 bool error_found;
80 opterr = 0; /* We take charge of printing the error message */
81 config.verbose = false;
82 error_found = false;
83 for (;;) {
84 opt = getopt(argc, argv, ":d:e:f:hm:v");
85 if (opt == -1)
86 break;
88 switch (opt) {
89 case '?':
90 fprintf(stderr, "wmix:error: unknow option '-%c'\n", optopt);
91 error_found = true;
92 break;
94 case ':':
95 fprintf(stderr, "wmix:error: missing argument for option '-%c'\n", optopt);
96 error_found = true;
97 break;
99 case 'd':
100 config.display_name = strdup(optarg);
101 break;
103 case 'e':
104 if (count_exclude < SOUND_MIXER_NRDEVICES) {
105 config.exclude_channel[count_exclude] = strdup(optarg);
106 count_exclude++;
107 } else
108 fprintf(stderr, "Warning: You can't exclude this many channels\n");
109 break;
111 case 'f':
112 if (config.file != NULL)
113 free(config.file);
114 config.file = strdup(optarg);
115 break;
117 case 'h':
118 fputs(HELP_TEXT, stdout);
119 exit(0);
120 break;
122 case 'm':
123 config.mixer_device = strdup(optarg);
124 break;
126 case 'v':
127 config.verbose = true;
128 break;
130 default:
131 break;
134 config.exclude_channel[count_exclude] = NULL;
136 if (optind < argc) {
137 fprintf(stderr, "wmix:error: argument '%s' not understood\n", argv[optind]);
138 error_found = true;
141 if (error_found)
142 exit(EXIT_FAILURE);
146 * Read configuration from a file
148 * The file name is taken from CLI if available, of falls back to
149 * a default name.
151 void config_read(void)
153 const char *filename;
154 char buffer_fname[512];
155 FILE *fp;
156 int line;
157 char buf[512];
159 if (config.file != NULL) {
160 filename = config.file;
161 } else {
162 const char *home;
164 home = getenv("HOME");
165 if (home == NULL) {
166 fprintf(stderr, "wmix: warning, could not get $HOME, can't load configuration file\n");
167 return;
169 snprintf(buffer_fname, sizeof(buffer_fname), "%s/.wmixrc", home);
170 filename = buffer_fname;
173 fp = fopen(filename, "r");
174 if (fp == NULL) {
175 if (config.file != NULL) {
176 /* The config file was explicitely specified by user, tell him there's a problem */
177 fprintf(stderr, "wmix: error, could not load configuration file \"%s\"\n", filename);
178 exit(EXIT_FAILURE);
180 /* Otherwise, it is acceptable if the file does not exist */
181 return;
183 if (config.verbose)
184 printf("Using configuration file: %s\n", filename);
186 line = 0;
187 while (fgets(buf, 512, fp)) {
188 char *ptr;
189 char *keyword;
190 char *value;
192 line++;
194 ptr = buf;
195 while (isspace(*ptr))
196 ptr++;
198 if ((*ptr == '\0') || (*ptr == '#'))
199 continue;
201 /* Isolate the keyword */
202 keyword = ptr;
203 if (*ptr == '=') {
204 fprintf(stderr, "wmix:warning: syntax error at line %d in \"%s\", no keyword before '='\n",
205 line, filename);
206 continue;
208 value = NULL;
209 while (*ptr) {
210 if (*ptr == '=') {
211 value = ptr + 1;
212 break;
214 if (*ptr == '#')
215 break;
216 ptr++;
218 if (value == NULL) {
219 fprintf(stderr, "wmix:warning: syntax error at line %d in \"%s\", missing '='\n",
220 line, filename);
221 continue;
223 while (isspace(ptr[-1]))
224 ptr--;
225 *ptr = '\0';
227 /* Isolate the value */
228 while (isspace(*value))
229 value++;
230 ptr = value;
231 while (*ptr) {
232 if (*ptr == '#')
233 break;
234 ptr++;
236 while (isspace(ptr[-1]))
237 ptr--;
238 *ptr = '\0';
240 /* Check what keyword we have */
241 if (strcmp(keyword, "mousewheel") == 0) {
242 config.mousewheel = atoi(value);
244 } else if (strcmp(keyword, "osd") == 0) {
245 config.osd = atoi(value);
247 } else if (strcmp(keyword, "osdcolor") == 0) {
248 if (config.osd_color != default_osd_color)
249 free(config.osd_color);
250 config.osd_color = strdup(value);
252 } else if (strcmp(keyword, "scrolltext") == 0) {
253 config.scrolltext = atoi(value);
255 } else if (strcmp(keyword, "wheelbtn1") == 0) {
256 config.wheel_button_up = atoi(value);
258 } else if (strcmp(keyword, "wheelbtn2") == 0) {
259 config.wheel_button_down = atoi(value);
261 } else if (strcmp(keyword, "wheelstep") == 0) {
262 double val;
264 val = atof(value);
265 if (val < 0.0 || val > 100.0)
266 fprintf(stderr, "wmix:error: value %f is out of range for wheelstep in %s at line %d\n",
267 val, filename, line);
268 else if (val >= 1.0)
269 config.scrollstep = val / 100.0;
270 else if (val > 0.0)
271 config.scrollstep = val;
272 else
273 fprintf(stderr, "wmix:error: value '%s' not understood for wheelstep in %s at line %d\n",
274 value, filename, line);
275 } else {
276 fprintf(stderr, "wmix:warning: unknow keyword '%s' at line %d of \"%s\", ignored\n",
277 keyword, line, filename);
280 fclose(fp);