/*
* gkrellfire
* ----------
*
*/
#if defined(WIN32)
#include <src/gkrellm.h>
#include <src/win32-plugin.h>
#else
#include <gkrellm2/gkrellm.h>
#endif
// Make sure we have a compatible version of GKrellM (Version 2.0+ is required)
#if !defined(GKRELLM_VERSION_MAJOR) || (GKRELLM_VERSION_MAJOR < 2)
#error This plugin requires GKrellM version >= 2.0
#endif
#define VERSION_GKRELLFIRE "0.4.1"
#define CONFIG_NAME "GkrellFire"
#define STYLE_NAME "GkrellFire"
#define PLUGIN_PLACEMENT MON_CPU
#define CHART_HEIGHT 64
#define CHART_MAX_WIDTH 120
static GkrellmMonitor *mon;
static GkrellmChart *chart;
static GkrellmChartconfig *chart_config = NULL;
static GtkWidget *style_radio[4];
static GtkWidget *bg_radio[2];
static GtkWidget *color_button;
static GtkWidget *bgcolor_button;
static GtkWidget *monitor_check;
static GkrellmPiximage *piximage = NULL;
static GtkWidget *colorseldlg = NULL;
static GtkWidget *bgcolorseldlg = NULL;
static GdkColor fcolor;
static GdkColor bgcolor;
static gint flame_mode = 1;
static gint flame_style = 0;
static gint flame_color;
static gint bg_color;
static gint bg_transparent = 0;
static gint chart_width = 0;
static gint style_id;
static gint cpu_load;
static guchar rgbbuf[CHART_MAX_WIDTH * CHART_HEIGHT * 3];
static guchar firebuffer[CHART_MAX_WIDTH * CHART_HEIGHT];
static guchar xpm_buffer[64000];
static guchar *xpm[512];
static gint ftab[] = {25,15,8,7,6,5,4,3,3,2,2};
static struct
{
guchar red;
guchar green;
guchar blue;
} rgb[256];
static void calc_palette(int start_index, int end_index, long start_color, long end_color)
{
int cnt, ind;
float s_red, s_green, s_blue, e_red, e_green, e_blue;
float d_red, d_green, d_blue;
s_red = (start_color & 0xff0000) >> 16;
s_green = (start_color & 0xff00) >> 8;
s_blue = start_color & 0xff;
e_red = (end_color & 0xff0000) >> 16;
e_green = (end_color & 0xff00) >> 8;
e_blue = end_color & 0xff;
cnt = end_index - start_index;
d_red = (e_red - s_red) / cnt;
d_green = (e_green - s_green) / cnt;
d_blue = (e_blue - s_blue) / cnt;
for ( ind = 1; ind < cnt; ind++)
{
rgb[start_index + ind].red = s_red + d_red * ind;
rgb[start_index + ind].green = s_green + d_green * ind;
rgb[start_index + ind].blue = s_blue + d_blue * ind;
}
rgb[start_index].red = s_red;
rgb[start_index].green = s_green;
rgb[start_index].blue = s_blue;
rgb[end_index].red = e_red;
rgb[end_index].green = e_green;
rgb[end_index].blue = e_blue;
}
static void set_palette(int mode, int color, int bcolor)
{
if (bg_transparent)
{
switch (mode)
{
case 0 : calc_palette(0, 85, 0x000055, 0xff0000);
calc_palette(85, 170, 0xff0000, 0xffff00);
calc_palette(170, 255, 0xffff00, 0xffffff);
break;
case 1 : calc_palette(0, 85, 0x333333, 0xff0000);
calc_palette(85, 170, 0xff0000, 0xffff00);
calc_palette(170, 255, 0xffff00, 0xffffff);
break;
case 2 : calc_palette(0, 85, 0x550000, 0xff0000);
calc_palette(85, 170, 0xff0000, 0xffff00);
calc_palette(170, 255, 0xffff00, 0xffffff);
break;
case 3 : calc_palette(0, 255, 0x222222, color);
break;
}
}
else
{
switch (mode)
{
case 0 : calc_palette(1, 85, 0x000055, 0xff0000);
calc_palette(85, 170, 0xff0000, 0xffff00);
calc_palette(170, 255, 0xffff00, 0xffffff);
break;
case 1 : calc_palette(1, 85, 0x333333, 0xff0000);
calc_palette(85, 170, 0xff0000, 0xffff00);
calc_palette(170, 255, 0xffff00, 0xffffff);
break;
case 2 : calc_palette(1, 85, 0x550000, 0xff0000);
calc_palette(85, 170, 0xff0000, 0xffff00);
calc_palette(170, 255, 0xffff00, 0xffffff);
break;
case 3 : calc_palette(1, 255, 0x222222, color);
break;
}
rgb[0].red = (bcolor & 0xff0000) >> 16;
rgb[0].green = (bcolor & 0xff00) >> 8;
rgb[0].blue = bcolor & 0xff;
}
}
static void bottom_line(unsigned char *buffer)
{
int x, y;
unsigned char c;
y = (chart_width * (CHART_HEIGHT - 1));
for (x = 0; x < chart_width ; x++)
{
if (rand() % 10 < 5)
c = 255;
else
c = 0;
buffer[y + x] = c;
}
}
static void fire(int fire_height)
{
int x, y, yo, xo, r, c;
for (y = CHART_HEIGHT - 1; y > 0; y--)
{
yo = y * chart_width;
for (x = 0; x < chart_width; x++)
{
c = ((firebuffer[yo + x - 1] + firebuffer[yo + x] + firebuffer[yo + x + 1]) / 3);
r = rand() % 30;
if (r < 5)
{
xo = 1;
c -= fire_height;
}
else
{
xo = 0;
c -= fire_height;
}
if (c < 0)
c = 0;
firebuffer[(yo - chart_width) + x + xo] = c;
}
}
yo = chart_width * (CHART_HEIGHT - 1);
r = rand() % 10;
if (r < 5)
c = 0;
else
c = 255;
firebuffer[yo + (rand() % chart_width)] = c;
}
static gint calc_cpu_load(void)
{
static int prev_load = 0;
static int first_time = 1;
int load, r, fp;
int cpu, nice, system, idle;
char b[1024];
fp = open("/proc/stat", O_RDONLY);
r = read(fp, b, sizeof(b));
close(fp);
if (r < 0)
return;
sscanf(b, "%*s %d %d %d %d", &cpu, &nice, &system, &idle);
load = cpu + nice + system;
if (first_time)
{
prev_load = load;
first_time = 0;
}
cpu_load = load - prev_load;
prev_load = load;
if (cpu_load < 0)
cpu_load = 0;
else
if (cpu_load > 100)
cpu_load = 100;
return TRUE;
}
char get_hb_a(int c, int h)
{
if (h)
{
c &= 0xf0;
c /= 16;
}
else
c &= 0x0f;
if (c > 9)
{
c -= 10;
c += 'A';
}
else
c += '0';
return(c);
}
static void gen_xpm(void)
{
int n, x, y, i;
char *p, *f;
i = 0;
p = xpm_buffer;
f = firebuffer;
xpm[i++] = p;
p += sprintf(p ,"%d %d 256 2", chart_width, CHART_HEIGHT) + 1;
xpm[i++] = p;
if (bg_transparent)
{
strcpy(p, "00 c None");
p += 10;
}
else
p += sprintf(p, "00 c #%02X%02X%02X", rgb[0].red, rgb[0].green, rgb[0].blue) + 1;
for (n = 1; n <= 255; n++)
{
xpm[i++] = p;
*p++ = get_hb_a(n, 1);
*p++ = get_hb_a(n, 0);
*p++ = ' ';
*p++ = 'c';
*p++ = ' ';
*p++ = '#';
*p++ = get_hb_a(rgb[n].red, 1);
*p++ = get_hb_a(rgb[n].red, 0);
*p++ = get_hb_a(rgb[n].green, 1);
*p++ = get_hb_a(rgb[n].green, 0);
*p++ = get_hb_a(rgb[n].blue, 1);
*p++ = get_hb_a(rgb[n].blue, 0);
*p++ = 0;
}
for (y = 0; y < CHART_HEIGHT; y++)
{
xpm[i++] = p;
for (x = 0; x < chart_width; x++)
{
*p++ = get_hb_a(*f, 1);
*p++ = get_hb_a(*f++, 0);
}
*p++ = 0;
}
xpm[i++] = p;
*p++ = 0;
}
static gint chart_expose_event(GtkWidget *widget, GdkEventExpose *event)
{
if (bg_transparent)
{
gkrellm_draw_chart_to_screen(chart);
gkrellm_paste_piximage(piximage, widget->window, 0 , 0, chart_width, CHART_HEIGHT);
}
else
gdk_draw_rgb_image (widget->window, widget->style->fg_gc[GTK_STATE_NORMAL], 0, 0, chart_width, CHART_HEIGHT,
GDK_RGB_DITHER_MAX, rgbbuf, chart_width * 3);
return TRUE;
}
static gint timer_callback(GtkWidget *widget)
{
GdkEventExpose event;
gint ret_val;
guchar *pos;
gint x, y, c;
if (flame_mode)
fire(ftab[cpu_load / 10]);
else
fire(2);
if (bg_transparent)
{
gen_xpm();
if (piximage)
gkrellm_destroy_piximage(piximage);
piximage = gkrellm_piximage_new_from_xpm_data((gchar **) xpm);
}
else
{
pos = rgbbuf;
for (y = 0; y < (CHART_HEIGHT); y++)
{
for (x = 0; x < chart_width; x++)
{
c = firebuffer[y * chart_width + x];
*pos++ = rgb[c].red;
*pos++ = rgb[c].green;
*pos++ = rgb[c].blue;
}
}
}
gtk_signal_emit_by_name(GTK_OBJECT (chart->drawing_area), "expose_event", &event, &ret_val);
return TRUE;
}
static gint key_press(GtkWidget *widget, GdkEventButton *event)
{
if (event->button == 1)
{
flame_style++;
if (flame_style > 3)
flame_style = 0;
set_palette(flame_style, flame_color, bg_color);
}
if (event->button == 2)
{
bg_transparent ^= 1;
set_palette(flame_style, flame_color, bg_color);
}
if (event->button == 3)
{
gkrellm_open_config_window(mon);
}
return TRUE;
}
static void set_color()
{
flame_color = 0;
flame_color += (fcolor.red / 256) << 16;
flame_color += (fcolor.green / 256) << 8;
flame_color += fcolor.blue / 256;
bg_color = 0;
bg_color += (bgcolor.red / 256) << 16;
bg_color += (bgcolor.green / 256) << 8;
bg_color += bgcolor.blue / 256;
set_palette(flame_style, flame_color, bg_color);
}
static void color_changed(GtkWidget *widget, GtkColorSelection *colorsel)
{
gtk_color_selection_get_current_color(colorsel, &fcolor);
set_color();
set_palette(flame_style, flame_color, bg_color);
}
static void color_func(GtkWidget *widget, gpointer data)
{
gint res;
GtkColorSelection *colorsel;
GdkColor oldflamecol;
if (colorseldlg == NULL)
colorseldlg = gtk_color_selection_dialog_new("Select flame color");
colorsel = GTK_COLOR_SELECTION (GTK_COLOR_SELECTION_DIALOG (colorseldlg)->colorsel);
gtk_color_selection_set_previous_color(colorsel, &fcolor);
gtk_color_selection_set_current_color(colorsel, &fcolor);
gtk_color_selection_set_has_palette(colorsel, TRUE);
g_signal_connect(G_OBJECT (colorsel), "color_changed", G_CALLBACK (color_changed), (gpointer) colorsel);
oldflamecol = fcolor;
res = gtk_dialog_run(GTK_DIALOG (colorseldlg));
if (res == GTK_RESPONSE_OK)
{
gtk_color_selection_get_current_color(colorsel, &fcolor);
set_color();
set_palette(flame_style, flame_color, bg_color);
}
else
{
fcolor = oldflamecol;
set_color();
set_palette(flame_style, flame_color, bg_color);
}
gtk_widget_hide(colorseldlg);
}
static void bgcolor_changed(GtkWidget *widget, GtkColorSelection *colorsel)
{
gtk_color_selection_get_current_color(colorsel, &bgcolor);
set_color();
set_palette(flame_style, flame_color, bg_color);
}
static void bgcolor_func(GtkWidget *widget, gpointer data)
{
gint res;
GtkColorSelection *colorsel;
GdkColor oldbgcol;
if (bgcolorseldlg == NULL)
bgcolorseldlg = gtk_color_selection_dialog_new("Select background color");
colorsel = GTK_COLOR_SELECTION (GTK_COLOR_SELECTION_DIALOG (bgcolorseldlg)->colorsel);
gtk_color_selection_set_previous_color(colorsel, &bgcolor);
gtk_color_selection_set_current_color(colorsel, &bgcolor);
gtk_color_selection_set_has_palette(colorsel, TRUE);
g_signal_connect(G_OBJECT (colorsel), "color_changed", G_CALLBACK (bgcolor_changed), (gpointer) colorsel);
oldbgcol = bgcolor;
res = gtk_dialog_run(GTK_DIALOG (bgcolorseldlg));
if (res == GTK_RESPONSE_OK)
{
gtk_color_selection_get_current_color(colorsel, &bgcolor);
set_color();
set_palette(flame_style, flame_color, bg_color);
}
else
{
bgcolor = oldbgcol;
set_color();
set_palette(flame_style, flame_color, bg_color);
}
gtk_widget_hide(bgcolorseldlg);
}
static void create_plugin_tab(GtkWidget *tab_vbox)
{
GtkWidget *tabs;
GtkWidget *vbox, *vbox1;
GtkWidget *frame;
GtkWidget *text;
GtkWidget *label;
GSList *group = NULL, *group1 = NULL;
gchar buf[256];
gint n;
tabs = gtk_notebook_new();
gtk_notebook_set_tab_pos(GTK_NOTEBOOK (tabs), GTK_POS_TOP);
gtk_box_pack_start(GTK_BOX (tab_vbox), tabs, TRUE, TRUE, 0);
vbox = gkrellm_gtk_framed_notebook_page(tabs, "Setup");
frame = gtk_frame_new("General");
gtk_box_pack_start(GTK_BOX (vbox), frame, TRUE, TRUE, 0);
monitor_check = gtk_check_button_new_with_label("monitor system load");
if (flame_mode)
gtk_toggle_button_set_active((GtkToggleButton *) monitor_check, 1);
vbox1 = gtk_vbox_new(FALSE, 2);
gtk_container_add(GTK_CONTAINER (frame), vbox1);
gtk_box_pack_start(GTK_BOX (vbox1), monitor_check, TRUE, TRUE, 2);
frame = gtk_frame_new("Flame");
gtk_box_pack_start(GTK_BOX (vbox), frame, TRUE, TRUE, 2);
vbox1 = gtk_vbox_new(FALSE, 2);
gtk_container_add(GTK_CONTAINER (frame), vbox1);
style_radio[0] = gtk_radio_button_new_with_label(group, "Style 1");
style_radio[1] = gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON (style_radio[0]), "Style 2");
style_radio[2] = gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON (style_radio[0]), "Style 3");
style_radio[3] = gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON (style_radio[0]), "Style 4");
color_button = gtk_button_new_with_label("choose flame color ...");
g_signal_connect(G_OBJECT (color_button), "clicked", G_CALLBACK (color_func), (gpointer) NULL);
gtk_toggle_button_set_active((GtkToggleButton *) style_radio[flame_style], 1);
for (n = 0; n < 4; n++)
gtk_box_pack_start(GTK_BOX (vbox1), style_radio[n], TRUE, TRUE, 2);
gtk_box_pack_start(GTK_BOX (vbox1), color_button, TRUE, TRUE, 2);
frame = gtk_frame_new("Background");
gtk_box_pack_start(GTK_BOX (vbox), frame, TRUE, TRUE, 2);
vbox1 = gtk_vbox_new(FALSE, 2);
gtk_container_add(GTK_CONTAINER (frame), vbox1);
bg_radio[0] = gtk_radio_button_new_with_label(group1, "Transparency");
bg_radio[1] = gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON (bg_radio[0]), "Color");
bgcolor_button = gtk_button_new_with_label("choose background color ...");
g_signal_connect(G_OBJECT (bgcolor_button), "clicked", G_CALLBACK (bgcolor_func), (gpointer) NULL);
if (bg_transparent)
gtk_toggle_button_set_active((GtkToggleButton *) bg_radio[0], 1);
else
gtk_toggle_button_set_active((GtkToggleButton *) bg_radio[1], 1);
gtk_box_pack_start(GTK_BOX (vbox1), bg_radio[0], TRUE, TRUE, 2);
gtk_box_pack_start(GTK_BOX (vbox1), bg_radio[1], TRUE, TRUE, 2);
gtk_box_pack_start(GTK_BOX (vbox1), bgcolor_button, TRUE, TRUE, 2);
sprintf(buf, "GKrellFire %s\nGKrellM System Load Monitor\n\n(C)2003 Thomas Steinke\n"
"T.Steinke@web.de\n"
"http://people.freenet.de/thomas-steinke\n\n"
"Released under the GNU General Public License\n", VERSION_GKRELLFIRE);
label = gtk_label_new("About");
text = gtk_label_new(buf);
gtk_notebook_append_page(GTK_NOTEBOOK(tabs),text,label);
}
static void apply_plugin()
{
gint n;
if (gtk_toggle_button_get_active((GtkToggleButton *) monitor_check))
flame_mode = 1;
else
flame_mode = 0;
if (gtk_toggle_button_get_active((GtkToggleButton *) bg_radio[0]))
bg_transparent = 1;
else
bg_transparent = 0;
for (n = 0; n < 4; n++)
if (gtk_toggle_button_get_active((GtkToggleButton *) style_radio[n]))
flame_style = n;
set_palette(flame_style, flame_color, bg_color);
}
static void fire_save_config(FILE *file)
{
fprintf(file, "%s style %d\n", CONFIG_NAME, flame_style);
fprintf(file, "%s mode %d\n", CONFIG_NAME, flame_mode);
fprintf(file, "%s color.red %d\n", CONFIG_NAME, fcolor.red);
fprintf(file, "%s color.green %d\n", CONFIG_NAME, fcolor.green);
fprintf(file, "%s color.blue %d\n", CONFIG_NAME, fcolor.blue);
fprintf(file, "%s bgcolor.red %d\n", CONFIG_NAME, bgcolor.red);
fprintf(file, "%s bgcolor.green %d\n", CONFIG_NAME, bgcolor.green);
fprintf(file, "%s bgcolor.blue %d\n", CONFIG_NAME, bgcolor.blue);
fprintf(file, "%s transparent %d\n", CONFIG_NAME, bg_transparent);
}
static void fire_load_config(gchar *arg)
{
gchar s[32];
gint i;
sscanf(arg, "%s %d", s, &i);
if (!strcmp(s, "style"))
flame_style = i;
else if (!strcmp(s, "mode"))
flame_mode = i;
else if (!strcmp(s, "color.red"))
fcolor.red = i;
else if (!strcmp(s, "color.green"))
fcolor.green = i;
else if (!strcmp(s, "color.blue"))
fcolor.blue = i;
else if (!strcmp(s, "bgcolor.red"))
bgcolor.red = i;
else if (!strcmp(s, "bgcolor.green"))
bgcolor.green = i;
else if (!strcmp(s, "bgcolor.blue"))
bgcolor.blue = i;
else if (!strcmp(s, "transparent"))
bg_transparent = i;
set_color();
set_palette(flame_style, flame_color, bg_color);
}
static void update_plugin()
{
}
static void create_plugin(GtkWidget *vbox, gint first_create)
{
GkrellmStyle *style;
gint cw;
if (first_create)
{
chart = gkrellm_chart_new0();
}
gkrellm_set_chart_height_default(chart, CHART_HEIGHT);
gkrellm_chart_create(vbox, mon, chart, &chart_config);
style = gkrellm_meter_style(style_id);
cw = gkrellm_chart_width();
if (chart_width != cw)
{
chart_width = cw;
if (chart_width > CHART_MAX_WIDTH)
chart_width = CHART_MAX_WIDTH;
bottom_line(firebuffer);
}
if (first_create)
{
gtk_signal_connect(GTK_OBJECT (chart->drawing_area), "expose_event", (GtkSignalFunc) chart_expose_event, NULL);
gtk_signal_connect(GTK_OBJECT (chart->drawing_area), "button_press_event", (GtkSignalFunc) key_press, NULL);
gtk_timeout_add (60, (GtkFunction) timer_callback, GTK_WIDGET (chart->drawing_area));
gtk_timeout_add (1000, (GtkFunction) calc_cpu_load, NULL);
}
}
static GkrellmMonitor plugin_mon =
{
CONFIG_NAME, /* Name, for config tab. */
0, /* Id, 0 if a plugin */
create_plugin, /* The create function */
update_plugin, /* The update function */
create_plugin_tab, /* The config tab create function */
apply_plugin, /* Apply the config function */
fire_save_config, /* Save user config*/
fire_load_config, /* Load user config*/
CONFIG_NAME, /* config keyword*/
NULL, /* Undefined 2 */
NULL, /* Undefined 1 */
NULL, /* Undefined 0 */
PLUGIN_PLACEMENT, /* Insert plugin before this monitor*/
NULL, /* Handle if a plugin, filled in by GKrellM */
NULL /* path if a plugin, filled in by GKrellM */
};
// All GKrellM plugins must have one global routine named init_plugin()
// which returns a pointer to a filled in monitor structure.
#if defined(WIN32)
__declspec(dllexport) GkrellmMonitor *gkrellm_init_plugin(win32_plugin_callbacks* calls)
#else
GkrellmMonitor *gkrellm_init_plugin()
#endif
{
#if defined(WIN32)
callbacks = calls;
pwin32GK = calls->GK;
#endif
style_id = gkrellm_add_meter_style(&plugin_mon, STYLE_NAME);
chart_width = gkrellm_chart_width();
if (chart_width > CHART_MAX_WIDTH)
chart_width = CHART_MAX_WIDTH;
fcolor.red = 0;
fcolor.green = 65535;
fcolor.blue = 0;
bgcolor.red = 0;
bgcolor.green = 0;
bgcolor.blue = 13056;
set_color();
srand(time(NULL));
bottom_line(firebuffer);
mon = &plugin_mon;
return (&plugin_mon);
}
syntax highlighted by Code2HTML, v. 0.9.1