Mercurial > pidgin
annotate src/gtksound.c @ 6371:8f94cce8faa5
[gaim-migrate @ 6876]
I think I touched almost every file. Here's what happened.
I started off fixing up the Makefile.am and configure.ac files to help with
the core/UI split some. Then I got annoyed with the
build_{allow,deny}_list() functions that everything used, and decided to
core/UI split privacy. While doing that, I decided to redesign the dialog.
So now, a lot has changed, but not really so much. Just that most files
got affected.
Oh yeah, and the UI stuff was taken out of internal.h and moved to
gtkinternal.h. If you use this, please be aware of this change.
committer: Tailor Script <tailor@pidgin.im>
author | Christian Hammond <chipx86@chipx86.com> |
---|---|
date | Tue, 05 Aug 2003 10:55:04 +0000 |
parents | eb0fedc1ac09 |
children | 74d1cd241a3d |
rev | line source |
---|---|
5684 | 1 /* |
2 * gaim | |
3 * | |
4 * Copyright (C) 1998-1999, Mark Spencer <markster@marko.net> | |
5 * Copyright (C) 2003, Nathan Walp <faceprint@faceprint.com> | |
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, write to the Free Software | |
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
20 * | |
21 */ | |
6371
8f94cce8faa5
[gaim-migrate @ 6876]
Christian Hammond <chipx86@chipx86.com>
parents:
6199
diff
changeset
|
22 #include "gtkinternal.h" |
5684 | 23 |
5872
059d95c67cda
[gaim-migrate @ 6304]
Christian Hammond <chipx86@chipx86.com>
parents:
5794
diff
changeset
|
24 #ifdef _WIN32 |
5684 | 25 #include <windows.h> |
26 #include <mmsystem.h> | |
27 #endif | |
28 | |
29 #ifdef USE_AO | |
5872
059d95c67cda
[gaim-migrate @ 6304]
Christian Hammond <chipx86@chipx86.com>
parents:
5794
diff
changeset
|
30 # include <ao/ao.h> |
059d95c67cda
[gaim-migrate @ 6304]
Christian Hammond <chipx86@chipx86.com>
parents:
5794
diff
changeset
|
31 # include <audiofile.h> |
5684 | 32 #endif /* USE_AO */ |
33 | |
34 #ifdef USE_NAS_AUDIO | |
5872
059d95c67cda
[gaim-migrate @ 6304]
Christian Hammond <chipx86@chipx86.com>
parents:
5794
diff
changeset
|
35 # include <audio/audiolib.h> |
059d95c67cda
[gaim-migrate @ 6304]
Christian Hammond <chipx86@chipx86.com>
parents:
5794
diff
changeset
|
36 # include <audio/soundlib.h> |
5684 | 37 #endif /* USE_NAS_AUDIO */ |
38 | |
5872
059d95c67cda
[gaim-migrate @ 6304]
Christian Hammond <chipx86@chipx86.com>
parents:
5794
diff
changeset
|
39 #include "debug.h" |
059d95c67cda
[gaim-migrate @ 6304]
Christian Hammond <chipx86@chipx86.com>
parents:
5794
diff
changeset
|
40 #include "notify.h" |
5684 | 41 #include "prefs.h" |
5872
059d95c67cda
[gaim-migrate @ 6304]
Christian Hammond <chipx86@chipx86.com>
parents:
5794
diff
changeset
|
42 #include "sound.h" |
5684 | 43 |
5872
059d95c67cda
[gaim-migrate @ 6304]
Christian Hammond <chipx86@chipx86.com>
parents:
5794
diff
changeset
|
44 #include "gtksound.h" |
5684 | 45 |
46 | |
47 struct gaim_sound_event { | |
48 char *label; | |
49 char *pref; | |
50 char *def; | |
51 }; | |
52 | |
53 | |
54 | |
55 static gboolean mute_login_sounds = FALSE; | |
56 static gboolean mute_sounds = FALSE; | |
6199 | 57 static gboolean sound_initialized = FALSE; |
5684 | 58 static char *sound_cmd = NULL; |
59 | |
60 static struct gaim_sound_event sounds[GAIM_NUM_SOUNDS] = { | |
61 {N_("Buddy logs in"), "login", "arrive.wav"}, | |
62 {N_("Buddy logs out"), "logout", "leave.wav"}, | |
63 {N_("Message received"), "im_recv", "receive.wav"}, | |
64 {N_("Message received begins conversation"), "first_im_recv", "receive.wav"}, | |
65 {N_("Message sent"), "send_im", "send.wav"}, | |
66 {N_("Person enters chat"), "join_chat", "arrive.wav"}, | |
67 {N_("Person leaves chat"), "left_chat", "leave.wav"}, | |
68 {N_("You talk in chat"), "send_chat_msg", "send.wav"}, | |
69 {N_("Others talk in chat"), "chat_msg_recv", "receive.wav"}, | |
70 /* this isn't a terminator, it's the buddy pounce default sound event ;-) */ | |
71 {NULL, "pounce_default", "redalert.wav"}, | |
72 {N_("Someone says your name in chat"), "nick_said", "redalert.wav"} | |
73 }; | |
74 | |
75 #ifdef USE_AO | |
76 static int ao_driver = -1; | |
77 #endif /* USE_AO */ | |
78 | |
5794
5e93fc46d1af
[gaim-migrate @ 6219]
Christian Hammond <chipx86@chipx86.com>
parents:
5684
diff
changeset
|
79 static void _pref_sound_method_changed(const char *name, GaimPrefType type, |
5684 | 80 gpointer val, gpointer data); |
81 | |
82 static void gaim_gtk_sound_init(void) | |
83 { | |
84 gaim_prefs_add_none("/gaim/gtk/sound"); | |
85 gaim_prefs_add_none("/gaim/gtk/sound/enabled"); | |
86 gaim_prefs_add_none("/gaim/gtk/sound/file"); | |
87 gaim_prefs_add_bool("/gaim/gtk/sound/enabled/login", TRUE); | |
88 gaim_prefs_add_string("/gaim/gtk/sound/file/login", ""); | |
89 gaim_prefs_add_bool("/gaim/gtk/sound/enabled/logout", TRUE); | |
90 gaim_prefs_add_string("/gaim/gtk/sound/file/logout", ""); | |
91 gaim_prefs_add_bool("/gaim/gtk/sound/enabled/im_recv", TRUE); | |
92 gaim_prefs_add_string("/gaim/gtk/sound/file/im_recv", ""); | |
93 gaim_prefs_add_bool("/gaim/gtk/sound/enabled/first_im_recv", FALSE); | |
94 gaim_prefs_add_string("/gaim/gtk/sound/file/first_im_recv", ""); | |
95 gaim_prefs_add_bool("/gaim/gtk/sound/enabled/send_im", TRUE); | |
96 gaim_prefs_add_string("/gaim/gtk/sound/file/send_im", ""); | |
97 gaim_prefs_add_bool("/gaim/gtk/sound/enabled/join_chat", FALSE); | |
98 gaim_prefs_add_string("/gaim/gtk/sound/file/join_chat", ""); | |
99 gaim_prefs_add_bool("/gaim/gtk/sound/enabled/left_chat", FALSE); | |
100 gaim_prefs_add_string("/gaim/gtk/sound/file/left_chat", ""); | |
101 gaim_prefs_add_bool("/gaim/gtk/sound/enabled/send_chat_msg", FALSE); | |
102 gaim_prefs_add_string("/gaim/gtk/sound/file/send_chat_msg", ""); | |
103 gaim_prefs_add_bool("/gaim/gtk/sound/enabled/chat_msg_recv", FALSE); | |
104 gaim_prefs_add_string("/gaim/gtk/sound/file/chat_msg_recv", ""); | |
105 gaim_prefs_add_bool("/gaim/gtk/sound/enabled/nick_said", FALSE); | |
106 gaim_prefs_add_string("/gaim/gtk/sound/file/nick_said", ""); | |
107 gaim_prefs_add_bool("/gaim/gtk/sound/silent_signon", TRUE); | |
108 gaim_prefs_add_string("/gaim/gtk/sound/command", ""); | |
109 gaim_prefs_add_string("/gaim/gtk/sound/method", "automatic"); | |
110 | |
111 #ifdef USE_AO | |
112 gaim_debug(GAIM_DEBUG_INFO, "sound", | |
113 "Initializing sound output drivers.\n"); | |
114 ao_initialize(); | |
115 #endif /* USE_AO */ | |
116 | |
117 gaim_prefs_connect_callback("/gaim/gtk/sound/method", | |
5794
5e93fc46d1af
[gaim-migrate @ 6219]
Christian Hammond <chipx86@chipx86.com>
parents:
5684
diff
changeset
|
118 _pref_sound_method_changed, NULL); |
5684 | 119 } |
120 | |
121 | |
122 static void gaim_gtk_sound_shutdown(void) | |
123 { | |
124 #ifdef USE_AO | |
125 ao_shutdown(); | |
126 #endif | |
6199 | 127 sound_initialized = FALSE; |
5684 | 128 } |
129 | |
130 static void gaim_gtk_sound_play_file(const char *filename) | |
131 { | |
132 const char *method; | |
133 #if defined(USE_NAS_AUDIO) || defined(USE_AO) | |
134 pid_t pid; | |
135 #ifdef USE_AO | |
136 AFfilehandle file; | |
137 #endif | |
138 #endif | |
139 | |
6199 | 140 if (!sound_initialized) |
141 gaim_prefs_trigger_callback("/gaim/gtk/sound/method"); | |
142 | |
5684 | 143 if (mute_sounds) |
144 return; | |
145 | |
146 method = gaim_prefs_get_string("/gaim/gtk/sound/method"); | |
147 | |
148 if (!strcmp(method, "beep")) { | |
149 gdk_beep(); | |
150 return; | |
151 } | |
152 | |
153 if (!g_file_test(filename, G_FILE_TEST_EXISTS)) { | |
154 char *tmp = g_strdup_printf(_("Unable to play sound because the chosen file (%s) does not exist."), filename); | |
155 gaim_notify_error(NULL, NULL, tmp, NULL); | |
156 g_free(tmp); | |
157 return; | |
158 } | |
159 | |
160 #ifndef _WIN32 | |
161 if (!strcmp(method, "custom")) { | |
162 const char *sound_cmd; | |
163 char *command; | |
164 GError *error = NULL; | |
165 | |
166 sound_cmd = gaim_prefs_get_string("/gaim/gtk/sound/command"); | |
167 | |
168 if (!sound_cmd || *sound_cmd == '\0') { | |
169 gaim_notify_error(NULL, NULL, | |
170 _("Unable to play sound because the " | |
171 "'Command' sound method has been chosen, " | |
172 "but no command has been set."), NULL); | |
173 return; | |
174 } | |
175 | |
176 command = g_strdup_printf(sound_cmd, filename); | |
177 | |
178 if(!g_spawn_command_line_async(command, &error)) { | |
179 char *tmp = g_strdup_printf(_("Unable to play sound because the configured sound command could not be launched: %s"), error->message); | |
180 gaim_notify_error(NULL, NULL, tmp, NULL); | |
181 g_free(tmp); | |
182 g_error_free(error); | |
183 } | |
184 | |
185 g_free(command); | |
186 return; | |
187 } | |
188 #if defined(USE_NAS_AUDIO) || defined(USE_AO) | |
189 pid = fork(); | |
190 if (pid < 0) | |
191 return; | |
192 else if (pid == 0) { | |
193 #ifdef USE_NAS_AUDIO | |
194 if (!strcmp(method, "nas")) { | |
195 if (play_file_nas(filename)) | |
196 _exit(0); | |
197 } | |
198 #endif /* USE_NAS_AUDIO */ | |
199 | |
200 #ifdef USE_AO | |
201 file = afOpenFile(filename, "rb", NULL); | |
202 if(file) { | |
203 ao_device *device; | |
204 ao_sample_format format; | |
205 int in_fmt; | |
206 int bytes_per_frame; | |
207 | |
208 format.rate = afGetRate(file, AF_DEFAULT_TRACK); | |
209 format.channels = afGetChannels(file, AF_DEFAULT_TRACK); | |
210 afGetSampleFormat(file, AF_DEFAULT_TRACK, &in_fmt, | |
211 &format.bits); | |
212 | |
213 /* XXX: libao doesn't seem to like 8-bit sounds, so we'll | |
214 * let libaudiofile make them a bit better for us */ | |
215 if(format.bits == 8) | |
216 format.bits = 16; | |
217 | |
218 afSetVirtualSampleFormat(file, AF_DEFAULT_TRACK, | |
219 AF_SAMPFMT_TWOSCOMP, format.bits); | |
220 | |
221 #if __BYTE_ORDER == __BIG_ENDIAN | |
222 format.byte_format = AO_FMT_BIG; | |
223 afSetVirtualByteOrder(file, AF_DEFAULT_TRACK, | |
224 AF_BYTEORDER_BIGENDIAN); | |
225 #elif __BYTE_ORDER == __LITTLE_ENDIAN | |
226 format.byte_format = AO_FMT_LITTLE; | |
227 afSetVirtualByteOrder(file, AF_DEFAULT_TRACK, | |
228 AF_BYTEORDER_LITTLEENDIAN); | |
229 #endif | |
230 | |
231 bytes_per_frame = format.bits * format.channels / 8; | |
232 | |
233 device = ao_open_live(ao_driver, &format, NULL); | |
234 | |
235 if(device) { | |
236 int frames_read; | |
237 char buf[4096]; | |
238 int buf_frames = sizeof(buf) / bytes_per_frame; | |
239 | |
240 while((frames_read = afReadFrames(file, AF_DEFAULT_TRACK, | |
241 buf, buf_frames))) { | |
242 if(!ao_play(device, buf, frames_read * bytes_per_frame)) | |
243 break; | |
244 } | |
245 ao_close(device); | |
246 } | |
247 afCloseFile(file); | |
248 } | |
249 ao_shutdown(); | |
250 #endif /* USE_AO */ | |
251 _exit(0); | |
252 } | |
253 #else /* USE_NAS_AUDIO || USE_AO */ | |
254 gdk_beep(); | |
255 return; | |
256 #endif /* USE_NAS_AUDIO || USE_AO */ | |
257 #else /* _WIN32 */ | |
258 gaim_debug(GAIM_DEBUG_INFO, "sound", "Playing %s\n", filename); | |
259 | |
260 if (!PlaySound(filename, 0, SND_ASYNC | SND_FILENAME)) | |
261 gaim_debug(GAIM_DEBUG_ERROR, "sound", "Error playing sound.\n"); | |
262 #endif /* _WIN32 */ | |
263 } | |
264 | |
265 static void gaim_gtk_sound_play_event(GaimSoundEventID event) | |
266 { | |
267 char *enable_pref; | |
268 char *file_pref; | |
269 | |
270 if ((event == GAIM_SOUND_BUDDY_ARRIVE) && mute_login_sounds) | |
271 return; | |
272 | |
273 if (event >= GAIM_NUM_SOUNDS) { | |
274 gaim_debug(GAIM_DEBUG_MISC, "sound", | |
275 "got request for unknown sound: %d\n", event); | |
276 return; | |
277 } | |
278 | |
279 enable_pref = g_strdup_printf("/gaim/gtk/sound/enabled/%s", | |
280 sounds[event].pref); | |
281 file_pref = g_strdup_printf("/gaim/gtk/sound/file/%s", sounds[event].pref); | |
282 | |
283 /* check NULL for sounds that don't have an option, ie buddy pounce */ | |
284 if (gaim_prefs_get_bool(enable_pref)) { | |
285 char *filename = g_strdup(gaim_prefs_get_string(file_pref)); | |
286 if(!filename || !strlen(filename)) { | |
287 if(filename) g_free(filename); | |
288 filename = g_build_filename(DATADIR, "sounds", "gaim", sounds[event].def, NULL); | |
289 } | |
290 | |
291 gaim_sound_play_file(filename); | |
292 g_free(filename); | |
293 } | |
294 | |
295 g_free(enable_pref); | |
296 g_free(file_pref); | |
297 } | |
298 | |
299 static GaimSoundUiOps sound_ui_ops = | |
300 { | |
301 gaim_gtk_sound_init, | |
302 gaim_gtk_sound_shutdown, | |
303 gaim_gtk_sound_play_file, | |
304 gaim_gtk_sound_play_event | |
305 }; | |
306 | |
307 GaimSoundUiOps *gaim_get_gtk_sound_ui_ops(void) | |
308 { | |
309 return &sound_ui_ops; | |
310 } | |
311 | |
312 | |
5794
5e93fc46d1af
[gaim-migrate @ 6219]
Christian Hammond <chipx86@chipx86.com>
parents:
5684
diff
changeset
|
313 static void _pref_sound_method_changed(const char *name, GaimPrefType type, |
5684 | 314 gpointer val, gpointer data) { |
6199 | 315 sound_initialized = TRUE; |
316 | |
5684 | 317 if(type != GAIM_PREF_STRING || strcmp(name, "/gaim/gtk/sound/method")) |
318 return; | |
319 #ifdef USE_AO | |
320 ao_driver = -1; | |
321 | |
322 if(!strcmp(val, "esd")) | |
323 ao_driver = ao_driver_id("esd"); | |
324 else if(!strcmp(val, "arts")) | |
325 ao_driver = ao_driver_id("arts"); | |
326 else if(!strcmp(val, "automatic")) | |
327 ao_driver = ao_default_driver_id(); | |
328 | |
329 if(ao_driver != -1) { | |
330 ao_info *info = ao_driver_info(ao_driver); | |
331 gaim_debug(GAIM_DEBUG_INFO, "sound", | |
332 "Sound output driver loaded: %s\n", info->name); | |
333 } | |
334 #endif /* USE_AO */ | |
335 #ifdef USE_NAS | |
336 if (!strcmp(val, "nas")) | |
337 gaim_debug(GAIM_DEBUG_INFO, "sound", | |
338 "Sound output driver loaded: NAS output\n"); | |
339 #endif /* USE_NAS */ | |
340 } | |
341 | |
342 #ifdef USE_NAS_AUDIO | |
343 static gboolean play_file_nas(const char *filename) | |
344 { | |
345 AuServer *nas_serv; | |
346 gboolean ret = FALSE; | |
347 | |
348 if((nas_serv = AuOpenServer(NULL, 0, NULL, 0, NULL, NULL))) { | |
349 ret = AuSoundPlaySynchronousFromFile(nas_serv, filename, 100); | |
350 AuCloseServer(nas_serv); | |
351 } | |
352 | |
353 return ret; | |
354 } | |
355 | |
356 #endif /* USE_NAS_AUDIO */ | |
357 | |
358 void gaim_gtk_sound_set_mute(gboolean mute) | |
359 { | |
360 mute_sounds = mute; | |
361 } | |
362 | |
363 gboolean gaim_gtk_sound_get_mute() | |
364 { | |
365 return mute_sounds; | |
366 } | |
367 | |
368 void gaim_gtk_sound_set_login_mute(gboolean mute) | |
369 { | |
370 mute_login_sounds = mute; | |
371 } | |
372 | |
373 const char *gaim_gtk_sound_get_event_option(GaimSoundEventID event) | |
374 { | |
375 if(event >= GAIM_NUM_SOUNDS) | |
376 return 0; | |
377 | |
378 return sounds[event].pref; | |
379 } | |
380 | |
381 char *gaim_gtk_sound_get_event_label(GaimSoundEventID event) | |
382 { | |
383 if(event >= GAIM_NUM_SOUNDS) | |
384 return NULL; | |
385 | |
386 return sounds[event].label; | |
387 } | |
388 | |
389 | |
390 void gaim_sound_set_command(const char *cmd) | |
391 { | |
392 if(sound_cmd) | |
393 g_free(sound_cmd); | |
394 if(strlen(cmd) > 0) | |
395 sound_cmd = g_strdup(cmd); | |
396 else | |
397 sound_cmd = NULL; | |
398 } | |
399 | |
400 char *gaim_sound_get_command() | |
401 { | |
402 return sound_cmd; | |
403 } | |
404 |