wmail: fixed error in build instructions.
[dockapps.git] / wmsm.app / wmsm / wmsm.c
blob88d1c6349a7854e5e4ccede9c5bec0b7fd08d644
1 /*
2 * Copyright (C) 2002 Sven Schaepe <schaepe@rz.tu-ilmenau.de>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <string.h>
22 #include <linux/version.h>
24 #include <X11/Xlib.h>
25 #include <X11/xpm.h>
26 #include <X11/extensions/shape.h>
28 #include <libdockapp/wmgeneral.h>
29 #include <libdockapp/misc.h>
31 #include "wmsm-master.xpm"
33 #define v_WMSM "0.2.1"
35 /* scale */
36 #define xpm_scale_width 35
37 #define xpm_scale_height 7
38 /* type 1 */
39 #define xpm_scale_1_f_x 67
40 #define xpm_scale_1_f_y 5
41 #define xpm_scale_1_b_x 67
42 #define xpm_scale_1_b_y 13
43 /* type 2 */
44 #define xpm_scale_2_f_x 67
45 #define xpm_scale_2_f_y 21
46 #define xpm_scale_2_b_x 67
47 #define xpm_scale_2_b_y 29
49 /* digit */
50 #define digit_width 6
51 #define digit_height 7
52 /* green */
53 #define digit_1_x 5
54 #define digit_1_y 66
55 /* blue */
56 #define digit_2_x 5
57 #define digit_2_y 76
59 /* ativation point */
60 #define point_width 2
61 #define point_height 2
62 /* disable point */
63 #define point_disable_x 66
64 #define point_disable_y 37
65 /* enable point */
66 #define point_enable_x 68
67 #define point_enable_y 37
68 /* read position */
69 #define point_read_x 5
70 #define point_read_y 37
71 /* write position */
72 #define point_write_x 5
73 #define point_write_y 46
75 #define cpu_s_x 24
76 #define cpu_s_y 5
77 #define mem_s_x 24
78 #define mem_s_y 14
79 #define swap_s_x 24
80 #define swap_s_y 23
81 #define ior_s_x 24
82 #define ior_s_y 32
83 #define iow_s_x 24
84 #define iow_s_y 41
86 typedef struct {
87 int cpu_idle;
88 int cpu_use;
89 long long r_diff_max;
90 unsigned long long r_io;
91 long long w_diff_max;
92 unsigned long long w_io;
93 int day;
94 int hour;
95 int min;
96 int sec;
97 } LAST;
98 LAST last;
100 char wmsm_mask_bits[64*64];
101 int wmsm_mask_width = 64;
102 int wmsm_mask_height = 64;
103 int scale_width;
104 int scale_height;
105 int scale_f_x;
106 int scale_f_y;
107 int scale_b_x;
108 int scale_b_y;
109 int mem_correction;
110 char *dev_name;
112 static void draw_digit(int value,int dx,int dy)
114 if(value>99) {
115 copyXPMArea(9*digit_width+digit_2_x,digit_2_y,digit_width,digit_height,dx,dy);
116 copyXPMArea(9*digit_width+digit_2_x,digit_2_y,digit_width,digit_height,dx+digit_width,dy);
117 } else {
118 copyXPMArea((value/10)*digit_width+digit_1_x,digit_1_y,digit_width,digit_height,dx,dy);
119 copyXPMArea((value%10)*digit_width+digit_1_x,digit_1_y,digit_width,digit_height,dx+digit_width,dy);
121 RedrawWindowXY(0,0);
124 static void draw_uptime(int day,int hour,int min,int sec)
126 if(sec!=last.sec) {
127 draw_digit(sec,48,51);
128 last.sec=sec;
129 if(min!=last.min) {
130 draw_digit(min,34,51);
131 last.min=min;
132 if(hour!=last.hour) {
133 draw_digit(hour,20,51);
134 last.hour=hour;
135 if(day!=last.day) {
136 draw_digit(day,5,51);
137 last.day=day;
144 static void draw_enable_point(int dx,int dy)
146 copyXPMArea(point_enable_x,point_enable_y,point_width,point_height,dx,dy);
147 RedrawWindowXY(0,0);
150 static void draw_disable_point(int dx,int dy)
152 copyXPMArea(point_disable_x,point_disable_y,point_width,point_height,dx,dy);
153 RedrawWindowXY(0,0);
156 static void draw_scale(int width,int dx,int dy)
158 copyXPMArea(scale_f_x,scale_f_y,width,scale_height,dx,dy);
159 if(width<scale_width) {
160 copyXPMArea(scale_b_x+width,scale_b_y,scale_width-width,scale_height,dx+width,dy);
162 RedrawWindowXY(0,0);
165 static int getDiskValue24(unsigned long long *r_io,unsigned long long *w_io)
167 FILE *file;
168 char line[256];
169 char tag[32];
170 int major=0,disk=0,all_io=0,r_blk=0,w_blk=0;
171 if((file=fopen("/proc/stat","r"))==NULL) {
172 return -1;
174 while(fgets(line,sizeof(line),file)!=NULL) {
175 sscanf(line,"%s",tag);
176 if(strcmp(tag,"disk_io:")==0) {
177 sscanf(line,"%s (%d,%d):(%d,%llu,%d,%llu,%d)",tag,&major,&disk,&all_io
178 ,r_io,&r_blk,w_io,&w_blk);
179 fclose(file);
180 return 0;
183 fclose(file);
184 return -1;
187 static int getDiskValue26(unsigned long long *r_io,unsigned long long *w_io)
189 FILE *file;
190 char line[256];
191 if((file=fopen("/proc/diskstats","r"))==NULL) {
192 return -1;
194 while(fgets(line,sizeof(line),file)!=NULL) {
195 int major,minor;
196 char devName[40];
197 unsigned int reads,readMerges,readTicks;
198 unsigned int writes,writeMerges,writeTicks;
199 unsigned int inFlight,ioTicks,timeInQueue;
200 unsigned long long readSectors,writeSectors;
201 if(sscanf(line,"%4d %4d %s %u %u %llu %u %u %u %llu %u %u %u %u",
202 &major,&minor,devName,&reads,&readMerges,&readSectors,&readTicks,
203 &writes,&writeMerges,&writeSectors,&writeTicks,&inFlight,&ioTicks,
204 &timeInQueue)==14) {
205 *r_io=readSectors;
206 *w_io=writeSectors;
207 if(strcmp(devName,dev_name)==0) {
208 fclose(file);
209 return 0;
213 fclose(file);
214 return -1;
217 static void get_values(int init,int kernelVersion)
219 FILE *file;
220 char line[256];
221 char tag[32];
222 int user,nice,system,idle;
223 unsigned long long r_io=0,w_io=0;
224 int mem_total=0,mem_free=0,mem_cached=0,mem_buffers=0;
225 int swap_total=0,swap_free=0;
226 float uptime=0.0;
228 file=fopen("/proc/stat","r");
229 while(fgets(line,sizeof(line),file)!=NULL) {
230 sscanf(line,"%s",tag);
231 if(strcmp(tag,"cpu")==0) {
232 sscanf(line,"%s %d %d %d %d",tag,&user,&nice,&system,&idle);
233 break;
236 fclose(file);
237 if(kernelVersion<KERNEL_VERSION(2,6,0)) {
238 getDiskValue24(&r_io,&w_io);
239 } else {
240 getDiskValue26(&r_io,&w_io);
242 file=fopen("/proc/meminfo","r");
243 while(fgets(line,sizeof(line),file)!=NULL) {
244 sscanf(line,"%s",tag);
245 if(strcmp(tag,"MemTotal:")==0) {
246 sscanf(line,"%s %d",tag,&mem_total);
247 continue;
249 if(strcmp(tag,"MemFree:")==0) {
250 sscanf(line,"%s %d",tag,&mem_free);
251 continue;
253 if(strcmp(tag,"Cached:")==0) {
254 sscanf(line,"%s %d",tag,&mem_cached);
255 continue;
257 if(strcmp(tag,"Buffers:")==0) {
258 sscanf(line,"%s %d",tag,&mem_buffers);
259 continue;
261 if(strcmp(tag,"SwapTotal:")==0) {
262 sscanf(line,"%s %d",tag,&swap_total);
263 continue;
265 if(strcmp(tag,"SwapFree:")==0) {
266 sscanf(line,"%s %d",tag,&swap_free);
267 break;
270 fclose(file);
272 file=fopen("/proc/uptime","r");
273 fscanf(file,"%f",&uptime);
274 fclose(file);
276 if(init) {
277 last.cpu_idle=idle;
278 last.cpu_use=user+nice+system;
279 last.r_diff_max=1;
280 last.r_io=r_io;
281 last.w_diff_max=1;
282 last.w_io=w_io;
283 } else {
284 long long diff;
285 long long diff1;
286 int width;
288 /* cpu */
289 diff=idle-last.cpu_idle;
290 diff1=user+nice+system-last.cpu_use;
291 width=diff1*scale_width/(diff+diff1+1);
292 last.cpu_idle=idle;
293 last.cpu_use=user+nice+system;
294 draw_scale(width,cpu_s_x,cpu_s_y);
296 /* r_io */
297 diff=r_io-last.r_io;
298 if(diff>last.r_diff_max) {
299 last.r_diff_max=diff;
301 width=abs(diff)*scale_width/last.r_diff_max;
302 last.r_io=r_io;
303 draw_scale(width,ior_s_x,ior_s_y);
304 if(diff && !width) {
305 draw_enable_point(point_read_x,point_read_y);
306 } else {
307 draw_disable_point(point_read_x,point_read_y);
310 /* w_io */
311 diff=w_io-last.w_io;
312 if(diff>last.w_diff_max) {
313 last.w_diff_max=diff;
315 width=abs(diff)*scale_width/last.w_diff_max;
316 last.w_io=w_io;
317 draw_scale(width,iow_s_x,iow_s_y);
318 if(diff && !width) {
319 draw_enable_point(point_write_x,point_write_y);
320 } else {
321 draw_disable_point(point_write_x,point_write_y);
324 /* mem */
325 if(!mem_total) {
326 width=0;
327 } else {
328 if(mem_correction) {
329 width=(mem_total-mem_free-mem_cached-mem_buffers)*scale_width/mem_total;
330 } else {
331 width=(mem_total-mem_free)*scale_width/mem_total;
334 draw_scale(width,mem_s_x,mem_s_y);
336 /* swap */
337 if(!swap_total) {
338 width=0;
339 } else {
340 width=(swap_total-swap_free)*scale_width/swap_total;
342 draw_scale(width,swap_s_x,swap_s_y);
344 /* uptime */
346 int day,hour,min,sec;
348 day=(int)uptime/(24*3600);
349 uptime-=day*24*3600;
350 hour=(int)uptime/3600;
351 uptime-=hour*3600;
352 min=(int)uptime/60;
353 uptime-=min*60;
354 sec=uptime;
355 draw_uptime(day,hour,min,sec);
360 static void usage(char *progname)
362 fprintf(stdout,"%s-%s "
363 "WindowMaker System Monitor\n"
364 "\t-t <num> scale type num={1,2,3,4}\n"
365 "\t-d <dev> device name without partion number, default: hda\n"
366 "\t-m mem correction\n"
367 "\t-h this\n"
368 ,progname,v_WMSM);
371 int main(int argc,char *argv[])
373 FILE *file;
374 char line[256];
375 char xx[256];
376 int revision=0,release=0,patchlevel=0;
377 XEvent event;
378 int opt;
380 scale_width=xpm_scale_width;
381 scale_height=xpm_scale_height;
382 scale_f_x=xpm_scale_2_f_x;
383 scale_f_y=xpm_scale_2_f_y;
384 scale_b_x=xpm_scale_1_b_x;
385 scale_b_y=xpm_scale_1_b_y;
386 mem_correction=0;
387 dev_name="hda";
389 while((opt=getopt(argc,argv,"hmt:d:"))!=-1) {
390 switch(opt) {
391 case 'd':
392 dev_name=optarg;
393 break;
394 case 'm':
395 mem_correction=1;
396 break;
397 case 't':
398 switch(atoi(optarg)) {
399 case 4:
400 scale_f_x=xpm_scale_2_f_x;
401 scale_f_y=xpm_scale_2_f_y;
402 scale_b_x=xpm_scale_2_b_x;
403 scale_b_y=xpm_scale_2_b_y;
404 break;
405 case 3:
406 scale_f_x=xpm_scale_1_f_x;
407 scale_f_y=xpm_scale_1_f_y;
408 scale_b_x=xpm_scale_1_b_x;
409 scale_b_y=xpm_scale_1_b_y;
410 break;
411 case 2:
412 scale_f_x=xpm_scale_1_f_x;
413 scale_f_y=xpm_scale_1_f_y;
414 scale_b_x=xpm_scale_2_b_x;
415 scale_b_y=xpm_scale_2_b_y;
416 break;
417 case 1:
418 default:
419 scale_f_x=xpm_scale_2_f_x;
420 scale_f_y=xpm_scale_2_f_y;
421 scale_b_x=xpm_scale_1_b_x;
422 scale_b_y=xpm_scale_1_b_y;
424 break;
425 case 'h':
426 default:
427 usage(argv[0]);
428 exit(0);
432 file=fopen("/proc/version","r");
433 fgets(line,sizeof(line),file);
434 sscanf(line,"%s %s %d.%d.%d%s",xx,xx,&revision,&release,&patchlevel,xx);
435 fclose(file);
437 createXBMfromXPM(wmsm_mask_bits,wmsm_master_xpm,wmsm_mask_width,wmsm_mask_height);
438 openXwindow(argc,argv,wmsm_master_xpm,wmsm_mask_bits,wmsm_mask_width,wmsm_mask_height);
439 RedrawWindowXY(0,0);
441 get_values(1,(revision<<16)+(release<<8)+patchlevel);
442 while(1) {
443 while (XPending(display)) {
444 XNextEvent(display, &event);
445 switch (event.type) {
446 case Expose:
447 RedrawWindowXY(0,0);
448 break;
449 case DestroyNotify:
450 XCloseDisplay(display);
451 exit(0);
454 get_values(0,(revision<<16)+(release<<8)+patchlevel);
455 usleep(150000L);