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 #include "xfsm.h"
20 
21 #ifdef ULTRIX
22 /* *** This defines the gt_names string which means that we have to *** */
23 /* ***        include it here to avoid multiple definitions         *** */
24 #include <sys/fs_types.h>
25 #endif
26 
27 
28 extern Display			*mydisplay;
29 extern char*			myname;
30 extern char*			title;
31 extern XrmDatabase		resourceDB;
32 extern WinType			main_win,
33 				menu[MENU_ITEMS],
34 				fs_win[MAXFS],
35 				detail_win;
36 extern XGCValues		gray_gc_val;
37 extern XEvent			myevent;
38 extern unsigned long		fg, bg,
39 				warncols[];
40 extern XWindowAttributes  	attribs;
41 extern XSizeHints		mainwin_hint,
42 				szhint;
43 extern Pixmap			warn_pix,
44 				popup_pix;
45 extern int 			show_use,
46 				upd_interval,
47 				NFS,
48 				detail_open,
49 				detail_share_color,
50 				minimize,
51 				menu_border,
52 				show_biggest,
53 				fs_border,
54 				percent,
55 				absolute,
56 				available,
57 				bell,
58 				alwaysbeep,
59 				popup,
60 				fs_level[],
61 				fs_warn[],
62 				fs_bell[],
63 				verbose,
64 				gray,
65 				idx[],		/* for compatability - xfsm */
66 				root,		/* for compatability - xfsm */
67 				show_blocks;	/* for compatability - xofm */
68 extern double			b_blocks,
69 				b_bytes,
70 				b_disk,
71 				b_bsize,
72 				o_b_blocks,
73 				o_b_bsize,
74 				o_b_bytes,
75 				o_b_disk;
76 extern unsigned long		turns;
77 extern float			fs_perc[],
78 				res_space,
79 				warnvals[],
80 				warn_val;
81 extern MyString			hname;
82 #ifdef XOFM
83 extern Stats 			stats[];
84 #else /* xfsm */
85 extern struct statfs		stats[];
86 extern StringInfo		strinfo[];
87 #endif
88 
89 
90 
91 
92 /* *** variables accessed only in util.c - make them static to make sure *** */
93 static char 	*Menu_Text[MENU_ITEMS]={
94 			" Update Now ",
95 			"    Quit    "};
96 
97 static int	percent_width,
98 		lname;
99 
100 
101 
102 
103 /* ************************************************************************ */
104 /* **** Here we adjust the main window if we add or loose an automount **** */
105 /* ****** file system. We also create or destroy any fs_win we need ******* */
106 /* ************************************************************************ */
handle_NFS_change(ppnfs,OFS)107 void handle_NFS_change (ppnfs, OFS)
108 int ppnfs, OFS;
109 {
110 	int i;
111 
112 	/* *** add a file system *** */
113 	if (NFS > OFS)
114 		for (i = OFS; i < NFS; i++)
115 			{
116 			set_fs_win_size (i, ppnfs);
117 			create_window (main_win.win, &fs_win[i],
118 				getColorResource(resourceDB,
119 				catlist(myname, ".", FsName,
120 				".foreground", (char*)NULL),
121 				"Xfsm.FileSystem.Foreground",
122 				fg), getColorResource ( resourceDB,
123 				catlist(myname, ".", FsName,
124 				".background", (char*)NULL),
125 				"Xfsm.FileSystem.Background",bg));
126 
127 			if (gray)
128 				XChangeGC (mydisplay, fs_win[i].gc,
129 					GCFillStyle | GCStipple, &gray_gc_val);
130 
131 			XMapRaised (mydisplay, fs_win[i].win);
132 #ifdef DEBUG
133 			printf("LEVEL: clearing level info for new FS %d\n",i);
134 #endif
135 			fs_level[i] = 0;
136 			fs_bell[i] = 0;
137 			fs_warn[i] = FALSE;
138 			}
139 
140 	/* *** remove a file system *** */
141 	else
142 	if (NFS < OFS)
143 		for (i = NFS; i < OFS; i++)
144 			{
145 			XFreeGC (mydisplay, fs_win[i].gc);
146 			XDestroyWindow (mydisplay, fs_win[i].win);
147 			fs_level[i] = 0;
148 			fs_bell[i] = 0;
149 			fs_warn[i] = FALSE;
150 			}
151 
152 	/* *** did the number of file systems change *** */
153 	if (NFS != OFS)
154 		{
155 		/* *** quick and dirty fix to force redisplaying *** */
156 		/* *** of bars which may otherwise be associated *** */
157 		/* *** with the wrong file system. On a decent   *** */
158 		/* *** machine this should be barley noticabel   *** */
159 		toggle_mode ();
160 		toggle_mode ();
161 		XResizeWindow (mydisplay, main_win.win, main_win.width,
162 			main_win.height);
163 		mainwin_hint.min_height = ((MIN_INTERVAL(main_win) * NFS) +
164 			BEGIN_NFS(main_win));
165 		XSetNormalHints (mydisplay, main_win.win, &mainwin_hint);
166 		}
167 
168 	/* *** check if the biggest file system changed *** */
169 	if (HAS_BIGGEST_CHANGED)
170 		for (i = 0; i < NFS; i++)
171 			{
172 			set_fs_win_size (i, ppnfs);
173 			XResizeWindow (mydisplay, fs_win[i].win,
174 				fs_win[i].width, fs_win[i].height);
175 			XClearWindow (mydisplay, fs_win[i].win);
176 			redraw_fs_win (i);
177 			}
178 
179 	redraw_main_win ();
180 	for (i = 0; i < NFS; i++)
181 		redraw_fs_win (i);
182 }
183 
184 
185 
186 /* ************************************************************************ */
187 /* ************************ set the menu's position *********************** */
188 /* ************************************************************************ */
fix_menu_pos(width)189 void fix_menu_pos (width)
190 int width;
191 {
192 	int i;
193 
194 	for (i=0; i<MENU_ITEMS; i++)
195 		{
196 		menu[i].x = ((width - SM_MENU_WIDTH(menu[i])) / 2);
197 		if (turns)
198 			XMoveWindow (mydisplay,menu[i].win,menu[i].x,menu[i].y);
199 		}
200 }
201 
202 
203 
204 /* ************************************************************************ */
205 /* ******************* this sets the window's dimensions ****************** */
206 /* ************************************************************************ */
set_fs_win_size(i,ppnfs)207 void set_fs_win_size (i, ppnfs)
208 int i, ppnfs;
209 {
210 	fs_win[i].x = OFF_X;
211 	fs_win[i].y = (BEGIN_NFS(fs_win[i]) + (ppnfs * i));
212 	fs_win[i].width = main_win.width - OFF_X * 2;
213 	if (turns)
214 		fix_fs_win_width (i);
215  	fs_win[i].height = ppnfs - LETTER_SPACE(fs_win[i]);
216 
217 #ifdef DEBUG
218   printf ("%d %d %d %d\n", fs_win[i].x, fs_win[i].y, fs_win[i].width,
219 	  fs_win[i].height);
220 #endif
221 }
222 
223 
224 
225 /* *********************************************************************** */
226 /* ********* toggle the display mode and update the windows ************** */
227 /* *********************************************************************** */
toggle_mode()228 void toggle_mode ()
229 {
230 	int i;
231 
232 	if (absolute)
233 		absolute=FALSE;
234 	else
235 		absolute=TRUE;
236 	for (i=0; i<NFS; i++)
237 		{
238 		fs_win[i].width=main_win.width-OFF_X*2;
239 		if (!absolute)
240 			fix_fs_win_width (i);
241 		XResizeWindow (mydisplay,fs_win[i].win, fs_win[i].width,
242 			fs_win[i].height);
243 		redraw_fs_win (i);
244 		}
245 
246 }
247 
248 
249 
250 /* *********************************************************************** */
251 /* *********************** redraw the main window ************************ */
252 /* *********************************************************************** */
redraw_main_win()253 void redraw_main_win ()
254 {
255 	int 		i, should_bell = FALSE, posx, posy;
256 	int		should_raise=FALSE;
257 	int 		text_width = main_win.width-(OFF_X+OFF_X+
258 				percent_width*(percent|available));
259 	char		s[10];
260 	unsigned long	color;
261 
262 	if (show_biggest)
263 		{
264 		if (b_disk > GB)
265 			sprintf (s, "%.1fGB ", b_disk/GB);
266 		else
267 			sprintf (s, "%.1fMB ", b_disk/MB);
268 		posx = main_win.width-XTextWidth(main_win.font_info,
269 			s, strlen (s));
270 		posy = main_win.height-MENU_HEIGHT(menu[0]);
271 		XDrawImageString (mydisplay, main_win.win, main_win.gc,
272 			posx, posy, s, strlen (s));
273 		}
274 	for (i = 0; i < NFS; i++)
275 		{
276 		if (minimize == MNL)
277 			XDrawImageString (mydisplay, main_win.win, main_win.gc,
278 				OFF_X+2, fs_win[i].y-2, FsName,
279 				strlen(FsName));
280 		else
281 			{
282 			int n = strlen(FsName);
283 
284 			/* *** find how much of the name we can write *** */
285 			while (XTextWidth(main_win.font_info, FsName, n) >
286 				text_width)
287 					n--;
288 			XDrawImageString (mydisplay, main_win.win,
289 				main_win.gc, OFF_X + 2,
290 				fs_win[i].y - 2, FsName, n);
291 			}
292 
293 		/* *** handle the exclamation mark after the FS name *** */
294 		if (warn_val > 0)
295 			{
296 			if (fs_perc[i] >= warn_val)
297 				{
298 				if (bell && !fs_bell[i])
299 					{
300 					should_bell=TRUE;
301 					if (!alwaysbeep)
302 						fs_bell[i] = 1;
303 					}
304 				XCopyArea (mydisplay, warn_pix, main_win.win,
305 					main_win.gc, 0, 0, warn_width,
306 					warn_height,
307 					(main_win.width-OFF_X)+2,
308 		   			fs_win[i].y-LETTER_HEIGHT(main_win));
309 				}
310 			else
311 				{
312 #ifdef DEBUG
313 				printf("LEVEL: clearing Warning Area %d - Warn_Val > 0\n",i);
314 #endif
315 				fs_bell[i] = 0;
316 				XClearArea (mydisplay, main_win.win,
317 					(main_win.width - OFF_X) + 2,
318 					fs_win[i].y - LETTER_HEIGHT(main_win),
319 					warn_width, warn_height, FALSE);
320 				}
321 			}
322 
323 		/* ** handle the color warning levels *** */
324 		/*
325 		 * EHR begin patch -- 1) warncols[0] as default color for bars
326 		 *  		      2) enable popup when level changes
327 		 *		      3) change to table rep of warn levels &
328 		 *			 bar colors
329 		 *		      4) change to have status set up in
330 		 *			 get_fs_stat. This section just
331 		 *			 sets up the screen as necessary.
332 		 */
333 
334 		/*
335 		 * Get Appropriate color.  Note that fs_level is set in
336 		 * the get_fs_stat routine.
337 		 */
338 		color=warncols[fs_level[i]];
339 #ifdef DEBUG
340 		printf("LEVEL: color set to %d\n", color);
341 #endif
342 
343 		/*
344 		 * Set up the warning/popup.  Note that fs_warn is set in
345 		 * the get_fs_stat routine.
346 		 */
347 		if (popup && fs_warn[i])
348 			{
349 #ifdef DEBUG
350 			printf("LEVEL: popup processed for fs %d\n",i);
351 #endif
352 			if (bell && !fs_bell[i])
353 				{
354 				should_bell = TRUE;
355 				if (!alwaysbeep)
356 					fs_bell[i] = 1;
357 				}
358 			should_raise = TRUE;
359 			XCopyArea (mydisplay, popup_pix, main_win.win,
360 				main_win.gc, 0, 0, popup_width,
361 				popup_height, (main_win.width-OFF_X)+2,
362 		   		fs_win[i].y-LETTER_HEIGHT(main_win));
363 			}
364 		else
365 		if (warn_val <= 0)
366 			{
367 			fs_bell[i] = 0;
368 #ifdef DEBUG
369 			printf("LEVEL: clearing popup warning area %d\n",i);
370 #endif
371 			XClearArea (mydisplay, main_win.win,
372 				(main_win.width - OFF_X) + 2,
373 				fs_win[i].y - LETTER_HEIGHT(main_win),
374 				popup_width, popup_height, FALSE);
375 			}
376 
377 		XSetForeground (mydisplay, fs_win[i].gc, color);
378 
379 		if (percent)
380 			write_percent (i);
381 		if (available)
382 			write_available (i);
383 		}
384 
385 	/* *** make sure window is raised when should_raise==TRUE *** */
386 	if (should_raise)
387 		{
388 		XWMHints wmhints;
389 		wmhints.initial_state = NormalState;
390 		wmhints.flags = StateHint;
391 		XSetWMHints(mydisplay, main_win.win, &wmhints);
392 		XMapRaised(mydisplay, main_win.win);
393 		}
394 
395 	if (should_bell)
396 		XBell (mydisplay, 0);
397 }
398 
399 
400 
401 /* *********************************************************************** */
402 /* *************************** redraw the bars *************************** */
403 /* *********************************************************************** */
redraw_fs_win(i)404 void redraw_fs_win(i)
405 int i;
406 {
407 	/* *** now draw bar *** */
408 	/* XClearWindow (mydisplay, fs_win[i].win); */
409 	XFillRectangle (mydisplay, fs_win[i].win, fs_win[i].gc, 0, 0,
410 		(int)(fs_perc[i]*fs_win[i].width), fs_win[i].height);
411 	XClearArea(mydisplay, fs_win[i].win,
412 		(int)(fs_perc[i] * fs_win[i].width), 0, 0, 0, False);
413 }
414 
415 
416 
417 /* *********************************************************************** */
418 /* ************************* write available space *********************** */
419 /* *********************************************************************** */
write_available(i)420 void write_available(i)
421 int i;
422 {
423 	char	s[30];
424 	long	bsize=stats[i].f_bsize;
425 
426 	sprintf (s, "%5.2f",
427 #ifdef SCO
428 		((double)(bsize)/(float)(MB))*(double)(stats[i].f_bfree));
429 #else
430 		((double)(bsize)/(float)(MB))*(double)(stats[i].f_bavail));
431 #endif /* SCO */
432 	XDrawImageString (mydisplay, main_win.win, main_win.gc,
433 		(main_win.width - OFF_Y -
434 		XTextWidth(main_win.font_info, s, strlen(s))),
435  		fs_win[i].y - 2, s, strlen (s));
436 }
437 
438 
439 
440 /* *********************************************************************** */
441 /* ************************* write the percentage ************************ */
442 /* *********************************************************************** */
write_percent(i)443 void write_percent(i)
444 int i;
445 {
446 	char 	s[30];
447 
448 	if (fs_perc[i] < 0 )
449 		strcpy (s, "N.A.");
450 	else
451 		sprintf (s, "%3d%%", (int)(fs_perc[i]*100 + 0.5));
452 	XDrawImageString (mydisplay, main_win.win, main_win.gc,
453 		(main_win.width - OFF_Y -
454 		XTextWidth(main_win.font_info, s, strlen(s))),
455  		fs_win[i].y - 2, s, strlen (s));
456 }
457 
458 
459 
460 /* *********************************************************************** */
461 /* ************************* write the percentage ************************ */
462 /* *********************************************************************** */
open_detail_win(argc,argv)463 void open_detail_win (argc, argv)
464 int	argc;
465 char 	**argv;
466 {
467 	XSizeHints szhint;
468 	XClassHint clshint;
469 	XWMHints wmhints;
470 
471 	szhint.min_width  = DETAIL_X;
472 	szhint.min_height = DETAIL_Y;
473 	szhint.max_width  = szhint.min_width;
474 	szhint.max_height = szhint.min_height;
475 	szhint.x = detail_win.x;
476 	szhint.y = detail_win.y;
477 	szhint.width = detail_win.width;
478 	szhint.height = detail_win.height;
479 	szhint.flags = detail_win.flags | PMinSize | PMaxSize | PSize;
480 
481 	clshint.res_name  = "detailWin";
482 	clshint.res_class = CLASS_NAME;
483 
484 	wmhints.input = True;
485 	wmhints.initial_state = NormalState;
486 	wmhints.window_group = main_win.win;
487 	wmhints.flags = InputHint | StateHint | WindowGroupHint;
488 
489 	create_window(DefaultRootWindow(mydisplay), &detail_win,
490 		getColorResource(resourceDB,
491 		catlist(myname, ".detailWin.foreground",
492 		(char*) NULL), "Xofm.DetailWin.Foreground", fg),
493 		getColorResource(resourceDB, catlist(myname,
494 			".detailWin.background", (char*) NULL),
495 			"Xofm.DetailWin.Background", bg));
496 
497 	/* *** set up the properties for the window. *** */
498 	XSetStandardProperties (mydisplay, detail_win.win,
499 		detail_win.text, detail_win.text, None, argv, argc,
500 		&szhint);
501 	XSetClassHint(mydisplay, detail_win.win, &clshint);
502 	XSetWMHints(mydisplay, detail_win.win, &wmhints);
503 
504 	XMapRaised (mydisplay, detail_win.win);
505 }
506 
507 
508 
509 /* *********************************************************************** */
510 /* *********************** create a single window ************************ */
511 /* *********************************************************************** */
create_window(parent_win,this_win,foreg,backg)512 void create_window (parent_win, this_win, foreg, backg)
513 Window	parent_win;
514 WinTypePtr this_win;
515 unsigned long foreg, backg;
516 {
517 	/* *** Create Actual Window *** */
518 	this_win->win = XCreateSimpleWindow (mydisplay, parent_win, this_win->x,
519 		this_win->y, this_win->width, this_win->height,
520 		this_win->line_thick, foreg, backg);
521 
522 	if (!this_win->win)
523 		{
524 		fprintf (stderr,
525 			"Error creating Simple Window %s ... Exiting.\n",
526 			this_win->text);
527 		exit (1);
528 		}
529 
530 #ifdef DEBUG
531 	fprintf (stdout, "Created Simple Window %s (%d) %d %d %d %d\n",
532 		this_win->text, this_win->win, this_win->x, this_win->y,
533 		this_win->width, this_win->height, this_win->line_thick);
534 #endif
535 
536 	/* *** set Graphics Content creation and initialize *** */
537 	this_win->gc = XCreateGC (mydisplay, this_win->win, 0, 0);
538 
539 	if (! this_win->gc)
540 		{
541 		fprintf (stderr, "Error creating GC for  %s ... Exiting.\n",
542 			this_win->text);
543 		exit (1);
544 		}
545 
546 #ifdef DEBUG
547 	fprintf (stdout, "Created GC %d\n", this_win->gc);
548 #endif
549 
550 	XSetBackground (mydisplay, this_win->gc, backg);
551 	XSetForeground (mydisplay, this_win->gc, foreg);
552 
553 	if (this_win->font_info != 0)
554 		XSetFont(mydisplay, this_win->gc, this_win->font_info->fid);
555 
556 	this_win->fg = foreg;
557 	this_win->bg = backg;
558 
559 	/* *** specify which input we want this window to process *** */
560 	XSelectInput (mydisplay, this_win->win, this_win->event_mask);
561 }
562 
563 
564 
565 
566 /* *********************************************************************** */
567 /* highlight menu item (window) in response to a mouse entering or leaving */
568 /* *********************************************************************** */
highlight_menu(menu,menu_num,highlight)569 int highlight_menu (menu, menu_num,highlight)
570 WinType menu[];
571 int	menu_num;
572 int	highlight;
573 {
574 	int i, state=NOGOOD;
575 
576 	/* *** figure out which menu *** */
577 	for (i = 0; i < menu_num; i++)
578 		if (myevent.xcrossing.window == menu[i].win)
579 			{
580 			state = i;
581 			i = menu_num;
582 			}
583 
584 	/* *** check if menu is valid and change fg & bg *** */
585 	if (state >= 0 && state < menu_num)
586 		{
587 		if (highlight)
588 			{
589 #ifdef DEBUG
590 			fprintf(stdout, "Enter state in button %s\n",
591 				menu[state].text);
592 #endif
593 		XSetBackground (mydisplay, menu[state].gc, fg);
594 		XSetForeground (mydisplay, menu[state].gc, bg);
595 			}
596 		else
597 			{
598 #ifdef DEBUG
599 			fprintf (stdout, "Exit state in button %s\n",
600 				menu[state].text);
601 #endif
602 			XSetBackground (mydisplay, menu[state].gc, bg);
603 			XSetForeground (mydisplay, menu[state].gc, fg);
604 			}
605 
606 		for (i = 0; i < menu_num; ++i)
607 			XDrawImageString (mydisplay, menu[i].win, menu[i].gc, 1,
608 			LETTER_ASCENT(menu[i]), menu[i].text,
609 			strlen(menu[i].text));
610 		return (state);
611 	}
612 	else
613 		return (NOGOOD);
614 }
615 
616 /* *********************************************************************** */
617 /* ************** redraw the string in an exposed window ***************** */
618 /* *********************************************************************** */
expose_win(menu,menu_num)619 int expose_win (menu, menu_num)
620 WinType	menu[];
621 int	menu_num;
622 {
623 	int i;
624 
625 	for (i = 0; i < menu_num; i++)
626 		{
627 		if (myevent.xexpose.window == menu[i].win)
628 			{
629 			XDrawImageString (mydisplay, menu[i].win, menu[i].gc, 1,
630 				LETTER_ASCENT(menu[i]), menu[i].text,
631 				strlen(menu[i].text));
632 			return (FALSE);
633 			}
634 		}
635 
636 	return (TRUE);
637 }
638 
639 
640 
641 
642 /* *********************************************************************** */
643 /* *********************** destroy an entire menu  *********************** */
644 /* *********************************************************************** */
destroy_menu(menu,menu_num)645 void destroy_menu (menu, menu_num)
646 WinType	menu[];
647 int	menu_num;
648 {
649 	int i;
650 
651 	for (i=0; i<menu_num; i++)
652 		{
653 		XDestroyWindow (mydisplay, menu[i].win);
654 #ifdef DEBUG
655 		fprintf (stdout, "Destroyed menu: %s\n", menu[i].text);
656 #endif
657 		XFreeGC (mydisplay, menu[i].gc);
658 #ifdef DEBUG
659 		fprintf (stdout, "Destroyed GC: %d\n", menu[i].gc);
660 #endif
661 		}
662 }
663 
664 
665 
666 
667 /* *********************************************************************** */
668 /* *************** return the number of the button pressed *************** */
669 /* *********************************************************************** */
which_button_pressed(menu,menu_num)670 int which_button_pressed (menu, menu_num)
671 WinType	menu[];
672 int	menu_num;
673 {
674 	int i;
675 
676 	for (i=0; i<menu_num; i++)
677 		if (myevent.xbutton.window == menu[i].win)
678 			return (i);
679 	return (NOGOOD);
680 }
681 
682 
683 
684 /* ***************************************************************** */
685 /* ********** this basically inits the window definitions ********** */
686 /* ***************************************************************** */
init_all_windows()687 void init_all_windows ()
688 {
689 	int i, x, y, flags, geom_used=FALSE, ppnfs;
690 	unsigned long small_event_mask, big_event_mask, fs_mask;
691 	unsigned int width, height;
692 #ifdef XOFM
693 	static char* bytes_or_blocks [] = {"bytes", "blocks"};
694 #else
695 	static char* userroot[] = {"user", "root"};
696 #endif
697 	static char* freeused[] = {"free", "used"};
698 	unsigned int border_width =
699 		getIntResource(resourceDB, catlist(myname, ".borderWidth",
700 			(char*) NULL), "Xfsm.BorderWidth", DEF_BORDER_WIDTH);
701 	XFontStruct* def_font = XLoadQueryFont(mydisplay, DEFAULT_FONT);
702 	XrmString str_type;
703 	XrmValue value;
704 	small_event_mask = ButtonPressMask | StructureNotifyMask |
705 		ExposureMask| KeyPressMask | EnterWindowMask | LeaveWindowMask;
706 	big_event_mask = ButtonPressMask | ExposureMask | EnterWindowMask |
707 		LeaveWindowMask;
708 	fs_mask = ButtonPressMask | ExposureMask;
709 
710 	if (def_font == NULL)
711 		{
712 		fprintf(stderr, "Could not load default font \"%s\".\n",
713 			DEFAULT_FONT);
714 		exit(1);
715 		}
716 
717 #ifdef XOFM
718 	sprintf (main_win.text, "%s %s %s", hname,
719 		bytes_or_blocks [show_blocks!=0], freeused[show_use != 0]);
720 #else /* xfsm */
721 	if (title != NULL)
722 		sprintf (main_win.text, "%s %s %s", title, userroot[root != 0],
723                		freeused[show_use != 0]);
724 	else
725 		sprintf (main_win.text, "%s %s %s", hname, userroot[root != 0],
726 			freeused[show_use != 0]);
727 
728 #endif
729 
730 	main_win.x = WIN_X;
731 	main_win.y = WIN_Y;
732 	main_win.font_info = getFontResource (resourceDB,
733 		catlist(myname, ".mainWin.font", (char*) NULL),
734 		"Xfsm.MainWin.Font", def_font);
735 	if (minimize)
736 		{
737 		if (minimize == MNL)
738 			{
739 			main_win.width = OFF_X + OFF_X + lname + percent_width;
740 			if (main_win.width < MIN_WIN_X)
741 				main_win.width = MIN_WIN_X;
742 			}
743 		else
744 			main_win.width = MIN_WIN_X;
745 		main_win.height = ((MIN_INTERVAL(main_win) * NFS) +
746 			BEGIN_NFS(main_win));
747 		}
748 	else
749 		{
750 		main_win.width = WIN_X;
751 		main_win.height = ((INTERVAL(main_win) * NFS) +
752 			BEGIN_NFS(main_win));
753 		}
754 	main_win.line_thick = border_width;
755 	main_win.event_mask = small_event_mask;
756 	main_win.flags = PPosition;
757 
758 	if (XrmGetResource(resourceDB, catlist(myname, ".mainWin.geometry",
759 		(char*) NULL), "Xfsm.MainWin.Geometry", &str_type, &value))
760 		{
761 		flags = XParseGeometry(value.addr, &x, &y, &width, &height);
762 		if (XValue & flags)
763 			{
764 			if (XNegative & flags)
765 			   x = DisplayWidth(mydisplay,
766 				DefaultScreen(mydisplay)) + x -
767 				main_win.width - 2 * main_win.line_thick;
768 			main_win.x = x;
769 			main_win.flags = USPosition;
770 			}
771 
772 		if (YValue & flags)
773 			{
774 			if (YNegative & flags)
775 			   y = DisplayHeight(mydisplay,
776 				DefaultScreen(mydisplay)) + y -
777 				main_win.height - 2 * main_win.line_thick;
778 			main_win.y = y;
779 			main_win.flags = USPosition;
780 			}
781 		if (WidthValue & flags)
782 			{
783 			if (width < MIN_WIN_X)
784 				{
785 				width = MIN_WIN_X;
786 				if (verbose)
787 					fprintf (stderr, "Specified width too \
788 small ... adjusting to minimum size\n");
789 				}
790 			else
791 			if (width >
792 			    DisplayWidth(mydisplay, DefaultScreen(mydisplay)))
793 				{
794 				width = DisplayWidth(mydisplay,
795 					DefaultScreen(mydisplay))-1;
796 				if (verbose)
797 					fprintf (stderr, "Specified width too \
798 large ... adjusting to maximum size\n");
799 				}
800 			main_win.width = width;
801 			main_win.flags = USPosition;
802 			geom_used=TRUE;
803 			}
804 		if (HeightValue & flags)
805 			{
806 			if (height <
807 			    ((MIN_INTERVAL(main_win)*NFS)+BEGIN_NFS(main_win)))
808 				{
809 				height = ((MIN_INTERVAL(main_win)*NFS)+
810 					BEGIN_NFS(main_win));
811 				if (verbose)
812 					fprintf (stderr, "Specified height too \
813 small ... adjusting to minimum size\n");
814 				}
815 			else
816 			if (height >
817 			    DisplayHeight(mydisplay, DefaultScreen(mydisplay)))
818 				{
819 				height = DisplayHeight(mydisplay,
820 					DefaultScreen(mydisplay))-1;
821 				if (verbose)
822 					fprintf (stderr, "Specified height too \
823 large ... adjusting to maximum size\n");
824 				}
825 			main_win.height = height;
826 			main_win.flags = USPosition;
827 			geom_used=TRUE;
828 			}
829 		}
830 
831 	for (i = 0; i < MENU_ITEMS; i++)
832 		{
833 		strcpy(menu[i].text, Menu_Text[i]);
834 		menu[i].font_info = main_win.font_info;
835 		menu[i].width = SM_MENU_WIDTH(menu[i]);
836 		menu[i].height = MENU_HEIGHT(menu[i]);
837 		menu[i].x = ((main_win.width - menu[i].width) / 2);
838 		menu[i].y = MENU_Y + MENU_HEIGHT(menu[i]) * i;
839 		if (menu_border)
840 			menu[i].line_thick = 1;
841 		else
842 			menu[i].line_thick = 0;
843 		menu[i].event_mask = big_event_mask;
844 		}
845 
846 	for (i = 0; i < MAXFS; i++)
847 		{
848 		fs_win[i].font_info = main_win.font_info;
849 		fs_win[i].line_thick = fs_border;
850 		fs_win[i].event_mask = fs_mask;
851 		}
852 
853 	for (i = 0; i < NFS; i++)
854 		{
855 		fs_win[i].x = OFF_X;
856 		if (geom_used)
857 			{
858 			ppnfs = ((main_win.height-BEGIN_NFS(main_win)) / NFS);
859 			set_fs_win_size (i, ppnfs);
860 			}
861 		else
862 		if (minimize)
863 			{
864 			fs_win[i].y = ((MIN_INTERVAL(fs_win[i]) * i) +
865 				BEGIN_NFS(fs_win[i]));
866 			fs_win[i].height = MIN_MENU_HEIGHT;
867 			}
868 		else
869 			{
870 			fs_win[i].y = ((INTERVAL(fs_win[i]) * i) +
871 				BEGIN_NFS(fs_win[i]));
872 			fs_win[i].height = MENU_HEIGHT(fs_win[i]);
873 			}
874 		fs_win[i].width = main_win.width - OFF_X * 2;
875 		}
876 	sprintf (detail_win.text, "%s detail", hname);
877 	detail_win.x = OFF_X;
878 	detail_win.y = OFF_Y;
879 	detail_win.font_info = getFontResource(resourceDB,
880 		catlist(myname, ".detailWin.font", (char*) NULL),
881 		"Xfsm.DetailWin.Font", def_font);
882 	detail_win.width = DETAIL_X;
883 	detail_win.height = DETAIL_Y;
884 	detail_win.line_thick = border_width;
885 	detail_win.event_mask = small_event_mask;
886 	detail_win.flags = PPosition;
887 	if (XrmGetResource(resourceDB,
888 		catlist(myname, ".detailWin.geometry", (char*) NULL),
889 		"Xfsm.DetailWin.Geometry", &str_type, &value))
890 		{
891 		flags = XParseGeometry(value.addr, &x, &y, &width, &height);
892 		if (XValue & flags)
893 			{
894  			if (XNegative & flags)
895 			   x  = DisplayWidth(mydisplay,
896 				DefaultScreen(mydisplay)) + x -
897 				detail_win.width - 2 * detail_win.line_thick;
898 			detail_win.x = x;
899 			detail_win.flags = USPosition;
900 			}
901 		if (YValue & flags)
902 			{
903 			if (YNegative & flags)
904 			   y = DisplayHeight(mydisplay,
905 				DefaultScreen(mydisplay)) + y -
906 				detail_win.height - 2 * detail_win.line_thick;
907 			detail_win.y = y;
908 			detail_win.flags = USPosition;
909 			}
910 		}
911 
912 	/* *** 4 spaces (3 digits + 1 %) + 1 space *** */
913 	percent_width = XTextWidth(main_win.font_info, "9999%", 5);
914 }
915 
916 
917 
918 /* ***************************************************************** */
919 /* ********** Returns the value of the given bool resource ********** */
920 /* ***************************************************************** */
getBoolResource(db,str_name,str_class,deflt)921 Bool getBoolResource(db, str_name, str_class, deflt)
922 XrmDatabase db;
923 char* str_name;
924 char* str_class;
925 Bool deflt;
926 {
927 	XrmString str_type;
928 	XrmValue value;
929 
930 	if (XrmGetResource(db, str_name, str_class, &str_type, &value))
931 		{
932 		return ((!strcmp(value.addr, "true")) ||
933 			(!strcmp(value.addr, "True")) ||
934 			(!strcmp(value.addr, "TRUE")) ||
935 			(!strcmp(value.addr, "yes")) ||
936 			(!strcmp(value.addr, "Yes")) ||
937 			(!strcmp(value.addr, "YES")) ||
938 			(!strcmp(value.addr, "on")) ||
939 			(!strcmp(value.addr, "On")) ||
940 			(!strcmp(value.addr, "ON")) ||
941 			(!strcmp(value.addr, "1")));
942 		}
943 	else
944 		return (deflt);
945 }
946 
947 
948 
949 /* ***************************************************************** */
950 /* ********** Returns the value of the given int resource ********** */
951 /* ***************************************************************** */
getIntResource(db,str_name,str_class,deflt)952 int getIntResource(db, str_name, str_class, deflt)
953 XrmDatabase db;
954 char* str_name;
955 char* str_class;
956 int deflt;
957 {
958 	XrmString str_type;
959 	XrmValue value;
960 
961 	if (XrmGetResource(db, str_name, str_class, &str_type, &value))
962 		return (atoi(value.addr));
963 	else
964 		return (deflt);
965 }
966 
967 
968 
969 /* ***************************************************************** */
970 /* ********** Returns the value of the given Font resource ********* */
971 /* ***************************************************************** */
getFontResource(db,str_name,str_class,deflt)972 XFontStruct* getFontResource(db, str_name, str_class, deflt)
973 XrmDatabase db;
974 char* str_name;
975 char* str_class;
976 XFontStruct* deflt;
977 {
978 	XrmString str_type;
979 	XrmValue value;
980 
981 	if (XrmGetResource(db, str_name, str_class, &str_type, &value))
982 		{
983 		XFontStruct* font = XLoadQueryFont(mydisplay, value.addr);
984 		if (font == NULL)
985 			{
986 			fprintf(stderr,
987 				"Could not load font \"%s\".\n", value.addr);
988 			return (deflt);
989 			}
990 		else
991 			return (font);
992   		}
993 	else
994 		return (deflt);
995 }
996 
997 
998 
999 /* ***************************************************************** */
1000 /* ********** Returns the value of the given color resource ******** */
1001 /* ***************************************************************** */
getColorResource(db,str_name,str_class,deflt)1002 unsigned long getColorResource(db, str_name, str_class, deflt)
1003 XrmDatabase db;
1004 char* str_name;
1005 char* str_class;
1006 unsigned long deflt;
1007 {
1008 	XrmString str_type;
1009 	XrmValue value;
1010 
1011 	if (XrmGetResource(db, str_name, str_class, &str_type, &value))
1012 		{
1013 		XColor screen_def;
1014 		if (XParseColor(mydisplay, DefaultColormapOfScreen
1015 			(DefaultScreenOfDisplay(mydisplay)), value.addr,
1016 			&screen_def) == 0
1017 		    ||
1018 		    XAllocColor(mydisplay, DefaultColormapOfScreen
1019 			(DefaultScreenOfDisplay(mydisplay)), &screen_def) == 0)
1020 			{
1021 			fprintf(stderr,
1022 			   "Color specification \"%s\" invalid.\n", value.addr);
1023 			return (deflt);
1024 			}
1025 		else
1026  			return (screen_def.pixel);
1027 		}
1028 	else
1029 		return (deflt);
1030 }
1031 
1032 
1033 
1034 /* ***************************************************************** */
1035 /* ********** Returns the concatenation of the NULL       ********** */
1036 /* ********** terminated list of strings.		  ********** */
1037 /* ***************************************************************** */
1038 #ifdef __STDC__
1039 #if NeedFunctionPrototypes
catlist(char * str1,...)1040 char* catlist(char *str1, ...)
1041 #else
1042 char* catlist(str1)
1043 char* str1;
1044 #endif /* NeedFunctionPrototypes */
1045 {
1046 	static char blocks[2][64];
1047 	static int current = 0;
1048 	va_list ap;
1049 	char* c;
1050 
1051 	strcpy(blocks[current], str1);
1052 	va_start(ap, str1);
1053 	while ((c = va_arg(ap, char*)) != NULL)
1054 		strcat(blocks[current], c);
1055 	va_end(ap);
1056 	c = blocks[current];
1057 	current = (current + 1) % 2;
1058 	return c;
1059 }
1060 #else
catlist(va_alist)1061 char* catlist(va_alist)
1062 va_dcl
1063 {
1064 	static char blocks[2][64];
1065 	static int current = 0;
1066 	va_list ap;
1067 	char* c;
1068 
1069 	va_start(ap);
1070 	blocks[current][0] = '\0';
1071 	while ((c = va_arg(ap, char*)) != NULL)
1072 		strcat(blocks[current], c);
1073 	va_end(ap);
1074 	c = blocks[current];
1075 	current = (current + 1) % 2;
1076 	return c;
1077 }
1078 #endif /* __STDC__ */
1079 
1080 
1081 #if defined (DYNIX) || defined (MACH)
1082 /* *** for some reason DYNIX does not have strstr *** */
1083 /* Copyright (C) 1991, 1992 Free Software Foundation, Inc. */
1084 /* This file is part of the GNU C Library.                 */
1085 /* Return the first ocurrence of NEEDLE in HAYSTACK.       */
1086 #ifdef __STDC__
strstr(const char * haystack,const char * needle)1087 char *strstr (const char* haystack, const char* needle)
1088 #else
1089 char *strstr (haystack, needle)
1090 char *haystack, *needle;
1091 #endif
1092 {
1093 	char 	*needle_end = strchr(needle, '\0');
1094 	char 	*haystack_end = strchr(haystack, '\0');
1095 	size_t needle_len = needle_end - needle;
1096 	size_t needle_last = needle_len - 1;
1097 	char 	*begin;
1098 
1099 	if (needle_len == 0)
1100  		return (char *) haystack_end;
1101 	if ((size_t) (haystack_end - haystack) < needle_len)
1102 		return NULL;
1103 
1104 	for (begin = &haystack[needle_last]; begin < haystack_end; ++begin)
1105 		{
1106  		char *n = &needle[needle_last];
1107 		char *h = begin;
1108 
1109 		do
1110 		if (*h != *n)
1111 			goto loop;		/* continue for loop */
1112 		while (--n >= needle && --h >= haystack);
1113 
1114 		return (char *) h;
1115 
1116 		loop:;
1117     		}
1118 
1119 	return NULL;
1120 }
1121 #endif /* DYNIX || MACH */
1122 
1123 
1124 /*  This routine clears the fs_warn[] flags for all of the currently active
1125  *  file systems.  This is done in a separate routine so that popup warnings
1126  *  stay active until the "Update Now" button is pressed.  Otherwise, every
1127  *  update pass (default is 1 per minute) will clear the popup warning field.
1128  *  When that happens, you can't tell what caused the popup if you've left it
1129  *  on overnight!!  So, we now only clear the popup warning field when pressing
1130  *  the "Update Now" button.
1131  */
1132 
clear_fs_warn_flags()1133 void clear_fs_warn_flags()
1134 {
1135 	int i;
1136 
1137 	for (i=0; i<NFS; i++)
1138 		{
1139 		fs_warn[i] = FALSE;
1140 		fs_bell[i] = 0;
1141 		}
1142 }
1143 
1144