aboutsummaryrefslogtreecommitdiffstats
path: root/applets/mb-applet-system-monitor.c
diff options
context:
space:
mode:
Diffstat (limited to 'applets/mb-applet-system-monitor.c')
-rw-r--r--applets/mb-applet-system-monitor.c369
1 files changed, 369 insertions, 0 deletions
diff --git a/applets/mb-applet-system-monitor.c b/applets/mb-applet-system-monitor.c
new file mode 100644
index 0000000..93053f6
--- /dev/null
+++ b/applets/mb-applet-system-monitor.c
@@ -0,0 +1,369 @@
+/*
+ * minisys - tiny sys monitor
+ *
+ * cpu reading code based on wmbubblemon
+ *
+ * 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 Street #330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/types.h>
+
+#include <libmb/mb.h>
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef ENABLE_NLS
+# include <libintl.h>
+# define _(text) gettext(text)
+#else
+# define _(text) (text)
+#endif
+
+#ifdef MB_HAVE_PNG
+#define IMG_EXT "png"
+#else
+#define IMG_EXT "xpm"
+#endif
+
+#define MINISYS_IMG "minisys." IMG_EXT
+
+struct {
+
+ /* cpu data */
+ int loadIndex;
+ int samples;
+ u_int64_t *load, *total;
+
+ /* memory data */
+ u_int64_t mem_used;
+ u_int64_t mem_max;
+ u_int64_t swap_used;
+ u_int64_t swap_max;
+ unsigned int swap_percent; /* swap used, in percent */
+ unsigned int mem_percent; /* memory used, in percent */
+
+} msd;
+
+MBPixbuf *pb = NULL;
+MBPixbufImage *ImgIcon = NULL, *ImgIconScaled = NULL, *ImgGraph = NULL;
+
+int GraphHeight = 0, GraphWidth = 0;
+
+char *ThemeName;
+
+/* returns current CPU load in percent, 0 to 100 */
+int system_cpu(void)
+{
+ unsigned int cpuload;
+ u_int64_t load, total, oload, ototal;
+ u_int64_t ab, ac, ad, ae;
+ int i;
+ FILE *stat;
+
+ stat = fopen("/proc/stat", "r");
+ fscanf(stat, "%*s %Ld %Ld %Ld %Ld", &ab, &ac, &ad, &ae);
+ fclose(stat);
+
+ /* Find out the CPU load */
+ /* user + sys = load
+ * total = total */
+ load = ab + ac + ad; /* cpu.user + cpu.sys; */
+ total = ab + ac + ad + ae; /* cpu.total; */
+
+ /* "i" is an index into a load history */
+ i = msd.loadIndex;
+ oload = msd.load[i];
+ ototal = msd.total[i];
+
+ msd.load[i] = load;
+ msd.total[i] = total;
+ msd.loadIndex = (i + 1) % msd.samples;
+
+ if (ototal == 0)
+ cpuload = 0;
+ else
+ cpuload = (100 * (load - oload)) / (total - ototal);
+
+ return cpuload;
+}
+
+int system_memory(void)
+{
+ u_int64_t my_mem_used, my_mem_max;
+ u_int64_t my_swap_max;
+
+ static int mem_delay = 0;
+ FILE *mem;
+ static u_int64_t total, used, mfree, shared, buffers, cached,
+ cache_total, cache_used;
+
+ /* put this in permanent storage instead of stack */
+ static char not_needed[2048];
+
+ if (mem_delay-- <= 0) {
+ mem = fopen("/proc/meminfo", "r");
+ fgets(not_needed, 2048, mem);
+
+ /*
+ total: used: free: shared: buffers: cached:
+ */
+
+ fscanf(mem, "%*s %Ld %Ld %Ld %Ld %Ld %Ld", &total, &used, &mfree,
+ &shared, &buffers, &cached);
+
+ fscanf(mem, "%*s %Ld %Ld", &cache_total, &cache_used);
+
+ fclose(mem);
+ mem_delay = 25;
+
+ /* calculate it */
+ my_mem_max = total;
+ my_swap_max = cache_total;
+
+ my_mem_used = cache_used + used - cached - buffers;
+
+ /* No swap on ipaq
+ if (my_mem_used > my_mem_max) {
+ my_swap_used = my_mem_used - my_mem_max;
+ my_mem_used = my_mem_max;
+ } else {
+ my_swap_used = 0;
+ }
+ */
+
+ msd.mem_used = my_mem_used;
+ msd.mem_max = my_mem_max;
+ //msd.swap_used = my_swap_used;
+ //msd.swap_max = my_swap_max;
+
+ msd.mem_percent = (100 * msd.mem_used) / msd.mem_max;
+ //msd.swap_percent = (100 * msd.swap_used) / msd.swap_max;
+
+ /* memory info changed - update things */
+ return 1;
+ }
+ /* nothing new */
+ return 0;
+}
+
+
+void
+paint_callback (MBTrayApp *app, Drawable drw )
+{
+ static int prev_cpu_pixels, prev_mem_pixels;
+ int cpu_pixels, mem_pixels;
+ int cpusize, memsize;
+ int x, y;
+
+ int membox_x, membox_y, membox_w, membox_h;
+ int cpubox_x, cpubox_y, cpubox_w, cpubox_h;
+
+ MBPixbufImage *img_backing = NULL;
+
+ system_memory(); /* Update reading */
+
+ cpusize = system_cpu();
+ memsize = msd.mem_percent;
+
+ cpubox_h = membox_h = (mb_pixbuf_img_get_width(ImgIconScaled)/16) * 10;
+
+ cpu_pixels = (cpusize * ( cpubox_h) )/ 100 ;
+ mem_pixels = (memsize * ( membox_h) )/ 100 ;
+
+ if (cpu_pixels == prev_cpu_pixels && mem_pixels == prev_mem_pixels)
+ return;
+
+ img_backing = mb_tray_app_get_background (app, pb);
+
+ mb_pixbuf_img_composite(pb, img_backing, ImgIconScaled, 0, 0);
+
+ membox_x = (mb_pixbuf_img_get_width(img_backing)/4) - (mb_pixbuf_img_get_width(img_backing)/16);
+ membox_y = membox_x;
+ membox_w = (mb_pixbuf_img_get_width(img_backing)/16) * 2;
+ cpubox_x = ((mb_pixbuf_img_get_width(img_backing)/4) * 3) - (mb_pixbuf_img_get_width(img_backing)/16);
+ cpubox_y = membox_y;
+ cpubox_w = membox_w;
+
+ /* clear boxes */
+
+ for ( y = membox_y; y < membox_y + membox_h; y++)
+ for ( x = 0; x < membox_w; x++)
+ {
+ mb_pixbuf_img_plot_pixel(pb, img_backing, membox_x + x, y,
+ 0x66, 0x66, 0x66);
+
+ mb_pixbuf_img_plot_pixel(pb, img_backing, cpubox_x + x, y,
+ 0x66, 0x66, 0x66);
+ }
+
+ if (cpusize > 0)
+ {
+ for ( y = cpubox_h; y > cpubox_h - cpu_pixels; y--)
+ for ( x = cpubox_x; x < cpubox_x + cpubox_w; x++)
+ mb_pixbuf_img_plot_pixel(pb, img_backing, x, y + cpubox_y,
+ 0, 0xff, 0);
+ }
+
+ if (memsize > 0)
+ {
+ for ( y = membox_h; y > membox_h - mem_pixels; y--)
+ for ( x = membox_x; x < membox_x + membox_w; x++)
+ mb_pixbuf_img_plot_pixel(pb, img_backing, x, y + membox_y,
+ 0xff, 0, 0);
+ }
+
+ /* XXX Alert here for low memory */
+
+ mb_pixbuf_img_render_to_drawable(pb, img_backing, drw, 0, 0);
+
+ mb_pixbuf_img_free( pb, img_backing );
+
+ prev_cpu_pixels = cpu_pixels;
+ prev_mem_pixels = mem_pixels;
+
+}
+
+void
+button_callback (MBTrayApp *app, int x, int y, Bool is_released )
+{
+ char tray_msg[256];
+ int cpu = system_cpu();
+
+ if (!is_released)
+ return;
+
+ sprintf(tray_msg, _("CPU: %i %%, MEMORY: %i %%\n"),cpu, msd.mem_percent);
+ mb_tray_app_tray_send_message(app, tray_msg, 5000);
+}
+
+void
+resize_callback (MBTrayApp *app, int w, int h )
+{
+
+ if (ImgIconScaled) mb_pixbuf_img_free(pb, ImgIconScaled);
+ if (ImgGraph) mb_pixbuf_img_free(pb, ImgGraph);
+
+ ImgIconScaled = mb_pixbuf_img_scale(pb, ImgIcon, w, h);
+
+}
+
+void
+load_icon(void)
+{
+ char *icon_path = NULL;
+
+ if (ImgIcon) mb_pixbuf_img_free(pb, ImgIcon);
+
+ icon_path = mb_dot_desktop_icon_get_full_path (ThemeName,
+ 32,
+ MINISYS_IMG );
+
+ if (icon_path == NULL
+ || !(ImgIcon = mb_pixbuf_img_new_from_file(pb, icon_path)))
+ {
+ fprintf(stderr, "miniapm: failed to load icon %s\n", MINISYS_IMG);
+ exit(1);
+ }
+
+ free(icon_path);
+
+ return;
+
+}
+
+void
+theme_callback (MBTrayApp *app, char *theme_name)
+{
+ if (!theme_name) return;
+ if (ThemeName) free(ThemeName);
+ ThemeName = strdup(theme_name);
+ load_icon();
+ resize_callback (app, mb_tray_app_width(app), mb_tray_app_width(app) );
+}
+
+void
+timeout_callback ( MBTrayApp *app )
+{
+ mb_tray_app_repaint (app);
+}
+
+int
+main( int argc, char *argv[])
+{
+ MBTrayApp *app = NULL;
+ struct timeval tv;
+
+ int i;
+ u_int64_t load = 0, total = 0;
+
+#if ENABLE_NLS
+ setlocale (LC_ALL, "");
+ bindtextdomain (PACKAGE, DATADIR "/locale");
+ bind_textdomain_codeset (PACKAGE, "UTF-8");
+ textdomain (PACKAGE);
+#endif
+
+ app = mb_tray_app_new ( _("CPU/Mem Monitor"),
+ resize_callback,
+ paint_callback,
+ &argc,
+ &argv );
+
+ msd.samples = 16;
+
+ if (msd.load) {
+ load = msd.load[msd.loadIndex];
+ free(msd.load);
+ }
+
+ if (msd.total) {
+ total = msd.total[msd.loadIndex];
+ free(msd.total);
+ }
+
+ msd.loadIndex = 0;
+ msd.load = malloc(msd.samples * sizeof(u_int64_t));
+ msd.total = malloc(msd.samples * sizeof(u_int64_t));
+ for (i = 0; i < msd.samples; i++) {
+ msd.load[i] = load;
+ msd.total[i] = total;
+ }
+
+ pb = mb_pixbuf_new(mb_tray_app_xdisplay(app),
+ mb_tray_app_xscreen(app));
+
+ memset(&tv,0,sizeof(struct timeval));
+ tv.tv_usec = 400000;
+
+ mb_tray_app_set_theme_change_callback (app, theme_callback );
+
+ mb_tray_app_set_timeout_callback (app, timeout_callback, &tv);
+
+ mb_tray_app_set_button_callback (app, button_callback );
+
+ load_icon();
+
+ mb_tray_app_set_icon(app, pb, ImgIcon);
+
+ mb_tray_app_main (app);
+
+ return 1;
+}