1 /*
2 * Copyright (c) 2000 Andrew Ferguson <andrew@owsla.cjb.net>
3 * Copyright (c) 1998 Sasha Vasko <sasha at aftercode.net>
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, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 *
19 */
20
21
22 #define LOCAL_DEBUG
23
24 #include "../configure.h"
25
26 #include "../libAfterStep/asapp.h"
27 #include "../libAfterStep/afterstep.h"
28 #include "../libAfterStep/parser.h"
29 #include "../libAfterStep/hints.h"
30 // :sG:!! Change to ALSA:
31 #ifdef HAVE_RPLAY_H
32 #include <rplay.h>
33 #endif
34
35 #include "afterconf.h"
36
37 /*****************************************************************************
38 *
39 * This routine is responsible for reading and parsing the config file
40 *
41 ****************************************************************************/
42
43 /* number after strings here is the len of str */
44 TermDef EventTerms[] = {
45 {TF_DONT_SPLIT | TF_NO_MYNAME_PREPENDING, "add_window", 10, TT_FILENAME,
46 EVENT_WindowAdded_ID, NULL}
47 ,
48 {TF_DONT_SPLIT | TF_NO_MYNAME_PREPENDING, "window_names", 8, TT_FILENAME,
49 EVENT_WindowNames_ID, NULL}
50 ,
51 {TF_DONT_SPLIT | TF_NO_MYNAME_PREPENDING, "destroy_window", 14,
52 TT_FILENAME, EVENT_WindowDestroyed_ID, NULL}
53 ,
54 {TF_DONT_SPLIT | TF_NO_MYNAME_PREPENDING, "focus_change", 12,
55 TT_FILENAME, EVENT_WindowActivated_ID, NULL}
56 ,
57 {TF_DONT_SPLIT | TF_NO_MYNAME_PREPENDING, "raise_window", 12,
58 TT_FILENAME, EVENT_WindowRaised_ID, NULL}
59 ,
60 {TF_DONT_SPLIT | TF_NO_MYNAME_PREPENDING, "iconify", 7, TT_FILENAME,
61 EVENT_WindowIconified_ID, NULL}
62 ,
63 {TF_DONT_SPLIT | TF_NO_MYNAME_PREPENDING, "deiconify", 9, TT_FILENAME,
64 EVENT_WindowDeiconified_ID, NULL}
65 ,
66 {TF_DONT_SPLIT | TF_NO_MYNAME_PREPENDING, "shade", 5, TT_FILENAME,
67 EVENT_WindowShaded_ID, NULL}
68 ,
69 {TF_DONT_SPLIT | TF_NO_MYNAME_PREPENDING, "unshade", 7, TT_FILENAME,
70 EVENT_WindowUnshaded_ID, NULL}
71 ,
72 {TF_DONT_SPLIT | TF_NO_MYNAME_PREPENDING, "stick", 5, TT_FILENAME,
73 EVENT_WindowStuck_ID, NULL}
74 ,
75 {TF_DONT_SPLIT | TF_NO_MYNAME_PREPENDING, "unstick", 7, TT_FILENAME,
76 EVENT_WindowUnstuck_ID, NULL}
77 ,
78 {TF_DONT_SPLIT | TF_NO_MYNAME_PREPENDING, "maximize", 8, TT_FILENAME,
79 EVENT_WindowMaximized_ID, NULL}
80 ,
81 {TF_DONT_SPLIT | TF_NO_MYNAME_PREPENDING, "restore", 7, TT_FILENAME,
82 EVENT_WindowRestored_ID, NULL}
83 ,
84
85 {TF_DONT_SPLIT | TF_NO_MYNAME_PREPENDING, "stuck", 5, TT_FILENAME,
86 EVENT_WindowStuck_ID, NULL}
87 ,
88 {TF_DONT_SPLIT | TF_NO_MYNAME_PREPENDING, "unstuck", 7, TT_FILENAME,
89 EVENT_WindowUnstuck_ID, NULL}
90 ,
91
92 {TF_DONT_SPLIT | TF_NO_MYNAME_PREPENDING, "new_background", 14,
93 TT_FILENAME, EVENT_BackgroundChanged_ID, NULL}
94 ,
95 {TF_DONT_SPLIT | TF_NO_MYNAME_PREPENDING, "new_viewport", 12,
96 TT_FILENAME, EVENT_DeskViewportChanged_ID, NULL}
97 ,
98 {TF_DONT_SPLIT | TF_NO_MYNAME_PREPENDING, "startup", 7, TT_FILENAME,
99 EVENT_Startup_ID, NULL}
100 ,
101 {TF_DONT_SPLIT | TF_NO_MYNAME_PREPENDING, "shutdown", 8, TT_FILENAME,
102 EVENT_Shutdown_ID, NULL}
103 ,
104
105 {TF_DONT_SPLIT | TF_NO_MYNAME_PREPENDING, "config", 6, TT_FILENAME,
106 EVENT_Config_ID, NULL}
107 ,
108 {TF_DONT_SPLIT | TF_NO_MYNAME_PREPENDING, "module_config", 13,
109 TT_FILENAME, EVENT_ModuleConfig_ID, NULL}
110 ,
111
112 {0, NULL, 0, 0, 0} /* end of structure */
113 };
114
115 SyntaxDef SoundEventsSyntax = {
116 ',',
117 '\n',
118 EventTerms,
119 0, /* use default hash size */
120 ' ',
121 "",
122 "\t",
123 "Module:Sound event configuration",
124 "SoundEvents",
125 "names for different windowing events",
126 NULL,
127 0
128 };
129
130
131 TermDef SoundTerms[] = {
132 {TF_DONT_SPLIT, "Path", 8, TT_TEXT, SOUND_PATH_ID, NULL}
133 ,
134 {TF_DONT_SPLIT, "PcmDevice", 7, TT_TEXT, SOUND_PCMDEVICE_ID, NULL}
135 ,
136 {0, "Delay", 5, TT_INTEGER, SOUND_DELAY_ID, NULL}
137 ,
138 {0, "RplayHost", 9, TT_TEXT, SOUND_RPLAY_HOST_ID, NULL}
139 ,
140 {0, "RplayPriority", 13, TT_INTEGER, SOUND_RPLAY_PRI_ID, NULL}
141 ,
142 {0, "Debug", 11, TT_INTEGER, SOUND_DEBUG_ID, NULL}
143 ,
144 {0, "", 0, TT_FLAG, SOUND_SOUND_ID, &SoundEventsSyntax}
145 ,
146 {0, NULL, 0, 0, 0} /* end of structure */
147
148 };
149
150 SyntaxDef SoundSyntax = {
151 '\n',
152 '\0',
153 SoundTerms,
154 0, /* use default hash size */
155 ' ',
156 "",
157 "\t",
158 "Module:Sound",
159 "Sound",
160 "AfterStep module for playing sounds when windowing event occurs",
161 NULL,
162 0
163 };
164
165 /************** Create/Destroy SoundConfig ***************/
166
CreateSoundConfig()167 SoundConfig *CreateSoundConfig ()
168 {
169 SoundConfig *config =
170 (SoundConfig *) safecalloc (1, sizeof (SoundConfig));
171
172 /* let's initialize Sound's config with some nice values: */
173 /*
174 #ifdef HAVE_RPLAY_H
175 config->rplay_volume = RPLAY_DEFAULT_VOLUME;
176 config->rplay_priority = RPLAY_DEFAULT_PRIORITY;
177 #endif
178 */
179 return config;
180 }
181
DestroySoundConfig(SoundConfig * config)182 void DestroySoundConfig (SoundConfig * config)
183 {
184 register int i;
185
186 for (i = EVENT_ID_END - EVENT_ID_START - 1; i >= 0; i--)
187 if (config->sounds[i])
188 free (config->sounds[i]);
189
190 if (config->pcmdevice)
191 free (config->pcmdevice);
192
193 DestroyFreeStorage (&(config->more_stuff));
194 free (config);
195 }
196
197 /************ Actual Parsing **************/
198
ParseSoundOptions(const char * filename,char * myname)199 SoundConfig *ParseSoundOptions (const char *filename, char *myname)
200 {
201 ConfigData cd;
202 ConfigDef *SoundConfigReader;
203 SoundConfig *config = CreateSoundConfig ();
204
205 FreeStorageElem *Storage = NULL, *pCurr;
206 ConfigItem item;
207
208 cd.filename = filename;
209 SoundConfigReader =
210 InitConfigReader (myname, &SoundSyntax, CDT_Filename, cd, NULL);
211 if (!SoundConfigReader)
212 return config;
213
214 item.memory = NULL;
215 PrintConfigReader (SoundConfigReader);
216 ParseConfig (SoundConfigReader, &Storage);
217
218 /* getting rid of all the crap first */
219 StorageCleanUp (&Storage, &(config->more_stuff), CF_DISABLED_OPTION);
220
221 for (pCurr = Storage; pCurr; pCurr = pCurr->next) {
222 if (pCurr->term == NULL)
223 continue;
224
225 {
226 if (!ReadConfigItem (&item, pCurr))
227 continue;
228
229 switch (pCurr->term->id) {
230 case SOUND_SOUND_ID:
231 if (pCurr->sub) {
232 if (pCurr->sub->term && pCurr->sub->argv)
233 if (pCurr->sub->term->id >= EVENT_ID_START
234 && pCurr->sub->term->id < EVENT_ID_END)
235 set_string (&
236 (config->
237 sounds[pCurr->sub->term->id - EVENT_ID_START]),
238 mystrdup (pCurr->sub->argv[0]));
239 }
240 break;
241 case SOUND_PCMDEVICE_ID:
242 //set_string( &(config->pcmdevice), item.data.string );
243 config->pcmdevice = item.data.string;
244 break;
245 case SOUND_PATH_ID:
246 config->path = item.data.string;
247 break;
248
249 case SOUND_DEBUG_ID:
250 config->debug = (int)item.data.integer;
251 break;
252 /*
253 case SOUND_DELAY_ID:
254 set_flags( config->set_flags, SOUND_SET_DELAY );
255 config->delay = (int)item.data.integer;
256 break;
257 */
258 /*
259 case SOUND_RPLAY_HOST_ID:
260 set_string_value( &(config->rplay_host), item.data.string, &(config->set_flags), SOUND_SET_RPLAY_HOST );
261 break;
262 case SOUND_RPLAY_PRI_ID:
263 set_flags( config->set_flags, SOUND_SET_RPLAY_PRIORITY );
264 config->rplay_priority = (int)item.data.integer;
265 break;
266 case SOUND_RPLAY_VOL_ID:
267 set_flags( config->set_flags, SOUND_SET_RPLAY_VOLUME );
268 config->rplay_volume = (int)item.data.integer;
269 break;
270 */
271 default:
272 item.ok_to_free = 1;
273 }
274 }
275 }
276
277 ReadConfigItem (&item, NULL);
278
279 DestroyConfig (SoundConfigReader);
280 DestroyFreeStorage (&Storage);
281 return config;
282
283 }
284
285 int
WriteSoundOptions(const char * filename,char * myname,SoundConfig * config,unsigned long flags)286 WriteSoundOptions (const char *filename, char *myname,
287 SoundConfig * config, unsigned long flags)
288 {
289 ConfigDef *SoundConfigWriter = NULL;
290 FreeStorageElem *Storage = NULL, **tail = &Storage;
291 register int i;
292 ConfigData cd;
293
294 if (config == NULL)
295 return 1;
296 cd.filename = filename;
297
298 if ((SoundConfigWriter =
299 InitConfigWriter (myname, &SoundSyntax, CDT_Filename, cd)) == NULL)
300 return 2;
301 CopyFreeStorage (&Storage, config->more_stuff);
302 /* building free storage here */
303 /* PCM Device */
304 if (config->pcmdevice)
305 tail =
306 String2FreeStorage (&SoundSyntax, tail, config->pcmdevice,
307 SOUND_PCMDEVICE_ID);
308
309 if (config->debug)
310 tail =
311 Integer2FreeStorage (&SoundSyntax, tail, NULL, config->debug,
312 SOUND_DEBUG_ID);
313 /* delay */
314 /*
315 if( get_flags(config->set_flags, SOUND_SET_DELAY) )
316 tail = Integer2FreeStorage (&SoundSyntax, tail, NULL, config->delay, SOUND_DELAY_ID);
317 */
318 /* rplay_host */
319 // if (get_flags(config->set_flags, SOUND_SET_RPLAY_HOST) && config->rplay_host)
320 // tail = String2FreeStorage (&SoundSyntax, tail, config->rplay_host, SOUND_RPLAY_HOST_ID);
321
322 /* rplay_priority */
323 // if (get_flags(config->set_flags, SOUND_SET_RPLAY_PRIORITY))
324 // tail = Integer2FreeStorage (&SoundSyntax, tail, NULL, config->rplay_priority, SOUND_RPLAY_PRI_ID);
325
326 /* rplay_volume */
327 // if( get_flags(config->set_flags, SOUND_SET_RPLAY_VOLUME) )
328 // tail = Integer2FreeStorage (&SoundSyntax, tail, NULL, config->rplay_volume, SOUND_RPLAY_VOL_ID);
329
330 /* line structure */
331 for (i = EVENT_ID_END - EVENT_ID_START - 1; i >= 0; i--)
332 if (config->sounds[i]) {
333 FreeStorageElem **dtail = tail;
334
335 tail = Flag2FreeStorage (&SoundSyntax, tail, SOUND_SOUND_ID);
336 if (*dtail)
337 Path2FreeStorage (&SoundEventsSyntax, &((*dtail)->sub), NULL,
338 config->sounds[i], EVENT_ID_START + i);
339 }
340
341 /* writing config into the file */
342 WriteConfig (SoundConfigWriter, Storage, CDT_Filename, &cd, flags);
343 DestroyFreeStorage (&Storage);
344 DestroyConfig (SoundConfigWriter);
345
346 if (Storage) {
347 fprintf (stderr,
348 "\n%s:Config Writing warning: Not all Free Storage discarded! Trying again...",
349 myname);
350 DestroyFreeStorage (&Storage);
351 fprintf (stderr, (Storage != NULL) ? " failed." : " success.");
352 }
353 return 0;
354 }
355