/*
* Copyright 2001, 2002 David J. Hawkey Jr.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose and without fee is hereby granted, provided
* that the above copyright notice appear in all copies and that both that
* copyright notice and this permission notice appear in supporting
* documentation, and that the name of the copyright holder or the author not
* be used in advertising or publicity pertaining to distribution of the
* software without specific, written prior permission. The copyright holder
* and the author make no representations about the suitability of this
* software for any purpose. It is provided "as is" without express or
* implied warranty.
*
* THE COPYRIGHT HOLDER AND THE AUTHOR DISCLAIM ALL WARRANTIES WITH REGARD
* TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDER OR THE AUTHOR BE LIABLE
* FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/*
* sound.c
*
* D. J. Hawkey Jr. - 6/22/01 8/16/01 11/15/02
*/
#ifdef NO_SOUND_SUPPORT
/* stub function for gram.y */
int
SetSound(function, filename, volume)
char *function, *filename;
int volume;
{
return (1);
}
#else /* NO_SOUND_SUPPORT */
#include <X11/Xmu/CharSet.h>
#include <string.h>
#include <stdlib.h>
#include <rplay.h>
#include "gram.h"
#include "parse.h"
#include "twm.h"
#include "sound.h"
#ifndef MAXHOSTNAMELEN
#define MAXHOSTNAMELEN 256
#endif
extern int parse_keyword(); /* in parse.c */
extern void twmrc_error_prefix(); /* in gram.y */
typedef struct sound_keyword
{
char *name;
int value;
} sound_keyword;
static sound_keyword sound_keywords[] =
{
{"(vtwm start)", S_START},
{"(vtwm stop)", S_STOP},
{"(client map)", S_CMAP},
{"(client unmap)", S_CUNMAP},
{"(menu map)", S_MMAP},
{"(menu unmap)", S_MUNMAP},
{"(info unmap)", S_IUNMAP},
{"(autopan event)", S_APAN},
{"(bell event)", S_BELL}
};
#define MAX_SOUNDKEYWORDS (sizeof(sound_keywords) / sizeof(sound_keyword))
typedef struct sound_entry
{
int func;
RPLAY *rp;
} sound_entry;
static sound_entry *sound_entries = NULL;
static int sound_count = 0;
static int sound_size = 0;
static int sound_fd = -1;
static int sound_vol = 63; /* 1/4 attenuation */
static int sound_state = 0;
static char sound_host[MAXHOSTNAMELEN + 1] = "";
/* for qsort() */
static int
compare(p, q)
void *p, *q;
{
sound_entry *pp = (sound_entry *) p, *qq = (sound_entry *) q;
return (pp->func - qq->func);
}
static int
adjustVolume(volume)
int volume;
{
float vol;
if (volume > 100)
volume = 100;
/* volume for rplay is 1 to 255, not 1 to 100 */
vol = (float) volume / 100.0;
volume = vol * 255.0;
return (volume);
}
int
OpenSound()
{
if (sound_fd < 0)
{
if (sound_host[0] == '\0')
{
strncpy(sound_host, rplay_default_host(), MAXHOSTNAMELEN);
sound_host[MAXHOSTNAMELEN] = '\0';
}
if ((sound_fd = rplay_open(sound_host)) >= 0)
{
qsort((void *) sound_entries, (size_t) sound_count,
(size_t) sizeof(sound_entry), compare);
sound_state = 1;
}
}
return (sound_fd);
}
void
CloseSound()
{
int i;
for (i = 0; i < sound_count; i++)
rplay_destroy(sound_entries[i].rp);
if (sound_entries != NULL)
free((void *) sound_entries);
if (sound_fd >= 0)
rplay_close(sound_fd);
sound_entries = NULL;
sound_count = 0;
sound_size = 0;
sound_fd = -1;
sound_vol = 63;
sound_state = 0;
sound_host[0] = '\0';
}
int
SetSound(function, filename, volume)
char *function, *filename;
int volume;
{
sound_entry *sptr;
int i, func, subfunc;
func = parse_keyword(function, &subfunc);
if (func != FKEYWORD && func != FSKEYWORD)
{
XmuCopyISOLatin1Lowered(function, function);
for (i = 0; i < MAX_SOUNDKEYWORDS; i++)
if (strcmp(function, sound_keywords[i].name) == 0)
{
func = FKEYWORD;
subfunc = sound_keywords[i].value;
break;
}
}
if (func == FKEYWORD || func == FSKEYWORD)
{
if (sound_count >= sound_size)
{
sound_size += 10;
sptr = (sound_entry *) realloc((sound_entry *) sound_entries,
sound_size * sizeof(sound_entry));
if (sptr == NULL)
{
twmrc_error_prefix();
fprintf(stderr,
"unable to allocate %d bytes for sound_entries\n",
sound_size * sizeof(sound_entry));
Done();
}
else
sound_entries = sptr;
}
sptr = &sound_entries[sound_count];
sptr->func = subfunc;
if ((sptr->rp = rplay_create(RPLAY_PLAY)) == NULL)
{
twmrc_error_prefix();
fprintf(stderr, "unable to add to sound list\n");
Done();
}
sound_count++;
if (volume < 0)
volume = sound_vol;
else
volume = adjustVolume(volume);
if (rplay_set(sptr->rp, RPLAY_INSERT, 0, RPLAY_SOUND, filename,
RPLAY_VOLUME, volume, NULL) < 0)
{
twmrc_error_prefix();
fprintf(stderr, "unable to set \"%s\" in sound list\n",
filename);
Done();
}
return (1);
}
twmrc_error_prefix();
fprintf(stderr, "unknown function \"%s\" for sound_entry\n", function);
return (0);
}
int
PlaySound(function)
int function;
{
register int i, low, mid, high;
if (sound_fd < 0 || sound_state == 0)
return (1); /* pretend success */
low = 0;
high = sound_count - 1;
while (low <= high)
{
mid = (low + high) / 2;
i = sound_entries[mid].func - function;
if (i < 0)
low = mid + 1;
else if (i > 0)
high = mid - 1;
else
{
rplay(sound_fd, sound_entries[mid].rp);
return (1);
}
}
return (0);
}
int
PlaySoundAdhoc(filename)
char *filename;
{
RPLAY *rp;
int i;
if (sound_fd < 0 || sound_state == 0)
return (1); /* pretend success */
if ((rp = rplay_create(RPLAY_PLAY)) == NULL)
{
twmrc_error_prefix();
fprintf(stderr, "unable to create sound \"%s\"\n", filename);
return (0);
}
if ((i = rplay_set(rp, RPLAY_INSERT, 0, RPLAY_SOUND, filename,
RPLAY_VOLUME, sound_vol, NULL)) >= 0)
rplay(sound_fd, rp);
rplay_destroy(rp);
if (i < 0)
{
twmrc_error_prefix();
fprintf(stderr, "unable to set sound \"%s\"\n", filename);
return (0);
}
return (1);
}
void
SetSoundHost(host)
char *host;
{
strncpy(sound_host, host, MAXHOSTNAMELEN);
sound_host[MAXHOSTNAMELEN] = '\0';
}
void
SetSoundVolume(volume)
int volume;
{
if (volume < 0)
volume = 0;
sound_vol = adjustVolume(volume);
}
int
ToggleSounds()
{
return ((sound_state ^= 1));
}
#endif /* NO_SOUND_SUPPORT */
syntax highlighted by Code2HTML, v. 0.9.1