e16-epplets/epplets/E-SD.c

594 lines
13 KiB
C

/* E-SD.c
*
* Copyright (C) 1999-2000 Tom Gilbert
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA
*/
#include <esd.h>
#include <fcntl.h>
#include "config.h"
#include "epplet.h"
#include "esdcloak.h"
#include "utils.h"
extern int load_val;
extern int load_r;
extern int load_l;
RGB_buf rgbbuf;
static Epplet_gadget btn_conf, btn_close, btn_help, btn_ctimer;
static Epplet_gadget p, ctimer_p;
static Window win;
static Epplet_gadget da;
static int cloaked = 0;
static const int cloak_anims[] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16
};
static const int cloak_delays[] = {
1, 2, 3, 4, 5, 10, 15, 20, 30, 60, 120
};
struct {
int fd;
int vol_l;
int vol_r;
int vol_ave;
int standby;
} esd;
static Epplet_gadget lbar, rbar, standby;
struct {
int cloak_anim;
int do_cloak;
double cloak_delay;
double draw_interval;
char *dir;
} opt;
/* RATE is sample rate (samples/sec) */
#define BUFS 8 /* number of audio buffers (lag compensation) */
#define RATE 44100
static int nsamp; /* number of samples */
static void cb_in(void *data, Window w);
/*
short *incoming_buf[BUFS];
int last_is_full;
volatile int curbuf;
int pos;
int to_get;
int lag;
*/
static void
save_config(void)
{
char buf[10];
Esnprintf(buf, sizeof(buf), "%f", opt.cloak_delay);
Epplet_modify_config("CLOAK_DELAY", buf);
Esnprintf(buf, sizeof(buf), "%f", opt.draw_interval);
Epplet_modify_config("DRAW_INTERVAL", buf);
Esnprintf(buf, sizeof(buf), "%d", opt.do_cloak);
Epplet_modify_config("DO_CLOAK", buf);
Esnprintf(buf, sizeof(buf), "%d", opt.cloak_anim);
Epplet_modify_config("CLOAK_ANIM", buf);
Epplet_modify_config("DIRECTORY", opt.dir);
}
static void
load_config(void)
{
opt.do_cloak = atoi(Epplet_query_config_def("DO_CLOAK", "1"));
opt.cloak_anim = atoi(Epplet_query_config_def("CLOAK_ANIM", "4"));
opt.cloak_delay = atof(Epplet_query_config_def("CLOAK_DELAY", "3"));
opt.draw_interval = atof(Epplet_query_config_def("DRAW_INTERVAL", "0.05"));
if (opt.dir)
free(opt.dir);
opt.dir = _Strdup(Epplet_query_config_def("DIRECTORY", "~/"));
}
static void
cb_close(void *data __UNUSED__)
{
save_config();
Epplet_unremember();
esd_close(esd.fd);
Esync();
exit(0);
}
static void
cb_help(void *data __UNUSED__)
{
Epplet_show_about("E-SD");
}
static void
cloak_draw(void *data __UNUSED__)
{
switch (opt.cloak_anim)
{
case 0:
{
blank_buf();
break;
}
case 1:
{
draw_flame();
break;
}
case 2:
{
draw_aa_triangle();
break;
}
case 3:
{
draw_aa_star();
break;
}
case 4:
{
draw_scanner();
break;
}
case 5:
{
draw_colorwarp();
break;
}
case 6:
{
draw_ball();
break;
}
case 7:
{
draw_atoms();
break;
}
case 8:
{
draw_text();
break;
}
case 9:
{
draw_history();
break;
}
case 10:
{
draw_history_bar();
break;
}
default:
{
blank_buf();
break;
}
}
Epplet_paste_buf(rgbbuf, win, 0, 0);
Epplet_timer(cloak_draw, NULL, opt.draw_interval, "DRAW_TIMER");
}
static void
cloak_epplet(void *data __UNUSED__)
{
if (!cloaked)
{
Epplet_gadget_hide(btn_close);
Epplet_gadget_hide(btn_conf);
Epplet_gadget_hide(btn_help);
Epplet_gadget_show(da);
cloak_draw(NULL);
cloaked = 1;
}
}
static void
cb_cloak_anim(void *data)
{
cb_in(NULL, 0);
opt.do_cloak = 1;
opt.cloak_anim = *((int *)data);
Epplet_timer(cloak_epplet, NULL, opt.cloak_delay, "CLOAK_TIMER");
}
static void
cb_dont_cloak(void *data __UNUSED__)
{
opt.do_cloak = 0;
Epplet_remove_timer("CLOAK_TIMER");
if (cloaked)
{
Epplet_gadget_hide(da);
cloaked = 0;
Epplet_gadget_show(btn_close);
Epplet_gadget_show(btn_conf);
Epplet_gadget_show(btn_help);
}
}
static void
cb_in(void *data __UNUSED__, Window w __UNUSED__)
{
if (cloaked)
{
Epplet_gadget_hide(da);
cloaked = 0;
Epplet_gadget_show(btn_close);
Epplet_gadget_show(btn_conf);
Epplet_gadget_show(btn_help);
}
Epplet_remove_timer("CLOAK_TIMER");
Epplet_remove_timer("DRAW_TIMER");
}
static void
cb_out(void *data __UNUSED__, Window w __UNUSED__)
{
Epplet_remove_timer("CLOAK_TIMER");
if ((!cloaked) && (opt.do_cloak))
Epplet_timer(cloak_epplet, NULL, opt.cloak_delay, "CLOAK_TIMER");
}
static void
cb_cloak_delay(void *data)
{
Epplet_remove_timer("CLOAK_TIMER");
opt.cloak_delay = *(int *)data;
Epplet_timer(cloak_epplet, NULL, opt.cloak_delay, "CLOAK_TIMER");
}
/* This method was *really* laggy */
/*
static void
handle_data (void)
{
int buf;
short *ptr;
int count;
register int i;
register short val_l = 0, val_r = 0;
unsigned short bigl = 0, bigr = 0;
if (last_is_full)
{
curbuf++;
if (curbuf >= BUFS)
curbuf = 0;
}
count = read (esd.fd, incoming_buf[curbuf] + pos, to_get);
if (count < 0)
{
printf ("count < 0\n");
exit (1);
}
else
{
pos += count;
to_get -= count;
}
if (to_get <= 0)
{
to_get = nsamp;
pos = 0;
last_is_full = 1;
buf = ((BUFS * 2) + curbuf - lag) % BUFS;
bigl = bigr = 0;
for (i = 0; i < nsamp; i++)
{
val_l = abs (*(incoming_buf[buf] + i));
i++;
val_r = abs (*(incoming_buf[buf] + i));
bigl = (val_l > bigl) ? val_l : bigl;
bigr = (val_r > bigr) ? val_r : bigr;
}
bigl /= (nsamp / 8);
bigr /= (nsamp / 8);
esd.vol_l = bigl;
esd.vol_r = bigr;
esd.vol_ave = (bigl + bigr) / 2;
if (!cloaked)
{
Epplet_gadget_data_changed (lbar);
Epplet_gadget_data_changed (rbar);
}
}
else
{
last_is_full = 0;
}
}
*/
static void
esd_timer(void *data __UNUSED__)
{
fd_set rfds;
struct timeval tv;
int retval;
register short val_l = 0, val_r = 0;
unsigned short bigl = 0, bigr = 0;
int count, i;
short aubuf[8192] = { 0 };
FD_ZERO(&rfds);
FD_SET(esd.fd, &rfds);
tv.tv_sec = 0;
tv.tv_usec = 0;
/* tv is basically 0, so this should be a non-blocking select() */
/* It should immediately return whether there is anything in the stream */
retval = select(esd.fd + 1, &rfds, NULL, NULL, &tv);
if (retval)
{
count = read(esd.fd, aubuf, nsamp * 2);
if (count < 0)
{
printf("WARNING: Couldn't read EsounD monitor stream!\n");
return;
}
for (i = 0; i < count;)
{
val_r = abs(aubuf[i++]);
val_l = abs(aubuf[i++]);
bigl = (val_l > bigl) ? val_l : bigl;
bigr = (val_r > bigr) ? val_r : bigr;
}
bigl /= 327;
bigr /= 327;
esd.vol_l = bigl;
esd.vol_r = bigr;
esd.vol_ave = (bigl + bigr) / 2;
load_val = esd.vol_ave;
load_r = esd.vol_r;
load_l = esd.vol_l;
if (!cloaked)
{
Epplet_gadget_data_changed(lbar);
Epplet_gadget_data_changed(rbar);
}
}
else
{
if (esd.vol_ave != 0)
{
esd.vol_r = 0;
esd.vol_l = 0;
esd.vol_ave = 0;
load_val = esd.vol_ave;
load_r = esd.vol_r;
load_l = esd.vol_l;
if (!cloaked)
{
Epplet_gadget_data_changed(lbar);
Epplet_gadget_data_changed(rbar);
}
}
}
/*
if (retval)
{
handle_data ();
}
else
{
if (esd.vol_ave != 0)
{
esd.vol_r = 0;
esd.vol_l = 0;
esd.vol_ave = 0;
Epplet_gadget_data_changed (lbar);
Epplet_gadget_data_changed (rbar);
}
}
*/
Epplet_timer(esd_timer, NULL, 0.05, "ESD_TIMER");
}
static void
standby_cb(void *data __UNUSED__)
{
int fd = esd_open_sound(NULL);
if (esd.standby)
{
esd_resume(fd);
}
else
{
esd_standby(fd);
}
esd_close(fd);
}
static void
create_epplet_layout(void)
{
Epplet_gadget_show(btn_close = Epplet_create_button(NULL, NULL,
2, 2, 0, 0, "CLOSE",
0, NULL, cb_close,
NULL));
Epplet_gadget_show(btn_help =
Epplet_create_button(NULL, NULL, 18, 2, 0, 0, "HELP",
0, NULL, cb_help, NULL));
Epplet_gadget_show(lbar = Epplet_create_vbar(2, 18, 12, 28, 1, &esd.vol_l));
Epplet_gadget_show(rbar = Epplet_create_vbar(34, 18, 12, 28, 1, &esd.vol_r));
Epplet_gadget_show(standby =
Epplet_create_togglebutton(NULL, "E-SD_standby.png",
18, 18, 12, 12,
&esd.standby, standby_cb,
NULL));
p = Epplet_create_popup();
Epplet_add_popup_entry(p, "Don't Cloak", NULL, cb_dont_cloak, NULL);
Epplet_add_popup_entry(p, "Blank Epplet", NULL, cb_cloak_anim,
(void *)(&(cloak_anims[0])));
Epplet_add_popup_entry(p, "RasterFire", NULL, cb_cloak_anim,
(void *)(&(cloak_anims[1])));
Epplet_add_popup_entry(p, "AA Triangle", NULL, cb_cloak_anim,
(void *)(&(cloak_anims[2])));
Epplet_add_popup_entry(p, "AA Star", NULL, cb_cloak_anim,
(void *)(&(cloak_anims[3])));
Epplet_add_popup_entry(p, "Scanner", NULL, cb_cloak_anim,
(void *)(&(cloak_anims[4])));
Epplet_add_popup_entry(p, "ColorShift", NULL, cb_cloak_anim,
(void *)(&(cloak_anims[5])));
Epplet_add_popup_entry(p, "Bouncy Ball", NULL, cb_cloak_anim,
(void *)(&(cloak_anims[6])));
Epplet_add_popup_entry(p, "Atoms", NULL, cb_cloak_anim,
(void *)(&(cloak_anims[7])));
Epplet_add_popup_entry(p, "Banner", NULL, cb_cloak_anim,
(void *)(&(cloak_anims[8])));
Epplet_add_popup_entry(p, "History", NULL, cb_cloak_anim,
(void *)(&(cloak_anims[9])));
Epplet_add_popup_entry(p, "History Bar", NULL, cb_cloak_anim,
(void *)(&(cloak_anims[10])));
ctimer_p = Epplet_create_popup();
Epplet_add_popup_entry(ctimer_p, "Cloak Delay", NULL, NULL, NULL);
Epplet_add_popup_entry(ctimer_p, "1 Sec", NULL, cb_cloak_delay,
(void *)(&(cloak_delays[0])));
Epplet_add_popup_entry(ctimer_p, "2 Sec", NULL, cb_cloak_delay,
(void *)(&(cloak_delays[1])));
Epplet_add_popup_entry(ctimer_p, "3 Sec", NULL, cb_cloak_delay,
(void *)(&(cloak_delays[2])));
Epplet_add_popup_entry(ctimer_p, "4 Sec", NULL, cb_cloak_delay,
(void *)(&(cloak_delays[3])));
Epplet_add_popup_entry(ctimer_p, "5 Sec", NULL, cb_cloak_delay,
(void *)(&(cloak_delays[4])));
Epplet_add_popup_entry(ctimer_p, "10 Sec", NULL, cb_cloak_delay,
(void *)(&(cloak_delays[5])));
Epplet_add_popup_entry(ctimer_p, "15 Sec", NULL, cb_cloak_delay,
(void *)(&(cloak_delays[6])));
Epplet_add_popup_entry(ctimer_p, "20 Sec", NULL, cb_cloak_delay,
(void *)(&(cloak_delays[7])));
Epplet_add_popup_entry(ctimer_p, "30 Sec", NULL, cb_cloak_delay,
(void *)(&(cloak_delays[8])));
Epplet_add_popup_entry(ctimer_p, "1 min", NULL, cb_cloak_delay,
(void *)(&(cloak_delays[9])));
Epplet_add_popup_entry(ctimer_p, "2 mins", NULL, cb_cloak_delay,
(void *)(&(cloak_delays[10])));
Epplet_gadget_show(btn_ctimer =
Epplet_create_popupbutton(NULL, "E-SD_minitime.png",
18, 31, 12, 12, NULL,
ctimer_p));
Epplet_gadget_show(btn_conf = Epplet_create_popupbutton(NULL, NULL,
34, 2, 12, 12,
"CONFIGURE", p));
da = Epplet_create_drawingarea(2, 2, 44, 44);
win = Epplet_get_drawingarea_window(da);
rgbbuf = Epplet_make_rgb_buf(40, 40);
cloaked = 0;
if (opt.do_cloak)
Epplet_timer(cloak_epplet, NULL, opt.cloak_delay, "CLOAK_TIMER");
Epplet_timer(esd_timer, NULL, 0.05, "ESD_TIMER");
Epplet_register_mouse_enter_handler(cb_in, (void *)win);
Epplet_register_mouse_leave_handler(cb_out, NULL);
}
static void
clean_exit(void)
{
save_config();
Epplet_cleanup();
}
int
main(int argc, char **argv)
{
Epplet_adjust_priority(10);
atexit(clean_exit);
/* Initialise random numbers */
srand(time(0));
Epplet_Init("E-SD", "0.4", "Enlightenment ESD Monitor", 3, 3, argc, argv, 0);
Epplet_load_config();
esd.fd =
esd_monitor_stream(ESD_BITS16 | ESD_STEREO | ESD_STREAM | ESD_PLAY,
RATE, NULL, "E-SD");
if (esd.fd < 0)
{
printf("No ESD - exiting!\n");
exit(1);
}
fcntl(esd.fd, F_SETFL, O_NONBLOCK);
if (esd_get_standby_mode(esd.fd) == ESM_RUNNING)
esd.standby = 0;
else
esd.standby = 1;
nsamp = 4096;
/*
last_is_full = 1;
pos = 0;
to_get = nsamp;
lag = 0;
for (i = 0; i < BUFS; i++)
{
incoming_buf[i] = malloc (nsamp * sizeof (short));
if (incoming_buf[i] == NULL)
{
printf
("Audio Buffer Memory could NOT be allocated!!!!, Exiting now!\n");
exit (2);
}
}
*/
set_flame_col(0);
load_config();
create_epplet_layout();
Epplet_show();
Epplet_Loop();
return 0;
}