/* * gkrellfire * ---------- * */ #if defined(WIN32) #include #include #else #include #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); }