1 
2 /* jlh */
3 
4 /*
5     this file is part of: wmblob
6 
7     the GNU GPL license applies to this file, see file COPYING for details.
8     author: jean-luc herren.
9 */
10 
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <glib.h>
14 #include <string.h>
15 #include <stdlib.h>
16 #include "rcfile.h"
17 #include "wmblob.h"
18 
19 /* string to be placed at the beginning of rc files */
20 
21 #define RC_HEAD \
22 "# rc file for wmblob, see BSDforge.com\n" \
23 "# you can edit this file by hand, but be VERY careful, wmblobs's parser\n" \
24 "# is VERY cheap.  do not change the format in any way.  better not edit\n" \
25 "# while wmblob is running.\n\n"
26 
27 static char buf[1024];
28 static FILE *handle;
29 static char line[1024];
30 
31 GList *preset_list;
32 
33 /* prototypes */
34 
35 static int set_file();
36 static void create_default_file();
37 static void save_entry(SETTINGS *);
38 static int read_line();
39 static void read_entry(SETTINGS *settings, char *);
40 static PRESET *get_preset(const char *);
41 
42 
43 /* initialize stuff in this file */
44 
init_rcfile_c()45 int init_rcfile_c()
46 {
47 	preset_list = NULL;
48 	return(1);
49 }
50 
51 
52 /* uninitialize stuff in this file */
53 
done_rcfile_c()54 void done_rcfile_c()
55 {
56 	GList *node;
57 	PRESET *preset;
58 
59 	node = preset_list;
60 
61 	while (node)
62 	{
63 		preset = (PRESET *)(node->data);
64 		free(preset);
65 
66 		node = g_list_next(node);
67 	}
68 
69 	g_list_free(preset_list);
70 }
71 
72 
73 /* set path to config file in buf */
74 
set_file()75 static int set_file()
76 {
77 	char *home;
78 
79 	home = getenv("HOME");
80 
81 	if (!home)
82 	{
83 		printf("error: $HOME is not set.  cannot access rc file\n");
84 		return(0);
85 	}
86 
87 	sprintf(buf, "%s/.wmblobrc", home);
88 
89 	return(1);
90 }
91 
92 
93 /* write a default config file */
94 
create_default_file()95 static void create_default_file()
96 {
97 	if (!set_file()) return;
98 
99 	handle = fopen(buf, "wb");
100 	if (!handle) return;
101 
102 	fprintf(handle, "%s", RC_HEAD);
103 	fprintf(handle,
104 "current=255,255,255,0,0,255,0,0,0,5,0,2,16,255,2,9,128,16\n"
105 "preset=default,255,255,255,0,0,255,0,0,0,5,0,2,16,255,2,9,128,16\n"
106 "preset=dots,0,0,0,0,191,255,255,255,255,40,0,2,3,32,0,16,127,20\n"
107 "preset=electric charge,0,0,0,0,0,255,255,255,255,50,0,5,32,255,0,0,0,64\n"
108 "preset=flying dirt,64,64,0,128,128,0,240,240,220,50,1,0,0,10,0,64,64,100\n"
109 "preset=fire,238,219,0,255,82,0,165,42,42,20,1,3,16,224,3,32,128,16\n"
110 "preset=glow-worms,255,255,0,30,144,255,0,0,0,20,0,0,0,127,0,0,0,127\n"
111 "preset=green contour,0,0,0,0,255,0,0,0,0,3,0,20,16,255,0,16,128,24\n"
112 "preset=lonely blue,255,255,255,0,0,255,0,0,0,1,0,1,16,255,0,8,255,64\n"
113 "preset=noise,0,0,0,255,255,0,173,216,230,50,0,220,255,255,0,0,0,16\n"
114 "preset=orange,255,255,255,255,165,0,255,255,255,4,0,50,16,128,0,64,128,0\n"
115 "preset=wiggle,0,0,0,0,191,255,255,255,255,30,0,10,20,64,3,33,128,32\n"
116 "preset=yellow,255,255,255,255,255,0,0,0,0,5,0,2,20,255,0,24,96,8\n"
117 		);
118 
119 	fclose(handle);
120 }
121 
122 
123 /* save a set of settings */
124 
save_entry(SETTINGS * settings)125 static void save_entry(SETTINGS *settings)
126 {
127 	fprintf(handle, "%d,%d,%d,%d,%d,%d,%d,%d,%d,",
128 			settings->color[0].r,
129 			settings->color[0].g,
130 			settings->color[0].b,
131 			settings->color[1].r,
132 			settings->color[1].g,
133 			settings->color[1].b,
134 			settings->color[2].r,
135 			settings->color[2].g,
136 			settings->color[2].b);
137 
138 	fprintf(handle, "%d,%d,%d,%d,%d,%d,%d,%d,%d\n",
139 			settings->n_blobs,
140 			settings->gravity,
141 			settings->blob_size,
142 			settings->blob_falloff,
143 			settings->blob_presence,
144 			settings->border_size,
145 			settings->border_falloff,
146 			settings->border_presence,
147 			settings->multiplication);
148 }
149 
150 
151 /* save current settings and presets */
152 
settings_save()153 int settings_save()
154 {
155 	GList *node;
156 	PRESET *preset;
157 
158 	if (!set_file()) return(0);
159 
160 	handle = fopen(buf, "wb");
161 	if (!handle) return(0);
162 
163 	fprintf(handle, "%s", RC_HEAD);
164 
165 	fprintf(handle, "current=");
166 	save_entry(&current_settings);
167 
168 	node = preset_list;
169 
170 	while (node)
171 	{
172 		preset = (PRESET *)node->data;
173 		fprintf(handle, "preset=%s,", preset->name);
174 		save_entry(&preset->settings);
175 
176 		node = g_list_next(node);
177 	}
178 
179 	fclose(handle);
180 
181 	return(1);
182 }
183 
184 
185 /* read a line from the file */
186 
read_line()187 static int read_line()
188 {
189 	int c;
190 	char *p;
191 
192 	p = line;
193 
194 	while (1)
195 	{
196 		c = getc(handle);
197 
198 		if (c == EOF) return(0);
199 
200 		if (c == '\n')
201 		{
202 			*p = '\0';
203 			return(1);
204 		}
205 
206 		if (c == '\r') continue;
207 
208 		*p++ = c;
209 	}
210 }
211 
212 
213 /* read a settings entry.  well, this is cheaper than cheap, I know */
214 
read_entry(SETTINGS * settings,char * str)215 static void read_entry(SETTINGS *settings, char *str)
216 {
217 	settings->color[0].r = atoi(str);
218 	str = strchr(str, ',') + 1;
219 	settings->color[0].g = atoi(str);
220 	str = strchr(str, ',') + 1;
221 	settings->color[0].b = atoi(str);
222 	str = strchr(str, ',') + 1;
223 	settings->color[1].r = atoi(str);
224 	str = strchr(str, ',') + 1;
225 	settings->color[1].g = atoi(str);
226 	str = strchr(str, ',') + 1;
227 	settings->color[1].b = atoi(str);
228 	str = strchr(str, ',') + 1;
229 	settings->color[2].r = atoi(str);
230 	str = strchr(str, ',') + 1;
231 	settings->color[2].g = atoi(str);
232 	str = strchr(str, ',') + 1;
233 	settings->color[2].b = atoi(str);
234 	str = strchr(str, ',') + 1;
235 
236 	settings->n_blobs = atoi(str);
237 	str = strchr(str, ',') + 1;
238 	settings->gravity = atoi(str);
239 	str = strchr(str, ',') + 1;
240 	settings->blob_size = atoi(str);
241 	str = strchr(str, ',') + 1;
242 	settings->blob_falloff = atoi(str);
243 	str = strchr(str, ',') + 1;
244 	settings->blob_presence = atoi(str);
245 	str = strchr(str, ',') + 1;
246 	settings->border_size = atoi(str);
247 	str = strchr(str, ',') + 1;
248 	settings->border_falloff = atoi(str);
249 	str = strchr(str, ',') + 1;
250 	settings->border_presence = atoi(str);
251 	str = strchr(str, ',') + 1;
252 	settings->multiplication = atoi(str);
253 }
254 
255 
256 /* load current settings and presets.  cheap, cheap, cheap */
257 
settings_load()258 void settings_load()
259 {
260 	char *value;
261 
262 	if (!set_file()) return;
263 
264 	handle = fopen(buf, "rb");
265 
266 	if (!handle)
267 	{
268 		/* could not open file.  store a default config file
269 		   and try again. */
270 		create_default_file();
271 
272 		handle = fopen(buf, "rb");
273 		if (!handle) return;
274 	}
275 
276 	while (1)
277 	{
278 		if (!read_line()) break;
279 		if (*line == '#') continue;
280 		if (*line == '\n') continue;
281 		if (*line == '\0') continue;
282 
283 		/* look for the '=' */
284 
285 		value = line + 1;
286 		while (*value != '=')
287 			value++;
288 
289 		*value++ = '\0';
290 
291 		if (strcmp(line, "current") == 0)
292 		{
293 			read_entry(&current_settings, value);
294 		}
295 		else if (strcmp(line, "preset") == 0)
296 		{
297 			PRESET *preset;
298 			char *p;
299 
300 			p = strchr(value, ',');
301 			*p++ = '\0';
302 
303 			preset = (PRESET *)malloc(sizeof(PRESET));
304 			strcpy(preset->name, value);
305 			read_entry(&preset->settings, p);
306 			preset_list = g_list_append(preset_list, preset);
307 		}
308 		else
309 			printf("unknown option `%s' in rc file\n", line);
310 	}
311 
312 	fclose(handle);
313 }
314 
315 
316 /* look for a preset named name */
317 
get_preset(const char * name)318 static PRESET *get_preset(const char *name)
319 {
320 	GList *preset;
321 
322 	preset = preset_list;
323 
324 	while (preset)
325 	{
326 		if (strcmp(((PRESET *)preset->data)->name, name) == 0)
327 			return(preset->data);
328 
329 		preset = g_list_next(preset);
330 	}
331 
332 	return(NULL);
333 }
334 
335 
336 /* save a preset and create it, if not already in the list */
337 
preset_save(const char * name,SETTINGS * settings)338 void preset_save(const char *name, SETTINGS *settings)
339 {
340 	PRESET *preset;
341 
342 	preset = get_preset(name);
343 
344 	if (!preset)
345 	{
346 		preset = (PRESET *)malloc(sizeof(PRESET));
347 		strcpy(preset->name, name);
348 		preset_list = g_list_append(preset_list, preset);
349 	}
350 
351 	preset->settings = *settings;
352 
353 	settings_save();
354 }
355 
356 
357 /* delete the named preset */
358 
preset_delete(const char * name)359 void preset_delete(const char *name)
360 {
361 	PRESET *preset;
362 
363 	preset = get_preset(name);
364 	if (!preset) return;
365 
366 	preset_list = g_list_remove(preset_list, preset);
367 	free(preset);
368 
369 	settings_save();
370 }
371 
372 
373 /* load the named preset */
374 
preset_load(const char * name,SETTINGS * settings)375 int preset_load(const char *name, SETTINGS *settings)
376 {
377 	PRESET *preset;
378 
379 	preset = get_preset(name);
380 	if (!preset) return(0);
381 
382 	*settings = preset->settings;
383 
384 	return(1);
385 }
386 
387