Add plugin configuration page.
[lxde/lxpanel.git] / src / plugins / cpu / cpu.c
1 /*
2 * CPU usage plugin to lxpanel
3 *
4 * Copyright (C) 2004 by Alexandre Pereira da Silva <alexandre.pereira@poli.usp.br>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 *
20 */
21 /*A little bug fixed by Mykola <mykola@2ka.mipt.ru>:) */
22
23
24 #include <string.h>
25 #include <sys/time.h>
26 #include <time.h>
27 #include <sys/sysinfo.h>
28 #include <stdlib.h>
29 #include <glib/gi18n.h>
30
31 #include "plugin.h"
32 #include "panel.h"
33 #include "gtkbgbox.h"
34
35
36 #define KILOBYTE 1024
37 #define MAX_WGSIZE 100
38
39 //#define DEBUG
40 #include "dbg.h"
41 typedef unsigned long tick;
42
43 struct cpu_stat {
44 tick u, n, s, i;
45 };
46
47
48 typedef struct {
49 GdkGC *gc_cpu;
50 GdkColor *ccpu;
51 GtkWidget *da;
52 GtkWidget *evbox;
53 GdkPixmap *pixmap;
54 GtkTooltips *tip;
55
56 int timer;
57 tick *stats_cpu;
58 unsigned int ini_stats;
59 int Wwg;
60 int Hwg;
61 struct cpu_stat cpu_anterior;
62 } cpu_t;
63
64
65 static int
66 cpu_update(cpu_t *c)
67 {
68 int cpu_u=0, cpu_s=0, cpu_n=0, cpu_i=100;
69 unsigned int i;
70 struct cpu_stat cpu, cpu_r;
71 FILE *stat;
72 float total;
73
74 ENTER;
75 if(!c->pixmap)
76 RET(TRUE);
77
78 stat = fopen("/proc/stat", "r");
79 if(!stat)
80 RET(TRUE);
81 fscanf(stat, "cpu %lu %lu %lu %lu", &cpu.u, &cpu.n, &cpu.s, &cpu.i);
82 fclose(stat);
83
84 cpu_r.u = cpu.u - c->cpu_anterior.u;
85 cpu_r.n = cpu.n - c->cpu_anterior.n;
86 cpu_r.s = cpu.s - c->cpu_anterior.s;
87 cpu_r.i = cpu.i - c->cpu_anterior.i;
88
89 total = cpu_r.u + cpu_r.n + cpu_r.s + cpu_r.i;
90 cpu_u = cpu_r.u * c->Hwg / total;
91 cpu_s = cpu_r.n * c->Hwg / total;
92 cpu_n = cpu_r.s * c->Hwg / total;
93 cpu_i = cpu_r.i * c->Hwg / total;
94
95 c->cpu_anterior = cpu;
96
97 c->stats_cpu[c->ini_stats++] = cpu_u + cpu_s + cpu_n;
98 c->ini_stats %= c->Wwg;
99
100 gdk_draw_rectangle(c->pixmap, c->da->style->black_gc, TRUE, 0, 0, c->Wwg, c->Hwg);
101 for (i = 0; i < c->Wwg; i++) {
102 int val;
103
104 val = c->stats_cpu[(i + c->ini_stats) % c->Wwg];
105 if (val)
106 gdk_draw_line(c->pixmap, c->gc_cpu, i, c->Hwg, i, c->Hwg - val);
107 }
108 gtk_widget_queue_draw(c->da);
109 RET(TRUE);
110 }
111
112 static gint
113 configure_event(GtkWidget *widget, GdkEventConfigure *event, cpu_t *c)
114 {
115 ENTER;
116 if (c->pixmap)
117 g_object_unref(c->pixmap);
118 c->Wwg = widget->allocation.width;
119 c->Hwg = widget->allocation.height;
120 if (c->stats_cpu)
121 g_free(c->stats_cpu);
122 c->stats_cpu = g_new0( typeof(*c->stats_cpu), c->Wwg);
123 c->pixmap = gdk_pixmap_new (widget->window,
124 widget->allocation.width,
125 widget->allocation.height,
126 -1);
127 gdk_draw_rectangle (c->pixmap,
128 widget->style->black_gc,
129 TRUE,
130 0, 0,
131 widget->allocation.width,
132 widget->allocation.height);
133
134 RET(TRUE);
135 }
136
137
138 static gint
139 expose_event(GtkWidget *widget, GdkEventExpose *event, cpu_t *c)
140 {
141 ENTER;
142 gdk_draw_drawable (widget->window,
143 c->da->style->black_gc,
144 c->pixmap,
145 event->area.x, event->area.y,
146 event->area.x, event->area.y,
147 event->area.width, event->area.height);
148
149 RET(FALSE);
150 }
151
152 static int
153 cpu_constructor(plugin *p)
154 {
155 cpu_t *c;
156
157 ENTER;
158 c = g_new0(cpu_t, 1);
159 p->priv = c;
160
161
162 c->da = gtk_drawing_area_new();
163 gtk_widget_set_size_request(c->da, 40, 20);
164
165 gtk_widget_show(c->da);
166
167 c->tip = gtk_tooltips_new();
168
169 c->gc_cpu = gdk_gc_new(p->panel->topgwin->window);
170 DBG("here1\n");
171 c->ccpu = (GdkColor *)malloc(sizeof(GdkColor));
172 gdk_color_parse("green", c->ccpu);
173 gdk_colormap_alloc_color(gdk_drawable_get_colormap(p->panel->topgwin->window), c->ccpu, FALSE, TRUE);
174 gdk_gc_set_foreground(c->gc_cpu, c->ccpu);
175 gtk_bgbox_set_background(p->pwid, BG_STYLE, 0, 0);
176 gtk_container_add(GTK_CONTAINER(p->pwid), c->da);
177 gtk_container_set_border_width (GTK_CONTAINER (p->pwid), 1);
178 g_signal_connect (G_OBJECT (c->da),"configure_event",
179 G_CALLBACK (configure_event), (gpointer) c);
180 g_signal_connect (G_OBJECT (c->da), "expose_event",
181 G_CALLBACK (expose_event), (gpointer) c);
182
183 c->timer = g_timeout_add(1000, (GSourceFunc) cpu_update, (gpointer) c);
184 RET(1);
185 }
186
187 static void
188 cpu_destructor(plugin *p)
189 {
190 cpu_t *c = (cpu_t *) p->priv;
191
192 ENTER;
193 g_object_unref(c->pixmap);
194 g_object_unref(c->gc_cpu);
195 g_free(c->stats_cpu);
196 g_free(c->ccpu);
197 g_source_remove(c->timer);
198 g_free(p->priv);
199 RET();
200 }
201
202
203 plugin_class cpu_plugin_class = {
204 fname: NULL,
205 count: 0,
206
207 type : "cpu",
208 name : N_("CPU Usage Monitor"),
209 version: "1.0",
210 description : N_("Display CPU usage"),
211
212 constructor : cpu_constructor,
213 destructor : cpu_destructor,
214 };