/* * Copyright (c) 1994,1995 Dimitrios P. Bouras and William K. W. Cheung * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * Except as contained in this notice, the name of the X Consortium shall not be * used in advertising or otherwise to promote the sale, use or other dealings * in this Software without prior written authorization from the X Consortium. * * Derived from the MIT X11R5 xbiff, written by Jim Fulton, which is * copyrighted (c) 1988 X Consortium. * * Mailbox XPM additions-modifications: Dimitrios P. Bouras * Audio support and XPM icon animation: William K. W. Cheung * Derived from xmailbox by Dimitrios P. Bouras and William K. W. Cheung * as well as volume by Sam Lantinga. The above copyright notice is * from Dimitros and William's file Mailbox.c in the xmailbox application. * modified and integrated into Coolmail: Randall K. Sharpe */ #include /* for stat() ** needs types.h ***/ #include /* for signal() */ #include /* for printing error messages */ #include /* for getting username */ #include /* for getenv() */ #include #include #include #include #include extern int cool_vol; extern char *sndfile; /* I am only doing sun audio -- RKS */ /* Adapted from */ typedef unsigned u_32; /* we assume sizeof(unsigned) = 4 */ typedef struct { u_32 magic; /* magic number */ u_32 hdr_size; /* size of this header */ u_32 data_size; /* length of data (optional) */ u_32 encoding; /* data encoding format */ u_32 sample_rate; /* samples per second */ u_32 channels; /* number of interleaved channels */ } Audio_filehdr; #ifdef linux #include #define DEV_MIXER "/dev/mixer" #define MAX_VOLUME 100 #define MIN_VOLUME 1 #define RIGHT 0x01 #define LEFT 0x02 typedef struct stereovolume { unsigned char left; unsigned char right; unsigned char pad[2]; } StereoVolume; void setvolume(int which, unsigned char setting, StereoVolume *volptr) { if ( setting < MIN_VOLUME ) setting=MIN_VOLUME; if ( setting > MAX_VOLUME ) setting=MAX_VOLUME; if ( which&RIGHT ) volptr->right=setting; if ( which&LEFT ) volptr->left=setting; } #else #include #endif #ifndef min #define min(x,y) ((x) < (y)? (x): (y)) #endif #define CLOSE_FD(afd) { if (afd > -1) close(afd); afd = -1; } #ifdef linux #define INIT_FD { audiofd = filefd = mixer_fd = -1; } #define END_FD { CLOSE_FD(audiofd); CLOSE_FD(filefd); CLOSE_FD(mixer_fd); return; } #else #define INIT_FD { audiofd = filefd = 0; } #define END_FD { CLOSE_FD(audiofd); CLOSE_FD(filefd); return; } #endif void audio_beep (void) { int audiofd, filefd; int rn, wn, len; unsigned char buf[256]; Audio_filehdr *au_hdr; #ifdef linux StereoVolume origVol, volume; int mixer_fd; #else audio_info_t ais; int origVol; #endif INIT_FD; audiofd = open( "/dev/audio", O_WRONLY | O_NDELAY ); if (audiofd < 0) { perror("/dev/audio"); fprintf(stderr, "%s: Problem opening /dev/audio.\n", "Coolmail"); END_FD; } #ifdef linux if ( (mixer_fd=open(DEV_MIXER, O_RDWR, 0)) < 0 ) { fprintf(stderr, "Can't open %s: ", DEV_MIXER); END_FD; } if ( ioctl(mixer_fd, MIXER_READ(SOUND_MIXER_VOLUME), &origVol) < 0 ) { perror("Can't obtain current volume settings"); END_FD; } setvolume(LEFT|RIGHT, cool_vol, &volume); if ( ioctl(mixer_fd, MIXER_WRITE(SOUND_MIXER_VOLUME), &volume) < 0 ) { fprintf(stderr, "Can't set current volume settings"); END_FD; } #else if( ioctl( audiofd, AUDIO_GETINFO, &ais ) ) { fprintf(stderr, "%s: Problem retrieving /dev/audio info.\n", "Coolmail"); END_FD; } origVol = ais.play.gain; ais.play.gain = cool_vol; if( ioctl( audiofd, AUDIO_SETINFO, &ais ) ) { fprintf(stderr, "Coolmail: Error %d returned from ioctl.\n", errno); fprintf(stderr, "%s: Problem setting /dev/audio info.\n", "Coolmail"); END_FD; } #endif filefd = open(sndfile, O_RDONLY); if (filefd < 0) { fprintf(stderr, "%s: Couldn't play file \"%s\"\n", "Coolmail", sndfile); END_FD; } /* Read in the audio header */ rn = read(filefd, buf, sizeof(Audio_filehdr)); if (rn > 0 && strncmp(buf, ".snd", 4) != 0) { fprintf(stderr, "%s: Invalid audio file format.\n", "Coolmail"); END_FD; } /* Strip the header */ au_hdr = (Audio_filehdr *)buf; #ifdef linux rn = ntohl(au_hdr->hdr_size) - sizeof(Audio_filehdr); #else rn = au_hdr->hdr_size - sizeof(Audio_filehdr); #endif for( ; rn > 0; ) { len = min(rn, sizeof(buf)); len = read(filefd, buf, len); rn -= len; } while(1) { rn = read(filefd, buf, sizeof(buf)); if (rn < 0) { fprintf(stderr, "%s: Error reading from file \"%s\"\n", "Coolmail", sndfile); END_FD; } if (rn == 0) break; while(1) { wn = write(audiofd, buf, rn); if ( wn < 0 ) { fprintf(stderr, "%s: Error writing to /dev/audio.\n", "Coolmail"); END_FD; } if ( wn != 0 ) break; usleep(1000); } } #ifdef linux CLOSE_FD(audiofd); if ( ioctl(mixer_fd, MIXER_WRITE(SOUND_MIXER_VOLUME), &origVol) < 0 ) { fprintf(stderr, "Can't reset volume settings"); } CLOSE_FD(mixer_fd); #else ais.play.gain = origVol; if( ioctl( audiofd, AUDIO_SETINFO, &ais ) ) { fprintf(stderr, "%s: Problem setting /dev/audio info.\n", "Coolmail"); } #endif END_FD; return; }