Mercurial > hg > xemacs-beta
annotate src/sound.c @ 5518:3cc7470ea71c
gnuclient: if TMPDIR was set and connect failed, try again with /tmp
2011-06-03 Aidan Kehoe <kehoea@parhasard.net>
* gnuslib.c (connect_to_unix_server):
Retry with /tmp as a directory in which to search for Unix sockets
if an attempt to connect with some other directory failed (which
may be because gnuclient and gnuserv don't share an environment
value for TMPDIR, or because gnuserv was compiled with USE_TMPDIR
turned off).
author | Aidan Kehoe <kehoea@parhasard.net> |
---|---|
date | Fri, 03 Jun 2011 18:40:57 +0100 |
parents | 308d34e9f07d |
children | 56144c8593a8 |
rev | line source |
---|---|
428 | 1 /* Sound functions. |
2 Copyright (C) 1992, 1993, 1994 Lucid Inc. | |
3 Copyright (C) 1994, 1995 Free Software Foundation, Inc. | |
2526 | 4 Copyright (C) 2002, 2004 Ben Wing. |
428 | 5 |
6 This file is part of XEmacs. | |
7 | |
5402
308d34e9f07d
Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents:
4981
diff
changeset
|
8 XEmacs is free software: you can redistribute it and/or modify it |
428 | 9 under the terms of the GNU General Public License as published by the |
5402
308d34e9f07d
Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents:
4981
diff
changeset
|
10 Free Software Foundation, either version 3 of the License, or (at your |
308d34e9f07d
Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents:
4981
diff
changeset
|
11 option) any later version. |
428 | 12 |
13 XEmacs is distributed in the hope that it will be useful, but WITHOUT | |
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
16 for more details. | |
17 | |
18 You should have received a copy of the GNU General Public License | |
5402
308d34e9f07d
Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents:
4981
diff
changeset
|
19 along with XEmacs. If not, see <http://www.gnu.org/licenses/>. */ |
428 | 20 |
21 /* Synched up with: Not in FSF. */ | |
22 | |
563 | 23 /* This file Mule-ized by Ben Wing, 5-15-01. */ |
24 | |
428 | 25 /* Originally written by Jamie Zawinski. |
26 Hacked on quite a bit by various others. */ | |
27 | |
28 #include <config.h> | |
29 #include <time.h> | |
30 #include "lisp.h" | |
31 | |
32 #include "buffer.h" | |
33 #ifdef HAVE_X_WINDOWS | |
872 | 34 #include "console-x-impl.h" |
428 | 35 #endif |
872 | 36 #include "device-impl.h" |
428 | 37 #include "redisplay.h" |
563 | 38 #include "sound.h" |
39 | |
428 | 40 #include "sysdep.h" |
41 | |
442 | 42 #include "sysfile.h" |
428 | 43 |
44 #ifdef HAVE_NATIVE_SOUND | |
442 | 45 # include "sysproc.h" |
428 | 46 #endif |
47 | |
872 | 48 #ifdef WIN32_NATIVE |
49 #include "syswindows.h" | |
50 #endif | |
51 | |
3072 | 52 #ifdef HAVE_NAS_SOUND |
53 #define USED_IF_HAVE_NAS(decl) decl | |
54 #else | |
55 #define USED_IF_HAVE_NAS(decl) UNUSED (decl) | |
56 #endif | |
57 | |
58 #if defined(HAVE_NATIVE_SOUND) || defined(HAVE_NAS_SOUND) | |
59 #define USED_IF_HAVE_NATIVE_OR_NAS(decl) decl | |
60 #else | |
61 #define USED_IF_HAVE_NATIVE_OR_NAS(decl) UNUSED (decl) | |
62 #endif | |
63 | |
64 #if defined(HAVE_NATIVE_SOUND) || defined(HAVE_NAS_SOUND) \ | |
4343
fb73a2046d3e
Fix unused parameter warnings when compiling with ALSA sound support.
Jerry James <james@xemacs.org>
parents:
3731
diff
changeset
|
65 || defined(HAVE_ALSA_SOUND) || defined(HAVE_ESD_SOUND) |
3072 | 66 #define USED_IF_HAVE_ANY(decl) decl |
67 #else | |
68 #define USED_IF_HAVE_ANY(decl) UNUSED (decl) | |
69 #endif | |
70 | |
3308 | 71 #ifdef HAVE_ALSA_SOUND |
72 extern int alsa_play_sound_file (const Extbyte *file, int vol); | |
73 extern int alsa_play_sound_data (const Binbyte *data, int length, int vol); | |
74 # define DEVICE_CONNECTED_TO_ALSA_P(x) 1 /* #### better check */ | |
75 #endif | |
76 | |
428 | 77 #ifdef HAVE_ESD_SOUND |
563 | 78 extern int esd_play_sound_file (Extbyte *file, int vol); |
2367 | 79 extern int esd_play_sound_data (Binbyte *data, size_t length, int vol); |
563 | 80 # define DEVICE_CONNECTED_TO_ESD_P(x) 1 /* #### better check */ |
428 | 81 #endif |
82 | |
3308 | 83 #ifdef HAVE_NAS_SOUND |
84 extern int nas_play_sound_file (Extbyte *name, int volume); | |
85 extern int nas_play_sound_data (Binbyte *data, int length, int volume); | |
86 extern int nas_wait_for_sounds (void); | |
87 extern Extbyte *nas_init_play (Display *); | |
88 #endif | |
89 | |
458 | 90 Fixnum bell_volume; |
91 Fixnum bell_inhibit_time; | |
428 | 92 Lisp_Object Vsound_alist; |
93 Lisp_Object Vsynchronous_sounds; | |
94 Lisp_Object Vnative_sound_only_on_console; | |
95 Lisp_Object Q_volume, Q_pitch, Q_duration, Q_sound; | |
563 | 96 Lisp_Object Qsound_error; |
428 | 97 |
563 | 98 DOESNT_RETURN |
4952
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4343
diff
changeset
|
99 report_sound_error (const Ascbyte *reason, Lisp_Object data) |
563 | 100 { |
4952
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4343
diff
changeset
|
101 report_error_with_errno (Qsound_error, reason, data); |
563 | 102 } |
428 | 103 |
104 DEFUN ("play-sound-file", Fplay_sound_file, 1, 3, "fSound file name: ", /* | |
105 Play the named sound file on DEVICE's speaker at the specified volume | |
106 \(0-100, default specified by the `bell-volume' variable). | |
107 On Unix machines the sound file must be in the Sun/NeXT U-LAW format | |
108 except under Linux where WAV files are also supported. On Microsoft | |
109 Windows the sound file must be in WAV format. | |
110 DEVICE defaults to the selected device. | |
111 */ | |
3072 | 112 (file, volume, USED_IF_HAVE_ANY (device))) |
428 | 113 { |
114 /* This function can call lisp */ | |
115 int vol; | |
3308 | 116 #if defined (HAVE_NATIVE_SOUND) || defined (HAVE_ALSA_SOUND) || \ |
117 defined (HAVE_NAS_SOUND) || defined (HAVE_ESD_SOUND) | |
428 | 118 struct device *d = decode_device (device); |
119 #endif | |
120 struct gcpro gcpro1; | |
121 | |
122 CHECK_STRING (file); | |
123 if (NILP (volume)) | |
124 vol = bell_volume; | |
125 else | |
126 { | |
127 CHECK_INT (volume); | |
128 vol = XINT (volume); | |
129 } | |
130 | |
131 GCPRO1 (file); | |
132 while (1) | |
133 { | |
134 file = Fexpand_file_name (file, Qnil); | |
135 if (!NILP(Ffile_readable_p (file))) | |
136 break; | |
137 else | |
138 { | |
139 /* #### This is crockish. It might be a better idea to try | |
140 to open the file, and use report_file_error() if it | |
141 fails. --hniksic */ | |
142 if (NILP (Ffile_exists_p (file))) | |
143 file = | |
563 | 144 signal_continuable_error (Qfile_error, |
145 "File does not exist", file); | |
428 | 146 else |
147 file = | |
563 | 148 signal_continuable_error (Qfile_error, |
149 "File is unreadable", file); | |
428 | 150 } |
151 } | |
152 UNGCPRO; | |
153 | |
3308 | 154 #ifdef HAVE_ALSA_SOUND |
155 if (DEVICE_CONNECTED_TO_ALSA_P (d)) | |
156 { | |
157 Extbyte *fileext; | |
158 | |
4981
4aebb0131297
Cleanups/renaming of EXTERNAL_TO_C_STRING and friends
Ben Wing <ben@xemacs.org>
parents:
4952
diff
changeset
|
159 LISP_PATHNAME_CONVERT_OUT (file, fileext); |
3308 | 160 /* #### ALSA code should allow specification of a device. */ |
161 if (alsa_play_sound_file (fileext, vol)) | |
162 return Qnil; | |
163 } | |
164 #endif | |
165 | |
428 | 166 #ifdef HAVE_NAS_SOUND |
167 if (DEVICE_CONNECTED_TO_NAS_P (d)) | |
168 { | |
563 | 169 Extbyte *fileext; |
428 | 170 |
4981
4aebb0131297
Cleanups/renaming of EXTERNAL_TO_C_STRING and friends
Ben Wing <ben@xemacs.org>
parents:
4952
diff
changeset
|
171 LISP_PATHNAME_CONVERT_OUT (file, fileext); |
428 | 172 /* #### NAS code should allow specification of a device. */ |
173 if (nas_play_sound_file (fileext, vol)) | |
174 return Qnil; | |
175 } | |
176 #endif /* HAVE_NAS_SOUND */ | |
177 | |
178 #ifdef HAVE_ESD_SOUND | |
179 if (DEVICE_CONNECTED_TO_ESD_P (d)) | |
180 { | |
563 | 181 Extbyte *fileext; |
442 | 182 int result; |
428 | 183 |
4981
4aebb0131297
Cleanups/renaming of EXTERNAL_TO_C_STRING and friends
Ben Wing <ben@xemacs.org>
parents:
4952
diff
changeset
|
184 LISP_PATHNAME_CONVERT_OUT (file, fileext); |
442 | 185 |
186 /* #### ESD uses alarm(). But why should we also stop SIGIO? */ | |
187 stop_interrupts (); | |
188 result = esd_play_sound_file (fileext, vol); | |
189 start_interrupts (); | |
190 if (result) | |
428 | 191 return Qnil; |
192 } | |
193 #endif /* HAVE_ESD_SOUND */ | |
194 | |
195 #ifdef HAVE_NATIVE_SOUND | |
196 if (NILP (Vnative_sound_only_on_console) || DEVICE_ON_CONSOLE_P (d)) | |
197 { | |
2526 | 198 #ifdef WIN32_ANY |
199 nt_play_sound_file (file, vol); | |
200 #else | |
563 | 201 Extbyte *fileext; |
2526 | 202 LISP_PATHNAME_CONVERT_OUT (file, fileext); |
428 | 203 /* The sound code doesn't like getting SIGIO interrupts. |
204 Unix sucks! */ | |
205 stop_interrupts (); | |
563 | 206 play_sound_file (fileext, vol); |
428 | 207 start_interrupts (); |
2526 | 208 #endif /* WIN32_NATIVE */ |
428 | 209 QUIT; |
210 } | |
211 #endif /* HAVE_NATIVE_SOUND */ | |
212 | |
213 return Qnil; | |
214 } | |
215 | |
216 static void | |
217 parse_sound_alist_elt (Lisp_Object elt, | |
218 Lisp_Object *volume, | |
219 Lisp_Object *pitch, | |
220 Lisp_Object *duration, | |
221 Lisp_Object *sound) | |
222 { | |
223 *volume = Qnil; | |
224 *pitch = Qnil; | |
225 *duration = Qnil; | |
226 *sound = Qnil; | |
227 if (! CONSP (elt)) | |
228 return; | |
229 | |
230 /* The things we do for backward compatibility... | |
231 I wish I had just forced this to be a plist to begin with. | |
232 */ | |
233 | |
234 if (SYMBOLP (elt) || STRINGP (elt)) /* ( name . <sound> ) */ | |
235 { | |
236 *sound = elt; | |
237 } | |
238 else if (!CONSP (elt)) | |
239 { | |
240 return; | |
241 } | |
242 else if (NILP (XCDR (elt)) && /* ( name <sound> ) */ | |
243 (SYMBOLP (XCAR (elt)) || | |
244 STRINGP (XCAR (elt)))) | |
245 { | |
246 *sound = XCAR (elt); | |
247 } | |
248 else if (INT_OR_FLOATP (XCAR (elt)) && /* ( name <vol> . <sound> ) */ | |
249 (SYMBOLP (XCDR (elt)) || | |
250 STRINGP (XCDR (elt)))) | |
251 { | |
252 *volume = XCAR (elt); | |
253 *sound = XCDR (elt); | |
254 } | |
255 else if (INT_OR_FLOATP (XCAR (elt)) && /* ( name <vol> <sound> ) */ | |
256 CONSP (XCDR (elt)) && | |
257 NILP (XCDR (XCDR (elt))) && | |
258 (SYMBOLP (XCAR (XCDR (elt))) || | |
259 STRINGP (XCAR (XCDR (elt))))) | |
260 { | |
261 *volume = XCAR (elt); | |
262 *sound = XCAR (XCDR (elt)); | |
263 } | |
264 else if ((SYMBOLP (XCAR (elt)) || /* ( name <sound> . <vol> ) */ | |
265 STRINGP (XCAR (elt))) && | |
266 INT_OR_FLOATP (XCDR (elt))) | |
267 { | |
268 *sound = XCAR (elt); | |
269 *volume = XCDR (elt); | |
270 } | |
271 #if 0 /* this one is ambiguous with the plist form */ | |
272 else if ((SYMBOLP (XCAR (elt)) || /* ( name <sound> <vol> ) */ | |
273 STRINGP (XCAR (elt))) && | |
274 CONSP (XCDR (elt)) && | |
275 NILP (XCDR (XCDR (elt))) && | |
276 INT_OR_FLOATP (XCAR (XCDR (elt)))) | |
277 { | |
278 *sound = XCAR (elt); | |
279 *volume = XCAR (XCDR (elt)); | |
280 } | |
281 #endif /* 0 */ | |
282 else /* ( name [ keyword <value> ]* ) */ | |
283 { | |
284 while (CONSP (elt)) | |
285 { | |
286 Lisp_Object key, val; | |
287 key = XCAR (elt); | |
288 val = XCDR (elt); | |
289 if (!CONSP (val)) | |
290 return; | |
291 elt = XCDR (val); | |
292 val = XCAR (val); | |
293 if (EQ (key, Q_volume)) | |
294 { | |
295 if (INT_OR_FLOATP (val)) *volume = val; | |
296 } | |
297 else if (EQ (key, Q_pitch)) | |
298 { | |
299 if (INT_OR_FLOATP (val)) *pitch = val; | |
300 if (NILP (*sound)) *sound = Qt; | |
301 } | |
302 else if (EQ (key, Q_duration)) | |
303 { | |
304 if (INT_OR_FLOATP (val)) *duration = val; | |
305 if (NILP (*sound)) *sound = Qt; | |
306 } | |
307 else if (EQ (key, Q_sound)) | |
308 { | |
309 if (SYMBOLP (val) || STRINGP (val)) *sound = val; | |
310 } | |
311 } | |
312 } | |
313 } | |
314 | |
315 DEFUN ("play-sound", Fplay_sound, 1, 3, 0, /* | |
316 Play a sound of the provided type. | |
793 | 317 |
318 SOUND can a symbol, specifying a sound to be looked up in `sound-alist' | |
319 \(generally, either the symbol directly maps to a sound or is an "abstract" | |
320 symbol that maps to another symbol and is used to specify the sound that is | |
321 played when a particular behavior occurs. `ding' lists the built-in | |
322 abstract sounds and their intended purpose. | |
323 | |
324 SOUND can also be a string, which directly encodes the sound data to be played. | |
325 | |
326 If SOUND is nil, the abstract sound `default' will be used. | |
327 | |
328 VOLUME controls the volume (max is around 150? not sure). | |
329 | |
330 DEVICE is the device to play the sound on (defaults to the selected device). | |
609 | 331 |
332 If the sound cannot be played in any other way, the standard "bell" will sound. | |
428 | 333 */ |
334 (sound, volume, device)) | |
335 { | |
336 int looking_for_default = 0; | |
337 /* variable `sound' is anything that can be a cdr in sound-alist */ | |
338 Lisp_Object new_volume, pitch, duration, data; | |
339 int loop_count = 0; | |
340 int vol, pit, dur; | |
341 struct device *d = decode_device (device); | |
342 | |
343 /* NOTE! You'd better not signal an error in here. */ | |
344 | |
345 | |
346 try_it_again: | |
347 while (1) | |
348 { | |
349 if (SYMBOLP (sound)) | |
350 sound = Fcdr (Fassq (sound, Vsound_alist)); | |
351 parse_sound_alist_elt (sound, &new_volume, &pitch, &duration, &data); | |
352 sound = data; | |
353 if (NILP (volume)) volume = new_volume; | |
354 if (EQ (sound, Qt) || EQ (sound, Qnil) || STRINGP (sound)) | |
355 break; | |
356 if (loop_count++ > 500) /* much bogosity has occurred */ | |
357 break; | |
358 } | |
359 | |
360 if (NILP (sound) && !looking_for_default) | |
361 { | |
362 looking_for_default = 1; | |
363 loop_count = 0; | |
364 sound = Qdefault; | |
365 goto try_it_again; | |
366 } | |
367 | |
368 | |
369 vol = (INT_OR_FLOATP (volume) ? (int) XFLOATINT (volume) : bell_volume); | |
370 pit = (INT_OR_FLOATP (pitch) ? (int) XFLOATINT (pitch) : -1); | |
371 dur = (INT_OR_FLOATP (duration) ? (int) XFLOATINT (duration) : -1); | |
372 | |
3308 | 373 /* If the sound is a string, and we're connected to ALSA, NAS, or ESD, do |
374 that. Else if the sound is a string, and we're on console, play it | |
375 natively. Else just beep. | |
428 | 376 */ |
3308 | 377 #ifdef HAVE_ALSA_SOUND |
378 if (DEVICE_CONNECTED_TO_ALSA_P (d) && STRINGP (sound)) | |
379 { | |
380 Binbyte *soundext; | |
381 Bytecount soundextlen; | |
382 | |
4981
4aebb0131297
Cleanups/renaming of EXTERNAL_TO_C_STRING and friends
Ben Wing <ben@xemacs.org>
parents:
4952
diff
changeset
|
383 LISP_STRING_TO_SIZED_EXTERNAL (sound, soundext, soundextlen, Qbinary); |
3308 | 384 if (alsa_play_sound_data (soundext, soundextlen, vol)) |
385 return Qnil; | |
386 } | |
387 #endif /* HAVE_ALSA_SOUND */ | |
388 | |
428 | 389 #ifdef HAVE_NAS_SOUND |
390 if (DEVICE_CONNECTED_TO_NAS_P (d) && STRINGP (sound)) | |
391 { | |
2367 | 392 Binbyte *soundext; |
665 | 393 Bytecount soundextlen; |
428 | 394 |
4981
4aebb0131297
Cleanups/renaming of EXTERNAL_TO_C_STRING and friends
Ben Wing <ben@xemacs.org>
parents:
4952
diff
changeset
|
395 LISP_STRING_TO_SIZED_EXTERNAL (sound, soundext, soundextlen, Qbinary); |
563 | 396 if (nas_play_sound_data (soundext, soundextlen, vol)) |
428 | 397 return Qnil; |
398 } | |
399 #endif /* HAVE_NAS_SOUND */ | |
400 | |
401 #ifdef HAVE_ESD_SOUND | |
402 if (DEVICE_CONNECTED_TO_ESD_P (d) && STRINGP (sound)) | |
403 { | |
2367 | 404 Binbyte *soundext; |
665 | 405 Bytecount soundextlen; |
442 | 406 int succes; |
428 | 407 |
4981
4aebb0131297
Cleanups/renaming of EXTERNAL_TO_C_STRING and friends
Ben Wing <ben@xemacs.org>
parents:
4952
diff
changeset
|
408 LISP_STRING_TO_SIZED_EXTERNAL (sound, soundext, soundextlen, Qbinary); |
442 | 409 |
410 /* #### ESD uses alarm(). But why should we also stop SIGIO? */ | |
411 stop_interrupts (); | |
563 | 412 succes = esd_play_sound_data (soundext, soundextlen, vol); |
442 | 413 start_interrupts (); |
414 QUIT; | |
415 if(succes) | |
416 return Qnil; | |
428 | 417 } |
418 #endif /* HAVE_ESD_SOUND */ | |
419 | |
420 #ifdef HAVE_NATIVE_SOUND | |
421 if ((NILP (Vnative_sound_only_on_console) || DEVICE_ON_CONSOLE_P (d)) | |
422 && STRINGP (sound)) | |
423 { | |
2367 | 424 Binbyte *soundext; |
665 | 425 Bytecount soundextlen; |
442 | 426 int succes; |
428 | 427 |
4981
4aebb0131297
Cleanups/renaming of EXTERNAL_TO_C_STRING and friends
Ben Wing <ben@xemacs.org>
parents:
4952
diff
changeset
|
428 LISP_STRING_TO_SIZED_EXTERNAL (sound, soundext, soundextlen, Qbinary); |
428 | 429 /* The sound code doesn't like getting SIGIO interrupts. Unix sucks! */ |
430 stop_interrupts (); | |
563 | 431 succes = play_sound_data (soundext, soundextlen, vol); |
428 | 432 start_interrupts (); |
433 QUIT; | |
442 | 434 if (succes) |
435 return Qnil; | |
428 | 436 } |
437 #endif /* HAVE_NATIVE_SOUND */ | |
438 | |
439 DEVMETH (d, ring_bell, (d, vol, pit, dur)); | |
440 return Qnil; | |
441 } | |
442 | |
443 DEFUN ("device-sound-enabled-p", Fdevice_sound_enabled_p, 0, 1, 0, /* | |
444 Return t if DEVICE is able to play sound. Defaults to selected device. | |
445 */ | |
3072 | 446 (USED_IF_HAVE_NATIVE_OR_NAS (device))) |
428 | 447 { |
3308 | 448 #ifdef HAVE_ALSA_SOUND |
449 if (DEVICE_CONNECTED_TO_ALSA_P (decode_device (device))) | |
450 return Qt; | |
451 #endif | |
428 | 452 #ifdef HAVE_NAS_SOUND |
453 if (DEVICE_CONNECTED_TO_NAS_P (decode_device (device))) | |
454 return Qt; | |
455 #endif | |
456 #ifdef HAVE_NATIVE_SOUND | |
457 if (DEVICE_ON_CONSOLE_P (decode_device (device))) | |
458 return Qt; | |
459 #endif | |
460 return Qnil; | |
461 } | |
462 | |
463 DEFUN ("ding", Fding, 0, 3, 0, /* | |
464 Beep, or flash the frame. | |
793 | 465 |
466 \(See `visible-bell'; setting this makes the frame flash instead of | |
467 beeping.) Also, unless NO-TERMINATE is given, terminate any keyboard macro | |
468 currently executing. SOUND specifies the sound to make and DEVICE the | |
469 device to make it on (defaults to the selected device). | |
470 | |
471 SOUND is either a string (raw data to be played directly), a symbol, or | |
472 `nil' (equivalent to the symbol `default'). Sound symbols are looked up in | |
473 `sound-alist', and resolve either to strings of data or to other symbols. | |
474 Sound symbols that map directly to data should be considered named sounds; | |
475 sound symbols that map to other sounds should be considered abstract | |
476 sounds, and are used when a particular behavior or state occurs. | |
477 | |
2757 | 478 Remember that the sound symbol is the *second* argument to `ding', not the |
793 | 479 first. |
480 | |
481 The following abstract sounds are used by XEmacs itself: | |
482 | |
483 alarm when a package wants to remind the user | |
484 auto-save-error when an auto-save does not succeed | |
485 buffer-bound when you attempt to move off the end of a buffer | |
486 command-error any uncaught error (i.e. any error that the user | |
487 sees) except those handled by undefined-click, | |
488 undefined-key, buffer-bound, or read-only | |
489 default used when nothing else is appropriate. | |
490 isearch-failed unable to locate search text during incremental search | |
491 isearch-quit when you delete chars past the beginning of the search | |
492 text in isearch | |
493 no-completion during completing-read | |
494 quit when C-g is typed | |
495 read-only when you try to modify a read-only buffer | |
496 ready when a compile or other time-consuming task is done | |
497 undefined-click when you use an undefined mouse-click combination | |
498 undefined-key when you type a key that is undefined | |
499 warp XEmacs has changed the selected-window or frame | |
500 asynchronously -- e.g. a debugger breakpoint is hit | |
501 in an asynchronous process filter | |
502 y-or-n-p when you type something other than 'y' or 'n' | |
503 yes-or-no-p when you type something other than 'yes' or 'no' | |
504 | |
505 Other lisp packages may use other beep types, but these are the ones that | |
506 the C kernel of Emacs uses. | |
507 | |
428 | 508 */ |
793 | 509 (no_terminate, sound, device)) |
428 | 510 { |
430 | 511 static time_t last_bell_time; |
512 static struct device *last_bell_device; | |
428 | 513 time_t now; |
514 struct device *d = decode_device (device); | |
515 | |
793 | 516 device = wrap_device (d); |
428 | 517 now = time (0); |
518 | |
793 | 519 if (NILP (no_terminate) && !NILP (Vexecuting_macro)) |
428 | 520 /* Stop executing a keyboard macro. */ |
563 | 521 invalid_operation ("Keyboard macro terminated by a command ringing the bell", Qunbound); |
428 | 522 |
523 if (d == last_bell_device && now-last_bell_time < bell_inhibit_time) | |
524 return Qnil; | |
442 | 525 else if (!NILP (Vvisible_bell) && DEVMETH (d, flash, (d))) |
428 | 526 ; |
527 else | |
528 Fplay_sound (sound, Qnil, device); | |
529 | |
530 last_bell_time = now; | |
531 last_bell_device = d; | |
532 return Qnil; | |
533 } | |
534 | |
535 DEFUN ("wait-for-sounds", Fwait_for_sounds, 0, 1, 0, /* | |
536 Wait for all sounds to finish playing on DEVICE. | |
537 */ | |
2294 | 538 (USED_IF_HAVE_NAS (device))) |
428 | 539 { |
540 #ifdef HAVE_NAS_SOUND | |
541 struct device *d = decode_device (device); | |
542 if (DEVICE_CONNECTED_TO_NAS_P (d)) | |
543 { | |
544 /* #### somebody fix this to be device-dependent. */ | |
545 nas_wait_for_sounds (); | |
546 } | |
547 #endif | |
548 return Qnil; | |
549 } | |
550 | |
551 DEFUN ("connected-to-nas-p", Fconnected_to_nas_p, 0, 1, 0, /* | |
552 Return t if connected to NAS server for sounds on DEVICE. | |
553 */ | |
2294 | 554 (USED_IF_HAVE_NAS (device))) |
428 | 555 { |
556 #ifdef HAVE_NAS_SOUND | |
557 return DEVICE_CONNECTED_TO_NAS_P (decode_device (device)) ? Qt : Qnil; | |
558 #else | |
559 return Qnil; | |
560 #endif | |
561 } | |
562 #ifdef HAVE_NAS_SOUND | |
563 | |
564 static void | |
565 init_nas_sound (struct device *d) | |
566 { | |
567 #ifdef HAVE_X_WINDOWS | |
568 if (DEVICE_X_P (d)) | |
569 { | |
563 | 570 Extbyte *err_message = nas_init_play (DEVICE_X_DISPLAY (d)); |
442 | 571 DEVICE_CONNECTED_TO_NAS_P (d) = !err_message; |
428 | 572 /* Print out the message? */ |
573 } | |
574 #endif /* HAVE_X_WINDOWS */ | |
575 } | |
576 | |
577 #endif /* HAVE_NAS_SOUND */ | |
578 | |
579 #ifdef HAVE_NATIVE_SOUND | |
580 | |
581 static void | |
582 init_native_sound (struct device *d) | |
583 { | |
3731 | 584 if (!(DEVICE_X_P(d) || DEVICE_GTK_P(d))) |
428 | 585 DEVICE_ON_CONSOLE_P (d) = 1; |
586 #ifdef HAVE_X_WINDOWS | |
587 else | |
588 { | |
589 /* When running on a machine with native sound support, we cannot use | |
590 digitized sounds as beeps unless emacs is running on the same machine | |
591 that $DISPLAY points to, and $DISPLAY points to frame 0 of that | |
592 machine. | |
593 */ | |
594 | |
595 Display *display = DEVICE_X_DISPLAY (d); | |
563 | 596 Extbyte *dpy = DisplayString (display); |
597 Extbyte *tail = strchr (dpy, ':'); | |
428 | 598 if (! tail || |
599 strncmp (tail, ":0", 2)) | |
600 DEVICE_ON_CONSOLE_P (d) = 0; | |
601 else | |
602 { | |
563 | 603 Extbyte dpyname[255], localname[255]; |
428 | 604 |
605 /* some systems can't handle SIGIO or SIGALARM in gethostbyname. */ | |
606 stop_interrupts (); | |
607 strncpy (dpyname, dpy, tail-dpy); | |
608 dpyname [tail-dpy] = 0; | |
609 if (!*dpyname || | |
610 !strcmp (dpyname, "unix") || | |
611 !strcmp (dpyname, "localhost")) | |
612 DEVICE_ON_CONSOLE_P (d) = 1; | |
613 else if (gethostname (localname, sizeof (localname))) | |
614 DEVICE_ON_CONSOLE_P (d) = 0; /* can't find hostname? */ | |
615 else | |
616 { | |
617 /* We have to call gethostbyname() on the result of gethostname() | |
618 because the two aren't guaranteed to be the same name for the | |
619 same host: on some losing systems, one is a FQDN and the other | |
620 is not. Here in the wide wonderful world of Unix it's rocket | |
621 science to obtain the local hostname in a portable fashion. | |
622 | |
623 And don't forget, gethostbyname() reuses the structure it | |
624 returns, so we have to copy the fucker before calling it | |
625 again. | |
626 | |
627 Thank you master, may I have another. | |
628 */ | |
629 struct hostent *h = gethostbyname (dpyname); | |
630 if (!h) | |
631 DEVICE_ON_CONSOLE_P (d) = 0; | |
632 else | |
633 { | |
3504 | 634 Extbyte *hn = alloca_array (Extbyte, strlen (h->h_name) + 1); |
428 | 635 struct hostent *l; |
636 strcpy (hn, h->h_name); | |
637 l = gethostbyname (localname); | |
638 DEVICE_ON_CONSOLE_P (d) = (l && !(strcmp (l->h_name, hn))); | |
639 } | |
640 } | |
641 start_interrupts (); | |
642 } | |
643 } | |
644 #endif /* HAVE_X_WINDOWS */ | |
645 } | |
646 | |
647 #endif /* HAVE_NATIVE_SOUND */ | |
648 | |
649 void | |
3072 | 650 init_device_sound (struct device * USED_IF_HAVE_NATIVE_OR_NAS (d)) |
428 | 651 { |
652 #ifdef HAVE_NAS_SOUND | |
653 init_nas_sound (d); | |
654 #endif | |
655 | |
656 #ifdef HAVE_NATIVE_SOUND | |
657 init_native_sound (d); | |
658 #endif | |
659 } | |
660 | |
661 void | |
662 syms_of_sound (void) | |
663 { | |
563 | 664 DEFKEYWORD (Q_volume); |
665 DEFKEYWORD (Q_pitch); | |
666 DEFKEYWORD (Q_duration); | |
667 DEFKEYWORD (Q_sound); | |
428 | 668 |
563 | 669 DEFERROR_STANDARD (Qsound_error, Qio_error); |
428 | 670 |
671 DEFSUBR (Fplay_sound_file); | |
672 DEFSUBR (Fplay_sound); | |
673 DEFSUBR (Fding); | |
674 DEFSUBR (Fwait_for_sounds); | |
675 DEFSUBR (Fconnected_to_nas_p); | |
676 DEFSUBR (Fdevice_sound_enabled_p); | |
677 } | |
678 | |
679 | |
680 void | |
681 vars_of_sound (void) | |
682 { | |
3308 | 683 #ifdef HAVE_ALSA_SOUND |
684 Fprovide (intern ("alsa-sound")); | |
685 #endif | |
428 | 686 #ifdef HAVE_NATIVE_SOUND |
687 Fprovide (intern ("native-sound")); | |
688 #endif | |
689 #ifdef HAVE_NAS_SOUND | |
690 Fprovide (intern ("nas-sound")); | |
691 #endif | |
432 | 692 #ifdef HAVE_ESD_SOUND |
693 Fprovide (intern ("esd-sound")); | |
694 #endif | |
428 | 695 |
696 DEFVAR_INT ("bell-volume", &bell_volume /* | |
697 *How loud to be, from 0 to 100. | |
698 */ ); | |
699 bell_volume = 50; | |
700 | |
701 DEFVAR_INT ("bell-inhibit-time", &bell_inhibit_time /* | |
702 *Don't ring the bell on the same device more than once within this many seconds. | |
703 */ ); | |
704 bell_inhibit_time = 0; | |
705 | |
706 DEFVAR_LISP ("sound-alist", &Vsound_alist /* | |
707 An alist associating names with sounds. | |
708 When `beep' or `ding' is called with one of the name symbols, the associated | |
709 sound will be generated instead of the standard beep. | |
710 | |
711 Each element of `sound-alist' is a list describing a sound. | |
712 The first element of the list is the name of the sound being defined. | |
713 Subsequent elements of the list are alternating keyword/value pairs: | |
714 | |
715 Keyword: Value: | |
716 ------- ----- | |
717 sound A string of raw sound data, or the name of another sound to | |
718 play. The symbol `t' here means use the default X beep. | |
719 volume An integer from 0-100, defaulting to `bell-volume' | |
720 pitch If using the default X beep, the pitch (Hz) to generate. | |
721 duration If using the default X beep, the duration (milliseconds). | |
722 | |
723 For compatibility, elements of `sound-alist' may also be: | |
724 | |
725 ( sound-name . <sound> ) | |
726 ( sound-name <volume> <sound> ) | |
727 | |
728 You should probably add things to this list by calling the function | |
729 load-sound-file. | |
730 | |
731 Caveats: | |
732 - XEmacs must be built with sound support for your system. Not all | |
733 systems support sound. | |
734 | |
735 - The pitch, duration, and volume options are available everywhere, but | |
736 many X servers ignore the `pitch' option. | |
737 | |
793 | 738 Sound symbols that map directly to data should be considered named sounds; |
739 sound symbols that map to other sounds should be considered abstract | |
740 sounds, and are used when a particular behavior or state occurs. See | |
741 `ding' for a list of the standard abstract sounds. | |
428 | 742 */ ); |
743 Vsound_alist = Qnil; | |
744 | |
745 DEFVAR_LISP ("synchronous-sounds", &Vsynchronous_sounds /* | |
746 Play sounds synchronously, if non-nil. | |
747 Only applies if NAS is used and supports asynchronous playing | |
748 of sounds. Otherwise, sounds are always played synchronously. | |
749 */ ); | |
750 Vsynchronous_sounds = Qnil; | |
751 | |
752 DEFVAR_LISP ("native-sound-only-on-console", &Vnative_sound_only_on_console /* | |
753 Non-nil value means play sounds only if XEmacs is running | |
754 on the system console. | |
442 | 755 Nil means always play sounds, even if running on a non-console tty |
428 | 756 or a secondary X display. |
757 | |
758 This variable only applies to native sound support. | |
759 */ ); | |
760 Vnative_sound_only_on_console = Qt; | |
761 | |
762 #if defined (HAVE_NATIVE_SOUND) && defined (hp9000s800) | |
763 { | |
764 void vars_of_hpplay (void); | |
765 vars_of_hpplay (); | |
766 } | |
767 #endif | |
768 } |