1 /* ************************************************************************* *
2 xfsm - (C) Copyright 1993-1999 Robert Gasch (Robert_Gasch@peoplesoft.com)
3 http://www.peoplesoft.com/peoplepages/g/robert_gasch/src/
4
5 Permission to use, copy, modify and distribute this software for any
6 purpose and without fee is hereby granted, provided that this copyright
7 notice appear in all copies as well as supporting documentation. All
8 work developed as a consequence of the use of this program should duly
9 acknowledge such use.
10
11 No representations are made about the suitability of this software for
12 any purpose. This software is provided "as is" without express or implied
13 warranty.
14
15 See the GNU General Public Licence for more information.
16 * ************************************************************************* */
17
18
19
20 /* *************************************************************************
21 This program displays a list of bar graphs for the file systems of the
22 machine you are on. The following switches are supported:
23
24 +rv reverse video (use to override xrdb entry)
25 +synchronous syncronous mode (use to override xrdb entry)
26 -? help
27 -A show available space in MB
28 -a absolute display mode
29 -background <arg> backgound color
30 -b black bars (disable gray fill)
31 -bg <arg> same as -background
32 -bordercolor <arg> border color
33 -borderwidth <arg> border width
34 -d <arg1 ... argn> ignore these file systems
35 -D <arg1 ... argn> ignore file systems matching these patterns
36 -detailgeometry <arg> Geometry of detail window. Only X and Y are
37 honoured
38 -display display
39 -e extend warning to ring bell when at least
40 one file system is above warning level
41 -fg <arg> same as -forground
42 -font <arg> font
43 -foreground <arg> forground color (also file system bar color)
44 -geometry <arg> geometry (will override extreme window sizes to
45 apply reasonable settings)
46 -help help
47 -i <arg> interval at which stats are updated(default=60s)
48 -iconic iconic
49 -it <arg1 ... argn> ignore file systems of this type (*)
50 -m minimize window size
51 -mb draw menu borders
52 -mnl minimize window size so that the longest file
53 system name fits
54 -name <arg> run xfsm under this name
55 -ot <arg> show only file systems of this type (*)
56 -oi override ignore
57 -p don't display percentages
58 -pu popup alarm flag
59 -r display space with respect to root
60 -rootdf show df % values when running in root mode
61 -rs <arg> specify the amount of space reserved for root
62 -rv reverse video
63 -s <arg1 ... argn> show only these file systems
64 -S <arg1 ... argn> select only file systems matching these patterns
65 -sb show biggest file system size in lower right
66 -sort sort file systems according to name
67 -synchronous synchronous mode
68 -title title for main window
69 -v verbose
70 -w <arg> display warning when usage reaches <arg> %
71 -wl0c color for all entries below first warning level
72 -wl1 <arg> threshold for first warning level
73 -wl1c <arg> color for first warning level
74 -wl2 <arg> threshold for second warning level
75 -wl2c <arg> color for second warning level
76 -wl3 <arg> threshold for third warning level
77 -wl3c <arg> color for third warning level
78 -xrm set an entry in the resource database for this
79 execution only
80 help help
81
82
83
84 Version History:
85 24-03-93: 1.00
86 29-03-93: 1.01
87 Added support for gray filling of graphs
88 10-04-93: 1.10
89 Added resize support, detail window title,
90 fixed interval handling in msleep delay loop,
91 added -m, -p and -s option
92 12-04-93: 1.11
93 Fixed resize bug which resulted in graph
94 heights being too small
95 14-04-93: 1.20
96 Fixed percent display placement, added -t flag
97 and toggle handling
98 16-04-93: 1.21
99 Added MB line for detail window
100 18-04-93: 1.22
101 Fixed overflow problem for MB line (detail window)
102 for very large file systems, adapted sleep
103 handling to allow larger scaling of sleep time
104 19-04-93: 1.23
105 Added LINUX ifdefs
106 22-04-93: 1.24
107 Added close on direct mouse button in detail window
108 23-04-93: 1.30
109 Fixed Expose event handling problem which resulted
110 in too may redraws upon resizing, corrected the
111 handling of get_fs_stat, fixed problem where in a
112 small window percentages get overwritten by long
113 file system names and added some cosmetic
114 changes to the code.
115 25-04-93: 1.31
116 Fixed file system truncation for corrent handling
117 of percent option.
118 26-04-93: 1.32
119 Fixed AIX handling, added HPUX #defines and fixed some
120 problems which resulted in warnings and errors on
121 stringent compilers.
122 29-04-93: 1.40
123 Added OSF1, DYNIX, SOLARIS and ULTRIX #ifdefs, fixed
124 expose event handling problems, added warning pixmap
125 and bell options, fixed potential problem for command
126 line options handling for flags which require arguments,
127 added automount handling and -l flag, added window
128 resize code for changing number of FS, changed
129 workings of -d option in conjuction with -l option
130 05-05-93: 1.41
131 Added -v optionm, added -mb option, fixed bugs in
132 autmount resize code.
133 06-05-93: 1.42
134 Moved warning pixmap to right of percent display,
135 made 'q' global quit key, made 'c' close key for
136 detail window , added -D flag
137 19-05-93: 1.43
138 changed structure handling to #defines in main.h to
139 avoid all the porting exceptions messing up the code.
140 22-05-93: 1.50
141 changed popen() to actual system calls (*much* more
142 efficient), removed -l flag made the continoual
143 rechecking default (and only) mode, added device
144 name to detail window, added stat() check for
145 updating mounted FS list.
146 25-05-93: 1.51
147 Added "+" warning to device name string on length
148 overflow
149 01-06-93: 1.52
150 Standardized and fixed -d and -D options, fixed
151 update for OSF1, fixed some *nasty* bugs for AIX
152 02-06-93: 1.53
153 Added check for file system of type ignore,
154 fixed pointer to integer comarisons for strcmp()
155 03-06-93: 1.54
156 Added -mnl flag, fixed some redraw inefficiencies
157 07-06-93: 1.55
158 Fixed bug for -mnl option resizing, added ULTRIX &&
159 DYNIX patches, added strstr for DYNIX
160 10-06-93: 1.56
161 Added dynamic resizing for detail window.
162 10-06-93: 1.60
163 Added XResource handling, colors, fixed core
164 dump for AIX, added missing AIX ifdef, ifndefed
165 caluclations unsuitable for TOS
166 23-07-93: 1.61
167 Changed AIX getfsent to mntctl, fixed some resize
168 problems, extended -geometry option to include size.
169 04-08-93: 1.62
170 Removed f_bavail for HPUX, fix core causing bug in
171 call to fix_fs_win_width(), started wondering about
172 portability of catlist(), removed display of f_favail
173 for AIX, DYNIX and HPUX.
174 13-08-93: 1.63
175 Fixed problem for bar/percentage association when file systems are umounted (this is a rather quick
176 and dirty fix but it should not be a problem even
177 though it requires 2 extra redraws), improved
178 protability for catlist().
179 17-08-93: 1.64
180 Applied some OSF1 patches, fixed resize bug,
181 finally got warning levels correctly working,
182 added automatic disabling of gray fill upon use
183 of -fg, added -rs flag.
184 20-08-93: 1.65
185 fixed initialization of main window size in
186 conjunction with file system of size 0, cleaned
187 up old, outdated code ...
188 06-09-93: 1.66
189 fixed inconsistency with HPUX && SYSV #define,
190 made getBoolResource case insensitive, made
191 detail window resize font independent ...
192 10-09-93: 1.70
193 removed TOS support, added mount type and
194 option info, changed MOUNT_FILE for SOLARIS
195 14-09-93: 1.71
196 added SCO support, cleaned up some more code,
197 accounted for ULTRIX fixed block size (1K)
198 21-09-93: 1.72
199 added -sort option, changed warning levels
200 default to -1, added -fsb option
201 19-10-93: 1.73
202 added indexing scheme to make sort more efficient
203 and flexible, changed some data structures
204 11-02-94: 1.74
205 finished SCO support, added support for multiple
206 block sizes
207 14-02-94: 1.75
208 changed SCO stuff to use popen (), fixed some misspelled
209 OSF1 lables, fixed comparison in write_percent()
210
211 15-02-94: 1.76
212 changed comparison with warn<x>val to fix bug in
213 assigning warning colors, changes SYSV ifdefs back to
214 SVR4 to solve inconsistencies
215
216 17-02-94: 1.77
217 Fixed ULTRIX core dump, added FreeBSD #ifdefs,
218 changed AIX buffer to 128K, added NFS bounds
219 checking for AIX,
220 18-02-94: 1.78
221 changed AIX buffer size to #define BUFFERSIZE, added
222 -it and -ot options, ifndefed some more stuff for SCO
223
224 22-02-94: 1.79
225 added AUX support
226
227 04-03-94: 1.80
228 fixed -mnl option core dump under SunOS and -mnl
229 problems under other machines
230
231 10-03-94: 1.81
232 changed file structure to allow code sharing with
233 xofm
234 04-08-94: 1.82
235 changed Imakefile, APP_DEFAULTS_DIR handling and
236 the format of the call the DefaultDepth which
237 broke some preprocessors.
238 09-09-94: 1.83
239 added check for resrouce file. Xfsm will now look
240 first in XAPPLRESDIR. If that turns up empty, we
241 look in APP_DEFAULTS_DIR (which is the global
242 preferences stuff). Also fixed the problem with
243 system which don't allow the stat() shortcut where
244 file systems of size 0 are reported on each update
245 in verbose mode.
246 21-10-94: 1.84
247 fixed -fb flag message
248 11-11-94: 1.85
249 added SGI ifdefs
250 31-03-95: 1.86
251 Fixed handling of any file system type containing the
252 string "msdos": no reserved space is assumed now,
253 fixed potential core dump when checking non-existant
254 XAPPLRESDIR, reduced SCO detail window size, added
255 -sb flag, fixed unitialized msg in process_databases().
256
257 04-05-95: 1.87
258 Added -A, -s, -S flag, allowed SOLARIS to ignore
259 file systems via MNTOPT_IGNORE/MNTTYPE_IGNORE,
260 fixed slight resource problems, fixed man page.
261 28-03-96: 1.88
262 Changed address to Robert_Gasch@peoplesoft.com,
263 fixed some warnings gcc -Wall showed
264 07-07-96: 1.89
265 Fixed MS-DOS free system calculation, fixed
266 -e flag problems
267 14-10-96: 1.90
268 Changed LINUX default for reserverd space to
269 5% since this is the default for ext2.
270 20-01-97: 1.91
271 Added -wl0c argument to set a color for all file
272 systems below the wl1 warning level, added
273 -title argument which can override hostname in
274 Main window title (useful when monitoring other
275 system's NFS-mounted file systems -- you can put
276 the other host's name in the title bar). Also
277 added a port for DG/UX. (patch supplied by Eric
278 H. Raskin (ehr@internetmci.com))
279 01-02-97: 1.92
280 Added some minor fixes, most noticably whenever
281 you specify a other than -bg the gray fill pattern
282 will be turned off, fixed -w bug.
283 04-02-97: 1.93
284 Added -oi (override ignore) to keep file systems
285 which are marked ignore.
286
287 15-07-97: 1.94
288 Patch to fix minor SGI problem
289 10-08-97: 1.95
290 Not sure anymore, something minor
291 02-12-97: 1.96
292 added BSDI ifdefs
293 12-05-98: 1.97
294 added -rootdf flag, fixed round error for percentace
295 calculation.
296 07-02-98: 1.98
297 fixes for SGI and added -ab (alwaysbeep) flag
298 15-02-98: 1.99
299 added -n32 to SGI flags in Makefile.std
300
301 ************************************************************************* */
302
303
304 #include "xfsm.h"
305
306 Display *mydisplay;
307 char* myname; /* Name we hunt resources with */
308 char* title=NULL; /* Title to put on main window */
309 XrmDatabase resourceDB; /* X resources. */
310 WinType main_win, /* main window */
311 menu[MENU_ITEMS], /* menu items */
312 fs_win[MAXFS], /* FS graphs */
313 detail_win, /* detail window */
314 global_win; /* compatability in util.c */
315 XGCValues gray_gc_val; /* GC values for gray fill */
316 XEvent myevent; /* event */
317 unsigned long fg, bg; /* forgrund, background */
318 unsigned long warncols[4]; /* warning level colors */
319 XSizeHints mainwin_hint, /* main Window size hints */
320 szhint; /* detail Window size hints */
321 Pixmap warn_pix, /* Warning Pixmap */
322 popup_pix; /* Popup Pixmap */
323 int show_use=TRUE, /* do we show user or root */
324 upd_interval=60, /* when do we update stats */
325 NFS=0, /* number of file systems */
326 detail_open=NOGOOD, /* which detail_wind is open */
327 detail_share_color = FALSE, /* */
328 minimize=FALSE, /* minimize dimensions */
329 menu_border=FALSE, /* menu border */
330 fs_border=1, /* file system border */
331 percent=TRUE, /* show percent */
332 absolute=FALSE, /* make bar size relative */
333 available=FALSE, /* show available MB */
334 bell=FALSE, /* ring bell for warning */
335 alwaysbeep=FALSE, /* aways ring bell (or just first time) */
336 popup=FALSE, /* activate popup */
337 fs_level[MAXFS], /* warn level for FS */
338 fs_warn[MAXFS], /* warn this time? (per FS) */
339 fs_bell[MAXFS], /* sound bell this time? (per FS) */
340 verbose=FALSE, /* verbose mode */
341 sort=FALSE, /* do we sort by name? */
342 gray, /* use gray fill */
343 override_ignore, /* do we keep FSs marked ignore? */
344 rootdf=FALSE, /* show df % output when running in root mode */
345 idx[MAXFS], /* index to use when sorting */
346 show_blocks, /* compatability in util.c */
347 show_biggest=FALSE, /* show biggest size */
348 #ifdef SCO
349 root=TRUE; /* root or non-root */
350 #else
351 root=FALSE; /* root or non-root */
352 #endif /* SCO */
353 double b_blocks=0, /* biggest # of blocks */
354 b_bsize=0, /* biggest block size */
355 b_bytes, /*for compatability in util.c */
356 o_b_blocks, /* old biggest blocks */
357 o_b_bsize, /* old biggest block size */
358 o_b_bytes, /*for compatability in util.c */
359 b_disk, /* biggest disk */
360 o_b_disk; /* old biggest disk */
361 unsigned long turns=0; /* how many turns */
362 float fs_perc[MAXFS], /* percentage for FS */
363 res_space, /* % space reserved for root */
364 warnvals[4], /* warn val level 3 */
365 warn_val=0; /* waring threshold used
366 for "!" after FS name */
367 StringInfo strinfo[MAXFS]; /* all system static strings */
368 MyString hname; /* hostname */
369 struct statfs stats[MAXFS]; /* FS stats structure */
370
371
372 /* *** get the gray bitmap and define our warning bitmap *** */
373 #include <X11/bitmaps/gray1>
374 static char warn_bits[] = {
375 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x00, 0x06, 0x06};
376
377 static char popup_bits[] = {
378 0x18, 0x18, 0x18, 0x18, 0xFF, 0xFF, 0x18, 0x18, 0x18, 0x18};
379
380 static XrmOptionDescRec opTable[] = {
381 /* KEEP THIS SORTED BY THE FIRST ARGUMENT! */
382 /* the char * should be XPointer but many systems don't support it */
383 {"+rv", "*reverseVideo", XrmoptionNoArg, (char *) "off"},
384 {"+synchronous","*synchronous", XrmoptionNoArg, (char *) "off"},
385 {"-?", ".help", XrmoptionNoArg, (char *) "on"},
386 {"-A", ".available", XrmoptionNoArg, (char *) "on"},
387 {"-a", ".absolute", XrmoptionNoArg, (char *) "on"},
388 {"-ab", ".alwaysbeep", XrmoptionNoArg, (char *) "off"},
389 {"-background", "*background", XrmoptionSepArg, (char *) NULL},
390 {"-b", ".gray", XrmoptionNoArg, (char *) "off"},
391 {"-bg", "*background", XrmoptionSepArg, (char *) NULL},
392 {"-bordercolor","*borderColor", XrmoptionSepArg, (char *) NULL},
393 {"-borderwidth",".borderWidth", XrmoptionSepArg, (char *) NULL},
394 {"-detailgeometry", "*detailWin.geometry", XrmoptionSepArg, (char *) NULL},
395 {"-display", ".display", XrmoptionSepArg, (char *) NULL},
396 {"-e", ".bell", XrmoptionNoArg, (char *) "on"},
397 {"-f", ".used", XrmoptionNoArg, (char *) "off"},
398 {"-fg", "*foreground", XrmoptionSepArg, (char *) NULL},
399 {"-font", "*font", XrmoptionSepArg, (char *) NULL},
400 {"-foreground", "*foreground", XrmoptionSepArg, (char *) NULL},
401 {"-fsb", ".fs_border", XrmoptionNoArg, (char *) "off"},
402 {"-geometry", "*mainWin.geometry", XrmoptionSepArg,(char *) NULL},
403 {"-help", ".help", XrmoptionNoArg, (char *) "on"},
404 {"-i", ".updInterval", XrmoptionSepArg, (char *) NULL},
405 {"-iconic", ".iconic", XrmoptionNoArg, (char *) "on"},
406 {"-m", ".minimize", XrmoptionNoArg, (char *) "1"},
407 {"-mb", ".menuborder", XrmoptionNoArg, (char *) "on"},
408 {"-mnl", ".minimize", XrmoptionNoArg, (char *) "2"},
409 {"-name", ".name", XrmoptionSepArg, (char *) NULL},
410 {"-oi", ".override_ignore",XrmoptionNoArg, (char *) "on"},
411 {"-p", ".percent", XrmoptionNoArg, (char *) "off"},
412 {"-pu", ".popup", XrmoptionNoArg, (char *) "on"},
413 #ifndef SCO
414 {"-r", ".root", XrmoptionNoArg, (char *) "on"},
415 {"-rootdf", ".rootdf", XrmoptionNoArg, (char *) "on"},
416 #endif
417 {"-rs", ".reserved_space",XrmoptionSepArg, (char *) "NULL"},
418 {"-rv", "*reverseVideo", XrmoptionNoArg, (char *) "on"},
419 {"-sb", ".showbiggest" , XrmoptionNoArg, (char *) "on"},
420 {"-sort", ".sort", XrmoptionNoArg, (char *) "on"},
421 {"-synchronous","*synchronous", XrmoptionNoArg, (char *) "on"},
422 {"-title", ".title", XrmoptionSepArg, (char *) NULL},
423 {"-v", ".verbose", XrmoptionNoArg, (char *) "on"},
424 {"-w", ".warnval", XrmoptionSepArg, (char *) NULL},
425 {"-wl0c", ".warn0col", XrmoptionSepArg, (char *) NULL},
426 {"-wl1", ".warn1val", XrmoptionSepArg, (char *) NULL},
427 {"-wl1c", ".warn1col", XrmoptionSepArg, (char *) NULL},
428 {"-wl2", ".warn2val", XrmoptionSepArg, (char *) NULL},
429 {"-wl2c", ".warn2col", XrmoptionSepArg, (char *) NULL},
430 {"-wl3", ".warn3val", XrmoptionSepArg, (char *) NULL},
431 {"-wl3c", ".warn3col", XrmoptionSepArg, (char *) NULL},
432 {"-xrm", NULL, XrmoptionResArg, (char *) NULL},
433 {"help", ".help", XrmoptionNoArg, (char *) "on"},
434 };
435
436
main(argc,argv)437 int main (argc, argv)
438 int argc;
439 char **argv;
440 {
441 int i=0;
442 XrmDatabase commandlineDB=NULL;
443 char* myDisplayName = NULL;
444 XrmString str_type;
445 XrmValue value;
446
447 /* *** Try and work out the name the application will run under *** */
448 /* *** This needed for finding the correct resources. *** */
449 {
450 char** ptr = &argv[1];
451
452 for (; *ptr != NULL; ptr++)
453 if (strcmp(*ptr, "-name") == 0 && *(ptr + 1) != NULL)
454 {
455 myname = *(ptr + 1);
456 break;
457 }
458
459 if (*ptr == NULL)
460 {
461 char* ptr1 = rindex(argv[0], '/');
462 if (ptr1)
463 myname = ++ptr1;
464 else
465 myname = argv[0];
466 }
467 }
468
469 XrmInitialize();
470 XrmParseCommand(&commandlineDB, opTable,
471 sizeof(opTable) / sizeof(opTable[0]), myname, &argc, argv);
472 if (XrmGetResource(commandlineDB,
473 catlist(myname, ".name", (char*) NULL), "Xfsm.Name",
474 &str_type, &value))
475 myname = value.addr;
476
477 if (XrmGetResource(commandlineDB,
478 catlist(myname, ".title", (char*) NULL), "Xfsm.Title",
479 &str_type, &value))
480 title = value.addr;
481
482 if (XrmGetResource(commandlineDB,
483 catlist(myname, ".display", (char*) NULL), "Xfsm.Display",
484 &str_type, &value))
485 myDisplayName = value.addr;
486
487 /* *** connect to X Server and assign screen *** */
488 if ((mydisplay = XOpenDisplay(myDisplayName)) == NULL)
489 {
490 fprintf (stderr, "Error Opening Display ... Exiting\n");
491 exit (1);
492 }
493
494 /* *** process arguments and the resource database *** */
495 process_databases (argc, argv, commandlineDB);
496
497 /* *** Turn on X server synchronization if the user wants it. *** */
498 XSynchronize(mydisplay, getBoolResource(resourceDB,
499 catlist(myname, ".synchronous", (char*) NULL),
500 "Xfsm.Synchronous", False));
501
502 /* *** get hostname *** */
503 if (!(gethostname (hname, STRLENGTH)))
504 {
505 if (verbose)
506 printf ("Hostname = %s\n", hname);
507 }
508 else
509 fprintf (stderr, "Can't read hostname ...\n");
510
511 /* *** initialize index *** */
512 for (i=0; i<MAXFS; i++)
513 {
514 idx[i]=i;
515 fs_level[i]=0;
516 fs_bell[i]=0;
517 fs_warn[i]=FALSE;
518 }
519
520 /* *** get the file system statistics *** */
521 /* *** this also handles getting the *** */
522 /* *** info from mount *** */
523 if (minimize == MNL)
524 main_win.font_info = getFontResource (resourceDB,
525 catlist(myname, ".mainWin.font", (char*) NULL),
526 "Xfsm.MainWin.Font",
527 XLoadQueryFont(mydisplay, DEFAULT_FONT));
528 get_fs_stat();
529 if (verbose)
530 {
531 for (i = 0; i < NFS; i++)
532 printf ("%s\n", FsName);
533 printf ("%d valid file systems found ...\n", NFS);
534 }
535
536 init_all_windows();
537
538 /* *** Check to see of the user wants the colors reversed. *** */
539 if (getBoolResource(resourceDB,
540 catlist(myname, ".reverseVideo", (char*) NULL),
541 "Xfsm.ReverseVideo", False))
542 {
543 long temp;
544 temp = fg;
545 fg = bg ;
546 bg = temp;
547 }
548
549 /* *** create Main Program Window and set up the properties. *** */
550 {
551 XClassHint clshint;
552 XWMHints wmhints;
553
554 mainwin_hint.min_width = MIN_WIN_X;
555 mainwin_hint.min_height = ((MIN_INTERVAL(main_win) * NFS) +
556 BEGIN_NFS(main_win));
557 mainwin_hint.width = main_win.width;
558 mainwin_hint.height = main_win.height;
559 mainwin_hint.x = main_win.x;
560 mainwin_hint.y = main_win.y;
561 mainwin_hint.flags = main_win.flags | PMinSize | PSize;
562
563 clshint.res_name = myname;
564 clshint.res_class = CLASS_NAME;
565
566 wmhints.input = True;
567 wmhints.initial_state = (getBoolResource(resourceDB,
568 catlist(myname, ".iconic", (char*) NULL),
569 "Xfsm.Iconic", False))
570 ? IconicState : NormalState;
571 wmhints.window_group = main_win.win;
572 wmhints.flags = InputHint | StateHint | WindowGroupHint;
573
574 create_window (DefaultRootWindow(mydisplay), &main_win, fg, bg);
575 XSetStandardProperties (mydisplay, main_win.win, main_win.text,
576 main_win.text, None, argv, argc, &mainwin_hint);
577 XSetClassHint(mydisplay, main_win.win, &clshint);
578 XSetWMHints(mydisplay, main_win.win, &wmhints);
579 }
580
581 /* ** Create the pixmap of the gray background. ** */
582 gray_gc_val.stipple = XCreatePixmapFromBitmapData(mydisplay,
583 DefaultRootWindow(mydisplay), gray1_bits, gray1_width,
584 gray1_height, fg, bg, 1);
585
586 if (!gray_gc_val.stipple)
587 {
588 fprintf (stderr,
589 "Couldn't create gray tile ... escaping to black fill.\n");
590 gray = FALSE;
591 }
592 else
593 gray_gc_val.fill_style = FillOpaqueStippled;
594
595 /* *** create all the buttons using child windows *** */
596 for (i = 0; i < MENU_ITEMS ; ++i)
597 create_window (main_win.win, &menu[i], fg, bg);
598 for (i = 0; i < NFS; i++)
599 {
600 fix_fs_win_width(i);
601 create_window (main_win.win, &fs_win[i],
602 getColorResource(resourceDB,
603 catlist(myname, ".", FsName,
604 ".foreground", (char*)NULL),
605 "Xfsm.FileSystem.Foreground", fg),
606 getColorResource(resourceDB,
607 catlist(myname, ".", FsName,
608 ".background", (char*)NULL),
609 "Xfsm.FileSystem.Background", bg));
610
611 if (gray)
612 XChangeGC (mydisplay, fs_win[i].gc, GCFillStyle | GCStipple,
613 &gray_gc_val);
614 }
615
616 /* *** create warning pixmap *** */
617 if (!(warn_pix = XCreatePixmapFromBitmapData (mydisplay, main_win.win,
618 warn_bits, warn_width, warn_height, fg, bg,
619 DefaultDepth (mydisplay, DefaultScreen (mydisplay)))))
620 {
621 fprintf (stderr,
622 "Couldn't create Warning pixmap ... \
623 ignoring specified threshold.\n");
624 warn_val = FALSE;
625 }
626
627 /* *** create popup pixmap *** */
628 if (!(popup_pix = XCreatePixmapFromBitmapData (mydisplay, main_win.win,
629 popup_bits, popup_width, popup_height, fg, bg,
630 DefaultDepth (mydisplay, DefaultScreen (mydisplay)))))
631 {
632 fprintf (stderr,
633 "Couldn't create Popup pixmap ... \
634 ignoring Popup request.\n");
635 popup = FALSE;
636 }
637
638 /* *** Map window definitions onto screen *** */
639 XMapSubwindows (mydisplay, main_win.win);
640 XMapRaised (mydisplay, main_win.win);
641
642 if (popup)
643 redraw_main_win();
644
645 #ifdef DEBUG
646 fprintf (stdout, "Setup is Done!\n");
647 #endif
648
649 /* ************************************************************ */
650 /* ************** setup is done - main event loop ************* */
651 /* ************************************************************ */
652
653 do_event_loop (argc, argv);
654
655 /* *** we are done - destroy all the windows *** */
656 if (detail_open != NOGOOD)
657 {
658 XFreeGC (mydisplay, detail_win.gc);
659 XDestroyWindow (mydisplay, detail_win.win);
660 }
661
662 destroy_menu (menu, MENU_ITEMS);
663 destroy_menu (fs_win, NFS);
664 XFreeGC (mydisplay, main_win.gc);
665 XDestroyWindow (mydisplay, main_win.win);
666 XCloseDisplay (mydisplay);
667 exit (0);
668 }
669
670
671
672 /* *** This is the main event loop. Here we handle events and deal *** */
673 /* *** with all the user inputs we get *** */
do_event_loop(argc,argv)674 void do_event_loop (argc, argv)
675 int argc;
676 char **argv;
677 {
678 XEvent tevent;
679 int count, cont, this_item, i, ppnfs, OFS, done=FALSE;
680 long target = time(NULL) + upd_interval;
681 char text[10];
682
683 while (!done)
684 {
685 /* *** here we wait while there are no events *** */
686 /* *** and count out down our interval. *** */
687 while (XPending (mydisplay) == 0)
688 {
689 struct timeval sleept;
690 fd_set reads;
691
692 FD_ZERO(&reads);
693 FD_SET(ConnectionNumber(mydisplay), &reads);
694 sleept.tv_sec = target - time(NULL);
695 sleept.tv_usec = 0;
696 #ifdef HPUX
697 select(ConnectionNumber(mydisplay) + 1, (int *) &reads, NULL,
698 NULL, &sleept);
699 #else
700 select(ConnectionNumber(mydisplay) + 1, &reads, NULL, NULL,
701 &sleept);
702 #endif
703
704 if ((time(NULL)) >= target)
705 {
706 OFS = NFS;
707 o_b_blocks = b_blocks;
708 o_b_bsize = b_bsize;
709 o_b_disk = b_disk;
710 ppnfs = ((main_win.height - BEGIN_NFS(main_win)) / NFS);
711 get_fs_stat ();
712 /* XClearWindow (mydisplay, main_win.win); */
713 main_win.height = (BEGIN_NFS(main_win) + (ppnfs * NFS));
714 handle_NFS_change (ppnfs, OFS);
715 if (detail_open != NOGOOD)
716 write_detail (detail_open);
717 target = target + upd_interval;
718 }
719 }
720
721 /* *** read the next event *** */
722 XNextEvent (mydisplay, &myevent);
723
724 switch (myevent.type)
725 {
726 /* *** expose event -> redraw the window *** */
727 case Expose:
728 /* ********************************************* *
729 * since a window can generate multiple expose *
730 * events we can collapse these into one redraw *
731 * ********************************************* */
732 count=0;
733 do
734 {
735 if (XPending (mydisplay) == 0)
736 break;
737 XPeekEvent (mydisplay, &tevent);
738 if (tevent.xexpose.window == myevent.xexpose.window)
739 {
740 XNextEvent (mydisplay, &myevent);
741 count++;
742 }
743 }
744 while(tevent.xexpose.window==myevent.xexpose.window);
745
746 #ifdef DEBUG
747 if (!count)
748 fprintf(stdout, "got expose event in window: %d\n",
749 myevent.xexpose.window);
750 else
751 fprintf(stdout,
752 "Compressed %d expose events into 1 in window: %d\n",
753 count, myevent.xexpose.window);
754 #endif
755
756 /* ******************************************* *
757 * ** now deal with the actual expose event ** *
758 * ******************************************* */
759 if (myevent.xexpose.window == main_win.win &&
760 myevent.xexpose.count == 0)
761 {
762 redraw_main_win ();
763 break;
764 }
765 else
766 if (myevent.xexpose.window == detail_win.win)
767 write_detail (detail_open);
768
769 cont = TRUE;
770 cont = expose_win (menu, MENU_ITEMS);
771 if (!cont) break;
772 for (i = 0; i < NFS; i++)
773 if (myevent.xexpose.window == fs_win[i].win)
774 {
775 redraw_fs_win (i);
776 i = NFS;
777 }
778 break;
779
780 /* *** change work window if main window changes *** */
781 case ConfigureNotify:
782 #ifdef DEBUG
783 fprintf(stdout, "got configure notify event in window: %d\n",
784 myevent.xconfigure.window);
785 #endif
786 /* *** we don't allow changes in the detail window *** */
787 if (myevent.xconfigure.window != main_win.win)
788 break;
789
790 /* *** size stays the same -> nothing to do *** */
791 if (myevent.xconfigure.width == main_win.width &&
792 myevent.xconfigure.height == main_win.height)
793 break;
794
795 /* *** figure out how many points per nfs we have *** */
796 ppnfs = ((myevent.xconfigure.height -
797 BEGIN_NFS(main_win)) / NFS);
798 #ifdef DEBUG
799 fprintf (stdout,
800 "got resize event - new interval = %d\nwidth = %d height = %d\n",
801 ppnfs, myevent.xconfigure.width, myevent.xconfigure.height);
802 #endif
803
804 XClearWindow (mydisplay, main_win.win);
805 main_win.width = myevent.xconfigure.width;
806 main_win.height = myevent.xconfigure.height;
807 XResizeWindow (mydisplay, main_win.win, main_win.width,
808 main_win.height);
809 redraw_main_win ();
810 fix_menu_pos (myevent.xconfigure.width);
811
812 for (i = 0; i < NFS; i++)
813 {
814 set_fs_win_size (i, ppnfs);
815 XClearWindow (mydisplay, fs_win[i].win);
816 XMoveResizeWindow (mydisplay, fs_win[i].win, OFF_X,
817 fs_win[i].y, fs_win[i].width, fs_win[i].height);
818 /* XClearWindow (mydisplay, main_win.win); */
819 if (fs_perc[i] != NOGOOD)
820 redraw_fs_win (i);
821 }
822
823 XClearWindow (mydisplay, main_win.win);
824 break;
825
826 /* *** process keyboard mapping changes *** */
827 case MappingNotify:
828 #ifdef DEBUG
829 fprintf(stdout, "got mapping notify event in window: %d\n",
830 myevent.xexpose.window);
831 #endif
832
833 XRefreshKeyboardMapping ((XMappingEvent *) &myevent );
834 break;
835
836 /* *** drag in work window *** */
837 case MotionNotify:
838 #ifdef DEBUG
839 fprintf(stdout, "got motion notify event in window: %d\n",
840 myevent.xbutton.window);
841 #endif
842 break;
843
844 /* *** mouse enters a window *** */
845 case EnterNotify:
846 this_item = highlight_menu (menu, MENU_ITEMS, TRUE);
847 break;
848
849 /* *** Mouse Leaves a window *** */
850 case LeaveNotify:
851 this_item = highlight_menu (menu, MENU_ITEMS, FALSE);
852 break;
853
854 /* *** process mouse-button presses *** */
855 case ButtonPress:
856 #ifdef DEBUG
857 fprintf(stdout, "button press (%d) in window: %d\n",
858 myevent.xbutton.button, myevent.xbutton.window);
859 #endif
860
861 if (myevent.xbutton.button == 1 || myevent.xbutton.button == 2)
862 {
863 this_item = which_button_pressed (menu, MENU_ITEMS);
864
865 if (this_item == UPDATE)
866 {
867 clear_fs_warn_flags();
868 OFS = NFS;
869 o_b_blocks = b_blocks;
870 o_b_bsize = b_bsize;
871 o_b_disk = b_disk;
872 ppnfs = ((main_win.height - BEGIN_NFS(main_win)) / NFS);
873 get_fs_stat ();
874 main_win.height = (BEGIN_NFS(main_win) + (ppnfs * NFS));
875 handle_NFS_change (ppnfs, OFS);
876 if (detail_open != NOGOOD)
877 write_detail (detail_open);
878 redraw_main_win ();
879 target = time(NULL) + upd_interval;
880 break;
881 }
882 else if (this_item == QUIT)
883 {
884 done = TRUE;
885 break;
886 }
887
888 /* *** see if btnpress was in detail window *** */
889 if (myevent.xbutton.window == detail_win.win)
890 {
891 XFreeGC (mydisplay, detail_win.gc);
892 XDestroyWindow (mydisplay, detail_win.win);
893 detail_open = NOGOOD;
894 break;
895 }
896
897 /* *** see if btnpress was in a graph window *** */
898 this_item = which_button_pressed (fs_win, NFS);
899 if (this_item == NOGOOD)
900 break;
901
902 /* *** open a detail window *** */
903 if (detail_open == NOGOOD)
904 {
905 open_detail_win (argc, argv);
906 detail_open = this_item;
907 if (detail_share_color)
908 {
909 XSetBackground (mydisplay, detail_win.gc,
910 fs_win[this_item].bg);
911 XSetForeground (mydisplay, detail_win.gc,
912 fs_win[this_item].fg);
913 XSetWindowBackground(mydisplay, detail_win.win,
914 fs_win[this_item].bg);
915 }
916 }
917
918 /* *** det_win for this graph open - close it *** */
919 else
920 if (detail_open == this_item)
921 {
922 XFreeGC (mydisplay, detail_win.gc);
923 XDestroyWindow (mydisplay, detail_win.win);
924 detail_open = NOGOOD;
925 }
926 else
927 {
928 if (detail_share_color)
929 {
930 XSetBackground (mydisplay, detail_win.gc,
931 fs_win[this_item].bg);
932 XSetForeground (mydisplay, detail_win.gc,
933 fs_win[this_item].fg);
934 XSetWindowBackground(mydisplay, detail_win.win,
935 fs_win[this_item].bg);
936 }
937 detail_open = this_item;
938 write_detail (this_item);
939 }
940 }
941 /* *** Button 3 pressed *** */
942 else
943 toggle_mode();
944 break;
945
946 /* *** process mouse-button release *** */
947 case ButtonRelease:
948 #ifdef DEBUG
949 fprintf(stdout, "button release in window: %d\n",
950 myevent.xbutton.window);
951 #endif
952 break;
953
954 /* *** process Resize *** */
955 case ResizeRequest:
956 #ifdef DEBUG
957 fprintf (stdout, "got resize event \n");
958 #endif
959 break;
960
961 /* *** process keyboard input *** */
962 case KeyPress:
963 #ifdef DEBUG
964 fprintf (stdout, "got keypress event in window: %d\n",
965 myevent.xkey.window);
966 #endif
967 i = XLookupString ((XKeyEvent *)&myevent, text, 10, NULL, 0 );
968
969 if (text[0] == UPDATE_KEY)
970 {
971 clear_fs_warn_flags();
972 OFS = NFS;
973 o_b_blocks = b_blocks;
974 o_b_bsize = o_b_bsize;
975 o_b_disk = b_disk;
976 ppnfs = ((main_win.height - BEGIN_NFS(main_win)) / NFS);
977 get_fs_stat ();
978 main_win.height = (BEGIN_NFS(main_win) + (ppnfs * NFS));
979 handle_NFS_change (ppnfs, OFS);
980 if (detail_open != NOGOOD)
981 write_detail (detail_open);
982 redraw_main_win ();
983 target = time(NULL) + upd_interval;
984 break;
985 }
986 else
987 if (text[0] == QUIT_KEY)
988 {
989 done = TRUE;
990 break;
991 }
992 else
993 if (text[0] == CLOSE_KEY)
994 {
995 if (detail_open != NOGOOD)
996 {
997 XFreeGC (mydisplay, detail_win.gc);
998 XDestroyWindow (mydisplay, detail_win.win);
999 detail_open = NOGOOD;
1000 break;
1001 }
1002 }
1003 else
1004 if (text[0] == TOGGLE_KEY)
1005 {
1006 toggle_mode ();
1007 break;
1008 }
1009 break;
1010 } /* switch (myevent.type) */
1011 } /* while (done == 0) */
1012 }
1013