Blame src/StdCmap.c

Packit Service 2b1f13
/*
Packit Service 2b1f13
Packit Service 2b1f13
Copyright 1989, 1998  The Open Group
Packit Service 2b1f13
Packit Service 2b1f13
Permission to use, copy, modify, distribute, and sell this software and its
Packit Service 2b1f13
documentation for any purpose is hereby granted without fee, provided that
Packit Service 2b1f13
the above copyright notice appear in all copies and that both that
Packit Service 2b1f13
copyright notice and this permission notice appear in supporting
Packit Service 2b1f13
documentation.
Packit Service 2b1f13
Packit Service 2b1f13
The above copyright notice and this permission notice shall be included in
Packit Service 2b1f13
all copies or substantial portions of the Software.
Packit Service 2b1f13
Packit Service 2b1f13
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
Packit Service 2b1f13
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
Packit Service 2b1f13
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
Packit Service 2b1f13
OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
Packit Service 2b1f13
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
Packit Service 2b1f13
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Packit Service 2b1f13
Packit Service 2b1f13
Except as contained in this notice, the name of The Open Group shall not be
Packit Service 2b1f13
used in advertising or otherwise to promote the sale, use or other dealings
Packit Service 2b1f13
in this Software without prior written authorization from The Open Group.
Packit Service 2b1f13
Packit Service 2b1f13
*/
Packit Service 2b1f13
Packit Service 2b1f13
/*
Packit Service 2b1f13
 * Author:  Donna Converse, MIT X Consortium
Packit Service 2b1f13
 */
Packit Service 2b1f13
Packit Service 2b1f13
#ifdef HAVE_CONFIG_H
Packit Service 2b1f13
#include <config.h>
Packit Service 2b1f13
#endif
Packit Service 2b1f13
#include <stdio.h>
Packit Service 2b1f13
#include <X11/Xlib.h>
Packit Service 2b1f13
#include <X11/Xatom.h>
Packit Service 2b1f13
#include <X11/Xutil.h>
Packit Service 2b1f13
#include <X11/Xmu/StdCmap.h>
Packit Service 2b1f13
Packit Service 2b1f13
#define lowbit(x) ((x) & (~(x) + 1))
Packit Service 2b1f13
Packit Service 2b1f13
/*
Packit Service 2b1f13
 * Prototypes
Packit Service 2b1f13
 */
Packit Service 2b1f13
/* argument restrictions */
Packit Service 2b1f13
static Status valid_args(XVisualInfo*, unsigned long, unsigned long,
Packit Service 2b1f13
			 unsigned long, Atom);
Packit Service 2b1f13
Packit Service 2b1f13
/*
Packit Service 2b1f13
 * To create any one standard colormap, use XmuStandardColormap().
Packit Service 2b1f13
 *
Packit Service 2b1f13
 * Create a standard colormap for the given screen, visualid, and visual
Packit Service 2b1f13
 * depth, with the given red, green, and blue maximum values, with the
Packit Service 2b1f13
 * given standard property name.  Return a pointer to an XStandardColormap
Packit Service 2b1f13
 * structure which describes the newly created colormap, upon success.
Packit Service 2b1f13
 * Upon failure, return NULL.
Packit Service 2b1f13
 *
Packit Service 2b1f13
 * XmuStandardColormap() calls XmuCreateColormap() to create the map.
Packit Service 2b1f13
 *
Packit Service 2b1f13
 * Resources created by this function are not made permanent; that is the
Packit Service 2b1f13
 * caller's responsibility.
Packit Service 2b1f13
 */
Packit Service 2b1f13
Packit Service 2b1f13
XStandardColormap *
Packit Service 2b1f13
XmuStandardColormap(Display *dpy, int screen, VisualID visualid,
Packit Service 2b1f13
		    unsigned int depth, Atom property, Colormap cmap,
Packit Service 2b1f13
		    unsigned long red_max, unsigned long green_max,
Packit Service 2b1f13
		    unsigned long blue_max)
Packit Service 2b1f13
     /*
Packit Service 2b1f13
      * dpy				- specifies X server connection
Packit Service 2b1f13
      * screen				- specifies display screen
Packit Service 2b1f13
      * visualid			- identifies the visual type
Packit Service 2b1f13
      * depth				- identifies the visual type
Packit Service 2b1f13
      * property			- a standard colormap property
Packit Service 2b1f13
      * cmap				- specifies colormap ID or None
Packit Service 2b1f13
      * red_max, green_max, blue_max	- allocations
Packit Service 2b1f13
      */
Packit Service 2b1f13
{
Packit Service 2b1f13
    XStandardColormap	*stdcmap;
Packit Service 2b1f13
    Status		status;
Packit Service 2b1f13
    XVisualInfo		vinfo_template, *vinfo;
Packit Service 2b1f13
    long		vinfo_mask;
Packit Service 2b1f13
    int			n;
Packit Service 2b1f13
Packit Service 2b1f13
    /* Match the required visual information to an actual visual */
Packit Service 2b1f13
    vinfo_template.visualid = visualid;
Packit Service 2b1f13
    vinfo_template.screen = screen;
Packit Service 2b1f13
    vinfo_template.depth = depth;
Packit Service 2b1f13
    vinfo_mask = VisualIDMask | VisualScreenMask | VisualDepthMask;
Packit Service 2b1f13
    if ((vinfo = XGetVisualInfo(dpy, vinfo_mask, &vinfo_template, &n)) == NULL)
Packit Service 2b1f13
	return NULL;
Packit Service 2b1f13
Packit Service 2b1f13
    /* Check the validity of the combination of visual characteristics,
Packit Service 2b1f13
     * allocation, and colormap property.  Create an XStandardColormap
Packit Service 2b1f13
     * structure.
Packit Service 2b1f13
     */
Packit Service 2b1f13
Packit Service 2b1f13
    if (! valid_args(vinfo, red_max, green_max, blue_max, property)
Packit Service 2b1f13
	|| ((stdcmap = XAllocStandardColormap()) == NULL)) {
Packit Service 2b1f13
	XFree((char *) vinfo);
Packit Service 2b1f13
	return NULL;
Packit Service 2b1f13
    }
Packit Service 2b1f13
Packit Service 2b1f13
    /* Fill in the XStandardColormap structure */
Packit Service 2b1f13
Packit Service 2b1f13
    if (cmap == DefaultColormap(dpy, screen)) {
Packit Service 2b1f13
	/* Allocating out of the default map, cannot use XFreeColormap() */
Packit Service 2b1f13
	Window win = XCreateWindow(dpy, RootWindow(dpy, screen), 1, 1, 1, 1,
Packit Service 2b1f13
				   0, 0, InputOnly, vinfo->visual,
Packit Service 2b1f13
				   (unsigned long) 0,
Packit Service 2b1f13
				   (XSetWindowAttributes *)NULL);
Packit Service 2b1f13
	stdcmap->killid  = (XID) XCreatePixmap(dpy, win, 1, 1, depth);
Packit Service 2b1f13
	XDestroyWindow(dpy, win);
Packit Service 2b1f13
	stdcmap->colormap = cmap;
Packit Service 2b1f13
    } else {
Packit Service 2b1f13
	stdcmap->killid = ReleaseByFreeingColormap;
Packit Service 2b1f13
	stdcmap->colormap = XCreateColormap(dpy, RootWindow(dpy, screen),
Packit Service 2b1f13
					    vinfo->visual, AllocNone);
Packit Service 2b1f13
    }
Packit Service 2b1f13
    stdcmap->red_max = red_max;
Packit Service 2b1f13
    stdcmap->green_max = green_max;
Packit Service 2b1f13
    stdcmap->blue_max = blue_max;
Packit Service 2b1f13
    if (property == XA_RGB_GRAY_MAP)
Packit Service 2b1f13
	stdcmap->red_mult = stdcmap->green_mult = stdcmap->blue_mult = 1;
Packit Service 2b1f13
    else if (vinfo->class == TrueColor || vinfo->class == DirectColor) {
Packit Service 2b1f13
	stdcmap->red_mult = lowbit(vinfo->red_mask);
Packit Service 2b1f13
	stdcmap->green_mult = lowbit(vinfo->green_mask);
Packit Service 2b1f13
	stdcmap->blue_mult = lowbit(vinfo->blue_mask);
Packit Service 2b1f13
    } else {
Packit Service 2b1f13
	stdcmap->red_mult = (red_max > 0)
Packit Service 2b1f13
	    ? (green_max + 1) * (blue_max + 1) : 0;
Packit Service 2b1f13
	stdcmap->green_mult = (green_max > 0) ? blue_max + 1 : 0;
Packit Service 2b1f13
	stdcmap->blue_mult = (blue_max > 0) ? 1 : 0;
Packit Service 2b1f13
    }
Packit Service 2b1f13
    stdcmap->base_pixel = 0;			/* base pixel may change */
Packit Service 2b1f13
    stdcmap->visualid = vinfo->visualid;
Packit Service 2b1f13
Packit Service 2b1f13
    /* Make the colormap */
Packit Service 2b1f13
Packit Service 2b1f13
    status = XmuCreateColormap(dpy, stdcmap);
Packit Service 2b1f13
Packit Service 2b1f13
    /* Clean up */
Packit Service 2b1f13
Packit Service 2b1f13
    XFree((char *) vinfo);
Packit Service 2b1f13
    if (!status) {
Packit Service 2b1f13
Packit Service 2b1f13
	/* Free the colormap or the pixmap, if we created one */
Packit Service 2b1f13
	if (stdcmap->killid == ReleaseByFreeingColormap)
Packit Service 2b1f13
	    XFreeColormap(dpy, stdcmap->colormap);
Packit Service 2b1f13
	else if (stdcmap->killid != None)
Packit Service 2b1f13
	    XFreePixmap(dpy, stdcmap->killid);
Packit Service 2b1f13
Packit Service 2b1f13
	XFree((char *) stdcmap);
Packit Service 2b1f13
	return (XStandardColormap *) NULL;
Packit Service 2b1f13
    }
Packit Service 2b1f13
    return stdcmap;
Packit Service 2b1f13
}
Packit Service 2b1f13
Packit Service 2b1f13
/****************************************************************************/
Packit Service 2b1f13
static Status
Packit Service 2b1f13
valid_args(XVisualInfo *vinfo, unsigned long red_max, unsigned long green_max,
Packit Service 2b1f13
	   unsigned long blue_max, Atom property)
Packit Service 2b1f13
     /*
Packit Service 2b1f13
      * vinfo				- specifies visual
Packit Service 2b1f13
      * red_max, green_max, blue_max	- specifies alloc
Packit Service 2b1f13
      * property			- specifies property name
Packit Service 2b1f13
      */
Packit Service 2b1f13
{
Packit Service 2b1f13
    unsigned long	ncolors;	/* number of colors requested */
Packit Service 2b1f13
Packit Service 2b1f13
    /* Determine that the number of colors requested is <= map size */
Packit Service 2b1f13
Packit Service 2b1f13
    if ((vinfo->class == DirectColor) || (vinfo->class == TrueColor)) {
Packit Service 2b1f13
	unsigned long mask;
Packit Service 2b1f13
Packit Service 2b1f13
	mask = vinfo->red_mask;
Packit Service 2b1f13
	while (!(mask & 1))
Packit Service 2b1f13
	    mask >>= 1;
Packit Service 2b1f13
	if (red_max > mask)
Packit Service 2b1f13
	    return 0;
Packit Service 2b1f13
	mask = vinfo->green_mask;
Packit Service 2b1f13
	while (!(mask & 1))
Packit Service 2b1f13
	    mask >>= 1;
Packit Service 2b1f13
	if (green_max > mask)
Packit Service 2b1f13
	    return 0;
Packit Service 2b1f13
	mask = vinfo->blue_mask;
Packit Service 2b1f13
	while (!(mask & 1))
Packit Service 2b1f13
	    mask >>= 1;
Packit Service 2b1f13
	if (blue_max > mask)
Packit Service 2b1f13
	    return 0;
Packit Service 2b1f13
    } else if (property == XA_RGB_GRAY_MAP) {
Packit Service 2b1f13
	ncolors = red_max + green_max + blue_max + 1;
Packit Service 2b1f13
	if (ncolors > vinfo->colormap_size)
Packit Service 2b1f13
	    return 0;
Packit Service 2b1f13
    } else {
Packit Service 2b1f13
	ncolors = (red_max + 1) * (green_max + 1) * (blue_max + 1);
Packit Service 2b1f13
	if (ncolors > vinfo->colormap_size)
Packit Service 2b1f13
	    return 0;
Packit Service 2b1f13
    }
Packit Service 2b1f13
Packit Service 2b1f13
    /* Determine that the allocation and visual make sense for the property */
Packit Service 2b1f13
Packit Service 2b1f13
    switch (property)
Packit Service 2b1f13
    {
Packit Service 2b1f13
      case XA_RGB_DEFAULT_MAP:
Packit Service 2b1f13
	if (red_max == 0 || green_max == 0 || blue_max == 0)
Packit Service 2b1f13
	    return 0;
Packit Service 2b1f13
	break;
Packit Service 2b1f13
      case XA_RGB_RED_MAP:
Packit Service 2b1f13
	if (red_max == 0)
Packit Service 2b1f13
	    return 0;
Packit Service 2b1f13
	break;
Packit Service 2b1f13
      case XA_RGB_GREEN_MAP:
Packit Service 2b1f13
	if (green_max == 0)
Packit Service 2b1f13
	    return 0;
Packit Service 2b1f13
	break;
Packit Service 2b1f13
      case XA_RGB_BLUE_MAP:
Packit Service 2b1f13
	if (blue_max == 0)
Packit Service 2b1f13
	    return 0;
Packit Service 2b1f13
	break;
Packit Service 2b1f13
      case XA_RGB_BEST_MAP:
Packit Service 2b1f13
	if (red_max == 0 || green_max == 0 || blue_max == 0)
Packit Service 2b1f13
	    return 0;
Packit Service 2b1f13
	break;
Packit Service 2b1f13
      case XA_RGB_GRAY_MAP:
Packit Service 2b1f13
	if (red_max == 0 || blue_max == 0 || green_max == 0)
Packit Service 2b1f13
	    return 0;
Packit Service 2b1f13
	break;
Packit Service 2b1f13
      default:
Packit Service 2b1f13
	return 0;
Packit Service 2b1f13
    }
Packit Service 2b1f13
    return 1;
Packit Service 2b1f13
}