"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