home *** CD-ROM | disk | FTP | other *** search
/ Encyclopedia of Graphics File Formats Companion / GFF_CD.ISO / software / unix / saoimage / sao1_07.tar / clralloc.c < prev    next >
C/C++ Source or Header  |  1991-01-07  |  7KB  |  200 lines

  1. #ifndef lint
  2. static char SccsId[] = "%W%  %G%";
  3. #endif
  4.  
  5. /* Module:    clralloc.c (Color Alloc)
  6.  * Purpose:    Allocate and free colors
  7.  * Subroutine:    alloc_color()            returns: int
  8.  * Subroutine:    free_color_cells()        returns: void
  9.  * Xlib calls:    XAllocColorCells(), XFreeColors()
  10.  * Copyright:    1989 Smithsonian Astrophysical Observatory
  11.  *        You may do anything you like with this file except remove
  12.  *        this copyright.  The Smithsonian Astrophysical Observatory
  13.  *        makes no representations about the suitability of this
  14.  *        software for any purpose.  It is provided "as is" without
  15.  *        express or implied warranty.
  16.  * Modified:    {0} Michael VanHilst    initial version           9 May 1989
  17.  *        {1} David Muchmore    private colormap      20 May 1990
  18.  *        {2} MVH Allow 4&5 plane machines to use color       1 Jan 1991
  19.  *        {n} <who> -- <does what> -- <when>
  20.  */
  21.  
  22. #include <stdio.h>            /* stderr, FILE, NULL, etc. */
  23. #include <X11/Xlib.h>            /* X window stuff */
  24. #include <X11/Xutil.h>            /* X window manager stuff */
  25. #include "hfiles/define.h"        /* YES, NO, MIN, MAX and more */
  26. #include "hfiles/color.h"        /* color structs */
  27.  
  28. #define COPIES 20  /* max number of default colors to copy to private map */
  29.  
  30. static unsigned int _npixels;        /* for XAllocColorCells */
  31. static unsigned int _nplanes;        /* for XAllocColorCells */
  32. static unsigned long overlay_mask;    /* for XAllocColorCells */
  33.  
  34. /*
  35.  * Subroutine:    alloc_colors
  36.  * Purpose:    Allocate color cells with and overlay plane if possible
  37.  * Returns:    1 if allocated an acceptable number of cells, else 0
  38.  * Method:    Try for at least min cells in default colormap, if failed
  39.  *        try to create a private colormap.
  40.  */
  41. int alloc_colors( color )
  42.      struct colorRec *color;
  43. {
  44.   int verify_pseudocolor();
  45.   static Colormap create_colormap();
  46.   static int alloc_color_cells();
  47.  
  48.   if( (color->map.default_permit != NO) &&
  49.       (color->map.default_enable == YES) &&
  50.       (alloc_color_cells(color, color->map.default_colormap,
  51.              color->map.default_vinfo)) ) {
  52.     /* If the default colormap can satisfy our desires */
  53.     color->colormap = color->map.default_colormap;
  54.     return 1;
  55.   } else if( color->map.private_permit != NO ) {
  56.     /* If the existance of a pseudocolor visual has not yet been tested */
  57.     if( (color->map.private_enable == UNKNOWN) &&
  58.         (verify_pseudocolor(color, 4, 16) == 0) ) {
  59.       return 0;
  60.     }
  61.     if( color->map.private_enable == YES ) {
  62.       if( color->map.private_used == UNKNOWN ) {
  63.         if( (color->map.private_colormap =
  64.          create_colormap(color)) == 0 ) {
  65.       return 0;
  66.     }
  67.         color->colormap = color->map.private_colormap;
  68.     /* Redo the cursor color allocation */
  69.     init_hard_colors(color, color->colormap);
  70.     lookup_cursor_colors(color, color->colormap, 1);
  71.         color->map.private_used = 1;
  72.     XInstallColormap(color->display, color->colormap);
  73.         color->map.private_installed = 1;
  74.         color->visual = color->map.private_vinfo->visual;
  75.       }
  76.       if (alloc_color_cells(color, color->map.private_colormap,
  77.              color->map.private_vinfo) ) {
  78.     return 1;
  79.       }
  80.       else {
  81.     return 0;
  82.       }
  83.     }
  84.   }
  85.   return 0;
  86. }
  87.  
  88.  
  89. /* Subroutine:    alloc_color_cells
  90.  * Returns:    1 if alloc's at least min cells, else 0
  91.  * PostState:
  92.  * Xlib calls:    XAllocColorCells()
  93.  * Method:    Grab as many cells as possible with overlay as specified
  94.  */
  95. static int alloc_color_cells ( color, colormap, vinfo )
  96.      struct colorRec *color;    /* i: color info and handling struct */
  97.      Colormap colormap;        /* i: colormap in which to allocate */
  98.      XVisualInfo *vinfo;
  99. {
  100.   void free_color_cells();
  101.  
  102.   int contig = 0;
  103.   /*  For those with few colors, let them see what they can do  */
  104.   if( (vinfo->colormap_size < 100) && (vinfo->colormap_size < 8) ) {
  105.     /*  Drop from original default (hopefully user didn't specify this)  */
  106.     if( color->cells.min == 20 )
  107.       color->cells.min = 4;
  108.     /*  Reserve cells for image and 1 overlay  */
  109.     if( color->cells.overlay ) {
  110.       _nplanes = 1;
  111.       /*  Allow for 8 standard colors plus 2 overlayable fixed colors  */
  112.       _npixels = MIN(color->cells.wanted + 2, (vinfo->colormap_size) / 2);
  113.     } else {
  114.       _nplanes = 0;
  115.       _npixels = MIN(color->cells.wanted, vinfo->colormap_size);
  116.     }
  117.   } else {
  118.        /*  Reserve cells for image and 1 overlay  */
  119.     if( color->cells.overlay ) {
  120.       _nplanes = 1;
  121.       /*  Allow for 8 standard colors plus 2 overlayable fixed colors  */
  122.       _npixels = MIN(color->cells.wanted + 2, (vinfo->colormap_size - 8) / 2);
  123.     } else {
  124.       _nplanes = 0;
  125.       _npixels = MIN(color->cells.wanted, vinfo->colormap_size - 8);
  126.     }
  127.   }
  128.   while( (_npixels >= color->cells.min) &&
  129.      (XAllocColorCells(color->display, colormap, contig, &overlay_mask,
  130.                _nplanes, color->pixvalmap, _npixels) == NULL) )
  131.     /* Try again with fewer if request failed (down to mincells) */
  132.     _npixels--;
  133.   if( _npixels < color->cells.min )
  134.     return( 0 );
  135.   color->colormap = colormap;
  136.   color->ncolors = _npixels;
  137.   if( color->cells.overlay )
  138.     color->overlay_mask = overlay_mask;
  139.   else
  140.     color->overlay_mask = 0;
  141.   color->colors_alloced = 1;
  142.   return 1;
  143. }
  144.  
  145. /*
  146.  * Subroutine:    free_color_cells
  147.  * Purpose:    un-alloc alloc'd color map cells
  148.  * Xlib calls:    XFreeColors()
  149.  */
  150. void free_color_cells ( color, colormap )
  151.      struct colorRec *color;    /* i: color info and handling struct */
  152.      Colormap colormap;
  153. {  
  154.   XFreeColors (color->display, colormap, color->pixvalmap, _npixels, _nplanes);
  155.   bzero((char *)color->pixvalmap, COLMAPSZ * sizeof(int));
  156.   color->ncolors = 0;
  157.   color->colors_alloced = 0;
  158. }
  159.   
  160. /*
  161.  * Subroutine:    create_colormap
  162.  * Purpose:    Create a private colormap with some of the default map's colors
  163.  *        copied into it.  The copied colors are static (reducing the
  164.  *        number of available colors should the user attempt to increase
  165.  *        them later on.
  166.  */
  167. static Colormap create_colormap ( color )
  168.      struct colorRec *color;
  169. {
  170.   Colormap private_colormap;
  171.   XColor cdef[COPIES];
  172.   int color_levels, copy_levels, i;
  173.   void exit_errmsg();
  174.  
  175.   /* Get the colormap */
  176.   private_colormap =
  177.     XCreateColormap(color->display, RootWindow(color->display, color->screen),
  178.             color->map.private_vinfo->visual, AllocNone);
  179.   if( private_colormap ) {
  180.     /* Copy all of the default map's colors into the new map */
  181.     color_levels = DisplayCells(color->display, color->screen);
  182.     copy_levels = MIN(COPIES, (color_levels - (color->cells.wanted + 10)));
  183.     if( copy_levels > 0 ) {
  184.       for( i=0; i<copy_levels; i++ ) {
  185.     cdef[i].pixel = i;
  186.     cdef[i].flags = DoRed|DoGreen|DoBlue;
  187.       }
  188.       XQueryColors(color->display,
  189.            DefaultColormap(color->display, color->screen),
  190.            cdef, copy_levels);
  191.       /* We trust that the manger allocates starting at 0 */
  192.       for( i=0; i<copy_levels; i++ )
  193.     XAllocColor(color->display, private_colormap, &(cdef[i]));
  194.     }
  195.   } else
  196.     exit_errmsg("Unable to create new colormap");
  197.   /* use special distribution plan for allocation. */
  198.   return private_colormap;
  199. }
  200.