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

  1. /* $XConsortium: LookupCmap.c,v 1.8 92/11/23 15:43:44 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. extern char *malloc();
  32. static Status lookup();
  33.  
  34. /*
  35.  * To create a standard colormap if one does not currently exist, or
  36.  * replace the currently existing standard colormap, use 
  37.  * XmuLookupStandardColormap().
  38.  *
  39.  * Given a screen, a visual, and a property, XmuLookupStandardColormap()
  40.  * will determine the best allocation for the property under the specified
  41.  * visual, and determine the whether to create a new colormap or to use
  42.  * the default colormap of the screen.  It will call XmuStandardColormap()
  43.  * to create the standard colormap.
  44.  *
  45.  * If replace is true, any previous definition of the property will be 
  46.  * replaced.  If retain is true, the property and the colormap will be
  47.  * made permanent for the duration of the server session.  However,
  48.  * pre-existing property definitions which are not replaced cannot be made
  49.  * permanent by a call to XmuLookupStandardColormap(); a request to retain 
  50.  * resources pertains to newly created resources.
  51.  *
  52.  * Returns 0 on failure, non-zero on success.  A request to create a 
  53.  * standard colormap upon a visual which cannot support such a map is
  54.  * considered a failure.  An example of this would be requesting any
  55.  * standard colormap property on a monochrome visual, or, requesting an
  56.  * RGB_BEST_MAP on a display whose colormap size is 16.
  57.  */
  58.  
  59. Status XmuLookupStandardColormap(dpy, screen, visualid, depth, property,
  60.                  replace, retain)
  61.     Display        *dpy;        /* specifies X server connection */
  62.     int            screen;     /* specifies screen of display */
  63.     VisualID        visualid;    /* specifies the visual type */
  64.     unsigned int    depth;        /* specifies  the visual type */
  65.     Atom        property;    /* a standard colormap property */
  66.     Bool        replace;    /* specifies whether to replace */
  67.     Bool        retain;        /* specifies whether to retain */
  68. {
  69.     Display        *odpy;        /* original display connection */
  70.     XStandardColormap    *colormap;    
  71.     XVisualInfo        vinfo_template, *vinfo;    /* visual */
  72.     long        vinfo_mask;
  73.     unsigned long    r_max, g_max, b_max;    /* allocation */
  74.     int            count;    
  75.     Colormap        cmap;            /* colormap ID */
  76.     Status        status = 0;
  77.  
  78.  
  79.     /* Match the requested visual */
  80.  
  81.     vinfo_template.visualid = visualid;    
  82.     vinfo_template.screen = screen;
  83.     vinfo_template.depth = depth;
  84.     vinfo_mask = VisualIDMask | VisualScreenMask | VisualDepthMask;
  85.     if ((vinfo = XGetVisualInfo(dpy, vinfo_mask, &vinfo_template, &count)) ==
  86.     NULL)
  87.     return 0;
  88.  
  89.     /* Monochrome visuals have no standard maps */
  90.  
  91.     if (vinfo->colormap_size <= 2) {
  92.     XFree((char *) vinfo);
  93.     return 0;    
  94.     }
  95.  
  96.     /* If the requested property already exists on this screen, and, 
  97.      * if the replace flag has not been set to true, return success.
  98.      * lookup() will remove a pre-existing map if replace is true.
  99.      */
  100.  
  101.     if (lookup(dpy, screen, visualid, property, (XStandardColormap *) NULL,
  102.            replace) && !replace) {
  103.     XFree((char *) vinfo);
  104.     return 1;
  105.     }
  106.  
  107.     /* Determine the best allocation for this property under the requested
  108.      * visualid and depth, and determine whether or not to use the default
  109.      * colormap of the screen.
  110.      */
  111.  
  112.     if (!XmuGetColormapAllocation(vinfo, property, &r_max, &g_max, &b_max)) {
  113.     XFree((char *) vinfo);
  114.     return 0;
  115.     }
  116.  
  117.     cmap = (property == XA_RGB_DEFAULT_MAP &&
  118.         visualid == XVisualIDFromVisual(DefaultVisual(dpy, screen)))
  119.     ? DefaultColormap(dpy, screen) : None;
  120.  
  121.     /* If retaining resources, open a new connection to the same server */
  122.  
  123.     if (retain) {
  124.     odpy = dpy;
  125.     if ((dpy = XOpenDisplay(XDisplayString(odpy))) == NULL) {
  126.         XFree((char *) vinfo);
  127.         return 0;
  128.     }
  129.     }
  130.  
  131.     /* Create the standard colormap */
  132.  
  133.     colormap = XmuStandardColormap(dpy, screen, visualid, depth, property,
  134.                    cmap, r_max, g_max, b_max);
  135.  
  136.     /* Set the standard colormap property */
  137.  
  138.     if (colormap) {
  139.     XGrabServer(dpy);
  140.  
  141.     if (lookup(dpy, screen, visualid, property, colormap, replace) &&
  142.         !replace) {
  143.         /* Someone has defined the property since we last looked.
  144.          * Since we will not replace it, release our own resources.
  145.          * If this is the default map, our allocations will be freed 
  146.          * when this connection closes.
  147.          */
  148.         if (colormap->killid == ReleaseByFreeingColormap)
  149.         XFreeColormap(dpy, colormap->colormap);
  150.     }
  151.     else if (retain) {
  152.         XSetCloseDownMode(dpy, RetainPermanent);
  153.     }
  154.     XUngrabServer(dpy);
  155.     XFree((char *) colormap);
  156.     status = 1;
  157.     }
  158.  
  159.     if (retain)
  160.     XCloseDisplay(dpy);
  161.     XFree((char *) vinfo);
  162.     return status;
  163. }
  164.  
  165. /***************************************************************************/
  166.  
  167. /* Lookup a standard colormap property.  If the property is RGB_DEFAULT_MAP,
  168.  * the visualid is used to determine whether the indicated standard colormap
  169.  * exists.  If the map exists and replace is true, delete the resources used
  170.  * by the map and remove the property.  Return true if the map exists,
  171.  * or did exist and was deleted; return false if the map was not found.
  172.  *
  173.  * Note that this is not the way that a Status return is normally used.
  174.  *
  175.  * If new is not NULL, new points to an XStandardColormap structure which
  176.  * describes a standard colormap of the specified property.  It will be made
  177.  * a standard colormap of the screen if none already exists, or if replace 
  178.  * is true.
  179.  */
  180.  
  181. static Status lookup(dpy, screen, visualid, property, new, replace)
  182.     Display        *dpy;        /* specifies display connection */
  183.     int            screen;        /* specifies screen number */
  184.     VisualID        visualid;    /* specifies visualid for std map */
  185.     Atom        property;    /* specifies colormap property name */
  186.     XStandardColormap    *new;        /* specifies a standard colormap */
  187.     Bool        replace;    /* specifies whether to replace */
  188. {
  189.     register int    i;
  190.     int            count;
  191.     XStandardColormap    *stdcmaps, *s;
  192.     Window        win = RootWindow(dpy, screen);
  193.  
  194.     /* The property does not already exist */
  195.  
  196.     if (! XGetRGBColormaps(dpy, win, &stdcmaps, &count, property)) {
  197.     if (new)
  198.         XSetRGBColormaps(dpy, win, new, 1, property);
  199.     return 0;
  200.     }
  201.  
  202.     /* The property exists and is not describing the RGB_DEFAULT_MAP */
  203.  
  204.     if (property != XA_RGB_DEFAULT_MAP) {
  205.     if (replace) {
  206.         XmuDeleteStandardColormap(dpy, screen, property);
  207.         if (new)
  208.         XSetRGBColormaps(dpy, win, new, 1, property);
  209.     }
  210.     XFree((char *)stdcmaps);
  211.     return 1;
  212.     }
  213.  
  214.     /* The property exists and is RGB_DEFAULT_MAP */
  215.     
  216.     for (i=0, s=stdcmaps; (i < count) && (s->visualid != visualid); i++, s++)
  217.     ;
  218.  
  219.     /* No RGB_DEFAULT_MAP property matches the given visualid */
  220.  
  221.     if (i == count) {
  222.     if (new) {
  223.         XStandardColormap    *m, *maps;
  224.  
  225.         s = (XStandardColormap *) malloc((unsigned) ((count+1) * sizeof
  226.                           (XStandardColormap)));
  227.  
  228.         for (i = 0, m = s, maps = stdcmaps; i < count; i++, m++, maps++) {
  229.         m->colormap   = maps->colormap;
  230.         m->red_max    = maps->red_max;
  231.         m->red_mult   = maps->red_mult;
  232.         m->green_max  = maps->green_max;
  233.         m->green_mult = maps->green_mult;
  234.         m->blue_max   = maps->blue_max;
  235.         m->blue_mult  = maps->blue_mult;
  236.         m->visualid   = maps->visualid;
  237.         m->killid     = maps->killid;
  238.         }
  239.         m->colormap   = new->colormap;
  240.         m->red_max    = new->red_max;
  241.         m->red_mult   = new->red_mult;
  242.         m->green_max  = new->green_max;
  243.         m->green_mult = new->green_mult;
  244.         m->blue_max   = new->blue_max;
  245.         m->blue_mult  = new->blue_mult;
  246.         m->visualid   = new->visualid;
  247.         m->killid     = new->killid;
  248.  
  249.         XSetRGBColormaps(dpy, win, s, ++count, property);
  250.         free((char *) s);
  251.     }
  252.     XFree((char *) stdcmaps);
  253.     return 0;
  254.     }
  255.  
  256.     /* Found an RGB_DEFAULT_MAP property with a matching visualid */
  257.  
  258.     if (replace) {
  259.     /* Free old resources first - we may need them, particularly in 
  260.      * the default colormap of the screen.  However, because of this,
  261.      * it is possible that we will destroy the old resource and fail 
  262.      * to create a new one if XmuStandardColormap() fails.
  263.      */
  264.  
  265.     if (count == 1) {
  266.         XmuDeleteStandardColormap(dpy, screen, property);
  267.         if (new)
  268.         XSetRGBColormaps(dpy, win, new, 1, property);
  269.     }
  270.     else {
  271.         XStandardColormap    *map;
  272.  
  273.         /* s still points to the matching standard colormap */
  274.  
  275.         if (s->killid == ReleaseByFreeingColormap) {
  276.         if ((s->colormap != None) &&
  277.             (s->colormap != DefaultColormap(dpy, screen)))
  278.             XFreeColormap(dpy, s->colormap);
  279.         }
  280.         else if (s->killid != None)
  281.         XKillClient(dpy, s->killid);
  282.  
  283.         map = (new) ? new : stdcmaps + --count;
  284.  
  285.         s->colormap   = map->colormap;
  286.         s->red_max    = map->red_max;
  287.         s->red_mult   = map->red_mult;
  288.         s->green_max  = map->green_max;
  289.         s->green_mult = map->green_mult;
  290.         s->blue_max   = map->blue_max;
  291.         s->blue_mult  = map->blue_mult;
  292.         s->visualid   = map->visualid;
  293.         s->killid     = map->killid;
  294.  
  295.         XSetRGBColormaps(dpy, win, stdcmaps, count, property);
  296.     }
  297.     }
  298.     XFree((char *) stdcmaps);
  299.     return 1;
  300. }
  301.