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