mirror of
https://github.com/gryf/wmaker.git
synced 2025-12-23 06:38:05 +01:00
- standard colormap support for PseudoColor visuals
- set wrlib library version to 4:0:3 (1.3.0)
This commit is contained in:
335
wrlib/CmapAlloc.c
Normal file
335
wrlib/CmapAlloc.c
Normal file
@@ -0,0 +1,335 @@
|
|||||||
|
/* $XConsortium: CmapAlloc.c,v 1.9 94/04/17 20:15:52 rws Exp $ */
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
Copyright (c) 1989, 1994 X Consortium
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||||
|
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
Except as contained in this notice, the name of the X Consortium shall not be
|
||||||
|
used in advertising or otherwise to promote the sale, use or other dealings
|
||||||
|
in this Software without prior written authorization from the X Consortium.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Author: Donna Converse, MIT X Consortium
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <X11/Xlib.h>
|
||||||
|
#include <X11/Xatom.h>
|
||||||
|
#include <X11/Xutil.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#define lowbit(x) ((x) & (~(x) + 1))
|
||||||
|
|
||||||
|
static int default_allocation();
|
||||||
|
static void best_allocation();
|
||||||
|
static void gray_allocation();
|
||||||
|
static int icbrt();
|
||||||
|
static int icbrt_with_bits();
|
||||||
|
static int icbrt_with_guess();
|
||||||
|
|
||||||
|
/* To determine the best allocation of reds, greens, and blues in a
|
||||||
|
* standard colormap, use XmuGetColormapAllocation.
|
||||||
|
* vinfo specifies visual information for a chosen visual
|
||||||
|
* property specifies one of the standard colormap property names
|
||||||
|
* red_max returns maximum red value
|
||||||
|
* green_max returns maximum green value
|
||||||
|
* blue_max returns maximum blue value
|
||||||
|
*
|
||||||
|
* XmuGetColormapAllocation returns 0 on failure, non-zero on success.
|
||||||
|
* It is assumed that the visual is appropriate for the colormap property.
|
||||||
|
*/
|
||||||
|
|
||||||
|
Status XmuGetColormapAllocation(vinfo, property, red_max, green_max, blue_max)
|
||||||
|
XVisualInfo *vinfo;
|
||||||
|
Atom property;
|
||||||
|
unsigned long *red_max, *green_max, *blue_max;
|
||||||
|
{
|
||||||
|
Status status = 1;
|
||||||
|
|
||||||
|
if (vinfo->colormap_size <= 2)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
switch (property)
|
||||||
|
{
|
||||||
|
case XA_RGB_DEFAULT_MAP:
|
||||||
|
status = default_allocation(vinfo, red_max, green_max, blue_max);
|
||||||
|
break;
|
||||||
|
case XA_RGB_BEST_MAP:
|
||||||
|
best_allocation(vinfo, red_max, green_max, blue_max);
|
||||||
|
break;
|
||||||
|
case XA_RGB_GRAY_MAP:
|
||||||
|
gray_allocation(vinfo->colormap_size, red_max, green_max, blue_max);
|
||||||
|
break;
|
||||||
|
case XA_RGB_RED_MAP:
|
||||||
|
*red_max = vinfo->colormap_size - 1;
|
||||||
|
*green_max = *blue_max = 0;
|
||||||
|
break;
|
||||||
|
case XA_RGB_GREEN_MAP:
|
||||||
|
*green_max = vinfo->colormap_size - 1;
|
||||||
|
*red_max = *blue_max = 0;
|
||||||
|
break;
|
||||||
|
case XA_RGB_BLUE_MAP:
|
||||||
|
*blue_max = vinfo->colormap_size - 1;
|
||||||
|
*red_max = *green_max = 0;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
status = 0;
|
||||||
|
}
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************/
|
||||||
|
/* Determine the appropriate color allocations of a gray scale.
|
||||||
|
*
|
||||||
|
* Keith Packard, MIT X Consortium
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void gray_allocation(n, red_max, green_max, blue_max)
|
||||||
|
int n; /* the number of cells of the gray scale */
|
||||||
|
unsigned long *red_max, *green_max, *blue_max;
|
||||||
|
{
|
||||||
|
*red_max = (n * 30) / 100;
|
||||||
|
*green_max = (n * 59) / 100;
|
||||||
|
*blue_max = (n * 11) / 100;
|
||||||
|
*green_max += ((n - 1) - (*red_max + *green_max + *blue_max));
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************/
|
||||||
|
/* Determine an appropriate color allocation for the RGB_DEFAULT_MAP.
|
||||||
|
* If a map has less than a minimum number of definable entries, we do not
|
||||||
|
* produce an allocation for an RGB_DEFAULT_MAP.
|
||||||
|
*
|
||||||
|
* For 16 planes, the default colormap will have 27 each RGB; for 12 planes,
|
||||||
|
* 12 each. For 8 planes, let n = the number of colormap entries, which may
|
||||||
|
* be 256 or 254. Then, maximum red value = floor(cube_root(n - 125)) - 1.
|
||||||
|
* Maximum green and maximum blue values are identical to maximum red.
|
||||||
|
* This leaves at least 125 cells which clients can allocate.
|
||||||
|
*
|
||||||
|
* Return 0 if an allocation has been determined, non-zero otherwise.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static int default_allocation(vinfo, red, green, blue)
|
||||||
|
XVisualInfo *vinfo;
|
||||||
|
unsigned long *red, *green, *blue;
|
||||||
|
{
|
||||||
|
int ngrays; /* number of gray cells */
|
||||||
|
|
||||||
|
switch (vinfo->class) {
|
||||||
|
case PseudoColor:
|
||||||
|
|
||||||
|
if (vinfo->colormap_size > 65000)
|
||||||
|
/* intended for displays with 16 planes */
|
||||||
|
*red = *green = *blue = (unsigned long) 27;
|
||||||
|
else if (vinfo->colormap_size > 4000)
|
||||||
|
/* intended for displays with 12 planes */
|
||||||
|
*red = *green = *blue = (unsigned long) 12;
|
||||||
|
else if (vinfo->colormap_size < 250)
|
||||||
|
return 0;
|
||||||
|
else
|
||||||
|
/* intended for displays with 8 planes */
|
||||||
|
*red = *green = *blue = (unsigned long)
|
||||||
|
(icbrt(vinfo->colormap_size - 125) - 1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DirectColor:
|
||||||
|
|
||||||
|
if (vinfo->colormap_size < 10)
|
||||||
|
return 0;
|
||||||
|
*red = *green = *blue = vinfo->colormap_size / 2 - 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TrueColor:
|
||||||
|
|
||||||
|
*red = vinfo->red_mask / lowbit(vinfo->red_mask);
|
||||||
|
*green = vinfo->green_mask / lowbit(vinfo->green_mask);
|
||||||
|
*blue = vinfo->blue_mask / lowbit(vinfo->blue_mask);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GrayScale:
|
||||||
|
|
||||||
|
if (vinfo->colormap_size > 65000)
|
||||||
|
ngrays = 4096;
|
||||||
|
else if (vinfo->colormap_size > 4000)
|
||||||
|
ngrays = 512;
|
||||||
|
else if (vinfo->colormap_size < 250)
|
||||||
|
return 0;
|
||||||
|
else
|
||||||
|
ngrays = 12;
|
||||||
|
gray_allocation(ngrays, red, green, blue);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************/
|
||||||
|
/* Determine an appropriate color allocation for the RGB_BEST_MAP.
|
||||||
|
*
|
||||||
|
* For a DirectColor or TrueColor visual, the allocation is determined
|
||||||
|
* by the red_mask, green_mask, and blue_mask members of the visual info.
|
||||||
|
*
|
||||||
|
* Otherwise, if the colormap size is an integral power of 2, determine
|
||||||
|
* the allocation according to the number of bits given to each color,
|
||||||
|
* with green getting more than red, and red more than blue, if there
|
||||||
|
* are to be inequities in the distribution. If the colormap size is
|
||||||
|
* not an integral power of 2, let n = the number of colormap entries.
|
||||||
|
* Then maximum red value = floor(cube_root(n)) - 1;
|
||||||
|
* maximum blue value = floor(cube_root(n)) - 1;
|
||||||
|
* maximum green value = n / ((# red values) * (# blue values)) - 1;
|
||||||
|
* Which, on a GPX, allows for 252 entries in the best map, out of 254
|
||||||
|
* defineable colormap entries.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void best_allocation(vinfo, red, green, blue)
|
||||||
|
XVisualInfo *vinfo;
|
||||||
|
unsigned long *red, *green, *blue;
|
||||||
|
{
|
||||||
|
|
||||||
|
if (vinfo->class == DirectColor || vinfo->class == TrueColor)
|
||||||
|
{
|
||||||
|
*red = vinfo->red_mask;
|
||||||
|
while ((*red & 01) == 0)
|
||||||
|
*red >>= 1;
|
||||||
|
*green = vinfo->green_mask;
|
||||||
|
while ((*green & 01) == 0)
|
||||||
|
*green >>=1;
|
||||||
|
*blue = vinfo->blue_mask;
|
||||||
|
while ((*blue & 01) == 0)
|
||||||
|
*blue >>= 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
register int bits, n;
|
||||||
|
|
||||||
|
/* Determine n such that n is the least integral power of 2 which is
|
||||||
|
* greater than or equal to the number of entries in the colormap.
|
||||||
|
*/
|
||||||
|
n = 1;
|
||||||
|
bits = 0;
|
||||||
|
while (vinfo->colormap_size > n)
|
||||||
|
{
|
||||||
|
n = n << 1;
|
||||||
|
bits++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If the number of entries in the colormap is a power of 2, determine
|
||||||
|
* the allocation by "dealing" the bits, first to green, then red, then
|
||||||
|
* blue. If not, find the maximum integral red, green, and blue values
|
||||||
|
* which, when multiplied together, do not exceed the number of
|
||||||
|
|
||||||
|
* colormap entries.
|
||||||
|
*/
|
||||||
|
if (n == vinfo->colormap_size)
|
||||||
|
{
|
||||||
|
register int r, g, b;
|
||||||
|
b = bits / 3;
|
||||||
|
g = b + ((bits % 3) ? 1 : 0);
|
||||||
|
r = b + (((bits % 3) == 2) ? 1 : 0);
|
||||||
|
*red = 1 << r;
|
||||||
|
*green = 1 << g;
|
||||||
|
*blue = 1 << b;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*red = icbrt_with_bits(vinfo->colormap_size, bits);
|
||||||
|
*blue = *red;
|
||||||
|
*green = (vinfo->colormap_size / ((*red) * (*blue)));
|
||||||
|
}
|
||||||
|
(*red)--;
|
||||||
|
(*green)--;
|
||||||
|
(*blue)--;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* integer cube roots by Newton's method
|
||||||
|
*
|
||||||
|
* Stephen Gildea, MIT X Consortium, July 1991
|
||||||
|
*/
|
||||||
|
|
||||||
|
static int icbrt(a) /* integer cube root */
|
||||||
|
int a;
|
||||||
|
{
|
||||||
|
register int bits = 0;
|
||||||
|
register unsigned n = a;
|
||||||
|
|
||||||
|
while (n)
|
||||||
|
{
|
||||||
|
bits++;
|
||||||
|
n >>= 1;
|
||||||
|
}
|
||||||
|
return icbrt_with_bits(a, bits);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int icbrt_with_bits(a, bits)
|
||||||
|
int a;
|
||||||
|
int bits; /* log 2 of a */
|
||||||
|
{
|
||||||
|
return icbrt_with_guess(a, a>>2*bits/3);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef _X_ROOT_STATS
|
||||||
|
int icbrt_loopcount;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Newton's Method: x_n+1 = x_n - ( f(x_n) / f'(x_n) ) */
|
||||||
|
|
||||||
|
/* for cube roots, x^3 - a = 0, x_new = x - 1/3 (x - a/x^2) */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Quick and dirty cube roots. Nothing fancy here, just Newton's method.
|
||||||
|
* Only works for positive integers (since that's all we need).
|
||||||
|
* We actually return floor(cbrt(a)) because that's what we need here, too.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static int icbrt_with_guess(a, guess)
|
||||||
|
int a, guess;
|
||||||
|
{
|
||||||
|
register int delta;
|
||||||
|
|
||||||
|
#ifdef _X_ROOT_STATS
|
||||||
|
icbrt_loopcount = 0;
|
||||||
|
#endif
|
||||||
|
if (a <= 0)
|
||||||
|
return 0;
|
||||||
|
if (guess < 1)
|
||||||
|
guess = 1;
|
||||||
|
|
||||||
|
do {
|
||||||
|
#ifdef _X_ROOT_STATS
|
||||||
|
icbrt_loopcount++;
|
||||||
|
#endif
|
||||||
|
delta = (guess - a/(guess*guess))/3;
|
||||||
|
#ifdef DEBUG
|
||||||
|
printf("pass %d: guess=%d, delta=%d\n", icbrt_loopcount, guess, delta);
|
||||||
|
#endif
|
||||||
|
guess -= delta;
|
||||||
|
} while (delta != 0);
|
||||||
|
|
||||||
|
if (guess*guess*guess > a)
|
||||||
|
guess--;
|
||||||
|
|
||||||
|
return guess;
|
||||||
|
}
|
||||||
524
wrlib/CrCmap.c
Normal file
524
wrlib/CrCmap.c
Normal file
@@ -0,0 +1,524 @@
|
|||||||
|
/* $XConsortium: CrCmap.c,v 1.6 94/04/17 20:15:53 rws Exp $ */
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
Copyright (c) 1989 X Consortium
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||||
|
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
Except as contained in this notice, the name of the X Consortium shall not be
|
||||||
|
used in advertising or otherwise to promote the sale, use or other dealings
|
||||||
|
in this Software without prior written authorization from the X Consortium.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Author: Donna Converse, MIT X Consortium
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* CreateCmap.c - given a standard colormap description, make the map.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <X11/Xlib.h>
|
||||||
|
#include <X11/Xutil.h>
|
||||||
|
|
||||||
|
|
||||||
|
static int ROmap(); /* allocate entire map Read Only */
|
||||||
|
static Status ROorRWcell(); /* allocate a cell, prefer Read Only */
|
||||||
|
static Status RWcell(); /* allocate a cell Read Write */
|
||||||
|
static int compare(); /* for quicksort */
|
||||||
|
static Status contiguous(); /* find contiguous sequence of cells */
|
||||||
|
static void free_cells(); /* frees resources before quitting */
|
||||||
|
static Status readonly_map(); /* create a map in a RO visual type */
|
||||||
|
static Status readwrite_map(); /* create a map in a RW visual type */
|
||||||
|
|
||||||
|
#define lowbit(x) ((x) & (~(x) + 1))
|
||||||
|
#define TRUEMATCH(mult,max,mask) \
|
||||||
|
(colormap->max * colormap->mult <= vinfo->mask && \
|
||||||
|
lowbit(vinfo->mask) == colormap->mult)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* To create any one colormap which is described by an XStandardColormap
|
||||||
|
* structure, use XmuCreateColormap().
|
||||||
|
*
|
||||||
|
* Return 0 on failure, non-zero on success.
|
||||||
|
* Resources created by this function are not made permanent.
|
||||||
|
* No argument error checking is provided. Use at your own risk.
|
||||||
|
*
|
||||||
|
* All colormaps are created with read only allocations, with the exception
|
||||||
|
* of read only allocations of colors in the default map or otherwise
|
||||||
|
* which fail to return the expected pixel value, and these are individually
|
||||||
|
* defined as read/write allocations. This is done so that all the cells
|
||||||
|
* defined in the default map are contiguous, for use in image processing.
|
||||||
|
* This typically happens with White and Black in the default map.
|
||||||
|
*
|
||||||
|
* Colormaps of static visuals are considered to be successfully created if
|
||||||
|
* the map of the static visual matches the definition given in the
|
||||||
|
* standard colormap structure.
|
||||||
|
*/
|
||||||
|
|
||||||
|
Status XmuCreateColormap(dpy, colormap)
|
||||||
|
Display *dpy; /* specifies the connection under
|
||||||
|
* which the map is created */
|
||||||
|
XStandardColormap *colormap; /* specifies the map to be created,
|
||||||
|
* and returns, particularly if the
|
||||||
|
* map is created as a subset of the
|
||||||
|
* default colormap of the screen,
|
||||||
|
* the base_pixel of the map.
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
XVisualInfo vinfo_template; /* template visual information */
|
||||||
|
XVisualInfo *vinfo; /* matching visual information */
|
||||||
|
XVisualInfo *vpointer; /* for freeing the entire list */
|
||||||
|
long vinfo_mask; /* specifies the visual mask value */
|
||||||
|
int n; /* number of matching visuals */
|
||||||
|
int status;
|
||||||
|
|
||||||
|
vinfo_template.visualid = colormap->visualid;
|
||||||
|
vinfo_mask = VisualIDMask;
|
||||||
|
if ((vinfo = XGetVisualInfo(dpy, vinfo_mask, &vinfo_template, &n)) == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* A visual id may be valid on multiple screens. Also, there may
|
||||||
|
* be multiple visuals with identical visual ids at different depths.
|
||||||
|
* If the colormap is the Default Colormap, use the Default Visual.
|
||||||
|
* Otherwise, arbitrarily, use the deepest visual.
|
||||||
|
*/
|
||||||
|
vpointer = vinfo;
|
||||||
|
if (n > 1)
|
||||||
|
{
|
||||||
|
register int i;
|
||||||
|
register int screen_number;
|
||||||
|
Bool def_cmap;
|
||||||
|
|
||||||
|
def_cmap = False;
|
||||||
|
for (screen_number = ScreenCount(dpy); --screen_number >= 0; )
|
||||||
|
if (colormap->colormap == DefaultColormap(dpy, screen_number)) {
|
||||||
|
def_cmap = True;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (def_cmap) {
|
||||||
|
for (i=0; i < n; i++, vinfo++) {
|
||||||
|
if (vinfo->visual == DefaultVisual(dpy, screen_number))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
unsigned int maxdepth = 0;
|
||||||
|
XVisualInfo *v;
|
||||||
|
|
||||||
|
for (i=0; i < n; i++, vinfo++)
|
||||||
|
if (vinfo->depth > maxdepth) {
|
||||||
|
maxdepth = vinfo->depth;
|
||||||
|
v = vinfo;
|
||||||
|
}
|
||||||
|
vinfo = v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vinfo->class == PseudoColor || vinfo->class == DirectColor ||
|
||||||
|
vinfo->class == GrayScale)
|
||||||
|
status = readwrite_map(dpy, vinfo, colormap);
|
||||||
|
else if (vinfo->class == TrueColor)
|
||||||
|
status = TRUEMATCH(red_mult, red_max, red_mask) &&
|
||||||
|
TRUEMATCH(green_mult, green_max, green_mask) &&
|
||||||
|
TRUEMATCH(blue_mult, blue_max, blue_mask);
|
||||||
|
else
|
||||||
|
status = readonly_map(dpy, vinfo, colormap);
|
||||||
|
|
||||||
|
XFree((char *) vpointer);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************/
|
||||||
|
static Status readwrite_map(dpy, vinfo, colormap)
|
||||||
|
Display *dpy;
|
||||||
|
XVisualInfo *vinfo;
|
||||||
|
XStandardColormap *colormap;
|
||||||
|
{
|
||||||
|
register unsigned long i, n; /* index counters */
|
||||||
|
int ncolors; /* number of colors to be defined */
|
||||||
|
int npixels; /* number of pixels allocated R/W */
|
||||||
|
int first_index; /* first index of pixels to use */
|
||||||
|
int remainder; /* first index of remainder */
|
||||||
|
XColor color; /* the definition of a color */
|
||||||
|
unsigned long *pixels; /* array of colormap pixels */
|
||||||
|
unsigned long delta;
|
||||||
|
|
||||||
|
|
||||||
|
/* Determine ncolors, the number of colors to be defined.
|
||||||
|
* Insure that 1 < ncolors <= the colormap size.
|
||||||
|
*/
|
||||||
|
if (vinfo->class == DirectColor) {
|
||||||
|
ncolors = colormap->red_max;
|
||||||
|
if (colormap->green_max > ncolors)
|
||||||
|
ncolors = colormap->green_max;
|
||||||
|
if (colormap->blue_max > ncolors)
|
||||||
|
ncolors = colormap->blue_max;
|
||||||
|
ncolors++;
|
||||||
|
delta = lowbit(vinfo->red_mask) +
|
||||||
|
lowbit(vinfo->green_mask) +
|
||||||
|
lowbit(vinfo->blue_mask);
|
||||||
|
} else {
|
||||||
|
ncolors = colormap->red_max * colormap->red_mult +
|
||||||
|
colormap->green_max * colormap->green_mult +
|
||||||
|
colormap->blue_max * colormap->blue_mult + 1;
|
||||||
|
delta = 1;
|
||||||
|
}
|
||||||
|
if (ncolors <= 1 || ncolors > vinfo->colormap_size) return 0;
|
||||||
|
|
||||||
|
/* Allocate Read/Write as much of the colormap as we can possibly get.
|
||||||
|
* Then insure that the pixels we were allocated are given in
|
||||||
|
* monotonically increasing order, using a quicksort. Next, insure
|
||||||
|
* that our allocation includes a subset of contiguous pixels at least
|
||||||
|
* as long as the number of colors to be defined. Now we know that
|
||||||
|
* these conditions are met:
|
||||||
|
* 1) There are no free cells in the colormap.
|
||||||
|
* 2) We have a contiguous sequence of pixels, monotonically
|
||||||
|
* increasing, of length >= the number of colors requested.
|
||||||
|
*
|
||||||
|
* One cell at a time, we will free, compute the next color value,
|
||||||
|
* then allocate read only. This takes a long time.
|
||||||
|
* This is done to insure that cells are allocated read only in the
|
||||||
|
* contiguous order which we prefer. If the server has a choice of
|
||||||
|
* cells to grant to an allocation request, the server may give us any
|
||||||
|
* cell, so that is why we do these slow gymnastics.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if ((pixels = (unsigned long *) calloc((unsigned) vinfo->colormap_size,
|
||||||
|
sizeof(unsigned long))) == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if ((npixels = ROmap(dpy, colormap->colormap, pixels,
|
||||||
|
vinfo->colormap_size, ncolors)) == 0) {
|
||||||
|
free((char *) pixels);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
qsort((char *) pixels, npixels, sizeof(unsigned long), compare);
|
||||||
|
|
||||||
|
if (!contiguous(pixels, npixels, ncolors, delta, &first_index, &remainder))
|
||||||
|
{
|
||||||
|
/* can't find enough contiguous cells, give up */
|
||||||
|
XFreeColors(dpy, colormap->colormap, pixels, npixels,
|
||||||
|
(unsigned long) 0);
|
||||||
|
free((char *) pixels);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
colormap->base_pixel = pixels[first_index];
|
||||||
|
|
||||||
|
/* construct a gray map */
|
||||||
|
if (colormap->red_mult == 1 && colormap->green_mult == 1 &&
|
||||||
|
colormap->blue_mult == 1)
|
||||||
|
for (n=colormap->base_pixel, i=0; i < ncolors; i++, n += delta)
|
||||||
|
{
|
||||||
|
color.pixel = n;
|
||||||
|
color.blue = color.green = color.red =
|
||||||
|
(unsigned short) ((i * 65535) / (colormap->red_max +
|
||||||
|
colormap->green_max +
|
||||||
|
colormap->blue_max));
|
||||||
|
|
||||||
|
if (! ROorRWcell(dpy, colormap->colormap, pixels, npixels, &color,
|
||||||
|
first_index + i))
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* construct a red ramp map */
|
||||||
|
else if (colormap->green_max == 0 && colormap->blue_max == 0)
|
||||||
|
for (n=colormap->base_pixel, i=0; i < ncolors; i++, n += delta)
|
||||||
|
{
|
||||||
|
color.pixel = n;
|
||||||
|
color.red = (unsigned short) ((i * 65535) / colormap->red_max);
|
||||||
|
color.green = color.blue = 0;
|
||||||
|
|
||||||
|
if (! ROorRWcell(dpy, colormap->colormap, pixels, npixels, &color,
|
||||||
|
first_index + i))
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* construct a green ramp map */
|
||||||
|
else if (colormap->red_max == 0 && colormap->blue_max == 0)
|
||||||
|
for (n=colormap->base_pixel, i=0; i < ncolors; i++, n += delta)
|
||||||
|
{
|
||||||
|
color.pixel = n;
|
||||||
|
color.green = (unsigned short) ((i * 65535) / colormap->green_max);
|
||||||
|
color.red = color.blue = 0;
|
||||||
|
|
||||||
|
if (! ROorRWcell(dpy, colormap->colormap, pixels, npixels, &color,
|
||||||
|
first_index + i))
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* construct a blue ramp map */
|
||||||
|
else if (colormap->red_max == 0 && colormap->green_max == 0)
|
||||||
|
for (n=colormap->base_pixel, i=0; i < ncolors; i++, n += delta)
|
||||||
|
{
|
||||||
|
color.pixel = n;
|
||||||
|
color.blue = (unsigned short) ((i * 65535) / colormap->blue_max);
|
||||||
|
color.red = color.green = 0;
|
||||||
|
|
||||||
|
if (! ROorRWcell(dpy, colormap->colormap, pixels, npixels, &color,
|
||||||
|
first_index + i))
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* construct a standard red green blue cube map */
|
||||||
|
else
|
||||||
|
{
|
||||||
|
#define calc(max,mult) (((n / colormap->mult) % \
|
||||||
|
(colormap->max + 1)) * 65535) / colormap->max
|
||||||
|
|
||||||
|
for (n=0, i=0; i < ncolors; i++, n += delta)
|
||||||
|
{
|
||||||
|
color.pixel = n + colormap->base_pixel;
|
||||||
|
color.red = calc(red_max, red_mult);
|
||||||
|
color.green = calc(green_max, green_mult);
|
||||||
|
color.blue = calc(blue_max, blue_mult);
|
||||||
|
if (! ROorRWcell(dpy, colormap->colormap, pixels, npixels, &color,
|
||||||
|
first_index + i))
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#undef calc
|
||||||
|
}
|
||||||
|
/* We have a read-only map defined. Now free unused cells,
|
||||||
|
* first those occuring before the contiguous sequence begins,
|
||||||
|
* then any following the contiguous sequence.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (first_index)
|
||||||
|
XFreeColors(dpy, colormap->colormap, pixels, first_index,
|
||||||
|
(unsigned long) 0);
|
||||||
|
if (remainder)
|
||||||
|
XFreeColors(dpy, colormap->colormap,
|
||||||
|
&(pixels[first_index + ncolors]), remainder,
|
||||||
|
(unsigned long) 0);
|
||||||
|
|
||||||
|
free((char *) pixels);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/****************************************************************************/
|
||||||
|
static int ROmap(dpy, cmap, pixels, m, n)
|
||||||
|
Display *dpy; /* the X server connection */
|
||||||
|
Colormap cmap; /* specifies colormap ID */
|
||||||
|
unsigned long pixels[]; /* returns pixel allocations */
|
||||||
|
int m; /* specifies colormap size */
|
||||||
|
int n; /* specifies number of colors */
|
||||||
|
{
|
||||||
|
register int p;
|
||||||
|
|
||||||
|
/* first try to allocate the entire colormap */
|
||||||
|
if (XAllocColorCells(dpy, cmap, 1, (unsigned long *) NULL,
|
||||||
|
(unsigned) 0, pixels, (unsigned) m))
|
||||||
|
return m;
|
||||||
|
|
||||||
|
/* Allocate all available cells in the colormap, using a binary
|
||||||
|
* algorithm to discover how many cells we can allocate in the colormap.
|
||||||
|
*/
|
||||||
|
m--;
|
||||||
|
while (n <= m) {
|
||||||
|
p = n + ((m - n + 1) / 2);
|
||||||
|
if (XAllocColorCells(dpy, cmap, 1, (unsigned long *) NULL,
|
||||||
|
(unsigned) 0, pixels, (unsigned) p)) {
|
||||||
|
if (p == m)
|
||||||
|
return p;
|
||||||
|
else {
|
||||||
|
XFreeColors(dpy, cmap, pixels, p, (unsigned long) 0);
|
||||||
|
n = p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
m = p - 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/****************************************************************************/
|
||||||
|
static Status contiguous(pixels, npixels, ncolors, delta, first, rem)
|
||||||
|
unsigned long pixels[]; /* specifies allocated pixels */
|
||||||
|
int npixels; /* specifies count of alloc'd pixels */
|
||||||
|
int ncolors; /* specifies needed sequence length */
|
||||||
|
unsigned long delta; /* between pixels */
|
||||||
|
int *first; /* returns first index of sequence */
|
||||||
|
int *rem; /* returns first index after sequence,
|
||||||
|
* or 0, if none follow */
|
||||||
|
{
|
||||||
|
register int i = 1; /* walking index into the pixel array */
|
||||||
|
register int count = 1; /* length of sequence discovered so far */
|
||||||
|
|
||||||
|
*first = 0;
|
||||||
|
if (npixels == ncolors) {
|
||||||
|
*rem = 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
*rem = npixels - 1;
|
||||||
|
while (count < ncolors && ncolors - count <= *rem)
|
||||||
|
{
|
||||||
|
if (pixels[i-1] + delta == pixels[i])
|
||||||
|
count++;
|
||||||
|
else {
|
||||||
|
count = 1;
|
||||||
|
*first = i;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
(*rem)--;
|
||||||
|
}
|
||||||
|
if (count != ncolors)
|
||||||
|
return 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/****************************************************************************/
|
||||||
|
static Status ROorRWcell(dpy, cmap, pixels, npixels, color, p)
|
||||||
|
Display *dpy;
|
||||||
|
Colormap cmap;
|
||||||
|
unsigned long pixels[];
|
||||||
|
int npixels;
|
||||||
|
XColor *color;
|
||||||
|
unsigned long p;
|
||||||
|
{
|
||||||
|
unsigned long pixel;
|
||||||
|
XColor request;
|
||||||
|
|
||||||
|
/* Free the read/write allocation of one cell in the colormap.
|
||||||
|
* Request a read only allocation of one cell in the colormap.
|
||||||
|
* If the read only allocation cannot be granted, give up, because
|
||||||
|
* there must be no free cells in the colormap.
|
||||||
|
* If the read only allocation is granted, but gives us a cell which
|
||||||
|
* is not the one that we just freed, it is probably the case that
|
||||||
|
* we are trying allocate White or Black or some other color which
|
||||||
|
* already has a read-only allocation in the map. So we try to
|
||||||
|
* allocate the previously freed cell with a read/write allocation,
|
||||||
|
* because we want contiguous cells for image processing algorithms.
|
||||||
|
*/
|
||||||
|
|
||||||
|
pixel = color->pixel;
|
||||||
|
request.red = color->red;
|
||||||
|
request.green = color->green;
|
||||||
|
request.blue = color->blue;
|
||||||
|
|
||||||
|
XFreeColors(dpy, cmap, &pixel, 1, (unsigned long) 0);
|
||||||
|
if (! XAllocColor(dpy, cmap, color)
|
||||||
|
|| (color->pixel != pixel &&
|
||||||
|
(!RWcell(dpy, cmap, color, &request, &pixel))))
|
||||||
|
{
|
||||||
|
free_cells(dpy, cmap, pixels, npixels, (int)p);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/****************************************************************************/
|
||||||
|
static void free_cells(dpy, cmap, pixels, npixels, p)
|
||||||
|
Display *dpy;
|
||||||
|
Colormap cmap;
|
||||||
|
unsigned long pixels[]; /* to be freed */
|
||||||
|
int npixels; /* original number allocated */
|
||||||
|
int p;
|
||||||
|
{
|
||||||
|
/* One of the npixels allocated has already been freed.
|
||||||
|
* p is the index of the freed pixel.
|
||||||
|
* First free the pixels preceeding p, and there are p of them;
|
||||||
|
* then free the pixels following p, there are npixels - p - 1 of them.
|
||||||
|
*/
|
||||||
|
XFreeColors(dpy, cmap, pixels, p, (unsigned long) 0);
|
||||||
|
XFreeColors(dpy, cmap, &(pixels[p+1]), npixels - p - 1, (unsigned long) 0);
|
||||||
|
free((char *) pixels);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/****************************************************************************/
|
||||||
|
static Status RWcell(dpy, cmap, color, request, pixel)
|
||||||
|
Display *dpy;
|
||||||
|
Colormap cmap;
|
||||||
|
XColor *color;
|
||||||
|
XColor *request;
|
||||||
|
unsigned long *pixel;
|
||||||
|
{
|
||||||
|
unsigned long n = *pixel;
|
||||||
|
|
||||||
|
XFreeColors(dpy, cmap, &(color->pixel), 1, (unsigned long)0);
|
||||||
|
if (! XAllocColorCells(dpy, cmap, (Bool) 0, (unsigned long *) NULL,
|
||||||
|
(unsigned) 0, pixel, (unsigned) 1))
|
||||||
|
return 0;
|
||||||
|
if (*pixel != n)
|
||||||
|
{
|
||||||
|
XFreeColors(dpy, cmap, pixel, 1, (unsigned long) 0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
color->pixel = *pixel;
|
||||||
|
color->flags = DoRed | DoGreen | DoBlue;
|
||||||
|
color->red = request->red;
|
||||||
|
color->green = request->green;
|
||||||
|
color->blue = request->blue;
|
||||||
|
XStoreColors(dpy, cmap, color, 1);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/****************************************************************************/
|
||||||
|
static int compare(e1, e2)
|
||||||
|
unsigned long *e1, *e2;
|
||||||
|
{
|
||||||
|
if (*e1 < *e2) return -1;
|
||||||
|
if (*e1 > *e2) return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/****************************************************************************/
|
||||||
|
static Status readonly_map(dpy, vinfo, colormap)
|
||||||
|
Display *dpy;
|
||||||
|
XVisualInfo *vinfo;
|
||||||
|
XStandardColormap *colormap;
|
||||||
|
{
|
||||||
|
int i, last_pixel;
|
||||||
|
XColor color;
|
||||||
|
|
||||||
|
last_pixel = (colormap->red_max + 1) * (colormap->green_max + 1) *
|
||||||
|
(colormap->blue_max + 1) + colormap->base_pixel - 1;
|
||||||
|
|
||||||
|
for(i=colormap->base_pixel; i <= last_pixel; i++) {
|
||||||
|
|
||||||
|
color.pixel = (unsigned long) i;
|
||||||
|
color.red = (unsigned short)
|
||||||
|
(((i/colormap->red_mult) * 65535) / colormap->red_max);
|
||||||
|
|
||||||
|
if (vinfo->class == StaticColor) {
|
||||||
|
color.green = (unsigned short)
|
||||||
|
((((i/colormap->green_mult) % (colormap->green_max + 1)) *
|
||||||
|
65535) / colormap->green_max);
|
||||||
|
color.blue = (unsigned short)
|
||||||
|
(((i%colormap->green_mult) * 65535) / colormap->blue_max);
|
||||||
|
}
|
||||||
|
else /* vinfo->class == GrayScale, old style allocation XXX */
|
||||||
|
color.green = color.blue = color.red;
|
||||||
|
|
||||||
|
XAllocColor(dpy, colormap->colormap, &color);
|
||||||
|
if (color.pixel != (unsigned long) i)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
67
wrlib/DelCmap.c
Normal file
67
wrlib/DelCmap.c
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
/* $XConsortium: DelCmap.c,v 1.2 94/04/17 20:15:58 converse Exp $ */
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
Copyright (c) 1989 X Consortium
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||||
|
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
Except as contained in this notice, the name of the X Consortium shall not be
|
||||||
|
used in advertising or otherwise to promote the sale, use or other dealings
|
||||||
|
in this Software without prior written authorization from the X Consortium.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Author: Donna Converse, MIT X Consortium
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <X11/Xlib.h>
|
||||||
|
#include <X11/Xutil.h>
|
||||||
|
|
||||||
|
/* To remove any standard colormap property, use XmuDeleteStandardColormap().
|
||||||
|
* XmuDeleteStandardColormap() will remove the specified property from the
|
||||||
|
* specified screen, releasing any resources used by the colormap(s) of the
|
||||||
|
* property if possible.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void XmuDeleteStandardColormap(dpy, screen, property)
|
||||||
|
Display *dpy; /* specifies the X server to connect to */
|
||||||
|
int screen; /* specifies the screen of the display */
|
||||||
|
Atom property; /* specifies the standard colormap property */
|
||||||
|
{
|
||||||
|
XStandardColormap *stdcmaps, *s;
|
||||||
|
int count = 0;
|
||||||
|
|
||||||
|
if (XGetRGBColormaps(dpy, RootWindow(dpy, screen), &stdcmaps, &count,
|
||||||
|
property))
|
||||||
|
{
|
||||||
|
for (s=stdcmaps; count > 0; count--, s++) {
|
||||||
|
if ((s->killid == ReleaseByFreeingColormap) &&
|
||||||
|
(s->colormap != None) &&
|
||||||
|
(s->colormap != DefaultColormap(dpy, screen)))
|
||||||
|
XFreeColormap(dpy, s->colormap);
|
||||||
|
else if (s->killid != None)
|
||||||
|
XKillClient(dpy, s->killid);
|
||||||
|
}
|
||||||
|
XDeleteProperty(dpy, RootWindow(dpy, screen), property);
|
||||||
|
XFree((char *) stdcmaps);
|
||||||
|
XSync(dpy, False);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
312
wrlib/LookupCmap.c
Normal file
312
wrlib/LookupCmap.c
Normal file
@@ -0,0 +1,312 @@
|
|||||||
|
/* $XConsortium: LookupCmap.c,v 1.10 94/04/17 20:16:11 rws Exp $ */
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
Copyright (c) 1989 X Consortium
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||||
|
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
Except as contained in this notice, the name of the X Consortium shall not be
|
||||||
|
used in advertising or otherwise to promote the sale, use or other dealings
|
||||||
|
in this Software without prior written authorization from the X Consortium.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Author: Donna Converse, MIT X Consortium
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <X11/Xlib.h>
|
||||||
|
#include <X11/Xatom.h>
|
||||||
|
#include <X11/Xutil.h>
|
||||||
|
#include <X11/Xmu/StdCmap.h>
|
||||||
|
|
||||||
|
|
||||||
|
static Status lookup();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* To create a standard colormap if one does not currently exist, or
|
||||||
|
* replace the currently existing standard colormap, use
|
||||||
|
* XmuLookupStandardColormap().
|
||||||
|
*
|
||||||
|
* Given a screen, a visual, and a property, XmuLookupStandardColormap()
|
||||||
|
* will determine the best allocation for the property under the specified
|
||||||
|
* visual, and determine the whether to create a new colormap or to use
|
||||||
|
* the default colormap of the screen. It will call XmuStandardColormap()
|
||||||
|
* to create the standard colormap.
|
||||||
|
*
|
||||||
|
* If replace is true, any previous definition of the property will be
|
||||||
|
* replaced. If retain is true, the property and the colormap will be
|
||||||
|
* made permanent for the duration of the server session. However,
|
||||||
|
* pre-existing property definitions which are not replaced cannot be made
|
||||||
|
* permanent by a call to XmuLookupStandardColormap(); a request to retain
|
||||||
|
* resources pertains to newly created resources.
|
||||||
|
*
|
||||||
|
* Returns 0 on failure, non-zero on success. A request to create a
|
||||||
|
* standard colormap upon a visual which cannot support such a map is
|
||||||
|
* considered a failure. An example of this would be requesting any
|
||||||
|
* standard colormap property on a monochrome visual, or, requesting an
|
||||||
|
* RGB_BEST_MAP on a display whose colormap size is 16.
|
||||||
|
*/
|
||||||
|
|
||||||
|
Status XmuLookupStandardColormap(dpy, screen, visualid, depth, property,
|
||||||
|
replace, retain)
|
||||||
|
Display *dpy; /* specifies X server connection */
|
||||||
|
int screen; /* specifies screen of display */
|
||||||
|
VisualID visualid; /* specifies the visual type */
|
||||||
|
unsigned int depth; /* specifies the visual type */
|
||||||
|
Atom property; /* a standard colormap property */
|
||||||
|
Bool replace; /* specifies whether to replace */
|
||||||
|
Bool retain; /* specifies whether to retain */
|
||||||
|
{
|
||||||
|
Display *odpy; /* original display connection */
|
||||||
|
XStandardColormap *colormap;
|
||||||
|
XVisualInfo vinfo_template, *vinfo; /* visual */
|
||||||
|
long vinfo_mask;
|
||||||
|
unsigned long r_max, g_max, b_max; /* allocation */
|
||||||
|
int count;
|
||||||
|
Colormap cmap; /* colormap ID */
|
||||||
|
Status status = 0;
|
||||||
|
|
||||||
|
|
||||||
|
/* Match the requested visual */
|
||||||
|
|
||||||
|
vinfo_template.visualid = visualid;
|
||||||
|
vinfo_template.screen = screen;
|
||||||
|
vinfo_template.depth = depth;
|
||||||
|
vinfo_mask = VisualIDMask | VisualScreenMask | VisualDepthMask;
|
||||||
|
if ((vinfo = XGetVisualInfo(dpy, vinfo_mask, &vinfo_template, &count)) ==
|
||||||
|
NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* Monochrome visuals have no standard maps */
|
||||||
|
|
||||||
|
if (vinfo->colormap_size <= 2) {
|
||||||
|
XFree((char *) vinfo);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If the requested property already exists on this screen, and,
|
||||||
|
* if the replace flag has not been set to true, return success.
|
||||||
|
* lookup() will remove a pre-existing map if replace is true.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (lookup(dpy, screen, visualid, property, (XStandardColormap *) NULL,
|
||||||
|
replace) && !replace) {
|
||||||
|
XFree((char *) vinfo);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Determine the best allocation for this property under the requested
|
||||||
|
* visualid and depth, and determine whether or not to use the default
|
||||||
|
* colormap of the screen.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (!XmuGetColormapAllocation(vinfo, property, &r_max, &g_max, &b_max)) {
|
||||||
|
XFree((char *) vinfo);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
cmap = (property == XA_RGB_DEFAULT_MAP &&
|
||||||
|
visualid == XVisualIDFromVisual(DefaultVisual(dpy, screen)))
|
||||||
|
? DefaultColormap(dpy, screen) : None;
|
||||||
|
|
||||||
|
/* If retaining resources, open a new connection to the same server */
|
||||||
|
|
||||||
|
if (retain) {
|
||||||
|
odpy = dpy;
|
||||||
|
if ((dpy = XOpenDisplay(XDisplayString(odpy))) == NULL) {
|
||||||
|
XFree((char *) vinfo);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create the standard colormap */
|
||||||
|
|
||||||
|
colormap = XmuStandardColormap(dpy, screen, visualid, depth, property,
|
||||||
|
cmap, r_max, g_max, b_max);
|
||||||
|
|
||||||
|
/* Set the standard colormap property */
|
||||||
|
|
||||||
|
if (colormap) {
|
||||||
|
XGrabServer(dpy);
|
||||||
|
|
||||||
|
if (lookup(dpy, screen, visualid, property, colormap, replace) &&
|
||||||
|
!replace) {
|
||||||
|
/* Someone has defined the property since we last looked.
|
||||||
|
* Since we will not replace it, release our own resources.
|
||||||
|
* If this is the default map, our allocations will be freed
|
||||||
|
* when this connection closes.
|
||||||
|
*/
|
||||||
|
if (colormap->killid == ReleaseByFreeingColormap)
|
||||||
|
XFreeColormap(dpy, colormap->colormap);
|
||||||
|
}
|
||||||
|
else if (retain) {
|
||||||
|
XSetCloseDownMode(dpy, RetainPermanent);
|
||||||
|
}
|
||||||
|
XUngrabServer(dpy);
|
||||||
|
XFree((char *) colormap);
|
||||||
|
status = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (retain)
|
||||||
|
XCloseDisplay(dpy);
|
||||||
|
XFree((char *) vinfo);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
|
||||||
|
/* Lookup a standard colormap property. If the property is RGB_DEFAULT_MAP,
|
||||||
|
* the visualid is used to determine whether the indicated standard colormap
|
||||||
|
* exists. If the map exists and replace is true, delete the resources used
|
||||||
|
* by the map and remove the property. Return true if the map exists,
|
||||||
|
* or did exist and was deleted; return false if the map was not found.
|
||||||
|
*
|
||||||
|
* Note that this is not the way that a Status return is normally used.
|
||||||
|
*
|
||||||
|
* If new is not NULL, new points to an XStandardColormap structure which
|
||||||
|
* describes a standard colormap of the specified property. It will be made
|
||||||
|
* a standard colormap of the screen if none already exists, or if replace
|
||||||
|
* is true.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static Status lookup(dpy, screen, visualid, property, new, replace)
|
||||||
|
Display *dpy; /* specifies display connection */
|
||||||
|
int screen; /* specifies screen number */
|
||||||
|
VisualID visualid; /* specifies visualid for std map */
|
||||||
|
Atom property; /* specifies colormap property name */
|
||||||
|
XStandardColormap *new; /* specifies a standard colormap */
|
||||||
|
Bool replace; /* specifies whether to replace */
|
||||||
|
{
|
||||||
|
register int i;
|
||||||
|
int count;
|
||||||
|
XStandardColormap *stdcmaps, *s;
|
||||||
|
Window win = RootWindow(dpy, screen);
|
||||||
|
|
||||||
|
/* The property does not already exist */
|
||||||
|
|
||||||
|
if (! XGetRGBColormaps(dpy, win, &stdcmaps, &count, property)) {
|
||||||
|
if (new)
|
||||||
|
XSetRGBColormaps(dpy, win, new, 1, property);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The property exists and is not describing the RGB_DEFAULT_MAP */
|
||||||
|
|
||||||
|
if (property != XA_RGB_DEFAULT_MAP) {
|
||||||
|
if (replace) {
|
||||||
|
XmuDeleteStandardColormap(dpy, screen, property);
|
||||||
|
if (new)
|
||||||
|
XSetRGBColormaps(dpy, win, new, 1, property);
|
||||||
|
}
|
||||||
|
XFree((char *)stdcmaps);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The property exists and is RGB_DEFAULT_MAP */
|
||||||
|
|
||||||
|
for (i=0, s=stdcmaps; (i < count) && (s->visualid != visualid); i++, s++)
|
||||||
|
;
|
||||||
|
|
||||||
|
/* No RGB_DEFAULT_MAP property matches the given visualid */
|
||||||
|
|
||||||
|
if (i == count) {
|
||||||
|
if (new) {
|
||||||
|
XStandardColormap *m, *maps;
|
||||||
|
|
||||||
|
s = (XStandardColormap *) malloc((unsigned) ((count+1) * sizeof
|
||||||
|
(XStandardColormap)));
|
||||||
|
|
||||||
|
for (i = 0, m = s, maps = stdcmaps; i < count; i++, m++, maps++) {
|
||||||
|
m->colormap = maps->colormap;
|
||||||
|
m->red_max = maps->red_max;
|
||||||
|
m->red_mult = maps->red_mult;
|
||||||
|
m->green_max = maps->green_max;
|
||||||
|
m->green_mult = maps->green_mult;
|
||||||
|
m->blue_max = maps->blue_max;
|
||||||
|
m->blue_mult = maps->blue_mult;
|
||||||
|
m->base_pixel = maps->base_pixel;
|
||||||
|
m->visualid = maps->visualid;
|
||||||
|
m->killid = maps->killid;
|
||||||
|
}
|
||||||
|
m->colormap = new->colormap;
|
||||||
|
m->red_max = new->red_max;
|
||||||
|
m->red_mult = new->red_mult;
|
||||||
|
m->green_max = new->green_max;
|
||||||
|
m->green_mult = new->green_mult;
|
||||||
|
m->blue_max = new->blue_max;
|
||||||
|
m->blue_mult = new->blue_mult;
|
||||||
|
m->base_pixel = new->base_pixel;
|
||||||
|
m->visualid = new->visualid;
|
||||||
|
m->killid = new->killid;
|
||||||
|
|
||||||
|
XSetRGBColormaps(dpy, win, s, ++count, property);
|
||||||
|
free((char *) s);
|
||||||
|
}
|
||||||
|
XFree((char *) stdcmaps);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Found an RGB_DEFAULT_MAP property with a matching visualid */
|
||||||
|
|
||||||
|
if (replace) {
|
||||||
|
/* Free old resources first - we may need them, particularly in
|
||||||
|
* the default colormap of the screen. However, because of this,
|
||||||
|
* it is possible that we will destroy the old resource and fail
|
||||||
|
* to create a new one if XmuStandardColormap() fails.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (count == 1) {
|
||||||
|
XmuDeleteStandardColormap(dpy, screen, property);
|
||||||
|
if (new)
|
||||||
|
XSetRGBColormaps(dpy, win, new, 1, property);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
XStandardColormap *map;
|
||||||
|
|
||||||
|
/* s still points to the matching standard colormap */
|
||||||
|
|
||||||
|
if (s->killid == ReleaseByFreeingColormap) {
|
||||||
|
if ((s->colormap != None) &&
|
||||||
|
(s->colormap != DefaultColormap(dpy, screen)))
|
||||||
|
XFreeColormap(dpy, s->colormap);
|
||||||
|
}
|
||||||
|
else if (s->killid != None)
|
||||||
|
XKillClient(dpy, s->killid);
|
||||||
|
|
||||||
|
map = (new) ? new : stdcmaps + --count;
|
||||||
|
|
||||||
|
s->colormap = map->colormap;
|
||||||
|
s->red_max = map->red_max;
|
||||||
|
s->red_mult = map->red_mult;
|
||||||
|
s->green_max = map->green_max;
|
||||||
|
s->green_mult = map->green_mult;
|
||||||
|
s->blue_max = map->blue_max;
|
||||||
|
s->blue_mult = map->blue_mult;
|
||||||
|
s->visualid = map->visualid;
|
||||||
|
s->killid = map->killid;
|
||||||
|
|
||||||
|
XSetRGBColormaps(dpy, win, stdcmaps, count, property);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
XFree((char *) stdcmaps);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
@@ -4,7 +4,7 @@ AUTOMAKE_OPTIONS = no-dependencies
|
|||||||
|
|
||||||
lib_LTLIBRARIES = libwraster.la
|
lib_LTLIBRARIES = libwraster.la
|
||||||
|
|
||||||
libwraster_la_LDFLAGS = -version-info 3:1:2
|
libwraster_la_LDFLAGS = -version-info 4:0:3
|
||||||
|
|
||||||
bin_SCRIPTS = get-wraster-flags
|
bin_SCRIPTS = get-wraster-flags
|
||||||
|
|
||||||
@@ -14,6 +14,12 @@ EXTRA_DIST = test.png tile.xpm ballot_box.xpm
|
|||||||
include_HEADERS = wraster.h
|
include_HEADERS = wraster.h
|
||||||
|
|
||||||
libwraster_la_SOURCES = \
|
libwraster_la_SOURCES = \
|
||||||
|
LookupCmap.c \
|
||||||
|
StdCmap.c \
|
||||||
|
StdCmap.h \
|
||||||
|
CrCmap.c \
|
||||||
|
DelCmap.c \
|
||||||
|
CmapAlloc.c \
|
||||||
raster.c \
|
raster.c \
|
||||||
draw.c \
|
draw.c \
|
||||||
color.c \
|
color.c \
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ AUTOMAKE_OPTIONS = no-dependencies
|
|||||||
|
|
||||||
lib_LTLIBRARIES = libwraster.la
|
lib_LTLIBRARIES = libwraster.la
|
||||||
|
|
||||||
libwraster_la_LDFLAGS = -version-info 3:1:2
|
libwraster_la_LDFLAGS = -version-info 4:0:3
|
||||||
|
|
||||||
bin_SCRIPTS = get-wraster-flags
|
bin_SCRIPTS = get-wraster-flags
|
||||||
|
|
||||||
@@ -105,7 +105,7 @@ noinst_PROGRAMS = testgrad testdraw view
|
|||||||
EXTRA_DIST = test.png tile.xpm ballot_box.xpm
|
EXTRA_DIST = test.png tile.xpm ballot_box.xpm
|
||||||
include_HEADERS = wraster.h
|
include_HEADERS = wraster.h
|
||||||
|
|
||||||
libwraster_la_SOURCES = raster.c draw.c color.c load.c save.c gradient.c xpixmap.c convert.c context.c misc.c scale.c convolve.c nxpm.c xpm.c xutil.c ppm.c png.c jpeg.c tiff.c gif.c
|
libwraster_la_SOURCES = LookupCmap.c StdCmap.c StdCmap.h CrCmap.c DelCmap.c CmapAlloc.c raster.c draw.c color.c load.c save.c gradient.c xpixmap.c convert.c context.c misc.c scale.c convolve.c nxpm.c xpm.c xutil.c ppm.c png.c jpeg.c tiff.c gif.c
|
||||||
|
|
||||||
|
|
||||||
INCLUDES = @DFLAGS@ @HEADER_SEARCH_PATH@
|
INCLUDES = @DFLAGS@ @HEADER_SEARCH_PATH@
|
||||||
@@ -139,10 +139,10 @@ X_CFLAGS = @X_CFLAGS@
|
|||||||
X_LIBS = @X_LIBS@
|
X_LIBS = @X_LIBS@
|
||||||
X_PRE_LIBS = @X_PRE_LIBS@
|
X_PRE_LIBS = @X_PRE_LIBS@
|
||||||
libwraster_la_DEPENDENCIES = @ALLOCA@
|
libwraster_la_DEPENDENCIES = @ALLOCA@
|
||||||
libwraster_la_OBJECTS = raster.lo draw.lo color.lo load.lo save.lo \
|
libwraster_la_OBJECTS = LookupCmap.lo StdCmap.lo CrCmap.lo DelCmap.lo \
|
||||||
gradient.lo xpixmap.lo convert.lo context.lo misc.lo scale.lo \
|
CmapAlloc.lo raster.lo draw.lo color.lo load.lo save.lo gradient.lo \
|
||||||
convolve.lo nxpm.lo xpm.lo xutil.lo ppm.lo png.lo jpeg.lo tiff.lo \
|
xpixmap.lo convert.lo context.lo misc.lo scale.lo convolve.lo nxpm.lo \
|
||||||
gif.lo
|
xpm.lo xutil.lo ppm.lo png.lo jpeg.lo tiff.lo gif.lo
|
||||||
PROGRAMS = $(noinst_PROGRAMS)
|
PROGRAMS = $(noinst_PROGRAMS)
|
||||||
|
|
||||||
testgrad_OBJECTS = testgrad.o
|
testgrad_OBJECTS = testgrad.o
|
||||||
@@ -169,7 +169,7 @@ Makefile.in NEWS TODO alloca.c configure.in
|
|||||||
|
|
||||||
DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
|
DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
|
||||||
|
|
||||||
TAR = tar
|
TAR = gtar
|
||||||
GZIP_ENV = --best
|
GZIP_ENV = --best
|
||||||
SOURCES = $(libwraster_la_SOURCES) $(testgrad_SOURCES) $(testdraw_SOURCES) $(view_SOURCES)
|
SOURCES = $(libwraster_la_SOURCES) $(testgrad_SOURCES) $(testdraw_SOURCES) $(view_SOURCES)
|
||||||
OBJECTS = $(libwraster_la_OBJECTS) $(testgrad_OBJECTS) $(testdraw_OBJECTS) $(view_OBJECTS)
|
OBJECTS = $(libwraster_la_OBJECTS) $(testgrad_OBJECTS) $(testdraw_OBJECTS) $(view_OBJECTS)
|
||||||
@@ -178,7 +178,7 @@ all: all-redirect
|
|||||||
.SUFFIXES:
|
.SUFFIXES:
|
||||||
.SUFFIXES: .S .c .lo .o .s
|
.SUFFIXES: .S .c .lo .o .s
|
||||||
$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
|
$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
|
||||||
cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps wrlib/Makefile
|
cd $(top_srcdir) && $(AUTOMAKE) --gnu wrlib/Makefile
|
||||||
|
|
||||||
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
|
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
|
||||||
cd $(top_builddir) \
|
cd $(top_builddir) \
|
||||||
@@ -343,7 +343,7 @@ distdir: $(DISTFILES)
|
|||||||
@for file in $(DISTFILES); do \
|
@for file in $(DISTFILES); do \
|
||||||
d=$(srcdir); \
|
d=$(srcdir); \
|
||||||
if test -d $$d/$$file; then \
|
if test -d $$d/$$file; then \
|
||||||
cp -pr $$d/$$file $(distdir)/$$file; \
|
cp -pr $$/$$file $(distdir)/$$file; \
|
||||||
else \
|
else \
|
||||||
test -f $(distdir)/$$file \
|
test -f $(distdir)/$$file \
|
||||||
|| ln $$d/$$file $(distdir)/$$file 2> /dev/null \
|
|| ln $$d/$$file $(distdir)/$$file 2> /dev/null \
|
||||||
|
|||||||
219
wrlib/StdCmap.c
Normal file
219
wrlib/StdCmap.c
Normal file
@@ -0,0 +1,219 @@
|
|||||||
|
/* $XConsortium: StdCmap.c,v 1.14 94/04/17 20:16:14 rws Exp $ */
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
Copyright (c) 1989 X Consortium
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||||
|
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
Except as contained in this notice, the name of the X Consortium shall not be
|
||||||
|
used in advertising or otherwise to promote the sale, use or other dealings
|
||||||
|
in this Software without prior written authorization from the X Consortium.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Author: Donna Converse, MIT X Consortium
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <X11/Xlib.h>
|
||||||
|
#include <X11/Xatom.h>
|
||||||
|
#include <X11/Xutil.h>
|
||||||
|
#include <X11/Xmu/StdCmap.h>
|
||||||
|
|
||||||
|
#define lowbit(x) ((x) & (~(x) + 1))
|
||||||
|
|
||||||
|
static Status valid_args(); /* argument restrictions */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* To create any one standard colormap, use XmuStandardColormap().
|
||||||
|
*
|
||||||
|
* Create a standard colormap for the given screen, visualid, and visual
|
||||||
|
* depth, with the given red, green, and blue maximum values, with the
|
||||||
|
* given standard property name. Return a pointer to an XStandardColormap
|
||||||
|
* structure which describes the newly created colormap, upon success.
|
||||||
|
* Upon failure, return NULL.
|
||||||
|
*
|
||||||
|
* XmuStandardColormap() calls XmuCreateColormap() to create the map.
|
||||||
|
*
|
||||||
|
* Resources created by this function are not made permanent; that is the
|
||||||
|
* caller's responsibility.
|
||||||
|
*/
|
||||||
|
|
||||||
|
XStandardColormap *XmuStandardColormap(dpy, screen, visualid, depth, property,
|
||||||
|
cmap, red_max, green_max, blue_max)
|
||||||
|
Display *dpy; /* specifies X server connection */
|
||||||
|
int screen; /* specifies display screen */
|
||||||
|
VisualID visualid; /* identifies the visual type */
|
||||||
|
unsigned int depth; /* identifies the visual type */
|
||||||
|
Atom property; /* a standard colormap property */
|
||||||
|
Colormap cmap; /* specifies colormap ID or None */
|
||||||
|
unsigned long red_max, green_max, blue_max; /* allocations */
|
||||||
|
{
|
||||||
|
XStandardColormap *stdcmap;
|
||||||
|
Status status;
|
||||||
|
XVisualInfo vinfo_template, *vinfo;
|
||||||
|
long vinfo_mask;
|
||||||
|
int n;
|
||||||
|
|
||||||
|
/* Match the required visual information to an actual visual */
|
||||||
|
vinfo_template.visualid = visualid;
|
||||||
|
vinfo_template.screen = screen;
|
||||||
|
vinfo_template.depth = depth;
|
||||||
|
vinfo_mask = VisualIDMask | VisualScreenMask | VisualDepthMask;
|
||||||
|
if ((vinfo = XGetVisualInfo(dpy, vinfo_mask, &vinfo_template, &n)) == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* Check the validity of the combination of visual characteristics,
|
||||||
|
* allocation, and colormap property. Create an XStandardColormap
|
||||||
|
* structure.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (! valid_args(vinfo, red_max, green_max, blue_max, property)
|
||||||
|
|| ((stdcmap = XAllocStandardColormap()) == NULL)) {
|
||||||
|
XFree((char *) vinfo);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Fill in the XStandardColormap structure */
|
||||||
|
|
||||||
|
if (cmap == DefaultColormap(dpy, screen)) {
|
||||||
|
/* Allocating out of the default map, cannot use XFreeColormap() */
|
||||||
|
Window win = XCreateWindow(dpy, RootWindow(dpy, screen), 1, 1, 1, 1,
|
||||||
|
0, 0, InputOnly, vinfo->visual,
|
||||||
|
(unsigned long) 0,
|
||||||
|
(XSetWindowAttributes *)NULL);
|
||||||
|
stdcmap->killid = (XID) XCreatePixmap(dpy, win, 1, 1, depth);
|
||||||
|
XDestroyWindow(dpy, win);
|
||||||
|
stdcmap->colormap = cmap;
|
||||||
|
} else {
|
||||||
|
stdcmap->killid = ReleaseByFreeingColormap;
|
||||||
|
stdcmap->colormap = XCreateColormap(dpy, RootWindow(dpy, screen),
|
||||||
|
vinfo->visual, AllocNone);
|
||||||
|
}
|
||||||
|
stdcmap->red_max = red_max;
|
||||||
|
stdcmap->green_max = green_max;
|
||||||
|
stdcmap->blue_max = blue_max;
|
||||||
|
if (property == XA_RGB_GRAY_MAP)
|
||||||
|
stdcmap->red_mult = stdcmap->green_mult = stdcmap->blue_mult = 1;
|
||||||
|
else if (vinfo->class == TrueColor || vinfo->class == DirectColor) {
|
||||||
|
stdcmap->red_mult = lowbit(vinfo->red_mask);
|
||||||
|
stdcmap->green_mult = lowbit(vinfo->green_mask);
|
||||||
|
stdcmap->blue_mult = lowbit(vinfo->blue_mask);
|
||||||
|
} else {
|
||||||
|
stdcmap->red_mult = (red_max > 0)
|
||||||
|
? (green_max + 1) * (blue_max + 1) : 0;
|
||||||
|
stdcmap->green_mult = (green_max > 0) ? blue_max + 1 : 0;
|
||||||
|
stdcmap->blue_mult = (blue_max > 0) ? 1 : 0;
|
||||||
|
}
|
||||||
|
stdcmap->base_pixel = 0; /* base pixel may change */
|
||||||
|
stdcmap->visualid = vinfo->visualid;
|
||||||
|
|
||||||
|
/* Make the colormap */
|
||||||
|
|
||||||
|
status = XmuCreateColormap(dpy, stdcmap);
|
||||||
|
|
||||||
|
/* Clean up */
|
||||||
|
|
||||||
|
XFree((char *) vinfo);
|
||||||
|
if (!status) {
|
||||||
|
|
||||||
|
/* Free the colormap or the pixmap, if we created one */
|
||||||
|
if (stdcmap->killid == ReleaseByFreeingColormap)
|
||||||
|
XFreeColormap(dpy, stdcmap->colormap);
|
||||||
|
else if (stdcmap->killid != None)
|
||||||
|
XFreePixmap(dpy, stdcmap->killid);
|
||||||
|
|
||||||
|
XFree((char *) stdcmap);
|
||||||
|
return (XStandardColormap *) NULL;
|
||||||
|
}
|
||||||
|
return stdcmap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************/
|
||||||
|
static Status valid_args(vinfo, red_max, green_max, blue_max, property)
|
||||||
|
XVisualInfo *vinfo; /* specifies visual */
|
||||||
|
unsigned long red_max, green_max, blue_max; /* specifies alloc */
|
||||||
|
Atom property; /* specifies property name */
|
||||||
|
{
|
||||||
|
unsigned long ncolors; /* number of colors requested */
|
||||||
|
|
||||||
|
/* Determine that the number of colors requested is <= map size */
|
||||||
|
|
||||||
|
if ((vinfo->class == DirectColor) || (vinfo->class == TrueColor)) {
|
||||||
|
unsigned long mask;
|
||||||
|
|
||||||
|
mask = vinfo->red_mask;
|
||||||
|
while (!(mask & 1))
|
||||||
|
mask >>= 1;
|
||||||
|
if (red_max > mask)
|
||||||
|
return 0;
|
||||||
|
mask = vinfo->green_mask;
|
||||||
|
while (!(mask & 1))
|
||||||
|
mask >>= 1;
|
||||||
|
if (green_max > mask)
|
||||||
|
return 0;
|
||||||
|
mask = vinfo->blue_mask;
|
||||||
|
while (!(mask & 1))
|
||||||
|
mask >>= 1;
|
||||||
|
if (blue_max > mask)
|
||||||
|
return 0;
|
||||||
|
} else if (property == XA_RGB_GRAY_MAP) {
|
||||||
|
ncolors = red_max + green_max + blue_max + 1;
|
||||||
|
if (ncolors > vinfo->colormap_size)
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
ncolors = (red_max + 1) * (green_max + 1) * (blue_max + 1);
|
||||||
|
if (ncolors > vinfo->colormap_size)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Determine that the allocation and visual make sense for the property */
|
||||||
|
|
||||||
|
switch (property)
|
||||||
|
{
|
||||||
|
case XA_RGB_DEFAULT_MAP:
|
||||||
|
if (red_max == 0 || green_max == 0 || blue_max == 0)
|
||||||
|
return 0;
|
||||||
|
break;
|
||||||
|
case XA_RGB_RED_MAP:
|
||||||
|
if (red_max == 0)
|
||||||
|
return 0;
|
||||||
|
break;
|
||||||
|
case XA_RGB_GREEN_MAP:
|
||||||
|
if (green_max == 0)
|
||||||
|
return 0;
|
||||||
|
break;
|
||||||
|
case XA_RGB_BLUE_MAP:
|
||||||
|
if (blue_max == 0)
|
||||||
|
return 0;
|
||||||
|
break;
|
||||||
|
case XA_RGB_BEST_MAP:
|
||||||
|
if (red_max == 0 || green_max == 0 || blue_max == 0)
|
||||||
|
return 0;
|
||||||
|
break;
|
||||||
|
case XA_RGB_GRAY_MAP:
|
||||||
|
if (red_max == 0 || blue_max == 0 || green_max == 0)
|
||||||
|
return 0;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
112
wrlib/StdCmap.h
Normal file
112
wrlib/StdCmap.h
Normal file
@@ -0,0 +1,112 @@
|
|||||||
|
/* $XConsortium: StdCmap.h,v 1.4 94/04/17 20:16:15 converse Exp $ */
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
Copyright (c) 1988 X Consortium
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||||
|
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
Except as contained in this notice, the name of the X Consortium shall not be
|
||||||
|
used in advertising or otherwise to promote the sale, use or other dealings
|
||||||
|
in this Software without prior written authorization from the X Consortium.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The interfaces described by this header file are for miscellaneous utilities
|
||||||
|
* and are not part of the Xlib standard.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _XMU_STDCMAP_H_
|
||||||
|
#define _XMU_STDCMAP_H_
|
||||||
|
|
||||||
|
#include <X11/Xfuncproto.h>
|
||||||
|
|
||||||
|
_XFUNCPROTOBEGIN
|
||||||
|
|
||||||
|
Status XmuAllStandardColormaps(
|
||||||
|
#if NeedFunctionPrototypes
|
||||||
|
Display* /* dpy */
|
||||||
|
#endif
|
||||||
|
);
|
||||||
|
|
||||||
|
Status XmuCreateColormap(
|
||||||
|
#if NeedFunctionPrototypes
|
||||||
|
Display* /* dpy */,
|
||||||
|
XStandardColormap* /* colormap */
|
||||||
|
#endif
|
||||||
|
);
|
||||||
|
|
||||||
|
void XmuDeleteStandardColormap(
|
||||||
|
#if NeedFunctionPrototypes
|
||||||
|
Display* /* dpy */,
|
||||||
|
int /* screen */,
|
||||||
|
Atom /* property */
|
||||||
|
#endif
|
||||||
|
);
|
||||||
|
|
||||||
|
Status XmuGetColormapAllocation(
|
||||||
|
#if NeedFunctionPrototypes
|
||||||
|
XVisualInfo* /* vinfo */,
|
||||||
|
Atom /* property */,
|
||||||
|
unsigned long* /* red_max_return */,
|
||||||
|
unsigned long* /* green_max_return */,
|
||||||
|
unsigned long* /* blue_max_return */
|
||||||
|
#endif
|
||||||
|
);
|
||||||
|
|
||||||
|
Status XmuLookupStandardColormap(
|
||||||
|
#if NeedFunctionPrototypes
|
||||||
|
Display* /* dpy */,
|
||||||
|
int /* screen */,
|
||||||
|
VisualID /* visualid */,
|
||||||
|
unsigned int /* depth */,
|
||||||
|
Atom /* property */,
|
||||||
|
Bool /* replace */,
|
||||||
|
Bool /* retain */
|
||||||
|
#endif
|
||||||
|
);
|
||||||
|
|
||||||
|
XStandardColormap *XmuStandardColormap(
|
||||||
|
#if NeedFunctionPrototypes
|
||||||
|
Display* /* dpy */,
|
||||||
|
int /* screen */,
|
||||||
|
VisualID /* visualid */,
|
||||||
|
unsigned int /* depth */,
|
||||||
|
Atom /* property */,
|
||||||
|
Colormap /* cmap */,
|
||||||
|
unsigned long /* red_max */,
|
||||||
|
unsigned long /* green_max */,
|
||||||
|
unsigned long /* blue_max */
|
||||||
|
#endif
|
||||||
|
);
|
||||||
|
|
||||||
|
Status XmuVisualStandardColormaps(
|
||||||
|
#if NeedFunctionPrototypes
|
||||||
|
Display* /* dpy */,
|
||||||
|
int /* screen */,
|
||||||
|
VisualID /* visualid */,
|
||||||
|
unsigned int /* depth */,
|
||||||
|
Bool /* replace */,
|
||||||
|
Bool /* retain */
|
||||||
|
#endif
|
||||||
|
);
|
||||||
|
|
||||||
|
_XFUNCPROTOEND
|
||||||
|
|
||||||
|
#endif /* _XMU_STDCMAP_H_ */
|
||||||
200
wrlib/context.c
200
wrlib/context.c
@@ -32,6 +32,8 @@
|
|||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
|
#include "StdCmap.h"
|
||||||
|
|
||||||
#include "wraster.h"
|
#include "wraster.h"
|
||||||
|
|
||||||
|
|
||||||
@@ -49,11 +51,108 @@ static RContextAttributes DEFAULT_CONTEXT_ATTRIBS = {
|
|||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
True, /* use_shared_memory */
|
True, /* use_shared_memory */
|
||||||
RMitchellFilter
|
RMitchellFilter,
|
||||||
|
RUseStdColormap
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
static XColor*
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* Colormap allocation for PseudoColor visuals:
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* switch standardColormap:
|
||||||
|
* none:
|
||||||
|
* allocate colors according to colors_per_channel
|
||||||
|
*
|
||||||
|
* best/default:
|
||||||
|
* if there's a std colormap defined
|
||||||
|
then use it
|
||||||
|
*
|
||||||
|
* else
|
||||||
|
* create a std colormap and set it
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
*----------------------------------------------------------------------
|
||||||
|
* allocateStandardPseudoColor
|
||||||
|
* Creates the internal colormap for PseudoColor, setting the
|
||||||
|
* color values according to the supplied standard colormap.
|
||||||
|
*
|
||||||
|
* Returns: -
|
||||||
|
*
|
||||||
|
* Side effects: -
|
||||||
|
*
|
||||||
|
* Notes: -
|
||||||
|
*----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
static Bool
|
||||||
|
allocateStandardPseudoColor(RContext *ctx, XStandardColormap *stdcmap)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
ctx->ncolors = stdcmap->red_max * stdcmap->red_mult
|
||||||
|
+ stdcmap->green_max * stdcmap->green_mult
|
||||||
|
+ stdcmap->blue_max * stdcmap->blue_mult + 1;
|
||||||
|
|
||||||
|
if (ctx->ncolors <= 1) {
|
||||||
|
RErrorCode = RERR_INTERNAL;
|
||||||
|
puts("wraster: bad standard colormap");
|
||||||
|
|
||||||
|
return False;
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx->colors = malloc(sizeof(XColor)*ctx->ncolors);
|
||||||
|
if (!ctx->colors) {
|
||||||
|
RErrorCode = RERR_NOMEMORY;
|
||||||
|
|
||||||
|
return False;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define calc(max,mult) (((i / stdcmap->mult) % \
|
||||||
|
(stdcmap->max + 1)) * 65535) / stdcmap->max
|
||||||
|
|
||||||
|
for (i = 0; i < ctx->ncolors; i++) {
|
||||||
|
ctx->colors[i].pixel = i + stdcmap->base_pixel;
|
||||||
|
ctx->colors[i].red = calc(red_max, red_mult);
|
||||||
|
ctx->colors[i].green = calc(green_max, green_mult);
|
||||||
|
ctx->colors[i].blue = calc(blue_max, blue_mult);
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef calc
|
||||||
|
|
||||||
|
return True;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static Bool
|
||||||
|
setupStandardColormap(RContext *ctx, Atom property)
|
||||||
|
{
|
||||||
|
if (!XmuLookupStandardColormap(ctx->dpy, ctx->screen_number,
|
||||||
|
ctx->visual->visualid,
|
||||||
|
ctx->depth, property,
|
||||||
|
True, True)) {
|
||||||
|
RErrorCode = RERR_STDCMAPFAIL;
|
||||||
|
|
||||||
|
return False;
|
||||||
|
}
|
||||||
|
return True;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static Bool
|
||||||
allocatePseudoColor(RContext *ctx)
|
allocatePseudoColor(RContext *ctx)
|
||||||
{
|
{
|
||||||
XColor *colors;
|
XColor *colors;
|
||||||
@@ -76,7 +175,7 @@ allocatePseudoColor(RContext *ctx)
|
|||||||
colors = malloc(sizeof(XColor)*ncolors);
|
colors = malloc(sizeof(XColor)*ncolors);
|
||||||
if (!colors) {
|
if (!colors) {
|
||||||
RErrorCode = RERR_NOMEMORY;
|
RErrorCode = RERR_NOMEMORY;
|
||||||
return NULL;
|
return False;
|
||||||
}
|
}
|
||||||
i=0;
|
i=0;
|
||||||
|
|
||||||
@@ -173,7 +272,11 @@ allocatePseudoColor(RContext *ctx)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return colors;
|
|
||||||
|
ctx->colors = colors;
|
||||||
|
ctx->ncolors = ncolors;
|
||||||
|
|
||||||
|
return True;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -283,6 +386,86 @@ allocateGrayScale(RContext *ctx)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static Bool
|
||||||
|
setupPseudoColorColormap(RContext *context)
|
||||||
|
{
|
||||||
|
Atom property = 0;
|
||||||
|
|
||||||
|
if (context->attribs->standard_colormap_mode == RCreateStdColormap) {
|
||||||
|
property = XInternAtom(context->dpy, "RGB_DEFAULT_MAP", False);
|
||||||
|
|
||||||
|
if (!setupStandardColormap(context, property)) {
|
||||||
|
return False;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (context->attribs->standard_colormap_mode != RIgnoreStdColormap) {
|
||||||
|
XStandardColormap *maps;
|
||||||
|
int count, i;
|
||||||
|
|
||||||
|
if (!property) {
|
||||||
|
property = XInternAtom(context->dpy, "RGB_BEST_MAP", False);
|
||||||
|
if (!XGetRGBColormaps(context->dpy,
|
||||||
|
DefaultRootWindow(context->dpy),
|
||||||
|
&maps, &count, property)) {
|
||||||
|
maps = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!maps) {
|
||||||
|
property = XInternAtom(context->dpy, "RGB_DEFAULT_MAP", False);
|
||||||
|
if (!XGetRGBColormaps(context->dpy,
|
||||||
|
DefaultRootWindow(context->dpy),
|
||||||
|
&maps, &count, property)) {
|
||||||
|
maps = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!XGetRGBColormaps(context->dpy,
|
||||||
|
DefaultRootWindow(context->dpy),
|
||||||
|
&maps, &count, property)) {
|
||||||
|
maps = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (maps) {
|
||||||
|
int theMap = -1;
|
||||||
|
|
||||||
|
for (i = 0; i < count; i++) {
|
||||||
|
if (maps[i].visualid == context->visual->visualid) {
|
||||||
|
theMap = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (theMap < 0) {
|
||||||
|
puts("wrlib: no std cmap found");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (theMap >= 0
|
||||||
|
&& allocateStandardPseudoColor(context, &maps[theMap])) {
|
||||||
|
|
||||||
|
context->std_rgb_map = XAllocStandardColormap();
|
||||||
|
|
||||||
|
*context->std_rgb_map = maps[theMap];
|
||||||
|
|
||||||
|
XFree(maps);
|
||||||
|
|
||||||
|
return True;
|
||||||
|
}
|
||||||
|
|
||||||
|
XFree(maps);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
context->attribs->standard_colormap_mode = RIgnoreStdColormap;
|
||||||
|
|
||||||
|
/* RIgnoreStdColormap and fallback */
|
||||||
|
return allocatePseudoColor(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static char*
|
static char*
|
||||||
mygetenv(char *var, int scr)
|
mygetenv(char *var, int scr)
|
||||||
{
|
{
|
||||||
@@ -412,6 +595,10 @@ RCreateContext(Display *dpy, int screen_number, RContextAttributes *attribs)
|
|||||||
else
|
else
|
||||||
*context->attribs = *attribs;
|
*context->attribs = *attribs;
|
||||||
|
|
||||||
|
if (!(context->attribs->flags & RC_StandardColormap)) {
|
||||||
|
context->attribs->standard_colormap_mode = RUseStdColormap;
|
||||||
|
}
|
||||||
|
|
||||||
/* get configuration from environment variables */
|
/* get configuration from environment variables */
|
||||||
gatherconfig(context, screen_number);
|
gatherconfig(context, screen_number);
|
||||||
|
|
||||||
@@ -475,10 +662,11 @@ RCreateContext(Display *dpy, int screen_number, RContextAttributes *attribs)
|
|||||||
|GCGraphicsExposures, &gcv);
|
|GCGraphicsExposures, &gcv);
|
||||||
|
|
||||||
if (context->vclass == PseudoColor || context->vclass == StaticColor) {
|
if (context->vclass == PseudoColor || context->vclass == StaticColor) {
|
||||||
context->colors = allocatePseudoColor(context);
|
|
||||||
if (!context->colors) {
|
if (!setupPseudoColorColormap(context)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (context->vclass == GrayScale || context->vclass == StaticGray) {
|
} else if (context->vclass == GrayScale || context->vclass == StaticGray) {
|
||||||
context->colors = allocateGrayScale(context);
|
context->colors = allocateGrayScale(context);
|
||||||
if (!context->colors) {
|
if (!context->colors) {
|
||||||
|
|||||||
246
wrlib/convert.c
246
wrlib/convert.c
@@ -57,11 +57,24 @@ Pixmap R_CreateXImageMappedPixmap(RContext *context, RXImage *ximage);
|
|||||||
typedef struct RConversionTable {
|
typedef struct RConversionTable {
|
||||||
unsigned short table[256];
|
unsigned short table[256];
|
||||||
unsigned short index;
|
unsigned short index;
|
||||||
|
|
||||||
struct RConversionTable *next;
|
struct RConversionTable *next;
|
||||||
} RConversionTable;
|
} RConversionTable;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct RStdConversionTable {
|
||||||
|
unsigned int table[256];
|
||||||
|
|
||||||
|
unsigned short mult;
|
||||||
|
unsigned short max;
|
||||||
|
|
||||||
|
struct RStdConversionTable *next;
|
||||||
|
} RStdConversionTable;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static RConversionTable *conversionTable = NULL;
|
static RConversionTable *conversionTable = NULL;
|
||||||
|
static RStdConversionTable *stdConversionTable = NULL;
|
||||||
|
|
||||||
|
|
||||||
static unsigned short*
|
static unsigned short*
|
||||||
@@ -93,6 +106,38 @@ computeTable(unsigned short mask)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static unsigned int*
|
||||||
|
computeStdTable(unsigned int mult, unsigned int max)
|
||||||
|
{
|
||||||
|
RStdConversionTable *tmp = stdConversionTable;
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
while (tmp) {
|
||||||
|
if (tmp->mult == mult && tmp->max == max)
|
||||||
|
break;
|
||||||
|
tmp = tmp->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tmp)
|
||||||
|
return tmp->table;
|
||||||
|
|
||||||
|
tmp = (RStdConversionTable *)malloc(sizeof(RStdConversionTable));
|
||||||
|
if (tmp == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
for (i=0; i<256; i++) {
|
||||||
|
tmp->table[i] = (i*max)/0xff * mult;
|
||||||
|
}
|
||||||
|
tmp->mult = mult;
|
||||||
|
tmp->max = max;
|
||||||
|
|
||||||
|
tmp->next = stdConversionTable;
|
||||||
|
stdConversionTable = tmp;
|
||||||
|
|
||||||
|
return tmp->table;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static RXImage*
|
static RXImage*
|
||||||
image2TrueColorD16(RContext *ctx, RImage *image)
|
image2TrueColorD16(RContext *ctx, RImage *image)
|
||||||
@@ -585,6 +630,162 @@ image2PseudoColor(RContext *ctx, RImage *image)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For standard colormap
|
||||||
|
*/
|
||||||
|
static RXImage*
|
||||||
|
image2StandardPseudoColor(RContext *ctx, RImage *image)
|
||||||
|
{
|
||||||
|
RXImage *ximg;
|
||||||
|
register int x, y, r, g, b;
|
||||||
|
unsigned char *red, *grn, *blu;
|
||||||
|
unsigned long pixel;
|
||||||
|
unsigned char *data;
|
||||||
|
unsigned int *rtable, *gtable, *btable;
|
||||||
|
unsigned int base_pixel = ctx->std_rgb_map->base_pixel;
|
||||||
|
int ofs;
|
||||||
|
/*register unsigned char maxrgb = 0xff;*/
|
||||||
|
|
||||||
|
ximg = RCreateXImage(ctx, ctx->depth, image->width, image->height);
|
||||||
|
if (!ximg) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
red = image->data[0];
|
||||||
|
grn = image->data[1];
|
||||||
|
blu = image->data[2];
|
||||||
|
|
||||||
|
data = (unsigned char *)ximg->image->data;
|
||||||
|
|
||||||
|
|
||||||
|
rtable = computeStdTable(ctx->std_rgb_map->red_mult,
|
||||||
|
ctx->std_rgb_map->red_max);
|
||||||
|
|
||||||
|
gtable = computeStdTable(ctx->std_rgb_map->green_mult,
|
||||||
|
ctx->std_rgb_map->green_max);
|
||||||
|
|
||||||
|
btable = computeStdTable(ctx->std_rgb_map->blue_mult,
|
||||||
|
ctx->std_rgb_map->blue_max);
|
||||||
|
|
||||||
|
if (rtable==NULL || gtable==NULL || btable==NULL) {
|
||||||
|
RErrorCode = RERR_NOMEMORY;
|
||||||
|
RDestroyXImage(ctx, ximg);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (ctx->attribs->render_mode == RBestMatchRendering) {
|
||||||
|
for (y=0, ofs = 0; y<image->height; y++) {
|
||||||
|
for (x=0; x<image->width; x++, ofs++) {
|
||||||
|
/* reduce pixel */
|
||||||
|
|
||||||
|
pixel = (rtable[red[ofs]] + gtable[grn[ofs]]
|
||||||
|
+ btable[blu[ofs]] + base_pixel) & 0xffffffff;
|
||||||
|
|
||||||
|
XPutPixel(ximg->image, x, y, pixel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* dither */
|
||||||
|
short *rerr, *gerr, *berr;
|
||||||
|
short *nrerr, *ngerr, *nberr;
|
||||||
|
short *terr;
|
||||||
|
int rer, ger, ber;
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
printf("pseudo color dithering with %d colors per channel\n", cpc);
|
||||||
|
#endif
|
||||||
|
rerr = (short*)alloca((image->width+2)*sizeof(short));
|
||||||
|
gerr = (short*)alloca((image->width+2)*sizeof(short));
|
||||||
|
berr = (short*)alloca((image->width+2)*sizeof(short));
|
||||||
|
nrerr = (short*)alloca((image->width+2)*sizeof(short));
|
||||||
|
ngerr = (short*)alloca((image->width+2)*sizeof(short));
|
||||||
|
nberr = (short*)alloca((image->width+2)*sizeof(short));
|
||||||
|
if (!rerr || !gerr || !berr || !nrerr || !ngerr || !nberr) {
|
||||||
|
RErrorCode = RERR_NOMEMORY;
|
||||||
|
RDestroyXImage(ctx, ximg);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
for (x=0; x<image->width; x++) {
|
||||||
|
rerr[x] = red[x];
|
||||||
|
gerr[x] = grn[x];
|
||||||
|
berr[x] = blu[x];
|
||||||
|
}
|
||||||
|
rerr[x] = gerr[x] = berr[x] = 0;
|
||||||
|
/* convert and dither the image to XImage */
|
||||||
|
for (y=0, ofs=0; y<image->height; y++) {
|
||||||
|
if (y<image->height-1) {
|
||||||
|
int x1;
|
||||||
|
for (x=0, x1=ofs+image->width; x<image->width; x++, x1++) {
|
||||||
|
nrerr[x] = red[x1];
|
||||||
|
ngerr[x] = grn[x1];
|
||||||
|
nberr[x] = blu[x1];
|
||||||
|
}
|
||||||
|
/* last column */
|
||||||
|
x1--;
|
||||||
|
nrerr[x] = red[x1];
|
||||||
|
ngerr[x] = grn[x1];
|
||||||
|
nberr[x] = blu[x1];
|
||||||
|
}
|
||||||
|
for (x=0; x<image->width; x++, ofs++) {
|
||||||
|
/* reduce pixel */
|
||||||
|
if (rerr[x]>0xff) rerr[x]=0xff; else if (rerr[x]<0) rerr[x]=0;
|
||||||
|
if (gerr[x]>0xff) gerr[x]=0xff; else if (gerr[x]<0) gerr[x]=0;
|
||||||
|
if (berr[x]>0xff) berr[x]=0xff; else if (berr[x]<0) berr[x]=0;
|
||||||
|
|
||||||
|
r = rtable[rerr[x]];
|
||||||
|
g = gtable[gerr[x]];
|
||||||
|
b = btable[berr[x]];
|
||||||
|
|
||||||
|
pixel = r + g + b;
|
||||||
|
|
||||||
|
XPutPixel(ximg->image, x, y, pixel+base_pixel);
|
||||||
|
|
||||||
|
/* calc error */
|
||||||
|
rer = rerr[x] - (ctx->colors[pixel].red>>8);
|
||||||
|
ger = gerr[x] - (ctx->colors[pixel].green>>8);
|
||||||
|
ber = berr[x] - (ctx->colors[pixel].blue>>8);
|
||||||
|
|
||||||
|
/* distribute error */
|
||||||
|
rerr[x+1]+=(rer*7)/16;
|
||||||
|
gerr[x+1]+=(ger*7)/16;
|
||||||
|
berr[x+1]+=(ber*7)/16;
|
||||||
|
|
||||||
|
nrerr[x]+=(rer*5)/16;
|
||||||
|
ngerr[x]+=(ger*5)/16;
|
||||||
|
nberr[x]+=(ber*5)/16;
|
||||||
|
|
||||||
|
if (x>0) {
|
||||||
|
nrerr[x-1]+=(rer*3)/16;
|
||||||
|
ngerr[x-1]+=(ger*3)/16;
|
||||||
|
nberr[x-1]+=(ber*3)/16;
|
||||||
|
}
|
||||||
|
|
||||||
|
nrerr[x+1]+=rer/16;
|
||||||
|
ngerr[x+1]+=ger/16;
|
||||||
|
nberr[x+1]+=ber/16;
|
||||||
|
}
|
||||||
|
/* skip to next line */
|
||||||
|
terr = rerr;
|
||||||
|
rerr = nrerr;
|
||||||
|
nrerr = terr;
|
||||||
|
|
||||||
|
terr = gerr;
|
||||||
|
gerr = ngerr;
|
||||||
|
ngerr = terr;
|
||||||
|
|
||||||
|
terr = berr;
|
||||||
|
berr = nberr;
|
||||||
|
nberr = terr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ximg->image->data = (char*)data;
|
||||||
|
|
||||||
|
return ximg;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static RXImage*
|
static RXImage*
|
||||||
image2GrayScale(RContext *ctx, RImage *image)
|
image2GrayScale(RContext *ctx, RImage *image)
|
||||||
{
|
{
|
||||||
@@ -747,10 +948,18 @@ RConvertImage(RContext *context, RImage *image, Pixmap *pixmap)
|
|||||||
else
|
else
|
||||||
ximg = image2TrueColor(context, image);
|
ximg = image2TrueColor(context, image);
|
||||||
|
|
||||||
} else if (context->vclass == PseudoColor || context->vclass == StaticColor)
|
} else if (context->vclass == PseudoColor
|
||||||
|
|| context->vclass == StaticColor) {
|
||||||
|
|
||||||
|
if (context->attribs->standard_colormap_mode != RIgnoreStdColormap)
|
||||||
|
ximg = image2StandardPseudoColor(context, image);
|
||||||
|
else
|
||||||
ximg = image2PseudoColor(context, image);
|
ximg = image2PseudoColor(context, image);
|
||||||
else if (context->vclass == GrayScale || context->vclass == StaticGray)
|
|
||||||
|
} else if (context->vclass == GrayScale || context->vclass == StaticGray) {
|
||||||
|
|
||||||
ximg = image2GrayScale(context, image);
|
ximg = image2GrayScale(context, image);
|
||||||
|
}
|
||||||
|
|
||||||
if (!ximg) {
|
if (!ximg) {
|
||||||
#ifdef C_ALLOCA
|
#ifdef C_ALLOCA
|
||||||
@@ -875,7 +1084,36 @@ RGetClosestXColor(RContext *context, RColor *color, XColor *retColor)
|
|||||||
retColor->blue = color->blue << 8;
|
retColor->blue = color->blue << 8;
|
||||||
retColor->flags = DoRed|DoGreen|DoBlue;
|
retColor->flags = DoRed|DoGreen|DoBlue;
|
||||||
|
|
||||||
} else if (context->vclass == PseudoColor || context->vclass == StaticColor) {
|
} else if (context->vclass == PseudoColor
|
||||||
|
|| context->vclass == StaticColor) {
|
||||||
|
|
||||||
|
if (context->attribs->standard_colormap_mode != RIgnoreStdColormap) {
|
||||||
|
unsigned int *rtable, *gtable, *btable;
|
||||||
|
|
||||||
|
rtable = computeStdTable(context->std_rgb_map->red_mult,
|
||||||
|
context->std_rgb_map->red_max);
|
||||||
|
|
||||||
|
gtable = computeStdTable(context->std_rgb_map->green_mult,
|
||||||
|
context->std_rgb_map->green_max);
|
||||||
|
|
||||||
|
btable = computeStdTable(context->std_rgb_map->blue_mult,
|
||||||
|
context->std_rgb_map->blue_max);
|
||||||
|
|
||||||
|
if (rtable==NULL || gtable==NULL || btable==NULL) {
|
||||||
|
RErrorCode = RERR_NOMEMORY;
|
||||||
|
return False;
|
||||||
|
}
|
||||||
|
|
||||||
|
retColor->pixel = (rtable[color->red]
|
||||||
|
+ gtable[color->green]
|
||||||
|
+ btable[color->blue]
|
||||||
|
+ context->std_rgb_map->base_pixel) & 0xffffffff;
|
||||||
|
retColor->red = color->red<<8;
|
||||||
|
retColor->green = color->green<<8;
|
||||||
|
retColor->blue = color->blue<<8;
|
||||||
|
retColor->flags = DoRed|DoGreen|DoBlue;
|
||||||
|
|
||||||
|
} else {
|
||||||
const int cpc=context->attribs->colors_per_channel;
|
const int cpc=context->attribs->colors_per_channel;
|
||||||
const unsigned short rmask = cpc-1; /* different sizes could be used */
|
const unsigned short rmask = cpc-1; /* different sizes could be used */
|
||||||
const unsigned short gmask = rmask; /* for r,g,b */
|
const unsigned short gmask = rmask; /* for r,g,b */
|
||||||
@@ -895,6 +1133,8 @@ RGetClosestXColor(RContext *context, RColor *color, XColor *retColor)
|
|||||||
index = rtable[color->red]*cpccpc + gtable[color->green]*cpc
|
index = rtable[color->red]*cpccpc + gtable[color->green]*cpc
|
||||||
+ btable[color->blue];
|
+ btable[color->blue];
|
||||||
*retColor = context->colors[index];
|
*retColor = context->colors[index];
|
||||||
|
}
|
||||||
|
|
||||||
} else if (context->vclass == GrayScale || context->vclass == StaticGray) {
|
} else if (context->vclass == GrayScale || context->vclass == StaticGray) {
|
||||||
|
|
||||||
const int cpc = context->attribs->colors_per_channel;
|
const int cpc = context->attribs->colors_per_channel;
|
||||||
|
|||||||
26
wrlib/misc.c
26
wrlib/misc.c
@@ -133,41 +133,43 @@ RMessageForError(int errorCode)
|
|||||||
switch (errorCode) {
|
switch (errorCode) {
|
||||||
case RERR_NONE:
|
case RERR_NONE:
|
||||||
return "no error";
|
return "no error";
|
||||||
break;
|
|
||||||
case RERR_OPEN:
|
case RERR_OPEN:
|
||||||
return "could not open file";
|
return "could not open file";
|
||||||
break;
|
|
||||||
case RERR_READ:
|
case RERR_READ:
|
||||||
return "error reading from file";
|
return "error reading from file";
|
||||||
break;
|
|
||||||
case RERR_WRITE:
|
case RERR_WRITE:
|
||||||
return "error writing to file";
|
return "error writing to file";
|
||||||
break;
|
|
||||||
case RERR_NOMEMORY:
|
case RERR_NOMEMORY:
|
||||||
return "out of memory";
|
return "out of memory";
|
||||||
break;
|
|
||||||
case RERR_NOCOLOR:
|
case RERR_NOCOLOR:
|
||||||
return "out of color cells";
|
return "out of color cells";
|
||||||
break;
|
|
||||||
case RERR_BADIMAGEFILE:
|
case RERR_BADIMAGEFILE:
|
||||||
return "invalid or corrupted image file";
|
return "invalid or corrupted image file";
|
||||||
break;
|
|
||||||
case RERR_BADFORMAT:
|
case RERR_BADFORMAT:
|
||||||
return "the image format in the file is not supported and can't be loaded";
|
return "the image format in the file is not supported and can't be loaded";
|
||||||
break;
|
|
||||||
case RERR_BADINDEX:
|
case RERR_BADINDEX:
|
||||||
return "image file does not contain requested image index";
|
return "image file does not contain requested image index";
|
||||||
break;
|
|
||||||
case RERR_BADVISUALID:
|
case RERR_BADVISUALID:
|
||||||
return "request for an invalid visual ID";
|
return "request for an invalid visual ID";
|
||||||
break;
|
|
||||||
|
case RERR_STDCMAPFAIL:
|
||||||
|
return "failed to create standard colormap";
|
||||||
|
|
||||||
case RERR_XERROR:
|
case RERR_XERROR:
|
||||||
return "internal X error";
|
return "internal X error";
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
case RERR_INTERNAL:
|
case RERR_INTERNAL:
|
||||||
return "internal error";
|
return "internal error";
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -24,6 +24,8 @@ int main(int argc, char **argv)
|
|||||||
attr.render_mode = RDitheredRendering;
|
attr.render_mode = RDitheredRendering;
|
||||||
attr.colors_per_channel = 4;
|
attr.colors_per_channel = 4;
|
||||||
ctx = RCreateContext(dpy, DefaultScreen(dpy), &attr);
|
ctx = RCreateContext(dpy, DefaultScreen(dpy), &attr);
|
||||||
|
|
||||||
|
|
||||||
if (argc<2)
|
if (argc<2)
|
||||||
img = RGetImageFromXPMData(ctx, image_name);
|
img = RGetImageFromXPMData(ctx, image_name);
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -39,8 +39,8 @@
|
|||||||
#define RLRASTER_H_
|
#define RLRASTER_H_
|
||||||
|
|
||||||
|
|
||||||
/* version of the header for the library: 0.15 */
|
/* version of the header for the library: 0.16 */
|
||||||
#define WRASTER_HEADER_VERSION 15
|
#define WRASTER_HEADER_VERSION 16
|
||||||
|
|
||||||
|
|
||||||
#include <X11/Xlib.h>
|
#include <X11/Xlib.h>
|
||||||
@@ -50,6 +50,11 @@
|
|||||||
#include <X11/extensions/XShm.h>
|
#include <X11/extensions/XShm.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
/* RBestMatchRendering or RDitheredRendering */
|
/* RBestMatchRendering or RDitheredRendering */
|
||||||
#define RC_RenderMode (1<<0)
|
#define RC_RenderMode (1<<0)
|
||||||
|
|
||||||
@@ -71,9 +76,23 @@
|
|||||||
/* filter type for smoothed scaling */
|
/* filter type for smoothed scaling */
|
||||||
#define RC_ScalingFilter (1<<6)
|
#define RC_ScalingFilter (1<<6)
|
||||||
|
|
||||||
#ifdef __cplusplus
|
/* standard colormap usage */
|
||||||
extern "C" {
|
#define RC_StandardColormap (1<<7)
|
||||||
#endif /* __cplusplus */
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* std colormap usage/creation modes */
|
||||||
|
enum {
|
||||||
|
RUseStdColormap, /* default. fallbacks to RIgnore.. if
|
||||||
|
there is none defined */
|
||||||
|
RCreateStdColormap,
|
||||||
|
RIgnoreStdColormap
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct RContextAttributes {
|
typedef struct RContextAttributes {
|
||||||
int flags;
|
int flags;
|
||||||
@@ -85,6 +104,7 @@ typedef struct RContextAttributes {
|
|||||||
VisualID visualid; /* visual ID to use */
|
VisualID visualid; /* visual ID to use */
|
||||||
int use_shared_memory; /* True of False */
|
int use_shared_memory; /* True of False */
|
||||||
int scaling_filter;
|
int scaling_filter;
|
||||||
|
int standard_colormap_mode; /* what to do with std cma */
|
||||||
} RContextAttributes;
|
} RContextAttributes;
|
||||||
|
|
||||||
|
|
||||||
@@ -252,6 +272,7 @@ enum {
|
|||||||
#define RERR_BADINDEX 8 /* no such image index in file */
|
#define RERR_BADINDEX 8 /* no such image index in file */
|
||||||
|
|
||||||
#define RERR_BADVISUALID 16 /* invalid visual ID requested for context */
|
#define RERR_BADVISUALID 16 /* invalid visual ID requested for context */
|
||||||
|
#define RERR_STDCMAPFAIL 17 /* failed to created std colormap */
|
||||||
|
|
||||||
#define RERR_XERROR 127 /* internal X error */
|
#define RERR_XERROR 127 /* internal X error */
|
||||||
#define RERR_INTERNAL 128 /* should not happen */
|
#define RERR_INTERNAL 128 /* should not happen */
|
||||||
|
|||||||
Reference in New Issue
Block a user