wmail: updated the copyright notices.
[dockapps.git] / cputnik / src / cputnik.c
blob9a233b3708c0fbf8bacc2d7f0feddbf79ede57a6
2 /*
3 * Cputnik - a simple cpu and memory monitor
5 * Copyright (C) 2002-2005 pasp and sill
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 #include "cputnik.h"
26 FILE *fp_stat, *fp_loadavg, *fp_memory;
27 int cmd_lmb, cmd_rmb, update_period;
28 int show_memory, free_memory;
29 char command_lmb[PATH_MAX], command_rmb[PATH_MAX], *ProgName;
30 stat_dev cpu_device;
32 /*----------------------------------------------------------------------*/
34 void get_mem_statistics(int *free)
36 long long int m_total, m_free, m_cached;
37 char temp[BUFFER_SIZE];
39 fp_memory = freopen("/proc/meminfo", "r", fp_memory);
41 while(fscanf(fp_memory, "%s", temp)!=EOF) {
43 if(!strncmp(temp,"MemTotal:", 9))
44 fscanf(fp_memory, "%Ld", &m_total);
46 if(!strncmp(temp,"MemFree:", 8))
47 fscanf(fp_memory, "%Ld", &m_free);
49 if(!strncmp(temp,"Cached:", 7))
50 fscanf(fp_memory, "%Ld", &m_cached);
53 *free = (int)(((float)(m_total - m_free - m_cached) / m_total) * 100.0);
56 /*----------------------------------------------------------------------*/
58 void draw_memory_meter(void)
60 free_memory = free_memory * (METER_WIDTH / 100.0);
61 if (free_memory > METER_WIDTH) free_memory = METER_WIDTH;
62 dcl_copy_xpm_area(0, 64, METER_WIDTH, 5, 26, 12);
63 dcl_copy_xpm_area(32, 64, free_memory, 5, 26, 12);
66 /*----------------------------------------------------------------------*/
68 void get_cpu_statistics(char *devname, long *is, long *ds, long *idle)
70 char temp[BUFFER_SIZE], *p, *tokens = " \t\n";
71 int i;
72 float f;
74 *is = *ds = *idle = 0;
76 if (!strncmp(devname, "cpu", 3)) {
78 fseek(fp_stat, 0, SEEK_SET);
80 while (fgets(temp, 128, fp_stat)) {
82 if (strstr(temp, "cpu")) {
83 p = strtok(temp, tokens);
84 /* 1..3, 4 == idle, we don't want idle! */
85 for (i=0; i<3; i++) {
86 p = strtok(NULL, tokens);
87 *ds += atol(p);
90 p = strtok(NULL, tokens);
91 *idle = atol(p);
96 fp_loadavg = freopen("/proc/loadavg", "r", fp_loadavg);
97 fscanf(fp_loadavg, "%f", &f);
98 *is = (long) (100 * f);
103 /*----------------------------------------------------------------------*/
105 void draw_stats(int *his, int num, int size, int x_left, int y_bottom)
107 int pixels_per_byte, j, k, *p, d;
109 pixels_per_byte = 100;
110 p = his;
112 for (j=0; j<num; j++) {
113 if (p[0] > pixels_per_byte)
114 pixels_per_byte += 100;
115 p++;
118 p = his;
120 for (k=0; k<num; k++) {
121 d = (1.0 * p[0] / pixels_per_byte) * size;
123 for (j=0; j<size; j++) {
125 if (j < d - 3)
126 dcl_copy_xpm_area(0, 71, 1, 1, k+x_left, y_bottom-j);
127 else if (j < d)
128 dcl_copy_xpm_area(1, 71, 1, 1, k+x_left, y_bottom-j);
129 else
130 dcl_copy_xpm_area(2, 71, 1, 1, k+x_left, y_bottom-j);
132 p++;
135 /* horizontal line */
136 for (j = pixels_per_byte-100; j > 0; j-=100) {
137 for (k=0; k<num; k++) {
138 d = (40.0 / pixels_per_byte) * j;
139 dcl_copy_xpm_area(3, 71, 1, 1, k+x_left, y_bottom-d);
145 /*----------------------------------------------------------------------*/
147 void update_stat_cpu(stat_dev *st)
149 long k, istat, idle;
151 get_cpu_statistics(st->name, &k, &istat, &idle);
153 st->rt_idle = idle - st->idlelast;
154 st->idlelast = idle;
156 st->rt_stat = istat - st->statlast;
157 st->statlast = istat;
159 st->his[V_WIDTH] += k;
160 st->hisaddcnt++;
163 /*----------------------------------------------------------------------*/
165 void cputnik_routine(int argc, char **argv)
167 XEvent Event;
168 int but_stat = -1, xfd = 0;
169 long start_time, current_time, next_time, istat, idle, k;
170 unsigned long i, j;
171 fd_set inputs;
172 struct timeval timeout;
174 fp_memory = fopen("/proc/meminfo", "r");
175 fp_loadavg = fopen("/proc/loadavg", "r");
176 fp_stat = fopen("/proc/stat", "r");
178 for (j=0; j<V_WIDTH+1; j++)
179 cpu_device.his[j] = 0;
181 cpu_device.hisaddcnt = 0;
182 dcl_strcpy(cpu_device.name, CPU_NAME, CPU_NAME_LEN);
184 timeout.tv_sec = 0;
185 timeout.tv_usec = 250000;
187 dcl_open_x_window(argc, argv, cputnik_master_xpm, cputnik_mask_bits, MASK_WIDTH, MASK_HEIGHT);
189 /* add mouse region */
190 dcl_add_mouse_region(0, 4, 4, 59, 59);
192 start_time = time(0);
193 next_time = start_time + update_period;
195 get_cpu_statistics(cpu_device.name, &k, &istat, &idle);
196 cpu_device.statlast = istat;
197 cpu_device.idlelast = idle;
199 if (show_memory) {
201 dcl_draw_string(6, 5, "cpu", FONT_NORMAL, 3);
202 dcl_draw_string(6, 12, "mem", FONT_NORMAL, 3);
203 dcl_copy_xpm_area(5, 57, 54, 1, 5, 18);
204 get_mem_statistics(&free_memory);
205 draw_memory_meter();
206 draw_stats(cpu_device.his, V_WIDTH, V_HEIGHT_MEM, 5, 55);
208 } else {
210 dcl_draw_string(6, 5, "cpu", FONT_LARGE, 3);
211 dcl_copy_xpm_area(5, 57, 54, 1, 5, 13);
212 draw_stats(cpu_device.his, V_WIDTH, V_HEIGHT, 5, 55);
216 while(1) {
218 current_time = time(0);
220 waitpid(0, NULL, WNOHANG);
222 update_stat_cpu(&cpu_device);
224 /* cpu meter */
225 dcl_copy_xpm_area(0, 64, 32, 7-(show_memory*2), 26, 5);
227 j = (cpu_device.rt_stat + cpu_device.rt_idle);
228 if (j != 0) j = (cpu_device.rt_stat * 100) / j;
229 j = j * (METER_WIDTH / 100.0);
230 if (j > METER_WIDTH) j = METER_WIDTH;
232 dcl_copy_xpm_area(32, 64, j, 7-(show_memory*2), 26, 5);
234 if (current_time >= next_time) {
235 next_time += update_period;
237 if (cpu_device.his[V_WIDTH])
238 cpu_device.his[V_WIDTH] /= cpu_device.hisaddcnt;
240 for (j=1; j<V_WIDTH+1; j++)
241 cpu_device.his[j-1] = cpu_device.his[j];
243 if (show_memory) {
245 get_mem_statistics(&free_memory);
246 draw_memory_meter();
247 draw_stats(cpu_device.his, V_WIDTH, V_HEIGHT_MEM, 5, 55);
249 } else
250 draw_stats(cpu_device.his, V_WIDTH, V_HEIGHT, 5, 55);
252 cpu_device.his[V_WIDTH] = 0;
253 cpu_device.hisaddcnt = 0;
257 xfd = ConnectionNumber(display);
259 FD_ZERO(&inputs);
260 FD_SET(xfd, &inputs);
262 switch(select(FD_SETSIZE, &inputs, NULL, NULL, &timeout)) {
264 case 0:
265 timeout.tv_sec = 0;
266 timeout.tv_usec = 250000;
267 dcl_redraw_window();
268 break;
270 case -1:
271 break;
273 default:
274 break;
277 while(FD_ISSET(xfd, &inputs) && XPending(display)) {
278 XNextEvent(display, &Event);
279 switch (Event.type) {
280 case Expose:
281 dcl_redraw_window();
282 break;
283 case DestroyNotify:
284 XCloseDisplay(display);
285 exit(0);
286 break;
287 case ButtonPress:
288 but_stat = dcl_check_mouse_region(Event.xbutton.x, Event.xbutton.y);
289 break;
290 case ButtonRelease:
291 i = dcl_check_mouse_region(Event.xbutton.x, Event.xbutton.y);
293 if(!i && Event.xbutton.button == LMB && cmd_lmb)
294 dcl_execute_command(command_lmb, 0);
295 else if(!i && Event.xbutton.button == RMB && cmd_rmb)
296 dcl_execute_command(command_rmb, 0);
297 break;
304 /*----------------------------------------------------------------------*/
306 void cputnik_write_prefs(void)
309 if (dcl_prefs_openfile (dcl_getfilename_config (".clay", "cputnik.rc"), P_WRITE)) {
311 dcl_prefs_put_int ("update_period", update_period);
312 dcl_prefs_put_int ("show_memory", show_memory);
313 dcl_prefs_put_string ("command_lmb", command_lmb);
314 dcl_prefs_put_string ("command_rmb", command_rmb);
318 dcl_prefs_closefile ();
321 /*----------------------------------------------------------------------*/
323 void cputnik_read_prefs(void)
326 if (dcl_prefs_openfile (dcl_getfilename_config(".clay", "cputnik.rc"), P_READ)) {
328 update_period = dcl_prefs_get_int("update_period");
329 show_memory = dcl_prefs_get_int("show_memory") % 2;
330 dcl_strcpy(command_lmb, dcl_prefs_get_string("command_lmb"), BUFFER_SIZE);
331 dcl_strcpy(command_rmb, dcl_prefs_get_string("command_rmb"), BUFFER_SIZE);
333 cmd_lmb = cmd_rmb = 0;
335 if(strlen(command_lmb)) cmd_lmb = 1;
336 if(strlen(command_rmb)) cmd_rmb = 1;
338 dcl_prefs_closefile ();
340 } else {
342 update_period = 2;
343 show_memory = 1;
344 strcpy(command_lmb, "gnome-system-monitor");
345 strcpy(command_rmb, "xkill");
347 cputnik_write_prefs ();
352 /*----------------------------------------------------------------------*/
354 int main(int argc, char **argv)
356 cputnik_read_prefs();
357 cputnik_routine(argc, argv);
359 return 0;