2 * Cpumem-applet - status area plugin
4 * Copyright (c) 2005-2009 Jakub Pavelek
5 * Copyright (c) 2009-2010 Tuomo Tanskanen
9 #include <hildon/hildon.h>
10 #include <glib/gerror.h>
15 #include "cpumem_status_area_item.h"
17 #define CPUMEM_ICON_WIDTH 16
18 #define CPUMEM_ICON_HEIGHT 16
19 #define CPUMEM_BOX_WIDTH 5
20 #define CPUMEM_BOX_HEIGHT 3
21 #define CPUMEM_CPU_MAX 5
25 #define CPUMEM_APPLET_STATUS_AREA_ITEM_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE (obj, CPUMEM_APPLET_TYPE_STATUS_AREA_ITEM, CpumemAppletStatusAreaItemPrivate))
27 struct _CpumemAppletStatusAreaItemPrivate {
29 gint lastU, lastN, lastIO, lastI;
30 guchar last_mem_level;
31 guchar last_cpu_level;
34 GdkPixbuf *pixbuf_red;
35 GdkPixbuf *pixbuf_off;
40 HD_DEFINE_PLUGIN_MODULE (CpumemAppletStatusAreaItem, cpumem_applet_status_area_item, HD_TYPE_STATUS_PLUGIN_ITEM);
44 * Read current MEM usage and return indicator between 5 and 1 - how many bars are "full"
47 check_mem (CpumemAppletStatusAreaItemPrivate *priv)
49 #define MEMFILE "/proc/meminfo"
50 #define MAX_READ_CHARS 128
51 char read_buffer[MAX_READ_CHARS];
59 //Open the memory info file and get current free memory
60 fin = fopen(MEMFILE, "r");
62 g_warning("Can't open "MEMFILE"\n");
65 while (fgets(read_buffer, MAX_READ_CHARS, fin) != NULL) {
66 if (strncmp(read_buffer, "MemTotal", 8) == 0) {
67 sscanf(read_buffer + 10, "%d", &mem_total);
68 } else if (strncmp(read_buffer, "MemFree", 6) == 0) {
69 sscanf(read_buffer + 9, "%d", &mem_free);
70 } else if (strncmp(read_buffer, "Buffers", 6) == 0) {
71 sscanf(read_buffer + 9, "%d", &mem_buffers);
72 } else if (strncmp(read_buffer, "Cached", 6) == 0) {
73 sscanf(read_buffer + 8, "%d", &mem_cached);
79 mem_used = mem_total - mem_free - mem_buffers - mem_cached;
81 if (mem_used > 0.9*mem_total)
83 else if (mem_used > 0.7*mem_total)
85 else if (mem_used > 0.5*mem_total)
87 else if (mem_used > 0.3*mem_total)
95 * Read current CPU usage and return indicator between 5 and 1 - how many bars are "full"
98 check_cpu (CpumemAppletStatusAreaItemPrivate *priv)
100 #define CPUFILE "/proc/stat"
101 gint curU, curN, curIO, curI;
102 gint deltaU, deltaN, deltaIO, deltaI;
104 GError *error = NULL;
109 if (!g_file_get_contents (CPUFILE, &contents, &lenght, &error)) {
110 fprintf (stderr, "ERR: can't read file %s: %s\n", CPUFILE, error->message);
111 g_error_free (error);
115 splits = g_strsplit_set (contents, " ", -1);
117 sscanf(splits[2], "%d", &curU);
118 sscanf(splits[3], "%d", &curN);
119 sscanf(splits[4], "%d", &curIO);
120 sscanf(splits[5], "%d", &curI);
125 idle = (curI - priv->lastI);
126 if (idle == 0) load = 100;
127 else load = 100-idle;
128 if (load>100) load = 0;
129 deltaU = curU - priv->lastU;
130 deltaN = curN - priv->lastN;
131 deltaIO = curIO - priv->lastIO;
132 deltaI = curI - priv->lastI;
135 priv->lastIO = curIO;
153 * Compose and blit the current status of memory bars
156 blit_mem_barsconst guchar level, CpumemAppletStatusAreaItemPrivate *priv)
160 gdk_pixbuf_fill(priv->pixbuf, 0x00000000);
165 gdk_pixbuf_composite(priv->pixbuf_on, priv->pixbuf, x, y,
166 CPUMEM_BOX_WIDTH, CPUMEM_BOX_HEIGHT, x, y, 1, 1, GDK_INTERP_NEAREST, 255);
169 gdk_pixbuf_composite(priv->pixbuf_on, priv->pixbuf, x, y,
170 CPUMEM_BOX_WIDTH, CPUMEM_BOX_HEIGHT, x, y, 1, 1, GDK_INTERP_NEAREST, 255);
173 gdk_pixbuf_composite(priv->pixbuf_on, priv->pixbuf, x, y,
174 CPUMEM_BOX_WIDTH, CPUMEM_BOX_HEIGHT, x, y, 1, 1, GDK_INTERP_NEAREST, 255);
177 gdk_pixbuf_composite(priv->pixbuf_on, priv->pixbuf, x, y,
178 CPUMEM_BOX_WIDTH, CPUMEM_BOX_HEIGHT, x, y, 1, 1, GDK_INTERP_NEAREST, 255);
180 gdk_pixbuf_composite(priv->pixbuf_off, priv->pixbuf, x, y,
181 CPUMEM_BOX_WIDTH, CPUMEM_BOX_HEIGHT, x, y, 1, 1, GDK_INTERP_NEAREST, 255);
186 * Compose and blit current status of CPU bars
189 blit_cpu_bars (const guchar level, CpumemAppletStatusAreaItemPrivate *priv)
197 if (priv->red == TRUE) {
198 gdk_pixbuf_composite(priv->pixbuf_red, priv->pixbuf, x, y,
199 CPUMEM_BOX_WIDTH, CPUMEM_BOX_HEIGHT, x, y, 1, 1, GDK_INTERP_NEAREST, 255);
202 gdk_pixbuf_composite(priv->pixbuf_on, priv->pixbuf, x, y,
203 CPUMEM_BOX_WIDTH, CPUMEM_BOX_HEIGHT, x, y, 1, 1, GDK_INTERP_NEAREST, 255);
209 gdk_pixbuf_composite(priv->pixbuf_on, priv->pixbuf, x, y,
210 CPUMEM_BOX_WIDTH, CPUMEM_BOX_HEIGHT, x, y, 1, 1, GDK_INTERP_NEAREST, 255);
213 gdk_pixbuf_composite(priv->pixbuf_on, priv->pixbuf, x, y,
214 CPUMEM_BOX_WIDTH, CPUMEM_BOX_HEIGHT, x, y, 1, 1, GDK_INTERP_NEAREST, 255);
217 gdk_pixbuf_composite(priv->pixbuf_on, priv->pixbuf, x, y,
218 CPUMEM_BOX_WIDTH, CPUMEM_BOX_HEIGHT, x, y, 1, 1, GDK_INTERP_NEAREST, 255);
220 gdk_pixbuf_composite(priv->pixbuf_off, priv->pixbuf, x, y,
221 CPUMEM_BOX_WIDTH, CPUMEM_BOX_HEIGHT, x, y, 1, 1, GDK_INTERP_NEAREST, 255);
226 * Ran to check and update the CPU and memory reading
229 check_load (gpointer data)
231 guchar current_cpu_level;
232 guchar current_mem_level;
233 CpumemAppletStatusAreaItem *item = (CpumemAppletStatusAreaItem*)data;
234 CpumemAppletStatusAreaItemPrivate *priv = (CpumemAppletStatusAreaItemPrivate*)item->priv;
236 current_cpu_level = check_cpu(priv);
237 current_mem_level = check_mem(priv);
238 //g_debug(g_strdup_printf("LOADAPLET - UPDATED CPU %d MEM %d", current_cpu_level, current_mem_level));
240 //Update and blit only if data changed!
241 if ((current_mem_level != priv->last_mem_level) || (current_cpu_level != priv->last_cpu_level)) {
242 blit_mem_bars (current_mem_level, priv);
243 blit_cpu_bars (current_cpu_level, priv);
244 if (current_cpu_level == CPUMEM_CPU_MAX)
246 hd_status_plugin_item_set_status_area_icon (HD_STATUS_PLUGIN_ITEM(data), priv->pixbuf);
247 priv->last_mem_level = current_mem_level;
248 priv->last_cpu_level = current_cpu_level;
249 } else if (current_cpu_level == CPUMEM_CPU_MAX) {
250 //Pulsate max CPU load icon also when CPU load stays at max
251 blit_cpu_bars (current_cpu_level, priv);
252 hd_status_plugin_item_set_status_area_icon (HD_STATUS_PLUGIN_ITEM(data), priv->pixbuf);
259 * Get callback when display state changes
262 cpumem_applet_status_area_item_display_cb(osso_display_state_t state, gpointer user_data)
264 CpumemAppletStatusAreaItem *item = CPUMEM_APPLET_STATUS_AREA_ITEM(user_data);
266 g_return_if_fail (item != NULL && item->priv != NULL);
268 if (state == OSSO_DISPLAY_ON)
270 //Restart the updates, do one right away
271 if (item->priv->timeout_id == 0)
273 item->priv->timeout_id = gtk_timeout_add(1000, check_load, item);
277 //Suspend the updates - screen is off
278 if (item->priv->timeout_id) != 0) {
279 g_source_remove(item->priv->timeout_id);
280 item->priv->timeout_id = 0;
286 /*****************************************************************************
288 * Boilerplate code area - do not enter
290 *****************************************************************************/
293 cpumem_applet_status_area_item_set_area_icon (CpumemAppletStatusAreaItem *item)
295 item->priv = CPUMEM_APPLET_STATUS_AREA_ITEM_GET_PRIVATE (item);
297 hd_status_plugin_item_set_status_area_icon (HD_STATUS_PLUGIN_ITEM(item), item->priv->pixbuf);
302 cpumem_applet_status_area_item_class_finalize (CpumemAppletStatusAreaItemClass *klass)
309 cpumem_applet_status_area_item_finalize (GObject *object)
311 CpumemAppletStatusAreaItemPrivate *priv = CPUMEM_APPLET_STATUS_AREA_ITEM(object)->priv;
312 // Release and clean our stuff
313 G_OBJECT_CLASS (cpumem_applet_status_area_item_parent_class)->finalize (object);
316 osso_deinitialize(priv->osso);
325 cpumem_applet_status_area_item_class_init (CpumemAppletStatusAreaItemClass *klass)
327 GObjectClass *object_class = G_OBJECT_CLASS (klass);
329 object_class->finalize = cpumem_applet_status_area_item_finalize;
331 g_type_class_add_private (klass, sizeof (CpumemAppletStatusAreaItemPrivate));
336 cpumem_applet_status_area_item_init (CpumemAppletStatusAreaItem *item)
338 item->priv = CPUMEM_APPLET_STATUS_AREA_ITEM_GET_PRIVATE (item);
340 item->priv->last_mem_level = -1;
341 item->priv->last_cpu_level = -1;
342 item->priv->timeout_id = -1;
343 item->priv->red = FALSE;
344 item->priv->pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8, CPUMEM_ICON_WIDTH, CPUMEM_ICON_HEIGHT);
345 gdk_pixbuf_fill(item->priv->pixbuf, 0x00000000);
346 item->priv->pixbuf_on = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8, CPUMEM_BOX_WIDTH, CPUMEM_BOX_HEIGHT);
347 gdk_pixbuf_fill(item->priv->pixbuf_on, 0xffffffff);
348 item->priv->pixbuf_red = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8, CPUMEM_BOX_WIDTH, CPUMEM_BOX_HEIGHT);
349 gdk_pixbuf_fill(item->priv->pixbuf_red, 0xff0000ff);
350 item->priv->pixbuf_off = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8, CPUMEM_BOX_WIDTH, CPUMEM_BOX_HEIGHT);
351 gdk_pixbuf_fill(item->priv->pixbuf_off, 0x777777ff);
352 cpumem_applet_status_area_item_set_area_icon(item);
354 item->priv->osso = osso_initialize ("cpumem_applet_status_area_item", "Maemo5", TRUE, NULL);
355 item->priv->timeout_id = gtk_timeout_add(1000, check_load, item);
356 osso_hw_set_display_event_cb (item->priv->osso, cpumem_applet_status_area_item_display_cb, item);