Mercurial > pidgin.yaz
annotate src/gtksound.c @ 8705:543b19a96ac5
[gaim-migrate @ 9458]
" All preferences in gaim, except for "No sounds when you
log in", are "positive" preferences. For consistency
and to make it a bit easier to understand the
preference I think they should all be "positive"
preferences (there's probably something about this in
some HIG somewhere too)
This patch:
1. changes "No sounds when you log in" to "Sounds when
you log in"
2. adds a helper function for renaming old boolean
prefs and inverting their meaning
(gaim_prefs_rename_boolean_toggle)
3. Moves existing renames from prefs.c to gtkprefs.c
because they all reference gtk preferences.
Default behaviour for new users remains the same (no
sounds during log in), and existing user's preferences
are migrated correctly." --Stu Tomlinson
at one point possitive preferences were policy, i think we should maintain that policy.
committer: Tailor Script <tailor@pidgin.im>
author | Luke Schierer <lschiere@pidgin.im> |
---|---|
date | Sun, 18 Apr 2004 19:30:19 +0000 |
parents | f8292be3b45c |
children | fa6c2d893c51 |
rev | line source |
---|---|
5684 | 1 /* |
2 * gaim | |
3 * | |
8046 | 4 * Gaim is the legal property of its developers, whose names are too numerous |
5 * to list here. Please refer to the COPYRIGHT file distributed with this | |
6 * source distribution. | |
5684 | 7 * |
8 * This program is free software; you can redistribute it and/or modify | |
9 * it under the terms of the GNU General Public License as published by | |
10 * the Free Software Foundation; either version 2 of the License, or | |
11 * (at your option) any later version. | |
12 * | |
13 * This program is distributed in the hope that it will be useful, | |
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 * GNU General Public License for more details. | |
17 * | |
18 * You should have received a copy of the GNU General Public License | |
19 * along with this program; if not, write to the Free Software | |
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
21 * | |
22 */ | |
6371
8f94cce8faa5
[gaim-migrate @ 6876]
Christian Hammond <chipx86@chipx86.com>
parents:
6199
diff
changeset
|
23 #include "gtkinternal.h" |
5684 | 24 |
5872
059d95c67cda
[gaim-migrate @ 6304]
Christian Hammond <chipx86@chipx86.com>
parents:
5794
diff
changeset
|
25 #ifdef _WIN32 |
5684 | 26 #include <windows.h> |
27 #include <mmsystem.h> | |
28 #endif | |
29 | |
30 #ifdef USE_AO | |
5872
059d95c67cda
[gaim-migrate @ 6304]
Christian Hammond <chipx86@chipx86.com>
parents:
5794
diff
changeset
|
31 # include <ao/ao.h> |
059d95c67cda
[gaim-migrate @ 6304]
Christian Hammond <chipx86@chipx86.com>
parents:
5794
diff
changeset
|
32 # include <audiofile.h> |
5684 | 33 #endif /* USE_AO */ |
34 | |
35 #ifdef USE_NAS_AUDIO | |
5872
059d95c67cda
[gaim-migrate @ 6304]
Christian Hammond <chipx86@chipx86.com>
parents:
5794
diff
changeset
|
36 # include <audio/audiolib.h> |
059d95c67cda
[gaim-migrate @ 6304]
Christian Hammond <chipx86@chipx86.com>
parents:
5794
diff
changeset
|
37 # include <audio/soundlib.h> |
5684 | 38 #endif /* USE_NAS_AUDIO */ |
39 | |
5872
059d95c67cda
[gaim-migrate @ 6304]
Christian Hammond <chipx86@chipx86.com>
parents:
5794
diff
changeset
|
40 #include "debug.h" |
059d95c67cda
[gaim-migrate @ 6304]
Christian Hammond <chipx86@chipx86.com>
parents:
5794
diff
changeset
|
41 #include "notify.h" |
5684 | 42 #include "prefs.h" |
5872
059d95c67cda
[gaim-migrate @ 6304]
Christian Hammond <chipx86@chipx86.com>
parents:
5794
diff
changeset
|
43 #include "sound.h" |
7465 | 44 #include "util.h" |
5684 | 45 |
5872
059d95c67cda
[gaim-migrate @ 6304]
Christian Hammond <chipx86@chipx86.com>
parents:
5794
diff
changeset
|
46 #include "gtksound.h" |
5684 | 47 |
48 | |
49 struct gaim_sound_event { | |
50 char *label; | |
51 char *pref; | |
52 char *def; | |
53 }; | |
54 | |
55 | |
56 | |
57 static gboolean mute_login_sounds = FALSE; | |
58 static gboolean mute_sounds = FALSE; | |
6199 | 59 static gboolean sound_initialized = FALSE; |
5684 | 60 |
61 static struct gaim_sound_event sounds[GAIM_NUM_SOUNDS] = { | |
62 {N_("Buddy logs in"), "login", "arrive.wav"}, | |
63 {N_("Buddy logs out"), "logout", "leave.wav"}, | |
64 {N_("Message received"), "im_recv", "receive.wav"}, | |
65 {N_("Message received begins conversation"), "first_im_recv", "receive.wav"}, | |
66 {N_("Message sent"), "send_im", "send.wav"}, | |
67 {N_("Person enters chat"), "join_chat", "arrive.wav"}, | |
68 {N_("Person leaves chat"), "left_chat", "leave.wav"}, | |
69 {N_("You talk in chat"), "send_chat_msg", "send.wav"}, | |
70 {N_("Others talk in chat"), "chat_msg_recv", "receive.wav"}, | |
71 /* this isn't a terminator, it's the buddy pounce default sound event ;-) */ | |
72 {NULL, "pounce_default", "redalert.wav"}, | |
73 {N_("Someone says your name in chat"), "nick_said", "redalert.wav"} | |
74 }; | |
75 | |
76 #ifdef USE_AO | |
77 static int ao_driver = -1; | |
78 #endif /* USE_AO */ | |
79 | |
5794
5e93fc46d1af
[gaim-migrate @ 6219]
Christian Hammond <chipx86@chipx86.com>
parents:
5684
diff
changeset
|
80 static void _pref_sound_method_changed(const char *name, GaimPrefType type, |
5684 | 81 gpointer val, gpointer data); |
82 | |
83 static void gaim_gtk_sound_init(void) | |
84 { | |
85 gaim_prefs_add_none("/gaim/gtk/sound"); | |
86 gaim_prefs_add_none("/gaim/gtk/sound/enabled"); | |
87 gaim_prefs_add_none("/gaim/gtk/sound/file"); | |
88 gaim_prefs_add_bool("/gaim/gtk/sound/enabled/login", TRUE); | |
89 gaim_prefs_add_string("/gaim/gtk/sound/file/login", ""); | |
90 gaim_prefs_add_bool("/gaim/gtk/sound/enabled/logout", TRUE); | |
91 gaim_prefs_add_string("/gaim/gtk/sound/file/logout", ""); | |
92 gaim_prefs_add_bool("/gaim/gtk/sound/enabled/im_recv", TRUE); | |
93 gaim_prefs_add_string("/gaim/gtk/sound/file/im_recv", ""); | |
94 gaim_prefs_add_bool("/gaim/gtk/sound/enabled/first_im_recv", FALSE); | |
95 gaim_prefs_add_string("/gaim/gtk/sound/file/first_im_recv", ""); | |
96 gaim_prefs_add_bool("/gaim/gtk/sound/enabled/send_im", TRUE); | |
97 gaim_prefs_add_string("/gaim/gtk/sound/file/send_im", ""); | |
98 gaim_prefs_add_bool("/gaim/gtk/sound/enabled/join_chat", FALSE); | |
99 gaim_prefs_add_string("/gaim/gtk/sound/file/join_chat", ""); | |
100 gaim_prefs_add_bool("/gaim/gtk/sound/enabled/left_chat", FALSE); | |
101 gaim_prefs_add_string("/gaim/gtk/sound/file/left_chat", ""); | |
102 gaim_prefs_add_bool("/gaim/gtk/sound/enabled/send_chat_msg", FALSE); | |
103 gaim_prefs_add_string("/gaim/gtk/sound/file/send_chat_msg", ""); | |
104 gaim_prefs_add_bool("/gaim/gtk/sound/enabled/chat_msg_recv", FALSE); | |
105 gaim_prefs_add_string("/gaim/gtk/sound/file/chat_msg_recv", ""); | |
106 gaim_prefs_add_bool("/gaim/gtk/sound/enabled/nick_said", FALSE); | |
107 gaim_prefs_add_string("/gaim/gtk/sound/file/nick_said", ""); | |
7460
3973a09525b3
[gaim-migrate @ 8073]
Christian Hammond <chipx86@chipx86.com>
parents:
7035
diff
changeset
|
108 gaim_prefs_add_bool("/gaim/gtk/sound/enabled/pounce_default", TRUE); |
3973a09525b3
[gaim-migrate @ 8073]
Christian Hammond <chipx86@chipx86.com>
parents:
7035
diff
changeset
|
109 gaim_prefs_add_string("/gaim/gtk/sound/file/pounce_default", ""); |
8705 | 110 gaim_prefs_add_bool("/gaim/gtk/sound/signon", FALSE); |
8633 | 111 gaim_prefs_add_bool("/gaim/gtk/sound/conv_focus", TRUE); |
5684 | 112 gaim_prefs_add_string("/gaim/gtk/sound/command", ""); |
113 gaim_prefs_add_string("/gaim/gtk/sound/method", "automatic"); | |
114 | |
115 #ifdef USE_AO | |
116 gaim_debug(GAIM_DEBUG_INFO, "sound", | |
117 "Initializing sound output drivers.\n"); | |
118 ao_initialize(); | |
119 #endif /* USE_AO */ | |
120 | |
121 gaim_prefs_connect_callback("/gaim/gtk/sound/method", | |
5794
5e93fc46d1af
[gaim-migrate @ 6219]
Christian Hammond <chipx86@chipx86.com>
parents:
5684
diff
changeset
|
122 _pref_sound_method_changed, NULL); |
5684 | 123 } |
124 | |
125 | |
126 static void gaim_gtk_sound_shutdown(void) | |
127 { | |
128 #ifdef USE_AO | |
129 ao_shutdown(); | |
130 #endif | |
6199 | 131 sound_initialized = FALSE; |
5684 | 132 } |
133 | |
134 static void gaim_gtk_sound_play_file(const char *filename) | |
135 { | |
136 const char *method; | |
137 #if defined(USE_NAS_AUDIO) || defined(USE_AO) | |
138 pid_t pid; | |
139 #ifdef USE_AO | |
140 AFfilehandle file; | |
141 #endif | |
142 #endif | |
143 | |
6199 | 144 if (!sound_initialized) |
145 gaim_prefs_trigger_callback("/gaim/gtk/sound/method"); | |
146 | |
5684 | 147 if (mute_sounds) |
148 return; | |
149 | |
150 method = gaim_prefs_get_string("/gaim/gtk/sound/method"); | |
151 | |
152 if (!strcmp(method, "beep")) { | |
153 gdk_beep(); | |
154 return; | |
155 } | |
156 | |
157 if (!g_file_test(filename, G_FILE_TEST_EXISTS)) { | |
158 char *tmp = g_strdup_printf(_("Unable to play sound because the chosen file (%s) does not exist."), filename); | |
159 gaim_notify_error(NULL, NULL, tmp, NULL); | |
160 g_free(tmp); | |
161 return; | |
162 } | |
163 | |
164 #ifndef _WIN32 | |
165 if (!strcmp(method, "custom")) { | |
166 const char *sound_cmd; | |
167 char *command; | |
168 GError *error = NULL; | |
169 | |
170 sound_cmd = gaim_prefs_get_string("/gaim/gtk/sound/command"); | |
171 | |
172 if (!sound_cmd || *sound_cmd == '\0') { | |
173 gaim_notify_error(NULL, NULL, | |
174 _("Unable to play sound because the " | |
175 "'Command' sound method has been chosen, " | |
176 "but no command has been set."), NULL); | |
177 return; | |
178 } | |
179 | |
7464 | 180 if(strstr(sound_cmd, "%s")) |
181 command = gaim_strreplace(sound_cmd, "%s", filename); | |
182 else | |
183 command = g_strdup_printf("%s %s", sound_cmd, filename); | |
5684 | 184 |
185 if(!g_spawn_command_line_async(command, &error)) { | |
186 char *tmp = g_strdup_printf(_("Unable to play sound because the configured sound command could not be launched: %s"), error->message); | |
187 gaim_notify_error(NULL, NULL, tmp, NULL); | |
188 g_free(tmp); | |
189 g_error_free(error); | |
190 } | |
191 | |
192 g_free(command); | |
193 return; | |
194 } | |
195 #if defined(USE_NAS_AUDIO) || defined(USE_AO) | |
196 pid = fork(); | |
197 if (pid < 0) | |
198 return; | |
199 else if (pid == 0) { | |
200 #ifdef USE_NAS_AUDIO | |
201 if (!strcmp(method, "nas")) { | |
202 if (play_file_nas(filename)) | |
203 _exit(0); | |
204 } | |
205 #endif /* USE_NAS_AUDIO */ | |
206 | |
207 #ifdef USE_AO | |
208 file = afOpenFile(filename, "rb", NULL); | |
209 if(file) { | |
210 ao_device *device; | |
211 ao_sample_format format; | |
212 int in_fmt; | |
213 int bytes_per_frame; | |
214 | |
215 format.rate = afGetRate(file, AF_DEFAULT_TRACK); | |
216 format.channels = afGetChannels(file, AF_DEFAULT_TRACK); | |
217 afGetSampleFormat(file, AF_DEFAULT_TRACK, &in_fmt, | |
218 &format.bits); | |
219 | |
220 /* XXX: libao doesn't seem to like 8-bit sounds, so we'll | |
221 * let libaudiofile make them a bit better for us */ | |
222 if(format.bits == 8) | |
223 format.bits = 16; | |
224 | |
225 afSetVirtualSampleFormat(file, AF_DEFAULT_TRACK, | |
226 AF_SAMPFMT_TWOSCOMP, format.bits); | |
227 | |
228 #if __BYTE_ORDER == __BIG_ENDIAN | |
229 format.byte_format = AO_FMT_BIG; | |
230 afSetVirtualByteOrder(file, AF_DEFAULT_TRACK, | |
231 AF_BYTEORDER_BIGENDIAN); | |
232 #elif __BYTE_ORDER == __LITTLE_ENDIAN | |
233 format.byte_format = AO_FMT_LITTLE; | |
234 afSetVirtualByteOrder(file, AF_DEFAULT_TRACK, | |
235 AF_BYTEORDER_LITTLEENDIAN); | |
236 #endif | |
237 | |
238 bytes_per_frame = format.bits * format.channels / 8; | |
239 | |
240 device = ao_open_live(ao_driver, &format, NULL); | |
241 | |
242 if(device) { | |
243 int frames_read; | |
244 char buf[4096]; | |
245 int buf_frames = sizeof(buf) / bytes_per_frame; | |
246 | |
247 while((frames_read = afReadFrames(file, AF_DEFAULT_TRACK, | |
248 buf, buf_frames))) { | |
249 if(!ao_play(device, buf, frames_read * bytes_per_frame)) | |
250 break; | |
251 } | |
252 ao_close(device); | |
253 } | |
254 afCloseFile(file); | |
255 } | |
256 ao_shutdown(); | |
257 #endif /* USE_AO */ | |
258 _exit(0); | |
259 } | |
260 #else /* USE_NAS_AUDIO || USE_AO */ | |
261 gdk_beep(); | |
262 return; | |
263 #endif /* USE_NAS_AUDIO || USE_AO */ | |
264 #else /* _WIN32 */ | |
265 gaim_debug(GAIM_DEBUG_INFO, "sound", "Playing %s\n", filename); | |
266 | |
267 if (!PlaySound(filename, 0, SND_ASYNC | SND_FILENAME)) | |
268 gaim_debug(GAIM_DEBUG_ERROR, "sound", "Error playing sound.\n"); | |
269 #endif /* _WIN32 */ | |
270 } | |
271 | |
272 static void gaim_gtk_sound_play_event(GaimSoundEventID event) | |
273 { | |
274 char *enable_pref; | |
275 char *file_pref; | |
276 | |
277 if ((event == GAIM_SOUND_BUDDY_ARRIVE) && mute_login_sounds) | |
278 return; | |
279 | |
280 if (event >= GAIM_NUM_SOUNDS) { | |
281 gaim_debug(GAIM_DEBUG_MISC, "sound", | |
282 "got request for unknown sound: %d\n", event); | |
283 return; | |
284 } | |
285 | |
286 enable_pref = g_strdup_printf("/gaim/gtk/sound/enabled/%s", | |
287 sounds[event].pref); | |
288 file_pref = g_strdup_printf("/gaim/gtk/sound/file/%s", sounds[event].pref); | |
289 | |
290 /* check NULL for sounds that don't have an option, ie buddy pounce */ | |
291 if (gaim_prefs_get_bool(enable_pref)) { | |
292 char *filename = g_strdup(gaim_prefs_get_string(file_pref)); | |
293 if(!filename || !strlen(filename)) { | |
294 if(filename) g_free(filename); | |
295 filename = g_build_filename(DATADIR, "sounds", "gaim", sounds[event].def, NULL); | |
296 } | |
297 | |
298 gaim_sound_play_file(filename); | |
299 g_free(filename); | |
300 } | |
301 | |
302 g_free(enable_pref); | |
303 g_free(file_pref); | |
304 } | |
305 | |
306 static GaimSoundUiOps sound_ui_ops = | |
307 { | |
308 gaim_gtk_sound_init, | |
309 gaim_gtk_sound_shutdown, | |
310 gaim_gtk_sound_play_file, | |
311 gaim_gtk_sound_play_event | |
312 }; | |
313 | |
7035
feb3d21a7794
[gaim-migrate @ 7598]
Christian Hammond <chipx86@chipx86.com>
parents:
6778
diff
changeset
|
314 GaimSoundUiOps * |
feb3d21a7794
[gaim-migrate @ 7598]
Christian Hammond <chipx86@chipx86.com>
parents:
6778
diff
changeset
|
315 gaim_gtk_sound_get_ui_ops(void) |
5684 | 316 { |
317 return &sound_ui_ops; | |
318 } | |
319 | |
320 | |
5794
5e93fc46d1af
[gaim-migrate @ 6219]
Christian Hammond <chipx86@chipx86.com>
parents:
5684
diff
changeset
|
321 static void _pref_sound_method_changed(const char *name, GaimPrefType type, |
5684 | 322 gpointer val, gpointer data) { |
6778 | 323 if(type != GAIM_PREF_STRING || strcmp(name, "/gaim/gtk/sound/method")) |
324 return; | |
325 | |
6199 | 326 sound_initialized = TRUE; |
327 | |
5684 | 328 #ifdef USE_AO |
329 ao_driver = -1; | |
330 | |
331 if(!strcmp(val, "esd")) | |
332 ao_driver = ao_driver_id("esd"); | |
333 else if(!strcmp(val, "arts")) | |
334 ao_driver = ao_driver_id("arts"); | |
335 else if(!strcmp(val, "automatic")) | |
336 ao_driver = ao_default_driver_id(); | |
337 | |
338 if(ao_driver != -1) { | |
339 ao_info *info = ao_driver_info(ao_driver); | |
340 gaim_debug(GAIM_DEBUG_INFO, "sound", | |
341 "Sound output driver loaded: %s\n", info->name); | |
342 } | |
343 #endif /* USE_AO */ | |
344 #ifdef USE_NAS | |
345 if (!strcmp(val, "nas")) | |
346 gaim_debug(GAIM_DEBUG_INFO, "sound", | |
347 "Sound output driver loaded: NAS output\n"); | |
348 #endif /* USE_NAS */ | |
349 } | |
350 | |
351 #ifdef USE_NAS_AUDIO | |
352 static gboolean play_file_nas(const char *filename) | |
353 { | |
354 AuServer *nas_serv; | |
355 gboolean ret = FALSE; | |
356 | |
357 if((nas_serv = AuOpenServer(NULL, 0, NULL, 0, NULL, NULL))) { | |
358 ret = AuSoundPlaySynchronousFromFile(nas_serv, filename, 100); | |
359 AuCloseServer(nas_serv); | |
360 } | |
361 | |
362 return ret; | |
363 } | |
364 | |
365 #endif /* USE_NAS_AUDIO */ | |
366 | |
367 void gaim_gtk_sound_set_mute(gboolean mute) | |
368 { | |
369 mute_sounds = mute; | |
370 } | |
371 | |
372 gboolean gaim_gtk_sound_get_mute() | |
373 { | |
374 return mute_sounds; | |
375 } | |
376 | |
377 void gaim_gtk_sound_set_login_mute(gboolean mute) | |
378 { | |
379 mute_login_sounds = mute; | |
380 } | |
381 | |
382 const char *gaim_gtk_sound_get_event_option(GaimSoundEventID event) | |
383 { | |
384 if(event >= GAIM_NUM_SOUNDS) | |
385 return 0; | |
386 | |
387 return sounds[event].pref; | |
388 } | |
389 | |
390 char *gaim_gtk_sound_get_event_label(GaimSoundEventID event) | |
391 { | |
392 if(event >= GAIM_NUM_SOUNDS) | |
393 return NULL; | |
394 | |
395 return sounds[event].label; | |
396 } | |
397 |