e16-epplets/epplets/E-NetFlame.c

482 lines
14 KiB
C

/****************************************************************/
/* E-NetFlame v0.3 */
/* author: Shawn M. Veader */
/* email: veader@cc.gatech.edu */
/****************************************************************/
#include "config.h"
#include "epplet.h"
#include "net.h"
static double *prev_val = NULL;
static int *load_val = NULL;
static Window win;
static RGB_buf buf;
static Epplet_gadget da, b_close, b_config, b_help, pop, pop2, text;
static unsigned int *flame = NULL;
static int *vspread, *hspread, *residual;
static unsigned char rm[255], gm[255], bm[255];
static const char *netdev;
static double stream_max = 2000;
static const double bandwidths[] = {
1000000000, 100000000, 10000000, 2000000,
1540000, 1000000, 512000, 256000,
144000, 128000, 64000, 56000,
33600, 28800, 14400, 9600,
4800, 2400, 300, 75
};
static const int colors[] = {
30, 90, 90,
50, 255, 255,
255, 255, 255,
255, 0, 0,
255, 255, 0,
255, 255, 255,
0, 255, 0,
255, 255, 0,
255, 255, 255,
0, 0, 255,
255, 0, 255,
255, 255, 255,
0, 0, 200,
40, 80, 255,
100, 200, 255,
80, 90, 140,
140, 150, 180,
255, 230, 200,
20, 40, 180,
255, 160, 0,
255, 255, 100
};
static void save_conf(int d1, int d2, int d3, int d4, int d5,
int d6, int d7, int d8, int d9);
#define VARIANCE 40
#define VARTREND 16
#define HSPREAD 10
#define VSPREAD 160
#define RESIDUAL 75
#define DIVISIONS 2
#define WIDTH 40
#define HEIGHT 30
#define MAXVAL 255
#define DOWN 0
#define UP 1
/* set the flame color */
static void
flame_col(int r1, int g1, int b1,
int r2, int g2, int b2, int r3, int g3, int b3)
{
int i;
for (i = 0; i < 25; i++)
{
rm[i] = (r1 * i) / 25;
gm[i] = (g1 * i) / 25;
bm[i] = (b1 * i) / 25;
}
for (i = 0; i < 25; i++)
{
rm[25 + i] = ((r2 * i) + (r1 * (25 - i))) / 25;
gm[25 + i] = ((g2 * i) + (g1 * (25 - i))) / 25;
bm[25 + i] = ((b2 * i) + (b1 * (25 - i))) / 25;
}
for (i = 0; i < 25; i++)
{
rm[50 + i] = ((r3 * i) + (r2 * (25 - i))) / 25;
gm[50 + i] = ((g3 * i) + (g2 * (25 - i))) / 25;
bm[50 + i] = ((b3 * i) + (b2 * (25 - i))) / 25;
}
for (i = 75; i < 255; i++)
{
rm[i] = rm[74];
gm[i] = gm[74];
bm[i] = bm[74];
}
}
/* draw the flame to display */
static void
draw_flame(void)
{
unsigned char *rgb, *rptr;
unsigned int *ptr;
int x, y, val1, val2, val3, i, j;
/* initialize the flame if it isn't done already */
if (!flame)
{
vspread = malloc(WIDTH * sizeof(int));
hspread = malloc(WIDTH * sizeof(int));
residual = malloc(WIDTH * sizeof(int));
flame = calloc(WIDTH * HEIGHT, sizeof(unsigned int));
}
/* move to the bottom left of the drawing area */
ptr = flame + ((HEIGHT - 1) * WIDTH);
/* scan along the bottom row of pixels to start flames */
for (x = 0; x < WIDTH; x++)
{
/* adjust spreads and residual values to reflect the
* load values... */
vspread[x] = VSPREAD + (load_val[(x * DIVISIONS) / WIDTH] / 50);
hspread[x] = HSPREAD + (load_val[(x * DIVISIONS) / WIDTH] / 50);
residual[x] = RESIDUAL + (load_val[(x * DIVISIONS) / WIDTH] / 50);
/* assign a random value to the pixel according to the
* load ... gives randomness to flames */
ptr[x] = (rand() % ((load_val[(x * DIVISIONS) / WIDTH]) + 155));
/* bounds checking */
if (ptr[x] > MAXVAL)
ptr[x] = 0;
}
/* this divides up the chart into multiple sections
* depending on the cpus value */
for (i = 0; i < DIVISIONS; i++)
{
for (x = (WIDTH / (DIVISIONS * 2)) - 1 + (i * (WIDTH / DIVISIONS));
x <= (WIDTH / (DIVISIONS * 2)) + 1 + (i * (WIDTH / DIVISIONS));
x++)
{
j = (load_val[i] * HEIGHT) / 100;
ptr = flame + ((HEIGHT - j) * (WIDTH)) + (x);
/* marches down a column increasing the intensity
* as you travel down */
for (y = 0; y < j; y++)
{
ptr[0] += ((y * 64 * load_val[i]) / (j * 100));
ptr += WIDTH;
}
}
}
/* ----- *
* --A-- *
* -BCD- *
* ----- */
for (y = HEIGHT - 1; y >= 2; y--)
{
ptr = flame + (y * 40);
for (x = 1; x < WIDTH - 1; x++)
{
/* val1 = (C * vspread) / 256 */
val1 = (ptr[x] * vspread[x]) >> 8;
/* val2 = (C * hspread) / 256 */
val2 = (ptr[x] * hspread[x]) >> 8;
/* val3 = (C * residual) / 256 */
val3 = (ptr[x] * residual[x]) >> 8;
/* add val2 to B */
ptr[x - 1] += val2;
if (ptr[x - 1] > MAXVAL)
ptr[x - 1] = MAXVAL;
/* add val1 to A */
ptr[x - WIDTH] += val1;
if (ptr[x - WIDTH] > MAXVAL)
ptr[x - WIDTH] = MAXVAL;
/* add val2 to D */
ptr[x + 1] += val2;
if (ptr[x + 1] > MAXVAL)
ptr[x + 1] = MAXVAL;
/* add val3 to C */
ptr[x] = val3;
}
}
/* blank the top row of pixels */
for (x = 0; x < WIDTH; x++)
flame[x] = 0;
/* half the intensity of the second row */
for (x = 0; x < WIDTH; x++)
flame[WIDTH + x] /= 2;
/* blank out left most column */
for (y = 0; y < HEIGHT; y++)
flame[y * WIDTH] = 0;
/* half the intensity on second left most column */
for (y = 0; y < HEIGHT; y++)
flame[(y * WIDTH) + 1] /= 2;
/* blank out right most column */
for (y = 0; y < HEIGHT; y++)
flame[(y * WIDTH) + (WIDTH - 1)] = 0;
/* half the intensity of the second right most column */
for (y = 0; y < HEIGHT; y++)
flame[(y * WIDTH) + (WIDTH - 2)] /= 2;
rgb = Epplet_get_rgb_pointer(buf);
for (y = 0; y < HEIGHT; y++)
{
ptr = flame + (y * WIDTH);
rptr = rgb + (y * WIDTH * 4);
for (x = 0; x < WIDTH; x++)
{
val1 = ptr[x] & 0xff;
rptr[0] = rm[val1];
rptr[1] = gm[val1];
rptr[2] = bm[val1];
rptr += 4;
}
}
}
/* handles the timer, check /proc/net/dev to establish
* up and down load */
static void
epplet_timer(void *data __UNUSED__)
{
double val = -1.0, val2 = -1.0, dval, dval2;
unsigned char invalid;
invalid = net_get_bytes_inout(netdev, &val, &val2);
if (invalid)
{
Epplet_dialog_ok("Unable to get network device statistics for %s: %s",
netdev, net_strerror(invalid));
Epplet_unremember();
Esync();
exit(-1);
}
if (val != -1.0)
{
dval = val - prev_val[DOWN];
dval2 = val2 - prev_val[UP];
prev_val[DOWN] = val;
prev_val[UP] = val2;
load_val[DOWN] = (int)((dval * 800 * 3) / stream_max);
load_val[UP] = (int)((dval2 * 800 * 3) / stream_max);
if (load_val[DOWN] > 100)
load_val[DOWN] = 100;
if (load_val[UP] > 100)
load_val[UP] = 100;
}
draw_flame();
Epplet_paste_buf(buf, win, 0, 0);
Epplet_timer(epplet_timer, NULL, 0.1, "TIMER");
}
/* called when you close the epplet */
static void
epplet_close(void *data __UNUSED__)
{
Epplet_unremember();
Esync();
exit(0);
}
/* called when you select a color from the epplet color menu */
static void
epplet_color(void *data)
{
int *d;
d = (int *)data;
flame_col(d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7], d[8]);
save_conf(d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7], d[8]);
Epplet_gadget_hide(pop);
Epplet_gadget_hide(pop2);
}
/* called when you select a bandwidth from the epplet bandwidth menu */
static void
epplet_bandwidth(void *data)
{
double *d;
char s[64];
d = (double *)data;
stream_max = d[0];
Esnprintf(s, sizeof(s), "%f", stream_max);
Epplet_modify_config("bandwidth", s);
Epplet_save_config();
Epplet_gadget_hide(pop);
Epplet_gadget_hide(pop2);
}
/* called when the config button is pressed */
static void
epplet_config(void *data __UNUSED__)
{
Epplet_gadget_show(pop);
Epplet_gadget_show(pop2);
}
/* called when the help button is pressed */
static void
epplet_help(void *data __UNUSED__)
{
Epplet_show_about("E-NetFlame");
}
/* called when the epplet gets the focus */
static void
epplet_in(void *data __UNUSED__, Window w)
{
if (w == Epplet_get_main_window())
{
Epplet_gadget_show(b_close);
Epplet_gadget_show(b_config);
Epplet_gadget_show(b_help);
}
}
/* called when the epplet loses the focus */
static void
epplet_out(void *data __UNUSED__, Window w)
{
if (w == Epplet_get_main_window())
{
Epplet_gadget_hide(b_close);
Epplet_gadget_hide(b_config);
Epplet_gadget_hide(b_help);
}
}
/* save off the color of the flame in a config file */
static void
save_conf(int d1, int d2, int d3, int d4, int d5,
int d6, int d7, int d8, int d9)
{
char s[1024];
Esnprintf(s, sizeof(s), "%d %d %d", d1, d2, d3);
Epplet_modify_config("color1", s);
Esnprintf(s, sizeof(s), "%d %d %d", d4, d5, d6);
Epplet_modify_config("color2", s);
Esnprintf(s, sizeof(s), "%d %d %d", d7, d8, d9);
Epplet_modify_config("color3", s);
Esnprintf(s, sizeof(s), "%f", stream_max);
Epplet_modify_config("bandwidth", s);
Epplet_save_config();
}
/* load the color of the flame from a config file */
static void
load_conf(void)
{
int d1, d2, d3, d4, d5, d6, d7, d8, d9;
const char *str;
str = Epplet_query_config_def("color1", "30 90 90");
sscanf(str, "%d %d %d", &d1, &d2, &d3);
str = Epplet_query_config_def("color2", "50 255 255");
sscanf(str, "%d %d %d", &d4, &d5, &d6);
str = Epplet_query_config_def("color3", "255 255 255");
sscanf(str, "%d %d %d", &d7, &d8, &d9);
str = Epplet_query_config_def("bandwidth", "2400");
sscanf(str, "%lf", &stream_max);
#ifdef __sun__
netdev = Epplet_query_config_def("device", "hme0");
#else
netdev = Epplet_query_config_def("device", "eth0");
#endif
flame_col(d1, d2, d3, d4, d5, d6, d7, d8, d9);
}
/* where it all begins... */
int
main(int argc, char **argv)
{
Epplet_gadget p;
Epplet_adjust_priority(10);
atexit(Epplet_cleanup);
load_val = calloc(DIVISIONS, sizeof(int));
prev_val = calloc(DIVISIONS, sizeof(double));
Epplet_Init("E-NetFlame", "0.3", "E Net-Flame Epplet", 3, 3, argc, argv, 0);
Epplet_load_config();
Epplet_timer(epplet_timer, NULL, 0.1, "TIMER");
Epplet_gadget_show(da =
Epplet_create_drawingarea(2, 2, (WIDTH + 4),
(HEIGHT + 4)));
win = Epplet_get_drawingarea_window(da);
buf = Epplet_make_rgb_buf(WIDTH, HEIGHT);
Epplet_gadget_show(text = Epplet_create_label(8, 36, "IN OUT", 1));
b_close = Epplet_create_button(NULL, NULL,
3, 3, 0, 0, "CLOSE", 0, NULL,
epplet_close, NULL);
b_help = Epplet_create_button(NULL, NULL,
17, 3, 0, 0, "HELP", 0, NULL,
epplet_help, NULL);
b_config = Epplet_create_button(NULL, NULL,
31, 3, 0, 0, "CONFIGURE", 0, NULL,
epplet_config, NULL);
p = Epplet_create_popup();
Epplet_add_popup_entry(p, "Turquoise", NULL, epplet_color,
(void *)(&(colors[0 * 9])));
Epplet_add_popup_entry(p, "Fire ", NULL, epplet_color,
(void *)(&(colors[1 * 9])));
Epplet_add_popup_entry(p, "Copper", NULL, epplet_color,
(void *)(&(colors[2 * 9])));
Epplet_add_popup_entry(p, "Violet", NULL, epplet_color,
(void *)(&(colors[3 * 9])));
Epplet_add_popup_entry(p, "Night", NULL, epplet_color,
(void *)(&(colors[4 * 9])));
Epplet_add_popup_entry(p, "Sunrise", NULL, epplet_color,
(void *)(&(colors[5 * 9])));
Epplet_add_popup_entry(p, "Sunset", NULL, epplet_color,
(void *)(&(colors[6 * 9])));
pop = Epplet_create_popupbutton("Colors", NULL, 5, 24, 36, 12, NULL, p);
p = Epplet_create_popup();
Epplet_add_popup_entry(p, "1 Gbit", NULL, epplet_bandwidth,
(void *)(&(bandwidths[0])));
Epplet_add_popup_entry(p, "100 Mbit", NULL, epplet_bandwidth,
(void *)(&(bandwidths[1])));
Epplet_add_popup_entry(p, "10 Mbit", NULL, epplet_bandwidth,
(void *)(&(bandwidths[2])));
Epplet_add_popup_entry(p, "2 Mbit", NULL, epplet_bandwidth,
(void *)(&(bandwidths[3])));
Epplet_add_popup_entry(p, "1.54 Mbit T1", NULL, epplet_bandwidth,
(void *)(&(bandwidths[4])));
Epplet_add_popup_entry(p, "1 Mbit", NULL, epplet_bandwidth,
(void *)(&(bandwidths[5])));
Epplet_add_popup_entry(p, "512 Kbit", NULL, epplet_bandwidth,
(void *)(&(bandwidths[6])));
Epplet_add_popup_entry(p, "256 Kbit", NULL, epplet_bandwidth,
(void *)(&(bandwidths[7])));
Epplet_add_popup_entry(p, "144 Kbit", NULL, epplet_bandwidth,
(void *)(&(bandwidths[8])));
Epplet_add_popup_entry(p, "128 Kbit ISDN", NULL, epplet_bandwidth,
(void *)(&(bandwidths[9])));
Epplet_add_popup_entry(p, "64 Kbit ISDN", NULL, epplet_bandwidth,
(void *)(&(bandwidths[10])));
Epplet_add_popup_entry(p, "56 Kbit Modem", NULL, epplet_bandwidth,
(void *)(&(bandwidths[11])));
Epplet_add_popup_entry(p, "33.6 Kbit Modem", NULL, epplet_bandwidth,
(void *)(&(bandwidths[12])));
Epplet_add_popup_entry(p, "28.8 Kbit Modem", NULL, epplet_bandwidth,
(void *)(&(bandwidths[13])));
Epplet_add_popup_entry(p, "14.4 Kbit Modem", NULL, epplet_bandwidth,
(void *)(&(bandwidths[14])));
Epplet_add_popup_entry(p, "9600 baud Modem", NULL, epplet_bandwidth,
(void *)(&(bandwidths[15])));
Epplet_add_popup_entry(p, "4800 baud Modem", NULL, epplet_bandwidth,
(void *)(&(bandwidths[16])));
Epplet_add_popup_entry(p, "2400 baud Modem", NULL, epplet_bandwidth,
(void *)(&(bandwidths[17])));
Epplet_add_popup_entry(p, "300 baud Modem", NULL, epplet_bandwidth,
(void *)(&(bandwidths[18])));
Epplet_add_popup_entry(p, "75 baud Modem", NULL, epplet_bandwidth,
(void *)(&(bandwidths[19])));
pop2 = Epplet_create_popupbutton("Bandwidth", NULL, 2, 14, 44, 12, NULL, p);
Epplet_register_focus_in_handler(epplet_in, NULL);
Epplet_register_focus_out_handler(epplet_out, NULL);
load_conf();
Epplet_show();
Epplet_Loop();
return 0;
}