Mercurial > hg > xemacs-beta
comparison src/sound.c @ 412:697ef44129c6 r21-2-14
Import from CVS: tag r21-2-14
author | cvs |
---|---|
date | Mon, 13 Aug 2007 11:20:41 +0200 |
parents | de805c49cfc1 |
children | 11054d720c21 |
comparison
equal
deleted
inserted
replaced
411:12e008d41344 | 412:697ef44129c6 |
---|---|
23 | 23 |
24 /* Originally written by Jamie Zawinski. | 24 /* Originally written by Jamie Zawinski. |
25 Hacked on quite a bit by various others. */ | 25 Hacked on quite a bit by various others. */ |
26 | 26 |
27 #include <config.h> | 27 #include <config.h> |
28 #include <time.h> | |
29 #include "lisp.h" | 28 #include "lisp.h" |
30 | 29 |
31 #include "buffer.h" | 30 #include "buffer.h" |
32 #ifdef HAVE_X_WINDOWS | 31 #ifdef HAVE_X_WINDOWS |
33 #include "console-x.h" | 32 #include "console-x.h" |
35 | 34 |
36 #include "device.h" | 35 #include "device.h" |
37 #include "redisplay.h" | 36 #include "redisplay.h" |
38 #include "sysdep.h" | 37 #include "sysdep.h" |
39 | 38 |
40 #include "sysfile.h" | 39 #ifdef HAVE_UNISTD_H |
40 #include <unistd.h> | |
41 #endif | |
41 | 42 |
42 #ifdef HAVE_NATIVE_SOUND | 43 #ifdef HAVE_NATIVE_SOUND |
43 # include "sysproc.h" | 44 # include <netdb.h> |
44 # include "nativesound.h" | |
45 #endif | |
46 | |
47 #ifdef HAVE_ESD_SOUND | |
48 extern int esd_play_sound_file (char *file, int vol); | |
49 extern int esd_play_sound_data (unsigned char *data, size_t length, int vol); | |
50 # define DEVICE_CONNECTED_TO_ESD_P(x) 1 /* FIXME: better check */ | |
51 #endif | 45 #endif |
52 | 46 |
53 int bell_volume; | 47 int bell_volume; |
54 int bell_inhibit_time; | |
55 Lisp_Object Vsound_alist; | 48 Lisp_Object Vsound_alist; |
56 Lisp_Object Vsynchronous_sounds; | 49 Lisp_Object Vsynchronous_sounds; |
57 Lisp_Object Vnative_sound_only_on_console; | 50 Lisp_Object Vnative_sound_only_on_console; |
58 Lisp_Object Q_volume, Q_pitch, Q_duration, Q_sound; | 51 Lisp_Object Q_volume, Q_pitch, Q_duration, Q_sound; |
59 | 52 |
53 /* These are defined in the appropriate file (sunplay.c, sgiplay.c, | |
54 or hpplay.c). */ | |
55 | |
56 extern void play_sound_file (char *name, int volume); | |
57 extern void play_sound_data (unsigned char *data, int length, int volume); | |
60 | 58 |
61 #ifdef HAVE_NAS_SOUND | 59 #ifdef HAVE_NAS_SOUND |
62 extern int nas_play_sound_file (char *name, int volume); | 60 extern int nas_play_sound_file (char *name, int volume); |
63 extern int nas_play_sound_data (unsigned char *data, int length, int volume); | 61 extern int nas_play_sound_data (unsigned char *data, int length, int volume); |
64 extern int nas_wait_for_sounds (void); | 62 extern int nas_wait_for_sounds (void); |
77 */ | 75 */ |
78 (file, volume, device)) | 76 (file, volume, device)) |
79 { | 77 { |
80 /* This function can call lisp */ | 78 /* This function can call lisp */ |
81 int vol; | 79 int vol; |
82 #if defined (HAVE_NATIVE_SOUND) || defined (HAVE_NAS_SOUND) \ | 80 #if defined (HAVE_NATIVE_SOUND) || defined (HAVE_NAS_SOUND) |
83 || defined (HAVE_ESD_SOUND) | |
84 struct device *d = decode_device (device); | 81 struct device *d = decode_device (device); |
85 #endif | 82 #endif |
86 struct gcpro gcpro1; | 83 struct gcpro gcpro1; |
87 | 84 |
88 CHECK_STRING (file); | 85 CHECK_STRING (file); |
118 #ifdef HAVE_NAS_SOUND | 115 #ifdef HAVE_NAS_SOUND |
119 if (DEVICE_CONNECTED_TO_NAS_P (d)) | 116 if (DEVICE_CONNECTED_TO_NAS_P (d)) |
120 { | 117 { |
121 char *fileext; | 118 char *fileext; |
122 | 119 |
123 TO_EXTERNAL_FORMAT (LISP_STRING, file, | 120 GET_C_STRING_FILENAME_DATA_ALLOCA (file, fileext); |
124 C_STRING_ALLOCA, fileext, | |
125 Qfile_name); | |
126 /* #### NAS code should allow specification of a device. */ | 121 /* #### NAS code should allow specification of a device. */ |
127 if (nas_play_sound_file (fileext, vol)) | 122 if (nas_play_sound_file (fileext, vol)) |
128 return Qnil; | 123 return Qnil; |
129 } | 124 } |
130 #endif /* HAVE_NAS_SOUND */ | 125 #endif /* HAVE_NAS_SOUND */ |
131 | 126 |
132 #ifdef HAVE_ESD_SOUND | |
133 if (DEVICE_CONNECTED_TO_ESD_P (d)) | |
134 { | |
135 char *fileext; | |
136 int result; | |
137 | |
138 TO_EXTERNAL_FORMAT (LISP_STRING, file, | |
139 C_STRING_ALLOCA, fileext, | |
140 Qfile_name); | |
141 | |
142 /* #### ESD uses alarm(). But why should we also stop SIGIO? */ | |
143 stop_interrupts (); | |
144 result = esd_play_sound_file (fileext, vol); | |
145 start_interrupts (); | |
146 if (result) | |
147 return Qnil; | |
148 } | |
149 #endif /* HAVE_ESD_SOUND */ | |
150 | |
151 #ifdef HAVE_NATIVE_SOUND | 127 #ifdef HAVE_NATIVE_SOUND |
152 if (NILP (Vnative_sound_only_on_console) || DEVICE_ON_CONSOLE_P (d)) | 128 if (NILP (Vnative_sound_only_on_console) || DEVICE_ON_CONSOLE_P (d)) |
153 { | 129 { |
154 const char *fileext; | 130 CONST char *fileext; |
155 | 131 |
156 TO_EXTERNAL_FORMAT (LISP_STRING, file, | 132 GET_C_STRING_FILENAME_DATA_ALLOCA (file, fileext); |
157 C_STRING_ALLOCA, fileext, | |
158 Qfile_name); | |
159 /* The sound code doesn't like getting SIGIO interrupts. | 133 /* The sound code doesn't like getting SIGIO interrupts. |
160 Unix sucks! */ | 134 Unix sucks! */ |
161 stop_interrupts (); | 135 stop_interrupts (); |
162 play_sound_file ((char *) fileext, vol); | 136 play_sound_file ((char *) fileext, vol); |
163 start_interrupts (); | 137 start_interrupts (); |
315 Else just beep. | 289 Else just beep. |
316 */ | 290 */ |
317 #ifdef HAVE_NAS_SOUND | 291 #ifdef HAVE_NAS_SOUND |
318 if (DEVICE_CONNECTED_TO_NAS_P (d) && STRINGP (sound)) | 292 if (DEVICE_CONNECTED_TO_NAS_P (d) && STRINGP (sound)) |
319 { | 293 { |
320 const Extbyte *soundext; | 294 CONST Extbyte *soundext; |
321 Extcount soundextlen; | 295 Extcount soundextlen; |
322 | 296 |
323 TO_EXTERNAL_FORMAT (LISP_STRING, sound, | 297 GET_STRING_BINARY_DATA_ALLOCA (sound, soundext, soundextlen); |
324 ALLOCA, (soundext, soundextlen), | |
325 Qbinary); | |
326 if (nas_play_sound_data ((unsigned char*)soundext, soundextlen, vol)) | 298 if (nas_play_sound_data ((unsigned char*)soundext, soundextlen, vol)) |
327 return Qnil; | 299 return Qnil; |
328 } | 300 } |
329 #endif /* HAVE_NAS_SOUND */ | 301 #endif /* HAVE_NAS_SOUND */ |
330 | |
331 #ifdef HAVE_ESD_SOUND | |
332 if (DEVICE_CONNECTED_TO_ESD_P (d) && STRINGP (sound)) | |
333 { | |
334 Extbyte *soundext; | |
335 Extcount soundextlen; | |
336 int succes; | |
337 | |
338 TO_EXTERNAL_FORMAT (LISP_STRING, sound, ALLOCA, (soundext, soundextlen), | |
339 Qbinary); | |
340 | |
341 /* #### ESD uses alarm(). But why should we also stop SIGIO? */ | |
342 stop_interrupts (); | |
343 succes = esd_play_sound_data (soundext, soundextlen, vol); | |
344 start_interrupts (); | |
345 QUIT; | |
346 if(succes) | |
347 return Qnil; | |
348 } | |
349 #endif /* HAVE_ESD_SOUND */ | |
350 | 302 |
351 #ifdef HAVE_NATIVE_SOUND | 303 #ifdef HAVE_NATIVE_SOUND |
352 if ((NILP (Vnative_sound_only_on_console) || DEVICE_ON_CONSOLE_P (d)) | 304 if ((NILP (Vnative_sound_only_on_console) || DEVICE_ON_CONSOLE_P (d)) |
353 && STRINGP (sound)) | 305 && STRINGP (sound)) |
354 { | 306 { |
355 const Extbyte *soundext; | 307 CONST Extbyte *soundext; |
356 Extcount soundextlen; | 308 Extcount soundextlen; |
357 int succes; | 309 |
358 | 310 GET_STRING_BINARY_DATA_ALLOCA (sound, soundext, soundextlen); |
359 TO_EXTERNAL_FORMAT (LISP_STRING, sound, | |
360 ALLOCA, (soundext, soundextlen), | |
361 Qbinary); | |
362 /* The sound code doesn't like getting SIGIO interrupts. Unix sucks! */ | 311 /* The sound code doesn't like getting SIGIO interrupts. Unix sucks! */ |
363 stop_interrupts (); | 312 stop_interrupts (); |
364 succes = play_sound_data ((unsigned char*)soundext, soundextlen, vol); | 313 play_sound_data ((unsigned char*)soundext, soundextlen, vol); |
365 start_interrupts (); | 314 start_interrupts (); |
366 QUIT; | 315 QUIT; |
367 if (succes) | 316 return Qnil; |
368 return Qnil; | |
369 } | 317 } |
370 #endif /* HAVE_NATIVE_SOUND */ | 318 #endif /* HAVE_NATIVE_SOUND */ |
371 | 319 |
372 DEVMETH (d, ring_bell, (d, vol, pit, dur)); | 320 DEVMETH (d, ring_bell, (d, vol, pit, dur)); |
373 return Qnil; | 321 return Qnil; |
397 the third argument is the device to make it in (defaults to the selected | 345 the third argument is the device to make it in (defaults to the selected |
398 device). | 346 device). |
399 */ | 347 */ |
400 (arg, sound, device)) | 348 (arg, sound, device)) |
401 { | 349 { |
402 static time_t last_bell_time; | 350 struct device *d = decode_device (device); |
403 static struct device *last_bell_device; | |
404 time_t now; | |
405 struct device *d = decode_device (device); | |
406 | 351 |
407 XSETDEVICE (device, d); | 352 XSETDEVICE (device, d); |
408 now = time (0); | 353 |
409 | 354 /* #### This is utterly disgusting, and is probably a remnant from |
355 legacy code that used `ding'+`message' to signal error instead | |
356 calling `error'. As a result, there is no way to beep from Lisp | |
357 directly, without also invoking this aspect. Maybe we should | |
358 define a `ring-bell' function that simply beeps on the console, | |
359 which `ding' should invoke? --hniksic */ | |
410 if (NILP (arg) && !NILP (Vexecuting_macro)) | 360 if (NILP (arg) && !NILP (Vexecuting_macro)) |
411 /* Stop executing a keyboard macro. */ | 361 /* Stop executing a keyboard macro. */ |
412 error ("Keyboard macro terminated by a command ringing the bell"); | 362 error ("Keyboard macro terminated by a command ringing the bell"); |
413 | 363 else if (visible_bell && DEVMETH (d, flash, (d))) |
414 if (d == last_bell_device && now-last_bell_time < bell_inhibit_time) | |
415 return Qnil; | |
416 else if (!NILP (Vvisible_bell) && DEVMETH (d, flash, (d))) | |
417 ; | 364 ; |
418 else | 365 else |
419 Fplay_sound (sound, Qnil, device); | 366 Fplay_sound (sound, Qnil, device); |
420 | 367 |
421 last_bell_time = now; | 368 return Qnil; |
422 last_bell_device = d; | |
423 return Qnil; | |
424 } | 369 } |
425 | 370 |
426 DEFUN ("wait-for-sounds", Fwait_for_sounds, 0, 1, 0, /* | 371 DEFUN ("wait-for-sounds", Fwait_for_sounds, 0, 1, 0, /* |
427 Wait for all sounds to finish playing on DEVICE. | 372 Wait for all sounds to finish playing on DEVICE. |
428 */ | 373 */ |
454 #ifdef HAVE_NAS_SOUND | 399 #ifdef HAVE_NAS_SOUND |
455 | 400 |
456 static void | 401 static void |
457 init_nas_sound (struct device *d) | 402 init_nas_sound (struct device *d) |
458 { | 403 { |
404 char *error; | |
405 | |
459 #ifdef HAVE_X_WINDOWS | 406 #ifdef HAVE_X_WINDOWS |
460 if (DEVICE_X_P (d)) | 407 if (DEVICE_X_P (d)) |
461 { | 408 { |
462 char *err_message = nas_init_play (DEVICE_X_DISPLAY (d)); | 409 error = nas_init_play (DEVICE_X_DISPLAY (d)); |
463 DEVICE_CONNECTED_TO_NAS_P (d) = !err_message; | 410 DEVICE_CONNECTED_TO_NAS_P (d) = !error; |
464 /* Print out the message? */ | 411 /* Print out the message? */ |
465 } | 412 } |
466 #endif /* HAVE_X_WINDOWS */ | 413 #endif /* HAVE_X_WINDOWS */ |
467 } | 414 } |
468 | 415 |
578 Fprovide (intern ("native-sound")); | 525 Fprovide (intern ("native-sound")); |
579 #endif | 526 #endif |
580 #ifdef HAVE_NAS_SOUND | 527 #ifdef HAVE_NAS_SOUND |
581 Fprovide (intern ("nas-sound")); | 528 Fprovide (intern ("nas-sound")); |
582 #endif | 529 #endif |
583 #ifdef HAVE_ESD_SOUND | |
584 Fprovide (intern ("esd-sound")); | |
585 #endif | |
586 | 530 |
587 DEFVAR_INT ("bell-volume", &bell_volume /* | 531 DEFVAR_INT ("bell-volume", &bell_volume /* |
588 *How loud to be, from 0 to 100. | 532 *How loud to be, from 0 to 100. |
589 */ ); | 533 */ ); |
590 bell_volume = 50; | 534 bell_volume = 50; |
591 | |
592 DEFVAR_INT ("bell-inhibit-time", &bell_inhibit_time /* | |
593 *Don't ring the bell on the same device more than once within this many seconds. | |
594 */ ); | |
595 bell_inhibit_time = 0; | |
596 | 535 |
597 DEFVAR_LISP ("sound-alist", &Vsound_alist /* | 536 DEFVAR_LISP ("sound-alist", &Vsound_alist /* |
598 An alist associating names with sounds. | 537 An alist associating names with sounds. |
599 When `beep' or `ding' is called with one of the name symbols, the associated | 538 When `beep' or `ding' is called with one of the name symbols, the associated |
600 sound will be generated instead of the standard beep. | 539 sound will be generated instead of the standard beep. |
618 | 557 |
619 You should probably add things to this list by calling the function | 558 You should probably add things to this list by calling the function |
620 load-sound-file. | 559 load-sound-file. |
621 | 560 |
622 Caveats: | 561 Caveats: |
623 - XEmacs must be built with sound support for your system. Not all | 562 - You can only play audio data if running on the console screen of a |
624 systems support sound. | 563 Sun SparcStation, SGI, or HP9000s700. |
625 | 564 |
626 - The pitch, duration, and volume options are available everywhere, but | 565 - The pitch, duration, and volume options are available everywhere, but |
627 many X servers ignore the `pitch' option. | 566 many X servers ignore the `pitch' option. |
628 | 567 |
629 The following beep-types are used by emacs itself: | 568 The following beep-types are used by emacs itself: |