47cdc55ca1387d20003cc0bcdf477962479d7c8d
[dockapps.git] / wmSMPmon / wmSMPmon / wmSMPmon.c
blob47cdc55ca1387d20003cc0bcdf477962479d7c8d
1 /***************************************************************************
2 wmSMPmon III - Window Maker system monitor
3 VERSION : 3.1
4 DATE : 2005-11-06
5 ORIGINAL AUTHORS : redseb <redseb@goupilfr.org> and
6 PhiR <phir@gcu-squad.org>
7 CONTRIBUTORS : Alain Schröder <alain@parkautomat.net>
8 CURRENT MAINTAINER: Thomas Ribbrock <emgaron@gmx.net>
9 ****************************************************************************
10 This file is placed under the conditions of the GNU Library
11 General Public License, version 2, or any later version.
12 See file COPYING for information on distribution conditions.
13 ***************************************************************************/
15 #include <string.h>
16 #include <X11/Xlib.h>
17 #include <X11/xpm.h>
18 #include <X11/extensions/shape.h>
19 #include "../wmgeneral/wmgeneral.h"
20 #include "wmSMPmon_master.xpm"
21 #include "wmSMPmon_mask.xbm"
22 #include "general.h"
23 #include "standards.h"
24 #include "sysinfo-linux.h"
26 #define VERSION "3.1"
28 /*###### Dividers for redraw-loops ######################################*/
29 #define DIV1 6
30 #define DIV2 10
32 /*###### Messages #######################################################*/
33 #define MSG_NO_SWAP "No swap mode : Swap is not monitored.\n"
35 /*###### Funcition definitions ##########################################*/
36 void usage(int cpus, const char *str);
39 /*###### MAIN PROGRAM ###################################################*/
40 int main(int argc, char **argv)
42 XEvent Event ;
44 unsigned int t0[TAILLE_T], /* history for CPU 0 -> Graph */
45 t1[TAILLE_T], /* history for CPU 1 -> Graph */
46 tm[TAILLE_T], /* history for CPU 0+1 -> Graph */
47 c1 = 6,
48 c2 = 9,
49 etat = 1,
50 lecture = 1,
51 delay = 250000,
52 delta = 0,
53 load = 0,
54 load0o = 0,
55 load1o = 0,
56 no_swap = FAUX,
57 draw_graph = FAUX,
58 NumCPUs, /* number of CPUs */
59 i = 0, /* counter */
60 mem = 0, /* current memory/swap scaled to 0-100 */
61 prec_mem = 0, /* memory from previous round */
62 prec_swap = 0, /* swap from previous round */
63 load_width = 3; /* width of load bar: 3 for SMP, 8 for UP */
65 unsigned long load0t=0, load1t=0 ;
67 unsigned int *CPU_Load; /* CPU load per CPU array */
70 /********** Initialisation **********/
71 NumCPUs = NumCpus_DoInit();
72 CPU_Load = alloc_c((NumCPUs) * sizeof(int));
74 if(NumCPUs == 1)
76 load_width = 8;
78 else
80 load_width = 3;
83 Myname = strrchr(argv[0], '/');
84 if (Myname) ++Myname; else Myname = argv[0];
87 /* process command line args */
88 i = 1; /* skip program name (i=0) */
89 while(argc > i)
91 if(!strncmp(argv[i], "-r", 2))
93 i ++ ;
94 if(i == argc)
96 /* parameter missing! */
97 usage(NumCPUs, "no refresh rate given when using -r!");
99 else
101 delay = atol(argv[i]) ;
103 i ++ ;
104 continue;
106 if(!strncmp(argv[i], "-h", 2))
108 usage(NumCPUs, NULL) ;
110 if(!strncmp(argv[i], "-g", 2) && NumCPUs > 1)
112 /* we only support this on SMP systems */
113 i ++ ;
114 if(i == argc)
116 /* parameter missing! */
117 usage(NumCPUs, "no graph style given when using -g!");
119 else
121 etat = atoi(argv[i]) ;
124 if(1 > etat || etat > 3)
125 usage(NumCPUs, "Unknown graph style") ;
126 i ++ ;
127 continue;
129 if(!strncmp(argv[i], "-no-swap", 8))
131 puts(MSG_NO_SWAP) ;
132 no_swap = VRAI ;
133 i ++ ;
134 continue;
137 /* if we get here, we found an illegal option */
138 usage(NumCPUs, "Illegal option!");
141 /* open initial window */
142 if(NumCPUs == 1)
144 /* we only have a single CPU - change the mask accordingly
145 NOTE: The for loop was derived from the differences between
146 wmSMPmon_mask.xbm and wmSMPmon_mask-single.xbm.
147 wmSMPmon_mask-single.xbm as such is NOT used in this
148 program! */
149 for (i = 33; i <= 289; i = i+8)
151 wmSMPmon_mask_bits[i] = 0xDF;
155 openXwindow(argc,argv,wmSMPmon_master_xpm,wmSMPmon_mask_bits,wmSMPmon_mask_width,wmSMPmon_mask_height) ;
157 if(NumCPUs >= 2)
159 /* we have two CPUs -> draw separator between CPU load bars */
160 copyXPMArea(12, 4, 2, HAUTEUR + 2, 7, 4) ;
163 delay = delay / 2 ;
165 for(i = 0 ; i < TAILLE_T ; i ++)
166 t0[i] = 0 ;
167 for(i = 0 ; i < TAILLE_T ; i ++)
168 t1[i] = 0 ;
169 for(i = 0 ; i < TAILLE_T ; i ++)
170 tm[i] = 0 ;
172 /* -no-swap option was given */
173 if(no_swap)
174 copyXPMArea(60, 63, 60, 10, 6, 50) ;
176 /* MAIN LOOP */
177 while(VRAI)
179 if(lecture)
181 CPU_Load = Get_CPU_Load(CPU_Load, NumCPUs);
183 load = CPU_Load[0];
184 load0t = load0t + load ;
185 if(load != load0o)
187 /* redraw only if cpu load changed */
188 delta = HAUTEUR - load ;
189 copyXPMArea(108, 0, load_width, HAUTEUR, 4, 5) ;
190 copyXPMArea(108, delta + 32, load_width, load, 4, 5 + delta) ;
191 load0o = load;
194 if(NumCPUs >= 2)
196 /* we have two CPUs -> do CPU 1 */
197 /* FIXME: What about more CPUs? */
198 load = CPU_Load[1];
200 if(load != load1o)
202 /* redraw only if cpu load changed */
203 delta = HAUTEUR - load ;
204 copyXPMArea(108, 0, 3, HAUTEUR, 9, 5) ;
205 copyXPMArea(108, delta + 32, 3, load, 9, 5 + delta) ;
206 load1o = load;
210 /* we have to set load1t in any case to get the correct
211 graph below. With only one CPU, 'load' will still be
212 CPU_Load[0], on a SMP system, it will be CPU_Load[1]. */
213 load1t = load1t + load ;
216 if(c1 > DIV1)
218 mem = Get_Memory();
220 if(mem != prec_mem)
222 /* redraw only if mem changed */
223 copyXPMArea(30, 63, 30, 8, 29, 39) ;
224 copyXPMArea(0, 63, (mem * 30 / 100), 8, 29, 39) ;
225 prec_mem = mem ;
228 if(!no_swap)
230 mem = Get_Swap();
232 if(mem != prec_swap)
234 /* redraw if there was a change */
235 if(mem == 999)
237 /* swap is disabled => show "none" */
238 copyXPMArea(60, 63, 60, 10, 6, 50);
240 else
242 /* draw swap usage */
243 copyXPMArea(30, 63, 30, 8, 29, 50) ;
244 copyXPMArea(0, 63, (mem * 30 / 100), 8, 29, 50) ;
246 prec_swap = mem ;
249 c1 = 0;
252 if(c2 > DIV2)
253 draw_graph = VRAI ;
254 if(draw_graph)
256 for(i = 1 ; i < TAILLE_T ; i ++)
258 t0[i - 1] = t0[i] ;
259 t1[i - 1] = t1[i] ;
260 tm[i - 1] = tm[i] ;
262 if((t0[TAILLE_T - 1] = load0t / c2) > HAUTEUR)
263 t0[TAILLE_T - 1] = HAUTEUR ;
264 if((t1[TAILLE_T - 1] = load1t / c2) > HAUTEUR)
265 t1[TAILLE_T - 1] = HAUTEUR ;
266 if((tm[TAILLE_T - 1] = (load0t + load1t) / (2 * c2)) > HAUTEUR)
267 tm[TAILLE_T - 1] = HAUTEUR ;
268 load0t = 0 ;
269 load1t = 0 ;
271 /* draw graph */
272 switch(etat)
274 case 1 :
275 copyXPMArea(64, 32, TAILLE_T, HAUTEUR, 15, 5) ;
276 for(i = 0 ; i < TAILLE_T ; i ++)
277 copyXPMArea(116, 0, 1, tm[i], 15 + i, HAUTEUR + 5 - tm[i]) ;
278 break ;
279 case 2 :
280 copyXPMArea(64, 0, TAILLE_T, HAUTEUR, 15, 5) ;
281 for(i = 0 ; i < TAILLE_T ; i ++)
282 copyXPMArea(116, 0, 1, t0[i]/2, 15 + i, HAUTEUR/2 + 5 - t0[i]/2) ;
283 for(i = 0 ; i < TAILLE_T ; i ++)
284 copyXPMArea(116, 0, 1, t1[i]/2, 15 + i, HAUTEUR/2 + 21 - t1[i]/2) ;
285 break ;
286 case 3 :
287 copyXPMArea(64, 0, TAILLE_T, HAUTEUR, 15, 5) ;
288 for(i = 0 ; i < TAILLE_T ; i ++)
289 copyXPMArea(116, 0, 1, t0[i]/2, 15 + i, HAUTEUR/2 + 5 - t0[i]/2) ;
290 for(i = 0 ; i < TAILLE_T ; i ++)
291 copyXPMArea(117, (HAUTEUR - t1[i])/2, 1, t1[i]/2, 15 + i, HAUTEUR/2 + 6) ;
292 break ;
294 c2 = 0 ;
295 draw_graph = FAUX ;
297 c1 ++ ;
298 c2 ++ ;
300 lecture = 1 - lecture ;
301 RedrawWindow() ;
302 if(NumCPUs >= 2 && XCheckMaskEvent(display, ButtonPressMask, &Event))
304 /* changing graph style not supported on single CPU systems */
305 if(Event.type == ButtonPress)
307 if((etat ++) >= 3)
308 etat = 1 ;
309 draw_graph = VRAI ;
310 lecture = VRAI ;
313 usleep(delay);
318 /*###### Usage Message ##################################################*/
319 void usage(int cpus, const char *str)
321 fflush(stdout);
323 if (str)
325 fprintf(stderr, "\nERROR: %s\n", str);
328 fputs("\nwmSMPmon "VERSION" - display system load (", stderr);
329 if(cpus == 1)
331 fputs("uniprocessor system)\n\n", stderr);
333 else
335 fputs("(multiprocessor system)\n\n", stderr);
337 fputs("Options : -h this help screen.\n"
338 " -r RATE refresh rate (in microseconds, default 250000).\n", stderr);
340 if(cpus > 1)
342 fputs(" -g STYLE graph style (try 2 or 3, default is 1).\n", stderr);
345 fputs(" -no-swap don't monitore swap size.\n\n"
346 "<redseb@goupilfr.org> http://goupilfr.org\n"
347 "<phir@gcu-squad.org> http://gcu-squad.org\n"
348 "<emgaron@gmx.net> http://www.ribbrock.org\n",
349 stderr) ;
350 exit(OK) ;