"SfR Fresh" - the SfR Freeware/Shareware Archive 
Member "gmemusage-0.2/gmemusage.c" of archive gmemusage-0.2.tar.gz:
As a special service "SfR Fresh" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting with prefixed line numbers.
Alternatively you can here view or download the uninterpreted source code file.
That can be also achieved for any archive member file by clicking within an archive contents listing on the first character of the file(path) respectively on the according byte size field.
1 /*
2 * gmemusage.c
3 * main file for gmemusage
4 *
5 * Copyright (C) 1997, 1998 by Raju Mathur (raju@sgi.com)
6 * Some portions based on O'Reilly and Associates' Xlib Programming tutorial
7 * examples.
8 *
9 * See file COPYING (included in this distribution) for copyright information.
10 *
11 * Xemacs configuration for this indentation:
12 * (add-hook 'c-mode-common-hook
13 * '(lambda ()
14 * (c-set-style "ellemtel")
15 * (c-set-offset 'topmost-intro-cont '+)
16 * (c-set-offset 'topmost-intro '-)
17 * (c-set-offset 'case-label '*)
18 * (c-set-offset 'statement-case-intro '*)))
19 *
20 * Version 0.2, 980114
21 */
22 #include <X11/Xlib.h>
23 #include <X11/Xutil.h>
24 #include <X11/Xos.h>
25 #include <X11/Xatom.h>
26 #include <X11/keysym.h>
27
28 #include "memusage.xbm"
29
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <string.h>
33 #include <signal.h>
34 #include <malloc.h>
35
36 #include "common.h"
37 #include "defaults.h"
38
39 #define BITMAPDEPTH 1
40
41 #define TOO_SMALL 0
42 #define BIG_ENOUGH 1
43 /*
44 * I hate these file-wide variables, but since draw_window is going to be
45 * called from a signal, we can't pass it any args.
46 */
47 static Display
48 *display ;
49 static int
50 screen_num ;
51 char
52 progname [128] , /* other functions need to access this one */
53 *version = "0.1" ; /* and this one */
54 static Window
55 win ;
56 #ifndef SAVE_XSERVER_MEMORY
57 static Pixmap
58 pxm;
59 #endif
60 static int
61 window_width ,
62 window_height ;
63 static int
64 nColors ;
65 static int
66 Threshhold = -1 ;
67 static XColor
68 Foreground ,
69 Background ;
70 static XFontStruct
71 *font_info ;
72 static int
73 Exposed = 0 ;
74 /*
75 * Is this the right way to have (e.g.) 16 colors? 16 different GC's with
76 * a different foreground?
77 */
78 static GC
79 gc [MaxColors] ;
80 static GC
81 blackGC;
82 /*
83 * Protos.
84 */
85 void getGCs ( Window win , Colormap cmap ) ;
86 #if 0
87 void place_text ( Window win , GC gc , XFontStruct *font_info ,
88 unsigned int win_width , unsigned int win_height ) ;
89 void place_graphics ( Window win , GC gc , unsigned int window_width ,
90 unsigned int window_height ) ;
91 #endif
92 void draw_window ( void ) ;
93 void TooSmall ( Window win , GC gc , XFontStruct *font_into ) ;
94
95 void main ( int argc , char **argv )
96 {
97 int
98 default_height ,
99 default_width ,
100 default_x ,
101 default_y ;
102 int
103 x = 0 ,
104 y = 0 ,
105 width ,
106 height ;
107 unsigned int
108 border_width = 4 ,
109 display_width ,
110 display_height ;
111 char
112 *window_name = "gmemusage" ,
113 *icon_name = "gmemusage" ;
114 Pixmap
115 icon_pixmap ;
116 XSizeHints
117 *size_hints ;
118 XEvent
119 report ;
120 int
121 screen_num ;
122 Screen
123 *screen_ptr ;
124 XWMHints
125 *wm_hints ;
126 XClassHint
127 *class_hints ;
128 XTextProperty
129 windowName ,
130 iconName ;
131 Colormap
132 cmap ;
133 /*
134 * Remove leading dir.../ from argv[0] and store in progname
135 */
136 if ( strrchr ( argv [0] , '/' ) )
137 {
138 strcpy ( progname , strrchr ( argv [0] , '/' ) + 1 ) ;
139 }
140 else
141 {
142 strcpy ( progname , argv [0] ) ;
143 }
144 /*
145 * Allocate necessaru X structures for later use. Apparently this needs to
146 * be done before any other X stuff.
147 */
148 if ( !( size_hints = XAllocSizeHints () ) )
149 {
150 fprintf ( stderr , "%s: failure allocating SizeHints\n" , progname ) ;
151 exit ( 1 ) ;
152 }
153 if ( !( wm_hints = XAllocWMHints () ) )
154 {
155 fprintf ( stderr , "%s: failure allocating WMHints\n" , progname ) ;
156 exit ( 1 ) ;
157 }
158 if ( !( class_hints = XAllocClassHint () ) )
159 {
160 fprintf ( stderr , "%s: failure allocating ClassHints\n" , progname ) ;
161 exit ( 1 ) ;
162 }
163 /*
164 * Figure out resources from the command-line and screen resources.
165 */
166 GetInitialResources ( &argc , argv ) ;
167 if ( ( display = XOpenDisplay ( dDisplay ) ) == NULL )
168 {
169 (void) fprintf ( stderr , "%s: cannot connect to X server %s\n" ,
170 progname , XDisplayName ( dDisplay ) ) ;
171 exit ( 1 ) ;
172 }
173 GetResources ( display , argc , argv ) ;
174 XParseGeometry ( dGeometry , &default_x , &default_y , &default_width ,
175 &default_height ) ;
176
177 screen_num = DefaultScreen ( display ) ;
178 screen_ptr = DefaultScreenOfDisplay ( display ) ;
179
180 display_width = DisplayWidth ( display , screen_num ) ;
181 display_height = DisplayHeight ( display , screen_num ) ;
182 /*
183 * Get foreground and background colors for the window
184 */
185 cmap = DefaultColormap ( display , DefaultScreen ( display ) ) ;
186 if (!XParseColor ( display , cmap , dForeground , &Foreground ) )
187 {
188 fprintf ( stderr , "%s: Cannot parse color %s\n" , progname ,
189 dForeground ) ;
190 Foreground . pixel = BlackPixel ( display , screen_num ) ;
191 }
192 else
193 {
194 XAllocColor ( display , cmap , &Foreground ) ;
195 }
196 if (!XParseColor ( display , cmap , dBackground , &Background ) )
197 {
198 fprintf ( stderr , "%s: Cannot parse color %s\n" , progname ,
199 dBackground ) ;
200 Background . pixel = WhitePixel ( display , screen_num ) ;
201 }
202 else
203 {
204 XAllocColor ( display , cmap , &Background ) ;
205 }
206 width = default_width ;
207 height = default_height ;
208 win = XCreateSimpleWindow (
209 display ,
210 RootWindow ( display , screen_num ) ,
211 x ,
212 y ,
213 width ,
214 height ,
215 border_width ,
216 Foreground . pixel ,
217 Background . pixel ) ;
218 #ifndef SAVE_XSERVER_MEMORY
219 pxm = XCreatePixmap (
220 display ,
221 win ,
222 width ,
223 height ,
224 DefaultDepth ( display , screen_num ) );
225 #endif
226 icon_pixmap = XCreateBitmapFromData ( display , win , memusage_bits ,
227 memusage_width , memusage_height ) ;
228 size_hints -> flags = PPosition | PSize | PMinSize ;
229 size_hints -> min_width = default_width ;
230 size_hints -> min_height = default_height ;
231 if ( XStringListToTextProperty (&window_name , 1 , &windowName ) == 0 )
232 {
233 fprintf ( stderr , "%s: struct allocation for windowName failed\n" ,
234 progname ) ;
235 exit ( 1 ) ;
236 }
237 if ( XStringListToTextProperty ( &icon_name , 1 , &iconName ) == 0 )
238 {
239 fprintf ( stderr , "%s: struct allocation for iconName failed\n" ,
240 progname ) ;
241 exit ( 1 ) ;
242 }
243 wm_hints -> initial_state = NormalState ;
244 wm_hints -> input = True ;
245 wm_hints -> icon_pixmap = icon_pixmap ;
246 wm_hints -> flags = StateHint | IconPixmapHint | InputHint ;
247 class_hints -> res_name = progname ;
248 class_hints -> res_class = "BasicWin" ;
249 XSetWMProperties ( display , win , &windowName , &iconName , argv , argc ,
250 size_hints , wm_hints , class_hints ) ;
251
252 XSelectInput ( display , win , ExposureMask | KeyPressMask | ButtonPressMask
253 | StructureNotifyMask ) ;
254
255 getGCs ( win , cmap ) ;
256
257 XMapWindow ( display , win ) ;
258
259 while ( 1 )
260 {
261 XNextEvent ( display , &report ) ;
262 switch ( report . type )
263 {
264 char
265 keybuf [10] ;
266 KeySym
267 keysym ;
268 int
269 count ;
270 XComposeStatus
271 composestatus ;
272
273 case Expose:
274 if ( report . xexpose . count != 0 )
275 {
276 break ;
277 }
278 #if 0
279 printf("Expose %d %d %d %d\n",report.xexpose.x,report.xexpose.y,report.xexpose.width,report.xexpose.height);
280 #endif
281 #if 0
282 if ( window_size == TOO_SMALL )
283 {
284 TooSmall ( win , gc , font_info ) ;
285 }
286 else
287 #endif
288 {
289 Exposed = 1 ;
290 draw_window () ;
291 }
292 break ;
293
294 case ConfigureNotify:
295 window_width = report . xconfigure . width ;
296 window_height = report . xconfigure . height ;
297 #ifndef SAVE_XSERVER_MEMORY
298 XFreePixmap ( display , pxm );
299 pxm = XCreatePixmap (
300 display ,
301 win ,
302 window_width ,
303 window_height ,
304 DefaultDepth ( display , screen_num ) );
305 #endif
306 #if 0
307 if ( window_width < size_hints -> min_width
308 || window_height < size_hints -> min_height )
309 {
310 window_size = TOO_SMALL ;
311 }
312 else
313 {
314 window_size = BIG_ENOUGH ;
315 }
316 #endif
317 break ;
318
319 case ButtonPress: /* ignore buttons for now */
320 XBell ( display , 10 ) ;
321 break ;
322
323 case KeyPress:
324 count = XLookupString ( &report . xkey , keybuf ,
325 sizeof ( keybuf ) ,
326 &keysym , &composestatus ) ;
327 if ( ( keysym >= XK_KP_Space && keysym <= XK_KP_9 )
328 || ( keysym >= XK_space && keysym <= XK_asciitilde ) )
329 {
330 register int
331 i ;
332 for ( i = 0 ; keybuf [i] ; i++ )
333 {
334 switch ( keybuf [i] )
335 {
336 register int
337 j ;
338 case 'q':
339 case 'Q':
340 XUnloadFont ( display , font_info -> fid ) ;
341 for ( j = 0 ; j < nColors ; j++ )
342 {
343 XFreeGC ( display , gc [j] ) ;
344 }
345 XCloseDisplay ( display ) ;
346 exit ( 0 ) ;
347
348 default:
349 XBell ( display , 10 ) ;
350 break ;
351 }
352 }
353 }
354 else
355 {
356 switch ( keysym )
357 {
358 case XK_Up:
359 Threshhold += ThreshholdDelta ;
360 break ;
361
362 case XK_Down:
363 Threshhold -= ThreshholdDelta ;
364 if ( Threshhold < ThreshholdDelta )
365 {
366 XBell ( display , 0 ) ;
367 Threshhold = ThreshholdDelta ;
368 }
369 break ;
370
371 default:
372 #ifdef BELL_ON_UNKNOWN_KEYPRESS
373 XBell ( display , 10 ) ;
374 #endif
375 break ;
376 }
377 }
378 break ;
379
380 default:
381 #if 0
382 fprintf ( stderr , "%s: Unknown event: %d\n" , progname ,
383 report . type ) ;
384 #endif
385 break ;
386 }
387 }
388 exit ( 0 ) ;
389 }
390 /*
391 * Do all the drawing.
392 */
393 void draw_window ( void )
394 {
395 int
396 pcWidth ,
397 pcHeight ,
398 pixelWidth ,
399 pixelHeight ;
400 #ifdef SAVE_XSERVER_MEMORY
401 Pixmap
402 pxm;
403 #endif
404 struct XProcInfo
405 {
406 struct ProcInfo
407 *pi ;
408 int
409 pixelHeight ,
410 base ,
411 midpoint ;
412 } ;
413 register int
414 i ;
415 static int
416 nprocs ;
417 static int
418 oldThreshhold ;
419 int
420 oldnprocs ;
421 register struct XProcInfo
422 *this ;
423 static struct ProcInfo
424 *pi ;
425 static struct XProcInfo
426 *xpi ,
427 *oldxpi ;
428 int
429 alarmsecs ;
430 static int
431 done = 0 ;
432 int
433 basex ,
434 basey ;
435 #if 0
436 int
437 temp1 ;
438 #endif
439 GC
440 *thisGC ;
441 int
442 thxpi = -1 ;
443 struct ProcInfo
444 thProc ;
445 int
446 labelNumber = 0 ,
447 nLabels = 0 ;
448 int
449 longestLabel = 0 ;
450 /*
451 * No alarms while we're here.
452 */
453 (void) signal ( SIGALRM , SIG_IGN ) ;
454 /*
455 * See if we're being called due to an alarm, and schedule the next alarm.
456 * If the alarm is pending, we can reuse the old data rather than calling
457 * AllProcs again.
458 */
459 if ( alarmsecs = alarm ( dUpdate ) && done )
460 {
461 /*
462 * if the alarm didn't go off, we don't need to recalc everything.
463 */
464 #if 0
465 printf("called from expose\n");
466 #endif
467 alarm ( alarmsecs ) ;
468 }
469 else
470 {
471 /*
472 * Get the process info
473 */
474 #if 0
475 printf("called from alarm\n");
476 #endif
477 oldxpi = xpi ;
478 oldnprocs = nprocs ;
479 makeProcs () ;
480 pi = AllProcs ( &nprocs ) ;
481 done = 1 ;
482 }
483 /*
484 * Calculate width of memory bars as percentage and in pixels.
485 */
486 pcWidth = 40 ;
487 pixelWidth = window_width * pcWidth / 100.0 ;
488 pcHeight = 90 ;
489 pixelHeight = window_height * pcHeight / 100.0 ;
490 basex = DefaultBorder ;
491 basey = window_height - ( window_height - pixelHeight ) / 2 - 1 ;
492 if ( Threshhold < 0 )
493 {
494 Threshhold = dThreshhold ;
495 }
496 #if 0
497 printf("pcw %d, pw %d, pch %d, ph %d, base %d\n",pcWidth,pixelWidth,pcHeight,pixelHeight,basey);
498 #endif
499 /*
500 * Go through the array: allocate the ProcInfo pointer, calculate height,
501 * base, midpoint for each rectangle.
502 */
503 if ( ( xpi = calloc ( nprocs , sizeof ( struct XProcInfo ) ) ) == NULL )
504 {
505 fprintf ( stderr , "%s: calloc struct XProcInfo failed" , progname ) ;
506 perror ( "" ) ;
507 exit ( 1 ) ;
508 }
509 this = xpi ;
510 /*
511 * First get the sum of processes less than the threshhold size
512 */
513 for ( i = 0 ; i < nprocs ; i++ )
514 {
515 if ( pi [i] . totRSS < Threshhold
516 && strcmp ( pi [i] . procname , kernelname )
517 && strcmp ( pi [i] . procname , freename ) )
518 {
519 if ( thxpi < 0 )
520 {
521 thxpi = i ;
522 sprintf ( thProc . procname , "< %d" , Threshhold ) ;
523 thProc . totRSS = pi [i] . totRSS ;
524 thProc . totMem = 0 ;
525 thProc . nProcs = pi [i] . nProcs ;
526 this [i] . pi = &thProc ;
527 }
528 else
529 {
530 this [thxpi] . pi -> nProcs += pi [i] . nProcs ;
531 this [thxpi] . pi -> totRSS += pi [i] . totRSS ;
532 }
533 }
534 }
535 #if 0
536 temp1=0;
537 printf("%d %s %d\n",thxpi,this[thxpi].pi->procname,this[thxpi].pi->totRSS);
538 #endif
539 /*
540 * Now calculate percentages and sizes for the remaining (large-enough)
541 * processes.
542 */
543 for ( i = 0 ; i < nprocs ; i++ )
544 {
545 if ( i != thxpi )
546 {
547 if ( pi [i] . totRSS < Threshhold )
548 {
549 this [i] . pi = NULL ;
550 continue ;
551 }
552 else
553 {
554 this [i] . pi = &pi [i] ;
555 }
556 }
557 nLabels++ ;
558 #if 0
559 temp1+=pi[i].totRSS;
560 printf("%s %d %d %d\n",this[i].pi->procname,this[i].pi->totMem,this[i].pi->totRSS,temp1);
561 #endif
562 this [i] . pixelHeight = this [i] . pi -> totRSS * pixelHeight / sysmem ;
563 basey -= this [i] . pixelHeight ;
564 this [i] . base = basey ;
565 this [i] . midpoint = basey + this [i] . pixelHeight / 2 ;
566 if ( strlen ( this [i] . pi -> procname ) > longestLabel )
567 {
568 longestLabel = strlen ( this [i] . pi -> procname ) ;
569 }
570 }
571 #if 0 /* Needs much more work */
572 /*
573 * Check if the new values have changed at all from the previous values.
574 * If not, just deallocate and return without redrawing.
575 */
576 if ( oldThreshhold == Threshhold
577 && oldnprocs == nprocs
578 && !memcmp ( xpi , oldxpi , sizeof ( struct XProcInfo ) * nprocs )
579 && !Exposed )
580 {
581 free ( oldxpi ) ;
582 return ;
583 }
584 #endif
585 /*
586 * Make the boxes.
587 */
588 #if 0
589 XClearArea ( display , win , 0 , 0 , 0 , 0 , False ) ;
590 #else
591 #ifdef SAVE_XSERVER_MEMORY
592 pxm = XCreatePixmap (
593 display ,
594 win ,
595 window_width ,
596 window_height ,
597 DefaultDepth ( display , screen_num ) );
598 #endif
599 XFillRectangle ( display , pxm , blackGC , 0 , 0 ,
600 window_width , window_height ) ;
601 #endif
602 #if 0
603 printf("%d %d\n",window_height,window_width);
604 #endif
605 labelNumber = 0 ;
606 for ( i = 0 ; i < nprocs ; i++ )
607 {
608 if ( !this [i] . pi )
609 {
610 continue ;
611 }
612 thisGC = &gc [labelNumber % nColors] ;
613 #if 0
614 printf("%d %d %d %d\n",basex,this[i].base,pixelWidth,this[i].pixelHeight);
615 #endif
616 XFillRectangle ( display , pxm , *thisGC , basex , this [i] . base ,
617 pixelWidth , this [i] . pixelHeight ) ;
618 labelNumber++ ;
619 }
620 /*
621 * Make the lines and the text.
622 */
623 {
624 int
625 lineSpace = window_height / nLabels ,
626 longestLabelWidth ,
627 textXoffset ,
628 fontHeight ;
629 char
630 buf [128] ,
631 nprocbuf [10] ;
632 /* procname (nnn) : nnnnnK */
633 memset ( buf , 'W' , longestLabel + 6 + 2 + 7 ) ;
634 longestLabelWidth = XTextWidth ( font_info , buf ,
635 longestLabel + 6 + 2 + 7 ) ;
636 textXoffset = window_width - DefaultBorder
637 - longestLabelWidth ;
638 fontHeight = font_info -> ascent + font_info -> descent ;
639 labelNumber = 0 ;
640 for ( i = 0 ; i < nprocs ; i++ )
641 {
642 if ( !this [i] . pi )
643 {
644 continue ;
645 }
646 thisGC = &gc [labelNumber % nColors] ;
647 XDrawLine ( display , pxm , *thisGC ,
648 DefaultBorder + pixelWidth ,
649 this [i] . midpoint ,
650 textXoffset - 2 ,
651 window_height
652 - (labelNumber * lineSpace ) - lineSpace / 2 ) ;
653 if ( this [i] . pi -> nProcs > 1 )
654 {
655 sprintf ( nprocbuf , "(%d)" , this [i] . pi -> nProcs ) ;
656 }
657 else
658 {
659 nprocbuf [0] = '\0' ;
660 }
661 sprintf ( buf , "%-*s %6s : %5dK" , longestLabel ,
662 this [i] . pi -> procname , nprocbuf ,
663 this [i] . pi -> totRSS ) ;
664 #if 0
665 if ( strcmp ( this [i] . pi -> procname , kernelname )
666 && strcmp ( this [i] . pi -> procname , freename ) )
667 {
668 sprintf ( buf , "%s (%d)" , this [i] . pi -> procname ,
669 this [i] . pi -> nProcs ) ;
670 }
671 else
672 {
673 strcpy ( buf , this [i] . pi -> procname ) ;
674 }
675 #endif
676 XDrawString ( display , pxm , *thisGC ,
677 textXoffset ,
678 window_height - ( labelNumber * lineSpace )
679 - ( lineSpace - fontHeight ) / 2 - 2 ,
680 buf , strlen ( buf ) ) ;
681 labelNumber++ ;
682 }
683 }
684 XCopyArea ( display , pxm , win , blackGC, 0 , 0 , window_width,
685 window_height, 0 , 0 );
686 #ifdef SAVE_XSERVER_MEMORY
687 XFreePixmap ( display , pxm );
688 #endif
689 XFlush ( display ) ;
690 /*
691 * Save and clear some of the values.
692 */
693 oldThreshhold = Threshhold ;
694 Exposed = 0 ;
695 if ( oldxpi )
696 {
697 free ( oldxpi ) ;
698 oldxpi = NULL ;
699 }
700 /*
701 * We can accept alarms again
702 */
703 (void) signal ( SIGALRM , draw_window ) ;
704 return ;
705 }
706
707 void
708 getGCs ( Window win , Colormap cmap )
709 {
710 unsigned long
711 valuemask = 0 ;
712 XGCValues
713 values ;
714 unsigned int
715 line_width = 0 ; /* fastest server-dependent line */
716 int
717 line_style = LineSolid ,
718 cap_style = CapRound ,
719 join_style = JoinRound ;
720 XColor
721 rgb ;
722 register int
723 i ;
724
725 if ( ( font_info =
726 XLoadQueryFont ( display , dFont ) )
727 == NULL )
728 {
729 fprintf ( stderr , "%s: cannot load font %s\n" , progname , dFont ) ;
730 exit ( 1 ) ;
731 }
732 nColors = dnColors ;
733 for ( i = 0 ; i < nColors ; i++ )
734 {
735 if ( dColor [i] [0]
736 && !XParseColor ( display , cmap , dColor [i] , &rgb ) )
737 {
738 fprintf ( stderr , "%s: Cannot parse color %s\n" , progname ,
739 dColor [i] ) ;
740 rgb . pixel = BlackPixel ( display , screen_num ) ;
741 }
742 else
743 {
744 XAllocColor ( display , cmap , &rgb ) ;
745 }
746 gc [i] = XCreateGC ( display , win , valuemask , &values ) ;
747 XSetForeground ( display , gc [i] , rgb . pixel ) ;
748 XSetFont ( display , gc [i] , font_info -> fid ) ;
749 XSetLineAttributes ( display , gc [i] , line_width , line_style ,
750 cap_style , join_style ) ;
751 }
752 valuemask |= GCPlaneMask;
753 values.plane_mask = AllPlanes;
754 blackGC = XCreateGC ( display , win , valuemask , &values ) ;
755 XSetForeground ( display , blackGC , BlackPixel ( display , screen_num ) ) ;
756 return ;
757 }
758 #if 0
759 void
760 place_text ( Window win , GC gc , XFontStruct *font_info ,
761 unsigned int win_width , unsigned int win_height )
762 {
763 char
764 *string1 = "Hi! I'm a window, who are you?" ,
765 *string2 = "To terminate program: press any key" ,
766 *string3 = "or button while in this window." ,
767 *string4 = "Screen Dimensions" ;
768 int
769 len1 ,
770 len2 ,
771 len3 ,
772 len4 ,
773 width1 ,
774 width2 ,
775 width3 ;
776 char
777 cd_height[50] ,
778 cd_width [50] ,
779 cd_depth [50] ;
780 int
781 font_height ,
782 initial_y_offset ,
783 x_offset ;
784
785 len1 = strlen ( string1 ) ;
786 len2 = strlen ( string2 ) ;
787 len3 = strlen ( string3 ) ;
788 width1 = XTextWidth ( font_info , string1 , len1 ) ;
789 width2 = XTextWidth ( font_info , string2 , len2 ) ;
790 width3 = XTextWidth ( font_info , string3 , len3 ) ;
791 font_height = font_info -> ascent + font_info -> descent ;
792
793 XDrawString ( display , win , gc , ( win_width - width1 ) / 2 , font_height ,
794 string1 , len1 ) ;
795 XDrawString ( display , win , gc , ( win_width - width2 ) / 2 ,
796 win_height - 2 * font_height , string2 , len2 ) ;
797 XDrawString ( display , win , gc , ( win_width - width3 ) / 2 ,
798 win_height - 3 * font_height , string3 , len3 ) ;
799 sprintf ( cd_height , " Height - %d pixels" ,
800 DisplayHeight ( display , screen_num ) ) ;
801 sprintf ( cd_width , " Width - %d pixels" ,
802 DisplayWidth ( display , screen_num ) ) ;
803 sprintf ( cd_depth , " Depth - %d planes" ,
804 DefaultDepth ( display , screen_num ) ) ;
805 len4 = strlen ( string4 ) ;
806 len1 = strlen ( cd_height ) ;
807 len2 = strlen ( cd_width ) ;
808 len3 = strlen ( cd_depth ) ;
809 initial_y_offset = win_height / 2 - font_height - font_info -> descent ;
810 x_offset = win_width / 4 ;
811 XDrawString ( display , win , gc , x_offset , initial_y_offset , string4 ,
812 len4 ) ;
813 XDrawString ( display , win , gc , x_offset ,
814 initial_y_offset + font_height , cd_height , len1 ) ;
815 XDrawString ( display , win , gc , x_offset ,
816 initial_y_offset + 2 * font_height , cd_width , len2 ) ;
817 XDrawString ( display , win , gc , x_offset ,
818 initial_y_offset + 3 * font_height , cd_depth , len3 ) ;
819 }
820
821 void
822 place_graphics ( Window win , GC gc , unsigned int window_width ,
823 unsigned int window_height )
824 {
825 int
826 x ,
827 y ,
828 width ,
829 height ;
830
831 height = window_height / 2 ;
832 width = 3 * window_width / 4 ;
833 x = window_width / 2 - width / 2 ;
834 y = window_height / 2 - height / 2 ;
835 XDrawRectangle ( display , win , gc , x , y , width , height ) ;
836 }
837
838 void
839 TooSmall ( Window win , GC gc , XFontStruct *font_info )
840 {
841 char
842 *string1 = "Too Small" ;
843 int
844 x_offset ,
845 y_offset ;
846
847 y_offset = font_info -> ascent + 2 ;
848 x_offset = 2 ;
849 XDrawString ( display , win , gc , x_offset , y_offset , string1 ,
850 strlen ( string1 ) ) ;
851 }
852 #endif