home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / X / mit / lib / Xmu / LookupCmap.c.orig < prev    next >
Encoding:
Text File  |  1989-10-08  |  9.9 KB  |  300 lines

  1. /* $XConsortium: LookupCmap.c,v 1.7 89/10/08 15:00: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.     ? DefaultColormap(dpy, screen) : None;
  119.  
  120.     /* If retaining resources, open a new connection to the same server */
  121.  
  122.     if (retain) {
  123.     odpy = dpy;
  124.     if ((dpy = XOpenDisplay(XDisplayString(odpy))) == NULL) {
  125.         XFree((char *) vinfo);
  126.         return 0;
  127.     }
  128.     }
  129.  
  130.     /* Create the standard colormap */
  131.  
  132.     colormap = XmuStandardColormap(dpy, screen, visualid, depth, property,
  133.                    cmap, r_max, g_max, b_max);
  134.  
  135.     /* Set the standard colormap property */
  136.  
  137.     if (colormap) {
  138.     XGrabServer(dpy);
  139.  
  140.     if (lookup(dpy, screen, visualid, property, colormap, replace) &&
  141.         !replace) {
  142.         /* Someone has defined the property since we last looked.
  143.          * Since we will not replace it, release our own resources.
  144.          * If this is the default map, our allocations will be freed 
  145.          * when this connection closes.
  146.          */
  147.         if (colormap->killid == ReleaseByFreeingColormap)
  148.         XFreeColormap(dpy, colormap->colormap);
  149.     }
  150.     else if (retain) {
  151.         XSetCloseDownMode(dpy, RetainPermanent);
  152.     }
  153.     XUngrabServer(dpy);
  154.     XFree((char *) colormap);
  155.     status = 1;
  156.     }
  157.  
  158.     if (retain)
  159.     XCloseDisplay(dpy);
  160.     XFree((char *) vinfo);
  161.     return status;
  162. }
  163.  
  164. /***************************************************************************/
  165.  
  166. /* Lookup a standard colormap property.  If the property is RGB_DEFAULT_MAP,
  167.  * the visualid is used to determine whether the indicated standard colormap
  168.  * exists.  If the map exists and replace is true, delete the resources used
  169.  * by the map and remove the property.  Return true if the map exists,
  170.  * or did exist and was deleted; return false if the map was not found.
  171.  *
  172.  * Note that this is not the way that a Status return is normally used.
  173.  *
  174.  * If new is not NULL, new points to an XStandardColormap structure which
  175.  * describes a standard colormap of the specified property.  It will be made
  176.  * a standard colormap of the screen if none already exists, or if replace 
  177.  * is true.
  178.  */
  179.  
  180. static Status lookup(dpy, screen, visualid, property, new, replace)
  181.     Display        *dpy;        /* specifies display connection */
  182.     int            screen;        /* specifies screen number */
  183.     VisualID        visualid;    /* specifies visualid for std map */
  184.     Atom        property;    /* specifies colormap property name */
  185.     XStandardColormap    *new;        /* specifies a standard colormap */
  186.     Bool        replace;    /* specifies whether to replace */
  187. {
  188.     register int    i;
  189.     int            count;
  190.     XStandardColormap    *stdcmaps, *s;
  191.     Window        win = RootWindow(dpy, screen);
  192.  
  193.     /* The property does not already exist */
  194.  
  195.     if (! XGetRGBColormaps(dpy, win, &stdcmaps, &count, property)) {
  196.     if (new)
  197.         XSetRGBColormaps(dpy, win, new, 1, property);
  198.     return 0;
  199.     }
  200.  
  201.     /* The property exists and is not describing the RGB_DEFAULT_MAP */
  202.  
  203.     if (property != XA_RGB_DEFAULT_MAP) {
  204.     if (replace) {
  205.         XmuDeleteStandardColormap(dpy, screen, property);
  206.         if (new)
  207.         XSetRGBColormaps(dpy, win, new, 1, property);
  208.     }
  209.     XFree((char *)stdcmaps);
  210.     return 1;
  211.     }
  212.  
  213.     /* The property exists and is RGB_DEFAULT_MAP */
  214.     
  215.     for (i=0, s=stdcmaps; (i < count) && (s->visualid != visualid); i++, s++)
  216.     ;
  217.  
  218.     /* No RGB_DEFAULT_MAP property matches the given visualid */
  219.  
  220.     if (i == count) {
  221.     if (new) {
  222.         XStandardColormap    *m, *maps;
  223.  
  224.         s = (XStandardColormap *) malloc((unsigned) ((count+1) * sizeof
  225.                           (XStandardColormap)));
  226.  
  227.         for (i = 0, m = s, maps = stdcmaps; i < count; i++, m++, maps++) {
  228.         m->colormap   = maps->colormap;
  229.         m->red_max    = maps->red_max;
  230.         m->red_mult   = maps->red_mult;
  231.         m->green_max  = maps->green_max;
  232.         m->green_mult = maps->green_mult;
  233.         m->blue_max   = maps->blue_max;
  234.         m->blue_mult  = maps->blue_mult;
  235.         m->visualid   = maps->visualid;
  236.         m->killid     = maps->killid;
  237.         }
  238.         m->colormap   = new->colormap;
  239.         m->red_max    = new->red_max;
  240.         m->red_mult   = new->red_mult;
  241.         m->green_max  = new->green_max;
  242.         m->green_mult = new->green_mult;
  243.         m->blue_max   = new->blue_max;
  244.         m->blue_mult  = new->blue_mult;
  245.         m->visualid   = new->visualid;
  246.         m->killid     = new->killid;
  247.  
  248.         XSetRGBColormaps(dpy, win, s, ++count, property);
  249.         free((char *) s);
  250.     }
  251.     XFree((char *) stdcmaps);
  252.     return 0;
  253.     }
  254.  
  255.     /* Found an RGB_DEFAULT_MAP property with a matching visualid */
  256.  
  257.     if (replace) {
  258.     /* Free old resources first - we may need them, particularly in 
  259.      * the default colormap of the screen.  However, because of this,
  260.      * it is possible that we will destroy the old resource and fail 
  261.      * to create a new one if XmuStandardColormap() fails.
  262.      */
  263.  
  264.     if (count == 1) {
  265.         XmuDeleteStandardColormap(dpy, screen, property);
  266.         if (new)
  267.         XSetRGBColormaps(dpy, win, new, 1, property);
  268.     }
  269.     else {
  270.         XStandardColormap    *map;
  271.  
  272.         /* s still points to the matching standard colormap */
  273.  
  274.         if (s->killid == ReleaseByFreeingColormap) {
  275.         if ((s->colormap != None) &&
  276.             (s->colormap != DefaultColormap(dpy, screen)))
  277.             XFreeColormap(dpy, s->colormap);
  278.         }
  279.         else if (s->killid != None)
  280.         XKillClient(dpy, s->killid);
  281.  
  282.         map = (new) ? new : stdcmaps + --count;
  283.  
  284.         s->colormap   = map->colormap;
  285.         s->red_max    = map->red_max;
  286.         s->red_mult   = map->red_mult;
  287.         s->green_max  = map->green_max;
  288.         s->green_mult = map->green_mult;
  289.         s->blue_max   = map->blue_max;
  290.         s->blue_mult  = map->blue_mult;
  291.         s->visualid   = map->visualid;
  292.         s->killid     = map->killid;
  293.  
  294.         XSetRGBColormaps(dpy, win, stdcmaps, count, property);
  295.     }
  296.     }
  297.     XFree((char *) stdcmaps);
  298.     return 1;
  299. }
  300.