304.1.2
by Matthew Fuller
Run 'make indent' to reindent the world. |
1 |
/*
|
2 |
* These routines were extracted from the sound hack for olvwm3.3 by
|
|
463.1.29
by Matthew Fuller
Slightly improve history doc based on sound.txt. |
3 |
* Andrew "Ender" Scherpbier (turtle@sciences.sdsu.edu, Andrew@SDSU.Edu)
|
4 |
* and modified by J.E. Sacco (jsacco @ssl.com) for tvtwm and twm. They
|
|
5 |
* were then slightly adapted for ctwm by Mark Boyns (boyns@sdsu.edu),
|
|
6 |
* and have since been reworked more.
|
|
9
by Claude Lecommandeur
CTWM version 3.1 |
7 |
*/
|
8 |
||
395.1.1
by Matthew Fuller
Move ctwm.h to always be included first. |
9 |
#include "ctwm.h" |
10 |
||
9
by Claude Lecommandeur
CTWM version 3.1 |
11 |
#include <rplay.h> |
12 |
#include <string.h> |
|
13 |
#include <stdio.h> |
|
136.1.14
by Richard Levitte
Add sound.h to declare the sound functions properly. |
14 |
#include <ctype.h> |
15 |
||
459.1.8
by Matthew Fuller
Start adding new definitions for magic events for the sound into a |
16 |
#include "event_names.h" |
136.1.14
by Richard Levitte
Add sound.h to declare the sound functions properly. |
17 |
#include "sound.h" |
9
by Claude Lecommandeur
CTWM version 3.1 |
18 |
|
459.1.7
by Matthew Fuller
Move rp to the heap, allowing us to get away from needing to know the |
19 |
RPLAY **rp = NULL; |
9
by Claude Lecommandeur
CTWM version 3.1 |
20 |
|
21 |
static int need_sound_init = 1; |
|
463.1.9
by Matthew Fuller
Add a flag for when we set sounds in the config file, and refuse to |
22 |
static int sound_from_config = 0; |
9
by Claude Lecommandeur
CTWM version 3.1 |
23 |
static int sound_fd = 0; |
24 |
static int sound_state = 1; |
|
459.1.3
by Matthew Fuller
Use strncpy() when copying into hostname so we can't blow it out. |
25 |
#define HOSTNAME_LEN 200
|
26 |
static char hostname[HOSTNAME_LEN]; |
|
9
by Claude Lecommandeur
CTWM version 3.1 |
27 |
|
143
by Richard Levitte
Comment on the trimming function and simplify it. |
28 |
/*
|
29 |
* Function to trim away spaces at the start and end of a string
|
|
30 |
*/
|
|
142
by Richard Levitte
Teach the sound file reader to trim spaces. |
31 |
static char * |
32 |
trim_spaces(char *str) |
|
33 |
{
|
|
304.1.2
by Matthew Fuller
Run 'make indent' to reindent the world. |
34 |
if(str != NULL) { |
35 |
char *p = str + strlen(str); |
|
36 |
while(*str != '\0' && *str != '\r' && *str != '\n' && isspace(*str)) { |
|
37 |
str++; |
|
38 |
}
|
|
39 |
/* Assume all line end characters are at the end */
|
|
40 |
while(p > str && isspace(p[-1])) { |
|
41 |
p--; |
|
42 |
}
|
|
43 |
*p = '\0'; |
|
44 |
}
|
|
45 |
return str; |
|
142
by Richard Levitte
Teach the sound file reader to trim spaces. |
46 |
}
|
47 |
||
9
by Claude Lecommandeur
CTWM version 3.1 |
48 |
/*
|
459.1.8
by Matthew Fuller
Start adding new definitions for magic events for the sound into a |
49 |
* Define stuff related to "magic" names.
|
50 |
*/
|
|
51 |
static const char *magic_events[] = { |
|
52 |
"Startup", |
|
53 |
"Shutdown", |
|
54 |
};
|
|
55 |
#define NMAGICEVENTS (sizeof(magic_events) / sizeof(*magic_events))
|
|
56 |
||
57 |
static int |
|
58 |
sound_magic_event_name2num(const char *name) |
|
59 |
{
|
|
60 |
int i; |
|
61 |
||
62 |
for(i = 0 ; i < NMAGICEVENTS ; i++) { |
|
63 |
if(strcasecmp(name, magic_events[i]) == 0) { |
|
64 |
/* We number these off the far end of the non-magic events */
|
|
65 |
return event_names_size() + i; |
|
66 |
}
|
|
67 |
}
|
|
68 |
||
69 |
return -1; |
|
70 |
}
|
|
71 |
||
72 |
||
459.1.10
by Matthew Fuller
Now we can define NEVENTS dynamically from out figured-up size rather |
73 |
/*
|
74 |
* Now we know how many events we need to store up info for
|
|
75 |
*/
|
|
76 |
#define NEVENTS (event_names_size() + NMAGICEVENTS)
|
|
77 |
||
78 |
||
459.1.8
by Matthew Fuller
Start adding new definitions for magic events for the sound into a |
79 |
|
80 |
/*
|
|
463.1.2
by Matthew Fuller
Split up sound subsystem init from parsing the .ctwm-sounds file for |
81 |
* Initialize the subsystem and its necessary bits
|
9
by Claude Lecommandeur
CTWM version 3.1 |
82 |
*/
|
463.1.5
by Matthew Fuller
Export sound_init() and call it explicitly in main. |
83 |
void
|
304.1.2
by Matthew Fuller
Run 'make indent' to reindent the world. |
84 |
sound_init(void) |
9
by Claude Lecommandeur
CTWM version 3.1 |
85 |
{
|
463.1.4
by Matthew Fuller
sound_init() now has nothing to do if sound is already init'd, so swap |
86 |
if(!need_sound_init) { |
87 |
return; |
|
88 |
}
|
|
89 |
||
90 |
/* Can't happen */
|
|
91 |
if(sound_fd != 0) { |
|
92 |
fprintf(stderr, "BUG: sound_fd not set but sound inited.\n"); |
|
93 |
exit(1); |
|
94 |
}
|
|
95 |
||
304.1.2
by Matthew Fuller
Run 'make indent' to reindent the world. |
96 |
need_sound_init = 0; |
463.1.4
by Matthew Fuller
sound_init() now has nothing to do if sound is already init'd, so swap |
97 |
if(hostname[0] == '\0') { |
98 |
strncpy(hostname, rplay_default_host(), HOSTNAME_LEN - 1); |
|
99 |
hostname[HOSTNAME_LEN - 1] = '\0'; /* JIC */ |
|
100 |
}
|
|
304.1.2
by Matthew Fuller
Run 'make indent' to reindent the world. |
101 |
|
463.1.4
by Matthew Fuller
sound_init() now has nothing to do if sound is already init'd, so swap |
102 |
if((sound_fd = rplay_open(hostname)) < 0) { |
103 |
rplay_perror("create"); |
|
304.1.2
by Matthew Fuller
Run 'make indent' to reindent the world. |
104 |
}
|
105 |
||
106 |
/*
|
|
459.1.7
by Matthew Fuller
Move rp to the heap, allowing us to get away from needing to know the |
107 |
* Init rp if necessary
|
108 |
*/
|
|
109 |
if(rp == NULL) { |
|
110 |
if((rp = calloc(NEVENTS, sizeof(RPLAY *))) == NULL) { |
|
111 |
perror("calloc() rplay control"); |
|
112 |
exit(1); |
|
113 |
/*
|
|
459.1.19
by Matthew Fuller
Don't need to XXX this, it's not so much a 'todo' as 'well...'. |
114 |
* Should maybe just bomb out of sound stuff, but there's
|
459.1.7
by Matthew Fuller
Move rp to the heap, allowing us to get away from needing to know the |
115 |
* currently no provision for that. If malloc fails, we're
|
116 |
* pretty screwed anyway, so it's not much loss to just die.
|
|
117 |
*/
|
|
118 |
}
|
|
119 |
}
|
|
463.1.2
by Matthew Fuller
Split up sound subsystem init from parsing the .ctwm-sounds file for |
120 |
}
|
121 |
||
122 |
||
123 |
/*
|
|
463.1.10
by Matthew Fuller
Pull the list-clearing out of the file-reading func and ref it |
124 |
* Clear out any set sounds
|
125 |
*/
|
|
126 |
void
|
|
127 |
sound_clear_list(void) |
|
128 |
{
|
|
129 |
int i; |
|
130 |
||
131 |
/* JIC */
|
|
132 |
if(rp == NULL) { |
|
133 |
return; |
|
134 |
}
|
|
135 |
||
136 |
/*
|
|
137 |
* Destroy any old sounds
|
|
138 |
*/
|
|
139 |
for(i = 0; i < NEVENTS; i++) { |
|
140 |
if(rp[i] != NULL) { |
|
141 |
rplay_destroy(rp[i]); |
|
142 |
}
|
|
143 |
rp[i] = NULL; |
|
144 |
}
|
|
145 |
}
|
|
146 |
||
147 |
||
148 |
/*
|
|
463.1.2
by Matthew Fuller
Split up sound subsystem init from parsing the .ctwm-sounds file for |
149 |
* [Re]load the sounds
|
150 |
*/
|
|
463.1.6
by Matthew Fuller
Export and load the list in the main func too. Remove the code in |
151 |
void
|
463.1.2
by Matthew Fuller
Split up sound subsystem init from parsing the .ctwm-sounds file for |
152 |
sound_load_list(void) |
153 |
{
|
|
154 |
FILE *fl; |
|
155 |
char *home; |
|
156 |
char *soundfile; |
|
157 |
char buffer[100]; |
|
459.1.7
by Matthew Fuller
Move rp to the heap, allowing us to get away from needing to know the |
158 |
|
463.1.11
by Matthew Fuller
Adjust logic flow in reading .ctwm-sounds file so it doesn't clear |
159 |
/* Guard; shouldn't be possible */
|
463.1.3
by Matthew Fuller
Add a guard; this shouldn't happen. |
160 |
if(rp == NULL) { |
161 |
fprintf(stderr, "Tried to load sounds before subsystem inited.\n"); |
|
162 |
exit(1); |
|
163 |
}
|
|
164 |
||
463.1.11
by Matthew Fuller
Adjust logic flow in reading .ctwm-sounds file so it doesn't clear |
165 |
/* Find the .ctwm-sounds file */
|
459.1.1
by Matthew Fuller
Use asprintf() instead of an unchecked fixed-length buffer for |
166 |
if((home = getenv("HOME")) == NULL) { |
167 |
home = ""; |
|
168 |
}
|
|
169 |
if(asprintf(&soundfile, "%s/.ctwm-sounds", home) < 0) { |
|
170 |
perror("Failed building path to sound file"); |
|
171 |
return; |
|
172 |
}
|
|
304.1.2
by Matthew Fuller
Run 'make indent' to reindent the world. |
173 |
fl = fopen(soundfile, "r"); |
459.1.1
by Matthew Fuller
Use asprintf() instead of an unchecked fixed-length buffer for |
174 |
free(soundfile); |
463.1.9
by Matthew Fuller
Add a flag for when we set sounds in the config file, and refuse to |
175 |
|
176 |
/*
|
|
463.1.11
by Matthew Fuller
Adjust logic flow in reading .ctwm-sounds file so it doesn't clear |
177 |
* If it was found, but we already have sound set from the config
|
178 |
* file, complain on stderr and then return.
|
|
463.1.9
by Matthew Fuller
Add a flag for when we set sounds in the config file, and refuse to |
179 |
*/
|
463.1.11
by Matthew Fuller
Adjust logic flow in reading .ctwm-sounds file so it doesn't clear |
180 |
if(fl != NULL && sound_from_config) { |
463.1.9
by Matthew Fuller
Add a flag for when we set sounds in the config file, and refuse to |
181 |
fprintf(stderr, "RplaySounds set in ctwmrc, not reading " |
463.1.33
by Matthew Fuller
make indent. |
182 |
"~/.ctwm-sounds.\n"); |
463.1.9
by Matthew Fuller
Add a flag for when we set sounds in the config file, and refuse to |
183 |
fclose(fl); |
184 |
return; |
|
185 |
}
|
|
186 |
||
463.1.11
by Matthew Fuller
Adjust logic flow in reading .ctwm-sounds file so it doesn't clear |
187 |
/* Clear out the old list, whether we have new or not */
|
188 |
sound_clear_list(); |
|
189 |
||
190 |
/* If there wasn't a .ctwm-sounds file, we're done now */
|
|
191 |
if(fl == NULL) { |
|
192 |
return; |
|
193 |
}
|
|
194 |
||
195 |
/* Now go ahead and parse it in */
|
|
304.1.2
by Matthew Fuller
Run 'make indent' to reindent the world. |
196 |
while(fgets(buffer, 100, fl) != NULL) { |
459.1.5
by Matthew Fuller
Add a set_sound_event_name() function to take the event name (versus |
197 |
char *ename, *sndfile; |
198 |
||
199 |
ename = trim_spaces(strtok(buffer, ": \t")); |
|
200 |
if(ename == NULL || *ename == '#') { |
|
201 |
continue; |
|
202 |
}
|
|
203 |
||
204 |
sndfile = trim_spaces(strtok(NULL, "\r\n")); |
|
205 |
if(sndfile == NULL || *sndfile == '#') { |
|
206 |
continue; |
|
207 |
}
|
|
208 |
||
463.1.14
by Matthew Fuller
Show warnings when parsing .ctwm-sounds too. |
209 |
if(set_sound_event_name(ename, sndfile) != 0) { |
210 |
fprintf(stderr, "Error adding sound for %s; maybe event " |
|
463.1.33
by Matthew Fuller
make indent. |
211 |
"name is invalid?\n", ename); |
463.1.14
by Matthew Fuller
Show warnings when parsing .ctwm-sounds too. |
212 |
}
|
304.1.2
by Matthew Fuller
Run 'make indent' to reindent the world. |
213 |
}
|
214 |
fclose(fl); |
|
9
by Claude Lecommandeur
CTWM version 3.1 |
215 |
}
|
216 |
||
217 |
||
218 |
/*
|
|
219 |
* Play sound
|
|
220 |
*/
|
|
136.1.14
by Richard Levitte
Add sound.h to declare the sound functions properly. |
221 |
void
|
304.1.2
by Matthew Fuller
Run 'make indent' to reindent the world. |
222 |
play_sound(int snd) |
9
by Claude Lecommandeur
CTWM version 3.1 |
223 |
{
|
459.1.17
by Matthew Fuller
Comment. |
224 |
/* Bounds */
|
459.1.15
by Matthew Fuller
Improve bounds checking. |
225 |
if(snd < 0 || snd >= NEVENTS) { |
304.1.2
by Matthew Fuller
Run 'make indent' to reindent the world. |
226 |
return; |
227 |
}
|
|
459.1.17
by Matthew Fuller
Comment. |
228 |
|
229 |
/* Playing enabled */
|
|
304.1.2
by Matthew Fuller
Run 'make indent' to reindent the world. |
230 |
if(sound_state == 0) { |
231 |
return; |
|
232 |
}
|
|
233 |
||
463.1.6
by Matthew Fuller
Export and load the list in the main func too. Remove the code in |
234 |
/* Better already be initted */
|
304.1.2
by Matthew Fuller
Run 'make indent' to reindent the world. |
235 |
if(need_sound_init) { |
463.1.6
by Matthew Fuller
Export and load the list in the main func too. Remove the code in |
236 |
fprintf(stderr, "BUG: play_sound() Sound should be initted already.\n"); |
237 |
return; |
|
304.1.2
by Matthew Fuller
Run 'make indent' to reindent the world. |
238 |
}
|
239 |
||
459.1.17
by Matthew Fuller
Comment. |
240 |
/* Skip if this isn't a sound we have set */
|
304.1.2
by Matthew Fuller
Run 'make indent' to reindent the world. |
241 |
if(rp[snd] == NULL) { |
242 |
return; |
|
243 |
}
|
|
459.1.17
by Matthew Fuller
Comment. |
244 |
|
245 |
/* And if all else fails, play it */
|
|
304.1.2
by Matthew Fuller
Run 'make indent' to reindent the world. |
246 |
if(rplay(sound_fd, rp[snd]) < 0) { |
459.1.2
by Matthew Fuller
Adjust text in this perror() to be less inaccurate. |
247 |
rplay_perror("rplay"); |
304.1.2
by Matthew Fuller
Run 'make indent' to reindent the world. |
248 |
}
|
9
by Claude Lecommandeur
CTWM version 3.1 |
249 |
}
|
250 |
||
136.1.14
by Richard Levitte
Add sound.h to declare the sound functions properly. |
251 |
void
|
252 |
play_startup_sound(void) |
|
9
by Claude Lecommandeur
CTWM version 3.1 |
253 |
{
|
459.1.9
by Matthew Fuller
Now we can use the function to lookup the id's for these, rather than |
254 |
play_sound(sound_magic_event_name2num("Startup")); |
9
by Claude Lecommandeur
CTWM version 3.1 |
255 |
}
|
256 |
||
136.1.14
by Richard Levitte
Add sound.h to declare the sound functions properly. |
257 |
void
|
258 |
play_exit_sound(void) |
|
9
by Claude Lecommandeur
CTWM version 3.1 |
259 |
{
|
459.1.9
by Matthew Fuller
Now we can use the function to lookup the id's for these, rather than |
260 |
play_sound(sound_magic_event_name2num("Shutdown")); |
9
by Claude Lecommandeur
CTWM version 3.1 |
261 |
}
|
262 |
||
463.1.9
by Matthew Fuller
Add a flag for when we set sounds in the config file, and refuse to |
263 |
|
264 |
/*
|
|
265 |
* Flag that we loaded sounds from the ctwmrc
|
|
266 |
*/
|
|
267 |
void
|
|
268 |
sound_set_from_config(void) |
|
269 |
{
|
|
270 |
sound_from_config = 1; |
|
271 |
}
|
|
272 |
||
273 |
||
9
by Claude Lecommandeur
CTWM version 3.1 |
274 |
/*
|
275 |
* Toggle the sound on/off
|
|
276 |
*/
|
|
136.1.14
by Richard Levitte
Add sound.h to declare the sound functions properly. |
277 |
void
|
304.1.2
by Matthew Fuller
Run 'make indent' to reindent the world. |
278 |
toggle_sound(void) |
9
by Claude Lecommandeur
CTWM version 3.1 |
279 |
{
|
304.1.2
by Matthew Fuller
Run 'make indent' to reindent the world. |
280 |
sound_state ^= 1; |
9
by Claude Lecommandeur
CTWM version 3.1 |
281 |
}
|
282 |
||
283 |
||
284 |
/*
|
|
285 |
* Re-read the sounds mapping file
|
|
286 |
*/
|
|
136.1.14
by Richard Levitte
Add sound.h to declare the sound functions properly. |
287 |
void
|
304.1.2
by Matthew Fuller
Run 'make indent' to reindent the world. |
288 |
reread_sounds(void) |
9
by Claude Lecommandeur
CTWM version 3.1 |
289 |
{
|
463.1.2
by Matthew Fuller
Split up sound subsystem init from parsing the .ctwm-sounds file for |
290 |
sound_load_list(); |
9
by Claude Lecommandeur
CTWM version 3.1 |
291 |
}
|
292 |
||
293 |
/*
|
|
294 |
* Set the SoundHost and force the sound_fd to be re-opened.
|
|
295 |
*/
|
|
136.1.14
by Richard Levitte
Add sound.h to declare the sound functions properly. |
296 |
void
|
297 |
set_sound_host(char *host) |
|
9
by Claude Lecommandeur
CTWM version 3.1 |
298 |
{
|
459.1.3
by Matthew Fuller
Use strncpy() when copying into hostname so we can't blow it out. |
299 |
strncpy(hostname, host, HOSTNAME_LEN - 1); |
300 |
hostname[HOSTNAME_LEN - 1] = '\0'; /* JIC */ |
|
304.1.2
by Matthew Fuller
Run 'make indent' to reindent the world. |
301 |
if(sound_fd != 0) { |
9
by Claude Lecommandeur
CTWM version 3.1 |
302 |
rplay_close(sound_fd); |
303 |
}
|
|
304 |
sound_fd = 0; |
|
305 |
}
|
|
306 |
||
459.1.4
by Matthew Fuller
Break out actually setting the sound for a given even into a separate |
307 |
/*
|
308 |
* Set the sound to play for a given event
|
|
309 |
*/
|
|
463.1.12
by Matthew Fuller
Make these setter funcs actually return info about whether they |
310 |
int
|
459.1.5
by Matthew Fuller
Add a set_sound_event_name() function to take the event name (versus |
311 |
set_sound_event_name(const char *ename, const char *soundfile) |
312 |
{
|
|
313 |
int i; |
|
314 |
||
459.1.11
by Matthew Fuller
Update set_sound_event_name() to use our local magic lookup and new |
315 |
/* Find the index we'll use in rp[] for it */
|
316 |
i = sound_magic_event_name2num(ename); |
|
317 |
if(i < 0) { |
|
318 |
i = event_num_by_name(ename); |
|
319 |
}
|
|
320 |
if(i < 0) { |
|
463.1.12
by Matthew Fuller
Make these setter funcs actually return info about whether they |
321 |
return -1; |
459.1.11
by Matthew Fuller
Update set_sound_event_name() to use our local magic lookup and new |
322 |
}
|
323 |
||
324 |
/* Gotcha */
|
|
463.1.34
by Matthew Fuller
Pass the set_sound_event() return straight through instead of ignoring |
325 |
return set_sound_event(i, soundfile); |
459.1.5
by Matthew Fuller
Add a set_sound_event_name() function to take the event name (versus |
326 |
}
|
327 |
||
463.1.12
by Matthew Fuller
Make these setter funcs actually return info about whether they |
328 |
int
|
459.1.4
by Matthew Fuller
Break out actually setting the sound for a given even into a separate |
329 |
set_sound_event(int snd, const char *soundfile) |
330 |
{
|
|
459.1.16
by Matthew Fuller
Add a guard to be sure this doesn't get called too early. |
331 |
/* This shouldn't get called before things are initialized */
|
332 |
if(rp == NULL) { |
|
333 |
fprintf(stderr, "%s(): internal error: called before initialized.\n", __func__); |
|
334 |
exit(1); |
|
335 |
}
|
|
336 |
||
459.1.4
by Matthew Fuller
Break out actually setting the sound for a given even into a separate |
337 |
/* Cleanup old if necessary */
|
338 |
if(rp[snd] != NULL) { |
|
339 |
rplay_destroy(rp[snd]); |
|
340 |
}
|
|
341 |
||
342 |
/* Setup new */
|
|
343 |
rp[snd] = rplay_create(RPLAY_PLAY); |
|
344 |
if(rp[snd] == NULL) { |
|
345 |
rplay_perror("create"); |
|
463.1.12
by Matthew Fuller
Make these setter funcs actually return info about whether they |
346 |
return -1; |
459.1.4
by Matthew Fuller
Break out actually setting the sound for a given even into a separate |
347 |
}
|
348 |
if(rplay_set(rp[snd], RPLAY_INSERT, 0, RPLAY_SOUND, soundfile, NULL) |
|
459.1.23
by Matthew Fuller
make indent. |
349 |
< 0) { |
459.1.4
by Matthew Fuller
Break out actually setting the sound for a given even into a separate |
350 |
rplay_perror("rplay"); |
351 |
}
|
|
352 |
||
463.1.12
by Matthew Fuller
Make these setter funcs actually return info about whether they |
353 |
return 0; |
459.1.4
by Matthew Fuller
Break out actually setting the sound for a given even into a separate |
354 |
}
|