wmmon: debian patches applied to upstream
[dockapps.git] / wmmon / wmmon / wmmon.c
blob4e9868e9b9edc884a3d2be086c517c3344ed60b9
1 /*
2 Code based on wmppp/wmifs
4 [Orig WMPPP comments]
6 This code was mainly put together by looking at the
7 following programs:
9 asclock
10 A neat piece of equip, used to display the date
11 and time on the screen.
12 Comes with every AfterStep installation.
14 Source used:
15 How do I create a not so solid window?
16 How do I open a window?
17 How do I use pixmaps?
19 ------------------------------------------------------------
21 Authors: Martijn Pieterse (pieterse@xs4all.nl)
22 Antoine Nulle (warp@xs4all.nl)
24 This program is distributed under the GPL license.
25 (as were asclock and pppstats)
27 ----
28 Changes:
29 ----
31 17/10/2009 (Romuald Delavergne, romuald.delavergne@free.fr)
32 * Support SMP processors in realtime CPU stress meter
33 15/05/2004 (Simon Law, sfllaw@debian.org)
34 * Support disabling of mode-cycling
35 23/10/2003 (Simon Law, sfllaw@debian.org)
36 * Eliminated exploitable static buffers
37 * Added -geometry support.
38 * /proc/meminfo support for Linux 2.6
39 18/05/1998 (Antoine Nulle, warp@xs4all.nl)
40 * MEM/SWAP/UPTIME only updated when visible
41 * Using global file descriptors to reduce file
42 system overhead, both updates are based on a diff
43 supplied by Dave Harden (dharden@wisewire.com)
44 15/05/1998 (Antoine Nulle, warp@xs4all.nl)
45 * Fixed memory overflow in the MEM gaugebar
46 * MEM gauge displays now real used mem
47 (buffered + cached mem removed)
48 14/05/1998 (Antoine Nulle, warp@xs4all.nl)
49 * Added -i & -s kludge for selecting startupmode,
50 tijno, don't hate me for this :)
51 12/05/1998 (Antoine Nulle, warp@xs4all.nl)
52 * Finetuned master-xpm, tijno don't worry, no
53 reprogramming needed this time ;-)
54 07/05/1998 (Martijn Pieterse, pieterse@xs4all.nl)
55 * Added disk i/o
56 03/05/1998 (Antoine Nulle, warp@xs4all.nl)
57 * Added new master-xpm which contains the gfx
58 for the upcoming SysInfo part :P
59 02/05/1998 (Martijn Pieterse, pieterse@xs4all.nl)
60 * Removed a lot of code, that was put in wmgeneral
61 23/04/1998 (Martijn Pieterse, pieterse@xs4all.nl)
62 * Added zombie destroying code (aka wait :) )
63 18/04/1998 (Martijn Pieterse, pieterse@xs4all.nl)
64 * Added CPU-on-screen.
65 * Added -display command line
66 15/04/1998 (Martijn Pieterse, pieterse@xs4all.nl)
67 * Fixed a bug in the stats routine
68 (Top 3 bright pixels were not shown when 100% loaded)
69 * Changed xpm to a no-title one.
70 This included the reprogramming of all positions.
71 warpstah, i hate you! ;)
72 05/04/1998 (Martijn Pieterse, pieterse@xs4all.nl)
73 * First Working Version
76 #define _GNU_SOURCE
77 #include <stdlib.h>
78 #include <stdio.h>
79 #include <time.h>
80 #include <string.h>
81 #include <fcntl.h>
82 #include <unistd.h>
84 #include <sys/wait.h>
85 #include <sys/param.h>
86 #include <sys/types.h>
88 #include <X11/Xlib.h>
89 #include <X11/xpm.h>
90 #include <X11/extensions/shape.h>
92 #include "../wmgeneral/wmgeneral.h"
93 #include "../wmgeneral/misc.h"
95 #include "wmmon-master.xpm"
96 #include "wmmon-mask.xbm"
98 /***********/
99 /* Defines */
100 /***********/
102 #define LEFT_ACTION (NULL)
103 #define RIGHT_ACTION (NULL)
104 #define MIDDLE_ACTION (NULL)
106 #define WMMON_VERSION "1.0.b2"
108 /********************/
109 /* Global Variables */
110 /********************/
112 int stat_current = 0; /* now global */
113 int mode_cycling = 1; /* Allow mode-cycling */
114 int cpu_avg_max = 0; /* CPU stress meter with average and max for SMP */
115 FILE *fp_meminfo;
116 FILE *fp_stat;
117 FILE *fp_loadavg;
119 /* functions */
120 void usage(char*);
121 void printversion(void);
122 void DrawStats(int *, int, int, int, int);
123 void DrawStats_io(int *, int, int, int, int);
125 void wmmon_routine(int, char **);
127 int main(int argc, char *argv[]) {
129 int i;
130 char *name = argv[0];
133 /* Parse Command Line */
135 for (i=1; i<argc; i++) {
136 char *arg = argv[i];
138 if (*arg=='-') {
139 switch (arg[1]) {
140 case 'd' :
141 if (strcmp(arg+1, "display")) {
142 usage(name);
143 return 1;
145 break;
146 case 'g' :
147 if (strcmp(arg+1, "geometry")) {
148 usage(name);
149 return 1;
151 case 'l' :
152 mode_cycling = 0;
153 break;
154 case 'c' :
155 cpu_avg_max = 1;
156 break;
157 case 'i' :
158 stat_current = 1;
159 break;
160 case 's' :
161 stat_current = 2;
162 break;
163 case 'v' :
164 printversion();
165 return 0;
166 default:
167 usage(name);
168 return 1;
173 wmmon_routine(argc, argv);
175 exit (0);
179 /*******************************************************************************\
180 |* wmmon_routine *|
181 \*******************************************************************************/
183 #define MAX_CPU (10) /* depends on graph height */
184 typedef struct {
186 char name[5]; /* "cpu0..cpuz", eventually.. :) */
187 int his[55];
188 int hisaddcnt;
189 long rt_stat;
190 long statlast;
191 long rt_idle;
192 long idlelast;
193 /* Processors stats */
194 long *cpu_stat;
195 long *cpu_last;
196 long *idle_stat;
197 long *idle_last;
199 } stat_dev;
201 #define MAX_STAT_DEVICES (4)
202 stat_dev stat_device[MAX_STAT_DEVICES];
204 char *left_action;
205 char *right_action;
206 char *middle_action;
209 int nb_cpu, cpu_max;
210 int getNbCPU(void);
211 unsigned long getWidth(long, long);
212 int checksysdevs(void);
213 void get_statistics(char *, long *, long *, long *, long *, long *);
214 void DrawActive(char *);
216 void update_stat_cpu(stat_dev *, long *, long *);
217 void update_stat_io(stat_dev *);
218 void update_stat_mem(stat_dev *st, stat_dev *st2);
219 void update_stat_swp(stat_dev *);
221 void wmmon_routine(int argc, char **argv) {
223 rckeys wmmon_keys[] = {
224 { "left", &left_action },
225 { "right", &right_action },
226 { "middle", &middle_action },
227 { NULL, NULL }
230 unsigned long i,j;
231 long k;
232 XEvent Event;
233 int but_stat = -1;
235 int stat_online;
237 long starttime;
238 long curtime;
239 long nexttime;
241 long istat;
242 long idle;
243 long *istat2;
244 long *idle2;
246 FILE *fp;
247 char *conffile = NULL;
249 int xpm_X = 0, xpm_Y = 0;
251 long online_time = 0;
252 long ref_time = 0;
253 long cnt_time;
256 fp = fopen("/proc/uptime", "r");
257 fp_meminfo = fopen("/proc/meminfo", "r");
258 fp_loadavg = fopen("/proc/loadavg", "r");
259 fp_stat = fopen("/proc/stat", "r");
261 if (fp) {
262 fscanf(fp, "%ld", &online_time);
263 ref_time = time(0);
264 fclose(fp);
267 for (i=0; i<MAX_STAT_DEVICES; i++) {
268 for (j=0; j<55; j++) {
269 stat_device[i].his[j] = 0;
271 stat_device[i].hisaddcnt = 0;
274 if (LEFT_ACTION) left_action = strdup(LEFT_ACTION);
275 if (RIGHT_ACTION) right_action = strdup(RIGHT_ACTION);
276 if (MIDDLE_ACTION) middle_action = strdup(MIDDLE_ACTION);
278 /* Scan through the .rc files */
279 if (asprintf(&conffile, "/etc/wmmonrc") >= 0) {
280 parse_rcfile(conffile, wmmon_keys);
281 free(conffile);
284 if (asprintf(&conffile, "%s/.wmmonrc", getenv("HOME")) >= 0) {
285 parse_rcfile(conffile, wmmon_keys);
286 free(conffile);
289 if (asprintf(&conffile, "/etc/wmmonrc.fixed") >= 0) {
290 parse_rcfile(conffile, wmmon_keys);
291 free(conffile);
294 stat_online = checksysdevs();
296 nb_cpu = getNbCPU();
297 stat_device[0].cpu_stat = calloc(nb_cpu, sizeof(long));
298 stat_device[0].cpu_last = calloc(nb_cpu, sizeof(long));
299 stat_device[0].idle_stat = calloc(nb_cpu, sizeof(long));
300 stat_device[0].idle_last = calloc(nb_cpu, sizeof(long));
301 if (!stat_device[0].cpu_stat || !stat_device[0].cpu_last || !stat_device[0].idle_stat || !stat_device[0].idle_last) {
302 fprintf(stderr, "%s: Unable to alloc memory !\n", argv[0]);
303 exit(1);
305 istat2 = calloc(nb_cpu, sizeof(long));
306 idle2 = calloc(nb_cpu, sizeof(long));
307 if (!istat2 || !idle2) {
308 fprintf(stderr, "%s: Unable to alloc memory !!\n", argv[0]);
309 exit(1);
312 openXwindow(argc, argv, wmmon_master_xpm, wmmon_mask_bits, wmmon_mask_width, wmmon_mask_height);
314 /* add mouse region */
315 AddMouseRegion(0, 12, 13, 58, 57);
316 AddMouseRegion(1, 5, 5, 24, 14);
318 starttime = time(0);
319 nexttime = starttime + 10;
321 /* Collect information on each panel */
322 for (i=0; i<stat_online; i++) {
323 get_statistics(stat_device[i].name, &k, &istat, &idle, istat2, idle2);
324 stat_device[i].statlast = istat;
325 stat_device[i].idlelast = idle;
326 if (i == 0 && nb_cpu > 1) {
327 int cpu;
328 for (cpu = 0; cpu < nb_cpu; cpu++) {
329 stat_device[i].cpu_last[cpu] = istat2[cpu];
330 stat_device[i].idle_last[cpu] = idle2[cpu];
335 /* Set the mask for the current window */
336 switch (stat_current) {
337 case 0:
338 case 1:
339 xpm_X = 0;
340 setMaskXY(0, 0);
341 break;
342 case 2:
343 xpm_X = 64;
344 setMaskXY(-64, 0);
345 default:
346 break;
349 /* Draw statistics */
350 if (stat_current == 0)
351 DrawStats(stat_device[stat_current].his, 54, 40, 5, 58);
352 if (stat_current == 1)
353 DrawStats_io(stat_device[stat_current].his, 54, 40, 5, 58);
354 DrawActive(stat_device[stat_current].name);
356 while (1) {
357 curtime = time(NULL);
359 waitpid(0, NULL, WNOHANG);
362 update_stat_cpu(&stat_device[0], istat2, idle2);
363 update_stat_io(&stat_device[1]);
365 if(stat_current == 2) {
366 update_stat_mem(&stat_device[2], &stat_device[3]);
367 // update_stat_swp(&stat_device[3]);
370 if (stat_current < 2) {
371 i = stat_current;
373 /* Load ding is 45 pixels hoog */
374 copyXPMArea(0, 64, 32, 12, 28, 4);
376 if (i == 0 && nb_cpu > 1) {
377 if (nb_cpu > MAX_CPU || cpu_avg_max) {
378 /* show average CPU */
379 j = getWidth(stat_device[i].rt_stat, stat_device[i].rt_idle);
380 copyXPMArea(32, 64, j, 6, 28, 4);
381 /* Show max CPU */
382 j = getWidth(stat_device[i].cpu_stat[cpu_max], stat_device[i].idle_stat[cpu_max]);
383 copyXPMArea(32, 70, j, 6, 28, 10);
384 } else {
385 int cpu;
386 for (cpu = 0; cpu < nb_cpu; cpu++) {
387 j = getWidth(stat_device[i].cpu_stat[cpu], stat_device[i].idle_stat[cpu]);
388 copyXPMArea(32, 65, j, MAX_CPU/nb_cpu, 28, 5+(MAX_CPU/nb_cpu)*cpu);
392 else {
393 j = getWidth(stat_device[i].rt_stat, stat_device[i].rt_idle);
394 copyXPMArea(32, 64, j, 12, 28, 4);
396 } else {
397 /* Nu zal ie wel 3 zijn. */
399 copyXPMArea(0, 64, 32, 12, 28+64, 4);
400 copyXPMArea(0, 64, 32, 12, 28+64, 18);
402 j = stat_device[2].rt_idle;
403 if (j != 0) {
404 j = (stat_device[2].rt_stat * 100) / j;
406 j = j * 0.32;
407 if (j > 32) j = 32;
408 copyXPMArea(32, 64, j, 12, 28+64, 4);
409 /*--------------------- ------------------*/
410 j = stat_device[3].rt_idle;
411 if (j != 0) {
412 j = (stat_device[3].rt_stat * 100) / j;
414 j = j * 0.32;
415 if (j > 32) j = 32;
416 copyXPMArea(32, 64, j, 12, 28+64, 18);
418 /*----------- online tijd neerzetten! ----------*/
420 cnt_time = time(0) - ref_time + online_time;
422 /* cnt_time = uptime in seconden */
424 secs = 108,47
425 mins = 89,47
426 uren = 70,47
427 digits = 40,78, 6breed, 9hoog
429 i = cnt_time % 60;
430 cnt_time /= 60;
431 copyXPMArea(40 + (i % 10)*7, 78, 6, 9, 115, 47);
432 copyXPMArea(40 + (i / 10)*7, 78, 6, 9, 108, 47);
434 i = cnt_time % 60;
435 cnt_time /= 60;
436 copyXPMArea(40 + (i % 10)*7, 78, 6, 9, 96, 47);
437 copyXPMArea(40 + (i / 10)*7, 78, 6, 9, 89, 47);
439 i = cnt_time % 24;
440 cnt_time /= 24;
441 copyXPMArea(40 + (i % 10)*7, 78, 6, 9, 77, 47);
442 copyXPMArea(40 + (i / 10)*7, 78, 6, 9, 70, 47);
444 /* De rest is dagen! 5x7*/
446 i = cnt_time;
447 copyXPMArea(66 + (i % 10)*6, 66, 5, 7, 88, 35);
448 i /= 10;
449 copyXPMArea(66 + (i % 10)*6, 66, 5, 7, 82, 35);
450 i /= 10;
451 copyXPMArea(66 + (i % 10)*6, 66, 5, 7, 76, 35);
452 i /= 10;
453 copyXPMArea(66 + (i % 10)*6, 66, 5, 7, 70, 35);
456 if (curtime >= nexttime) {
457 nexttime+=10;
459 if (curtime > nexttime) /* dont let APM suspends make this crazy */
460 nexttime = curtime;
462 for (i=0; i<stat_online; i++) {
463 if (stat_device[i].his[54])
464 stat_device[i].his[54] /= stat_device[i].hisaddcnt;
466 for (j=1; j<55; j++) {
467 stat_device[i].his[j-1] = stat_device[i].his[j];
470 if (i == stat_current) {
471 if (i == 0) DrawStats(stat_device[i].his, 54, 40, 5, 58);
472 if (i == 1) DrawStats_io(stat_device[i].his, 54, 40, 5, 58);
474 stat_device[i].his[54] = 0;
475 stat_device[i].hisaddcnt = 0;
479 RedrawWindowXY(xpm_X, xpm_Y);
481 while (XPending(display)) {
482 XNextEvent(display, &Event);
483 switch (Event.type) {
484 case Expose:
485 RedrawWindowXY(xpm_X, xpm_Y);
486 break;
487 case DestroyNotify:
488 XCloseDisplay(display);
489 exit(0);
490 break;
491 case ButtonPress:
492 but_stat = CheckMouseRegion(Event.xbutton.x, Event.xbutton.y);
493 break;
494 case ButtonRelease:
495 i = CheckMouseRegion(Event.xbutton.x, Event.xbutton.y);
496 if (but_stat == i && but_stat >= 0 && mode_cycling) {
497 switch (but_stat) {
498 case 0:
499 switch (Event.xbutton.button) {
500 case 1:
501 if (left_action)
502 execCommand(left_action);
503 break;
504 case 2:
505 if (middle_action)
506 execCommand(middle_action);
507 break;
508 case 3:
509 if (right_action)
510 execCommand(right_action);
511 break;
513 case 1:
514 stat_current++;
515 if (stat_current == stat_online)
516 stat_current = 0;
518 DrawActive(stat_device[stat_current].name);
519 if (stat_current == 0) DrawStats(stat_device[stat_current].his, 54, 40, 5, 58);
520 if (stat_current == 1) {
521 DrawStats_io(stat_device[stat_current].his, 54, 40, 5, 58);
523 if (stat_current == 2) {
524 xpm_X = 64;
525 setMaskXY(-64, 0);
526 } else {
527 xpm_X = 0;
528 setMaskXY(0, 0);
530 RedrawWindowXY(xpm_X, xpm_Y);
531 break;
534 break;
538 usleep(250000L);
542 void update_stat_cpu(stat_dev *st, long *istat2, long *idle2) {
543 long k, istat, idle;
545 get_statistics(st->name, &k, &istat, &idle, istat2, idle2);
547 st->rt_idle = idle - st->idlelast;
548 st->idlelast = idle;
550 st->rt_stat = istat - st->statlast;
551 st->statlast = istat;
553 if (nb_cpu > 1) {
554 int cpu;
555 unsigned long max, j;
556 cpu_max = 0; max = 0;
557 for (cpu = 0; cpu < nb_cpu; cpu++) {
558 st->idle_stat[cpu] = idle2[cpu] - st->idle_last[cpu];
559 st->idle_last[cpu] = idle2[cpu];
561 st->cpu_stat[cpu] = istat2[cpu] - st->cpu_last[cpu];
562 st->cpu_last[cpu] = istat2[cpu];
564 j = st->cpu_stat[cpu] + st->idle_stat[cpu];
565 if (j != 0) j = (st->cpu_stat[cpu] << 7) / j;
566 if (j > max) {
567 max = j;
568 cpu_max = cpu;
573 st->his[54] += k;
574 st->hisaddcnt += 1;
577 void update_stat_io(stat_dev *st) {
579 long j, k, istat, idle;
580 static long maxdiskio = 0;
582 get_statistics(st->name, &k, &istat, &idle, NULL, NULL);
584 st->rt_idle = idle - st->idlelast;
585 st->idlelast = idle;
587 st->rt_stat = istat - st->statlast;
588 st->statlast = istat;
590 j = st->rt_stat;
591 if (maxdiskio < j) {
592 maxdiskio = j;
594 st->rt_idle = maxdiskio - j;
596 st->his[54] += st->rt_stat;
597 st->hisaddcnt += 1;
600 void update_stat_mem(stat_dev *st, stat_dev *st2) {
602 static char *line = NULL;
603 static size_t line_size = 0;
605 unsigned long swapfree;
606 unsigned long free, shared, buffers, cached;
608 freopen("/proc/meminfo", "r", fp_meminfo);
609 while ((getline(&line, &line_size, fp_meminfo)) > 0) {
610 /* The original format for the first two lines of /proc/meminfo was
611 * Mem: total used free shared buffers cached
612 * Swap: total used free
614 * As of at least 2.5.47 these two lines were removed, so that the
615 * required information has to come from the rest of the lines.
616 * On top of that, used is no longer recorded - you have to work
617 * this out yourself, from total - free.
619 * So, these changes below should work. They should also work with
620 * older kernels, too, since the new format has been available for
621 * ages.
623 if (strstr(line, "MemTotal:")) {
624 sscanf(line, "MemTotal: %ld", &st->rt_idle);
626 else if (strstr(line, "MemFree:")) {
627 sscanf(line, "MemFree: %ld", &free);
629 else if (strstr(line, "MemShared:")) {
630 sscanf(line, "MemShared: %ld", &shared);
632 else if (strstr(line, "Buffers:")) {
633 sscanf(line, "Buffers: %ld", &buffers);
635 else if (strstr(line, "Cached:")) {
636 sscanf(line, "Cached: %ld", &cached);
638 else if (strstr(line, "SwapTotal:")) {
639 sscanf(line, "SwapTotal: %ld", &st2->rt_idle);
641 else if (strstr(line, "SwapFree:")) {
642 sscanf(line, "SwapFree: %ld", &swapfree);
646 /* memory use - rt_stat is the amount used, it seems, and this isn't
647 * recorded in current version of /proc/meminfo (as of 2.5.47), so we
648 * calculate it from MemTotal - MemFree
650 st->rt_stat = st->rt_idle - free;
651 st->rt_stat -= buffers+cached;
652 /* As with the amount of memory used, it's not recorded any more, so
653 * we have to calculate it ourselves.
655 st2->rt_stat = st2->rt_idle - swapfree;
658 void update_stat_swp(stat_dev *st) {
660 static char *line = NULL;
661 static size_t line_size = 0;
662 unsigned long swapfree;
664 fseek(fp_meminfo, 0, SEEK_SET);
665 while ((getline(&line, &line_size, fp_meminfo)) > 0) {
666 /* As with update_stat_mem(), the format change to /proc/meminfo has
667 * forced some changes here. */
668 if (strstr(line, "SwapTotal:")) {
669 sscanf(line, "SwapTotal: %ld", &st->rt_idle);
671 else if (strstr(line, "SwapFree:")) {
672 sscanf(line, "SwapFree: %ld", &swapfree);
675 st->rt_stat = st->rt_idle - swapfree;
678 /*******************************************************************************\
679 |* get_statistics *|
680 \*******************************************************************************/
682 void get_statistics(char *devname, long *is, long *ds, long *idle, long *ds2, long *idle2) {
684 int i;
685 static char *line = NULL;
686 static size_t line_size = 0;
687 char *p;
688 char *tokens = " \t\n";
689 float f;
691 *is = 0;
692 *ds = 0;
693 *idle = 0;
695 if (!strncmp(devname, "cpu", 3)) {
696 fseek(fp_stat, 0, SEEK_SET);
697 while ((getline(&line, &line_size, fp_stat)) > 0) {
698 if (strstr(line, "cpu")) {
699 int cpu = -1; /* by default, cumul stats => average */
700 if (!strstr(line, "cpu ")) {
701 sscanf(line, "cpu%d", &cpu);
702 ds2[cpu] = 0;
703 idle2[cpu] = 0;
705 p = strtok(line, tokens);
706 /* 1..3, 4 == idle, we don't want idle! */
707 for (i=0; i<3; i++) {
708 p = strtok(NULL, tokens);
709 if (cpu == -1)
710 *ds += atol(p);
711 else
712 ds2[cpu] += atol(p);
714 p = strtok(NULL, tokens);
715 if (cpu == -1)
716 *idle = atol(p);
717 else
718 idle2[cpu] = atol(p);
721 fp_loadavg = freopen("/proc/loadavg", "r", fp_loadavg);
722 fscanf(fp_loadavg, "%f", &f);
723 *is = (long) (100 * f);
726 if (!strncmp(devname, "i/o", 3)) {
728 fseek(fp_stat, 0, SEEK_SET);
729 while ((getline(&line, &line_size, fp_stat)) > 0) {
730 if (strstr(line, "disk_rio") || strstr(line, "disk_wio")) {
731 p = strtok(line, tokens);
732 /* 1..4 */
733 for (i=0; i<4; i++) {
734 p = strtok(NULL, tokens);
735 *ds += atol(p);
738 else if (strstr(line, "disk_io")) {
739 int val;
740 unsigned int a, b, c, d, e, h, g;
742 p = strtok(line, tokens);
744 while ((p = strtok(NULL, tokens))) {
745 val = sscanf (p,
746 "(%d,%d):(%d,%d,%d,%d,%d)",
747 &a, &b, &c, &d, &e, &h,
748 &g);
750 if (val != 7)
751 continue;
753 *ds += d;
754 *ds += h;
761 /*******************************************************************************\
762 |* getWidth
763 \*******************************************************************************/
765 unsigned long getWidth(long actif, long idle) {
766 unsigned long j;
768 j = (actif + idle);
769 if (j != 0) {
770 j = (actif * 100) / j;
772 j = j * 0.32;
773 if (j > 32) j = 32;
775 return j;
779 /*******************************************************************************\
780 |* getNbCPU *|
781 \*******************************************************************************/
783 int getNbCPU(void) {
784 static char *line = NULL;
785 static size_t line_size = 0;
786 int cpu = 0;
788 fseek(fp_stat, 0, SEEK_SET);
789 while ((getline(&line, &line_size, fp_stat)) > 0) {
790 if (strstr(line, "cpu") && !strstr(line, "cpu "))
791 sscanf(line, "cpu%d", &cpu);
794 return cpu+1;
798 /*******************************************************************************\
799 |* checksysdevs *|
800 \*******************************************************************************/
802 int checksysdevs(void) {
804 strcpy(stat_device[0].name, "cpu0");
805 strcpy(stat_device[1].name, "i/o");
806 strcpy(stat_device[2].name, "sys");
808 return 3;
812 /*******************************************************************************\
813 |* void DrawActive(char *) *|
814 \*******************************************************************************/
816 void DrawActive(char *name) {
818 /* Alles op X,77
819 CPU: 0
820 I/O: 21
822 20 Breed, 10 hoog
823 Destinatie: 5,5
826 if (name[0] == 'c') {
827 copyXPMArea(0, 77, 19, 10, 5, 5);
828 } else if (name[0] == 'i') {
829 copyXPMArea(19, 77, 19, 10, 5, 5);
834 /*******************************************************************************\
835 |* DrawStats *|
836 \*******************************************************************************/
838 void DrawStats(int *his, int num, int size, int x_left, int y_bottom) {
840 int pixels_per_byte;
841 int j,k;
842 int *p;
843 int d;
845 pixels_per_byte = 100;
846 p = his;
847 for (j=0; j<num; j++) {
848 if (p[0] > pixels_per_byte)
849 pixels_per_byte += 100;
850 p += 1;
853 p = his;
855 for (k=0; k<num; k++) {
856 d = (1.0 * p[0] / pixels_per_byte) * size;
858 for (j=0; j<size; j++) {
860 if (j < d - 3)
861 copyXPMArea(2, 88, 1, 1, k+x_left, y_bottom-j);
862 else if (j < d)
863 copyXPMArea(2, 89, 1, 1, k+x_left, y_bottom-j);
864 else
865 copyXPMArea(2, 90, 1, 1, k+x_left, y_bottom-j);
867 p += 1;
870 /* Nu horizontaal op 100/200/300 etc lijntje trekken! */
871 for (j = pixels_per_byte-100; j > 0; j-=100) {
872 for (k=0; k<num; k++) {
873 d = (40.0 / pixels_per_byte) * j;
875 copyXPMArea(2, 91, 1, 1, k+x_left, y_bottom-d);
880 /*******************************************************************************\
881 |* DrawStats_io *|
882 \*******************************************************************************/
884 void DrawStats_io(int *his, int num, int size, int x_left, int y_bottom) {
886 float pixels_per_byte;
887 int j,k;
888 int *p;
889 int d;
891 static int global_io_scale = 1;
893 p = his;
894 for (j=0; j<num; j++) {
895 if (p[j] > global_io_scale) global_io_scale = p[j];
898 pixels_per_byte = 1.0 * global_io_scale / size;
899 if (pixels_per_byte == 0) pixels_per_byte = 1;
901 for (k=0; k<num; k++) {
902 d = (1.0 * p[0] / pixels_per_byte);
904 for (j=0; j<size; j++) {
906 if (j < d - 3)
907 copyXPMArea(2, 88, 1, 1, k+x_left, y_bottom-j);
908 else if (j < d)
909 copyXPMArea(2, 89, 1, 1, k+x_left, y_bottom-j);
910 else
911 copyXPMArea(2, 90, 1, 1, k+x_left, y_bottom-j);
913 p += 1;
918 /*******************************************************************************\
919 |* usage *|
920 \*******************************************************************************/
922 void usage(char *name) {
923 printf("Usage: %s [OPTION]...\n", name);
924 printf("WindowMaker dockapp that displays system information.\n");
925 printf("\n");
926 printf(" -display DISPLAY contact the DISPLAY X server\n");
927 printf(" -geometry GEOMETRY position the clock at GEOMETRY\n");
928 printf(" -l locked view - cannot cycle modes\n");
929 printf(" -c show average and max CPU for SMP machine.\n");
930 printf(" default if there is more than %d processors\n", MAX_CPU);
931 printf(" -i start in Disk I/O mode\n");
932 printf(" -s start in System Info mode\n");
933 printf(" -h display this help and exit\n");
934 printf(" -v output version information and exit\n");
937 /*******************************************************************************\
938 |* printversion *|
939 \*******************************************************************************/
941 void printversion(void) {
943 printf("WMMon version %s\n", WMMON_VERSION);
945 /* vim: sw=4 ts=4 columns=82