File: clralloc.c

package info (click to toggle)
saoimage 1.19-5
  • links: PTS
  • area: main
  • in suites: slink
  • size: 3,256 kB
  • ctags: 3,610
  • sloc: ansic: 36,050; makefile: 215; sh: 11
file content (199 lines) | stat: -rw-r--r-- 6,935 bytes parent folder | download | duplicates (3)
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;
}