home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / X / mit / lib / Xmu / StdCmap.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-07-21  |  6.9 KB  |  211 lines

  1. /* $XConsortium: StdCmap.c,v 1.13 92/11/24 14:16:21 rws Exp $ 
  2.  * 
  3.  * Copyright 1989 by the Massachusetts Institute of Technology
  4.  *
  5.  * Permission to use, copy, modify, and distribute this software and its
  6.  * documentation for any purpose and without fee is hereby granted, provided 
  7.  * that the above copyright notice appear in all copies and that both that 
  8.  * copyright notice and this permission notice appear in supporting 
  9.  * documentation, and that the name of M.I.T. not be used in advertising
  10.  * or publicity pertaining to distribution of the software without specific, 
  11.  * written prior permission. M.I.T. makes no representations about the 
  12.  * suitability of this software for any purpose.  It is provided "as is"
  13.  * without express or implied warranty.
  14.  *
  15.  * M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
  16.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL M.I.T.
  17.  * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  18.  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
  19.  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  20.  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  21.  *
  22.  * Author:  Donna Converse, MIT X Consortium
  23.  */
  24.  
  25. #include <stdio.h>
  26. #include <X11/Xlib.h>
  27. #include <X11/Xatom.h>
  28. #include <X11/Xutil.h>
  29. #include <X11/Xmu/StdCmap.h>
  30.  
  31. #define lowbit(x) ((x) & (~(x) + 1))
  32.  
  33. static Status valid_args();        /* argument restrictions */
  34.  
  35. /*
  36.  * To create any one standard colormap, use XmuStandardColormap().
  37.  *
  38.  * Create a standard colormap for the given screen, visualid, and visual
  39.  * depth, with the given red, green, and blue maximum values, with the
  40.  * given standard property name.  Return a pointer to an XStandardColormap
  41.  * structure which describes the newly created colormap, upon success.
  42.  * Upon failure, return NULL.
  43.  * 
  44.  * XmuStandardColormap() calls XmuCreateColormap() to create the map.
  45.  *
  46.  * Resources created by this function are not made permanent; that is the
  47.  * caller's responsibility.
  48.  */
  49.  
  50. XStandardColormap *XmuStandardColormap(dpy, screen, visualid, depth, property,
  51.                        cmap, red_max, green_max, blue_max)
  52.     Display        *dpy;        /* specifies X server connection */
  53.     int            screen;     /* specifies display screen */
  54.     VisualID        visualid;    /* identifies the visual type */
  55.     unsigned int    depth;        /* identifies the visual type */
  56.     Atom        property;    /* a standard colormap property */
  57.     Colormap        cmap;        /* specifies colormap ID or None */
  58.     unsigned long    red_max, green_max, blue_max;    /* allocations */
  59. {
  60.     XStandardColormap    *stdcmap;
  61.     Status        status;
  62.     XVisualInfo        vinfo_template, *vinfo;
  63.     long        vinfo_mask;
  64.     int            n;
  65.  
  66.     /* Match the required visual information to an actual visual */
  67.     vinfo_template.visualid = visualid;    
  68.     vinfo_template.screen = screen;
  69.     vinfo_template.depth = depth;
  70.     vinfo_mask = VisualIDMask | VisualScreenMask | VisualDepthMask;
  71.     if ((vinfo = XGetVisualInfo(dpy, vinfo_mask, &vinfo_template, &n)) == NULL)
  72.     return 0;
  73.  
  74.     /* Check the validity of the combination of visual characteristics,
  75.      * allocation, and colormap property.  Create an XStandardColormap
  76.      * structure.
  77.      */
  78.  
  79.     if (! valid_args(vinfo, red_max, green_max, blue_max, property)
  80.     || ((stdcmap = XAllocStandardColormap()) == NULL)) {
  81.     XFree((char *) vinfo);
  82.     return 0;
  83.     }
  84.  
  85.     /* Fill in the XStandardColormap structure */
  86.  
  87.     if (cmap == DefaultColormap(dpy, screen)) {
  88.     /* Allocating out of the default map, cannot use XFreeColormap() */
  89.     Window win = XCreateWindow(dpy, RootWindow(dpy, screen), 1, 1, 1, 1,
  90.                    0, 0, InputOnly, vinfo->visual,
  91.                    (unsigned long) 0,
  92.                    (XSetWindowAttributes *)NULL);
  93.     stdcmap->killid  = (XID) XCreatePixmap(dpy, win, 1, 1, depth);
  94.     XDestroyWindow(dpy, win);
  95.     stdcmap->colormap = cmap;
  96.     } else {
  97.     stdcmap->killid = ReleaseByFreeingColormap;
  98.     stdcmap->colormap = XCreateColormap(dpy, RootWindow(dpy, screen),
  99.                         vinfo->visual, AllocNone);
  100.     }
  101.     stdcmap->red_max = red_max;
  102.     stdcmap->green_max = green_max;
  103.     stdcmap->blue_max = blue_max;
  104.     if (property == XA_RGB_GRAY_MAP) 
  105.     stdcmap->red_mult = stdcmap->green_mult = stdcmap->blue_mult = 1;
  106.     else if (vinfo->class == TrueColor || vinfo->class == DirectColor) {
  107.     stdcmap->red_mult = lowbit(vinfo->red_mask);
  108.     stdcmap->green_mult = lowbit(vinfo->green_mask);
  109.     stdcmap->blue_mult = lowbit(vinfo->blue_mask);
  110.     } else {
  111.     stdcmap->red_mult = (red_max > 0)
  112.         ? (green_max + 1) * (blue_max + 1) : 0;
  113.     stdcmap->green_mult = (green_max > 0) ? blue_max + 1 : 0;
  114.     stdcmap->blue_mult = (blue_max > 0) ? 1 : 0;
  115.     }
  116.     stdcmap->base_pixel = 0;            /* base pixel may change */
  117.     stdcmap->visualid = vinfo->visualid;
  118.  
  119.     /* Make the colormap */
  120.  
  121.     status = XmuCreateColormap(dpy, stdcmap);
  122.  
  123.     /* Clean up */
  124.  
  125.     XFree((char *) vinfo);
  126.     if (!status) {
  127.  
  128.     /* Free the colormap or the pixmap, if we created one */
  129.     if (stdcmap->killid == ReleaseByFreeingColormap)
  130.         XFreeColormap(dpy, stdcmap->colormap);
  131.     else if (stdcmap->killid != None)
  132.         XFreePixmap(dpy, stdcmap->killid);
  133.     
  134.     XFree((char *) stdcmap);
  135.     return (XStandardColormap *) NULL;
  136.     }
  137.     return stdcmap;
  138. }
  139.  
  140. /****************************************************************************/
  141. static Status valid_args(vinfo, red_max, green_max, blue_max, property)
  142.     XVisualInfo        *vinfo;        /* specifies visual */
  143.     unsigned long    red_max, green_max, blue_max;    /* specifies alloc */
  144.     Atom        property;    /* specifies property name */
  145. {
  146.     unsigned long    ncolors;    /* number of colors requested */
  147.  
  148.     /* Determine that the number of colors requested is <= map size */
  149.  
  150.     if ((vinfo->class == DirectColor) || (vinfo->class == TrueColor)) {
  151.     unsigned long mask;
  152.  
  153.     mask = vinfo->red_mask;
  154.     while (!(mask & 1))
  155.         mask >>= 1;
  156.     if (red_max > mask)
  157.         return 0;
  158.     mask = vinfo->green_mask;
  159.     while (!(mask & 1))
  160.         mask >>= 1;
  161.     if (green_max > mask)
  162.         return 0;
  163.     mask = vinfo->blue_mask;
  164.     while (!(mask & 1))
  165.         mask >>= 1;
  166.     if (blue_max > mask)
  167.         return 0;
  168.     } else if (property == XA_RGB_GRAY_MAP) {
  169.     ncolors = red_max + green_max + blue_max + 1;
  170.     if (ncolors > vinfo->colormap_size)
  171.         return 0;
  172.     } else {
  173.     ncolors = (red_max + 1) * (green_max + 1) * (blue_max + 1);
  174.     if (ncolors > vinfo->colormap_size)
  175.         return 0;
  176.     }
  177.     
  178.     /* Determine that the allocation and visual make sense for the property */
  179.  
  180.     switch (property)
  181.     {
  182.       case XA_RGB_DEFAULT_MAP:
  183.     if (red_max == 0 || green_max == 0 || blue_max == 0)
  184.         return 0;
  185.     break;
  186.       case XA_RGB_RED_MAP:
  187.     if (red_max == 0)
  188.         return 0;
  189.     break;
  190.       case XA_RGB_GREEN_MAP:
  191.     if (green_max == 0)
  192.         return 0;
  193.     break;
  194.       case XA_RGB_BLUE_MAP:    
  195.     if (blue_max == 0)
  196.         return 0;
  197.     break;
  198.       case XA_RGB_BEST_MAP:
  199.     if (red_max == 0 || green_max == 0 || blue_max == 0)
  200.         return 0;
  201.     break;
  202.       case XA_RGB_GRAY_MAP:
  203.     if (red_max == 0 || blue_max == 0 || green_max == 0)
  204.         return 0;
  205.     break;
  206.       default:
  207.     return 0;
  208.     }
  209.     return 1;
  210. }
  211.