Hacked on quite a bit by various others. */
#include <config.h>
+#include <time.h>
#include "lisp.h"
#include "buffer.h"
#include "redisplay.h"
#include "sysdep.h"
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
+#include "sysfile.h"
#ifdef HAVE_NATIVE_SOUND
-# include <netdb.h>
+# include "sysproc.h"
+# include "nativesound.h"
+#endif
+
+#ifdef HAVE_ESD_SOUND
+extern int esd_play_sound_file (char *file, int vol);
+extern int esd_play_sound_data (unsigned char *data, size_t length, int vol);
+# define DEVICE_CONNECTED_TO_ESD_P(x) 1 /* FIXME: better check */
#endif
-int bell_volume;
+Fixnum bell_volume;
+Fixnum bell_inhibit_time;
Lisp_Object Vsound_alist;
Lisp_Object Vsynchronous_sounds;
Lisp_Object Vnative_sound_only_on_console;
Lisp_Object Q_volume, Q_pitch, Q_duration, Q_sound;
-/* These are defined in the appropriate file (sunplay.c, sgiplay.c,
- or hpplay.c). */
-
-extern void play_sound_file (char *name, int volume);
-extern void play_sound_data (unsigned char *data, int length, int volume);
#ifdef HAVE_NAS_SOUND
extern int nas_play_sound_file (char *name, int volume);
Play the named sound file on DEVICE's speaker at the specified volume
\(0-100, default specified by the `bell-volume' variable).
On Unix machines the sound file must be in the Sun/NeXT U-LAW format
-except under Linux where WAV files are also supported. On Microsoft
+except under Linux where WAV files are also supported. On Microsoft
Windows the sound file must be in WAV format.
DEVICE defaults to the selected device.
*/
{
/* This function can call lisp */
int vol;
-#if defined (HAVE_NATIVE_SOUND) || defined (HAVE_NAS_SOUND)
+#if defined (HAVE_NATIVE_SOUND) || defined (HAVE_NAS_SOUND) \
+ || defined (HAVE_ESD_SOUND)
struct device *d = decode_device (device);
#endif
struct gcpro gcpro1;
{
char *fileext;
- GET_C_STRING_FILENAME_DATA_ALLOCA (file, fileext);
+ LISP_STRING_TO_EXTERNAL (file, fileext, Qfile_name);
/* #### NAS code should allow specification of a device. */
if (nas_play_sound_file (fileext, vol))
return Qnil;
}
#endif /* HAVE_NAS_SOUND */
+#ifdef HAVE_ESD_SOUND
+ if (DEVICE_CONNECTED_TO_ESD_P (d))
+ {
+ char *fileext;
+ int result;
+
+ LISP_STRING_TO_EXTERNAL (file, fileext, Qfile_name);
+
+ /* #### ESD uses alarm(). But why should we also stop SIGIO? */
+ stop_interrupts ();
+ result = esd_play_sound_file (fileext, vol);
+ start_interrupts ();
+ if (result)
+ return Qnil;
+ }
+#endif /* HAVE_ESD_SOUND */
+
#ifdef HAVE_NATIVE_SOUND
if (NILP (Vnative_sound_only_on_console) || DEVICE_ON_CONSOLE_P (d))
{
- CONST char *fileext;
+ const char *fileext;
- GET_C_STRING_FILENAME_DATA_ALLOCA (file, fileext);
+ LISP_STRING_TO_EXTERNAL (file, fileext, Qfile_name);
/* The sound code doesn't like getting SIGIO interrupts.
Unix sucks! */
stop_interrupts ();
#ifdef HAVE_NAS_SOUND
if (DEVICE_CONNECTED_TO_NAS_P (d) && STRINGP (sound))
{
- CONST Extbyte *soundext;
+ const Extbyte *soundext;
Extcount soundextlen;
- GET_STRING_BINARY_DATA_ALLOCA (sound, soundext, soundextlen);
+ TO_EXTERNAL_FORMAT (LISP_STRING, sound,
+ ALLOCA, (soundext, soundextlen),
+ Qbinary);
if (nas_play_sound_data ((unsigned char*)soundext, soundextlen, vol))
return Qnil;
}
#endif /* HAVE_NAS_SOUND */
+#ifdef HAVE_ESD_SOUND
+ if (DEVICE_CONNECTED_TO_ESD_P (d) && STRINGP (sound))
+ {
+ Extbyte *soundext;
+ Extcount soundextlen;
+ int succes;
+
+ TO_EXTERNAL_FORMAT (LISP_STRING, sound, ALLOCA, (soundext, soundextlen),
+ Qbinary);
+
+ /* #### ESD uses alarm(). But why should we also stop SIGIO? */
+ stop_interrupts ();
+ succes = esd_play_sound_data ((unsigned char *) soundext, soundextlen, vol);
+ start_interrupts ();
+ QUIT;
+ if(succes)
+ return Qnil;
+ }
+#endif /* HAVE_ESD_SOUND */
+
#ifdef HAVE_NATIVE_SOUND
if ((NILP (Vnative_sound_only_on_console) || DEVICE_ON_CONSOLE_P (d))
&& STRINGP (sound))
{
- CONST Extbyte *soundext;
+ const Extbyte *soundext;
Extcount soundextlen;
+ int succes;
- GET_STRING_BINARY_DATA_ALLOCA (sound, soundext, soundextlen);
+ TO_EXTERNAL_FORMAT (LISP_STRING, sound,
+ ALLOCA, (soundext, soundextlen),
+ Qbinary);
/* The sound code doesn't like getting SIGIO interrupts. Unix sucks! */
stop_interrupts ();
- play_sound_data ((unsigned char*)soundext, soundextlen, vol);
+ succes = play_sound_data ((unsigned char*)soundext, soundextlen, vol);
start_interrupts ();
QUIT;
- return Qnil;
+ if (succes)
+ return Qnil;
}
#endif /* HAVE_NATIVE_SOUND */
*/
(device))
{
- struct device *d = decode_device(device);
-
#ifdef HAVE_NAS_SOUND
- if (DEVICE_CONNECTED_TO_NAS_P (d))
+ if (DEVICE_CONNECTED_TO_NAS_P (decode_device (device)))
return Qt;
#endif
#ifdef HAVE_NATIVE_SOUND
- if (DEVICE_ON_CONSOLE_P (d))
+ if (DEVICE_ON_CONSOLE_P (decode_device (device)))
return Qt;
#endif
return Qnil;
*/
(arg, sound, device))
{
- struct device *d = decode_device (device);
+ static time_t last_bell_time;
+ static struct device *last_bell_device;
+ time_t now;
+ struct device *d = decode_device (device);
XSETDEVICE (device, d);
+ now = time (0);
- /* #### This is utterly disgusting, and is probably a remnant from
- legacy code that used `ding'+`message' to signal error instead
- calling `error'. As a result, there is no way to beep from Lisp
- directly, without also invoking this aspect. Maybe we should
- define a `ring-bell' function that simply beeps on the console,
- which `ding' should invoke? --hniksic */
if (NILP (arg) && !NILP (Vexecuting_macro))
/* Stop executing a keyboard macro. */
error ("Keyboard macro terminated by a command ringing the bell");
- else if (visible_bell && DEVMETH (d, flash, (d)))
+
+ if (d == last_bell_device && now-last_bell_time < bell_inhibit_time)
+ return Qnil;
+ else if (!NILP (Vvisible_bell) && DEVMETH (d, flash, (d)))
;
else
Fplay_sound (sound, Qnil, device);
-
- return Qnil;
+
+ last_bell_time = now;
+ last_bell_device = d;
+ return Qnil;
}
DEFUN ("wait-for-sounds", Fwait_for_sounds, 0, 1, 0, /*
static void
init_nas_sound (struct device *d)
{
- char *error;
-
#ifdef HAVE_X_WINDOWS
if (DEVICE_X_P (d))
{
- error = nas_init_play (DEVICE_X_DISPLAY (d));
- DEVICE_CONNECTED_TO_NAS_P (d) = !error;
+ char *err_message = nas_init_play (DEVICE_X_DISPLAY (d));
+ DEVICE_CONNECTED_TO_NAS_P (d) = !err_message;
/* Print out the message? */
}
#endif /* HAVE_X_WINDOWS */
#ifdef HAVE_NAS_SOUND
Fprovide (intern ("nas-sound"));
#endif
+#ifdef HAVE_ESD_SOUND
+ Fprovide (intern ("esd-sound"));
+#endif
DEFVAR_INT ("bell-volume", &bell_volume /*
*How loud to be, from 0 to 100.
*/ );
bell_volume = 50;
+
+ DEFVAR_INT ("bell-inhibit-time", &bell_inhibit_time /*
+*Don't ring the bell on the same device more than once within this many seconds.
+*/ );
+ bell_inhibit_time = 0;
DEFVAR_LISP ("sound-alist", &Vsound_alist /*
An alist associating names with sounds.
load-sound-file.
Caveats:
- - You can only play audio data if running on the console screen of a
- Sun SparcStation, SGI, or HP9000s700.
+ - XEmacs must be built with sound support for your system. Not all
+ systems support sound.
- The pitch, duration, and volume options are available everywhere, but
many X servers ignore the `pitch' option.
DEFVAR_LISP ("native-sound-only-on-console", &Vnative_sound_only_on_console /*
Non-nil value means play sounds only if XEmacs is running
on the system console.
-Nil means always always play sounds, even if running on a non-console tty
+Nil means always play sounds, even if running on a non-console tty
or a secondary X display.
This variable only applies to native sound support.