aboutsummaryrefslogtreecommitdiff
path: root/vendor/x11iraf/obm/ObmW/GtermCmap.c
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/x11iraf/obm/ObmW/GtermCmap.c')
-rw-r--r--vendor/x11iraf/obm/ObmW/GtermCmap.c765
1 files changed, 765 insertions, 0 deletions
diff --git a/vendor/x11iraf/obm/ObmW/GtermCmap.c b/vendor/x11iraf/obm/ObmW/GtermCmap.c
new file mode 100644
index 00000000..f4ec239e
--- /dev/null
+++ b/vendor/x11iraf/obm/ObmW/GtermCmap.c
@@ -0,0 +1,765 @@
+
+
+
+/*
+ * Internal procedures for the above code.
+ * ----------------------------------------
+ */
+
+/* get_colormap -- Get a private colormap. On all calls after the first
+ * this just returns the existing gterm widget colormap. On the first call
+ * we query the server for the named custom colormap, and if the colormap
+ * exists we modify the gterm widget to use it. If the custom colormap has
+ * not yet been created by some other client, we create it.
+ *
+ * This code creates a custom colormap using the "standard colormap"
+ * facilities provided by XLIB. Although we do not use any of the predefined
+ * standard colormaps, use of the standard colormap facilities allows any
+ * number of clients to share the same custom colormap. Use of a custom
+ * colormap helps avoid running out of space in the default colormap, ensures
+ * that the gterm widget will get the color cells it needs, and makes it
+ * easier for several imaging clients which share the same colormap to
+ * simultaneously display their windows.
+ *
+ * To minimize colormap flashing we try to avoid using the full colormap,
+ * setting the unused cells to the colors set in the default colormap. In
+ * most cases this will prevent the rest of the screen from changing color
+ * when the custom colormap is installed.
+ */
+static Colormap
+get_colormap (w)
+ GtermWidget w;
+{
+ register int i, j;
+ Display *display = w->gterm.display;
+ Screen *screen = w->gterm.screen;
+ XColor def_colors[SZ_STATIC_CMAP], *cp, *c1, *c2;
+ XStandardColormap cm, *cm_p;
+ XColor colors[MAX_SZCMAP];
+ int base_pixel, p1, p2;
+ Colormap colormap;
+ char property[128];
+ int ncmap, nitems;
+ Pixel pixel;
+ Atom atom;
+
+
+ if (DBG_TRACE && DBG_CM_VERB)
+ fprintf (stderr, "get_colormap: have=%d ncols=%d maxcols=%d base=%d\n",
+ w->gterm.haveColormap, w->gterm.ncolors, w->gterm.maxColors,
+ w->gterm.base_pixel);
+
+ if (w->gterm.haveColormap || w->gterm.useGlobalCmap)
+ return (w->core.colormap);
+
+ /* Map custom colormap name to atom. */
+ sprintf (property, "GT_%s", w->gterm.cmapName);
+ atom = XInternAtom (display, property, False);
+ w->gterm.cmapAtom = atom;
+
+
+ /* Get custom colormap.
+ */
+ if (DBG_TRACE && DBG_CM_VERB)
+ fprintf (stderr, "get_colormap: cmapInitialize=%d GetRGB=%d of %d\n",
+ w->gterm.cmapInitialize,
+ XGetRGBColormaps (display, w->gterm.root, &cm_p, &ncmap, atom),
+ ncmap);
+
+
+ if (!w->gterm.cmapInitialize &&
+ XGetRGBColormaps (display, w->gterm.root, &cm_p, &ncmap, atom)) {
+
+ /* Colormap aleady exists, just use it.
+ */
+ cm = *cm_p;
+ colormap = cm.colormap;
+ w->gterm.base_pixel = cm.base_pixel;
+
+ if (DBG_TRACE)
+ fprintf (stderr, "get_colormap: use existing cmap=0x%x; base=%d\n",
+ colormap, w->gterm.base_pixel);
+
+
+ } else if (w->gterm.w_depth > 8) {
+
+ /* Setup for TrueColor visual.
+ */
+ if (DBG_TRACE && DBG_CM_VERB)
+ fprintf (stderr, "get_colormap: TrueColor gt.ncolors=%d base=%d\n",
+ w->gterm.ncolors, w->gterm.base_pixel);
+
+ nitems = MAX_SZCMAP;
+ w->gterm.ncolors = SZ_STATIC_CMAP + w->gterm.maxColors;
+
+ /* Get a private colormap.
+ */
+ for (i=0; i < MAX_SZCMAP; i++)
+ colors[i].pixel = i;
+
+ for (i = SZ_STATIC_CMAP; i < w->gterm.ncolors; i++) {
+ w->gterm.color[i].pixel = w->gterm.cmap[i] = pixel =
+ min (nitems - 1, w->gterm.base_pixel + i - SZ_STATIC_CMAP);
+
+ w->gterm.color[i] = colors[pixel];
+ }
+
+ if (DBG_TRACE)
+ fprintf (stderr,
+ "\n\nget_colormap: gt.ncolors = %d maxcols = %d\n\n\n",
+ w->gterm.ncolors, w->gterm.maxColors);
+
+ goto use_default;
+
+ } else {
+ /* Create or reinitialize a global colormap.
+ */
+ XVisualInfo template, *vi;
+ Display *d;
+ Screen *s;
+ Window root;
+ long mask;
+
+
+ if (DBG_TRACE)
+ fprintf (stderr, "get_colormap: ...creating colormap, ncols=%d\n",
+ w->gterm.ncolors);
+
+
+ if (!(d = XOpenDisplay (DisplayString(display))))
+ goto use_default;
+ s = DefaultScreenOfDisplay (d);
+ root = DefaultRootWindow (d);
+
+ /* Try to get a pseudocolor visual. */
+ mask = 0;
+ template.screen = DefaultScreen(d); mask |= VisualScreenMask;
+ template.depth = RasterDepth; mask |= VisualDepthMask;
+ template.class = PseudoColor; mask |= VisualClassMask;
+
+ if (!(vi = XGetVisualInfo (d, mask, &template, &nitems))) {
+ XCloseDisplay (d);
+ goto use_default;
+ }
+
+ /* Create custom colormap with all cells allocated read/write */
+ colormap = XCreateColormap (d, root, vi->visual, AllocAll);
+
+ /* Initialize colormap to be same as default colormap. */
+ nitems = min (MAX_SZCMAP, CellsOfScreen(s));
+ for (i=0; i < nitems; i++)
+ colors[i].pixel = i;
+ XQueryColors (d, DefaultColormapOfScreen(s), colors, nitems);
+ XStoreColors (d, colormap, colors, nitems);
+
+ /* Globally define permanent server custom colormap. */
+ memset ((char *)&cm, 0, sizeof(cm));
+ cm.colormap = colormap;
+ cm.base_pixel = w->gterm.base_pixel;
+ cm.red_max = 0;
+ cm.visualid = vi->visualid;
+ cm.killid = 1;
+ XSetRGBColormaps (d, root, &cm, 1, atom);
+
+ XSetCloseDownMode (d, RetainPermanent);
+ XCloseDisplay (d);
+ w->gterm.cmapInitialize = False;
+
+ /* Free the XVisualInfo struct. */
+ if (vi)
+ XFree ((void *)vi); /* MF040 */
+
+
+ if (DBG_TRACE && DBG_CM_VERB)
+ fprintf (stderr, "get_colormap: .............creating done\n");
+ }
+
+ /* Save default color assignments for static colors. */
+ for (i=0; i < SZ_STATIC_CMAP; i++)
+ def_colors[i] = w->gterm.color[i];
+
+ nitems = min (MAX_SZCMAP, CellsOfScreen(screen));
+ w->gterm.ncolors = SZ_STATIC_CMAP + w->gterm.maxColors;
+ base_pixel = w->gterm.base_pixel;
+
+ if (DBG_TRACE && DBG_CM_VERB)
+ fprintf (stderr,
+ "\n\nget_colormap: gt.ncolors = %d maxcols = %d\n\n\n",
+ w->gterm.ncolors, w->gterm.maxColors);
+
+ /* Get the private colormap. */
+ for (i=0; i < nitems; i++)
+ colors[i].pixel = i;
+ XQueryColors (display, colormap, colors, nitems);
+
+ /* Initialize the raster pixel to display pixel mapping and set the
+ * color assigned to each pixel value in the private colormap.
+ */
+ for (i = SZ_STATIC_CMAP; i < w->gterm.ncolors; i++) {
+ w->gterm.color[i].pixel = w->gterm.cmap[i] = pixel =
+ min (nitems - 1, base_pixel + i - SZ_STATIC_CMAP);
+ w->gterm.color[i] = colors[pixel];
+ }
+
+ /* Check the static part of the cmap to make sure that the pixel numbers
+ * aren't aliased to pixels in the dynamic part of the custom colormap.
+ * If this happens, reassign these color numbers to the pixels just
+ * preceeding the dynamic part of the custom colormap. The red_max
+ * field of the colormap descriptor is used to keep track of the number
+ * of static colors allocated by different clients. These static colors
+ * are shared, hence the same color will not be stored twice.
+ */
+ p1 = p2 = base_pixel - cm.red_max;
+ for (i=0; i < SZ_STATIC_CMAP; i++) {
+ pixel = w->gterm.cmap[i];
+ if (pixel >= base_pixel && pixel < base_pixel+DEF_MAXCOLORS && p1 > 2) {
+ /* First check to see if we already have a static entry reserved
+ * for this color.
+ */
+ c1 = &def_colors[i];
+ for (j=p1, cp=NULL; j < base_pixel; j++) {
+ c2 = &colors[j];
+ if (c1->red == c2->red && c1->green == c2->green &&
+ c1->blue == c2->blue) {
+ cp = c2;
+ break;
+ }
+ }
+
+ /* Assign a new screen pixel value. */
+ if (cp)
+ w->gterm.cmap[i] = cp->pixel;
+ else {
+ cp = &colors[--p1];
+ *cp = def_colors[i];
+ cp->flags = (DoRed | DoGreen | DoBlue);
+ cp->pixel = w->gterm.cmap[i] = p1;
+ cm.red_max++;
+ }
+ w->gterm.color[i].pixel = w->gterm.cmap[i];
+ }
+ }
+ if (p1 < p2) {
+ XStoreColors (display, colormap, &colors[p1], p2 - p1);
+ XSetRGBColormaps (display, w->gterm.root, &cm, 1, atom);
+ }
+
+ /* Assign the new colormap to the gterm widget's window. */
+ XtVaSetValues ((Widget)w, XtNcolormap, (XtArgVal)colormap, NULL);
+ w->gterm.haveColormap++;
+
+ /* If the pointer is in the window, advise window manager to load the
+ * colortable for the window.
+ */
+ if (w->gterm.in_window)
+ request_colormap_focus (w);
+
+ return (colormap);
+
+use_default:
+ /* Unable to create custom colormap. */
+ w->gterm.useDefaultCM++;
+ w->gterm.haveColormap++;
+ return (w->core.colormap);
+}
+
+
+/* request_colormap_focus -- Modify the WM_COLORMAP_WINDOWS property on a
+ * widget's top level shell window to advise the window manager that the
+ * widget's window should have its colormap loaded. This should only be
+ * used for windows that have a colormap different than that of the top
+ * level window.
+ */
+static
+request_colormap_focus (w)
+ GtermWidget w;
+{
+ Widget p;
+
+
+ if (!w || !XtIsRealized ((Widget)w))
+ return;
+
+ /* Find the top level window. */
+ for (p = XtParent(w); !XtIsShell(p); p = XtParent(p))
+ ;
+
+ /* Modify WM_COLORMAP_WINDOWS to give the current window priority.
+ */
+ if (p) {
+ Window window = XtWindow (p);
+ Window *wl = NULL, n_wl[MAX_WMWIN+1];
+ register int n_nw, i;
+ int nw;
+
+ /* If WM_COLORMAP_WINDOWS is already set save its value, otherwise
+ * start a list initially containing only the top level window.
+ */
+ w->gterm.wmTop = window;
+ if (XGetWMColormapWindows (w->gterm.display, window, &wl, &nw)) {
+ memmove (w->gterm.wmWindows, (char *)wl, nw * sizeof(int));
+ w->gterm.n_wmWindows = nw = min (nw, MAX_WMWIN);
+ free ((char *)wl);
+ } else {
+ w->gterm.wmWindows[0] = window;
+ w->gterm.n_wmWindows = nw = 1;
+ }
+
+ n_nw = 0;
+ wl = w->gterm.wmWindows;
+ n_wl[n_nw++] = XtWindow(w);
+
+ for (i=0; i < nw; i++)
+ if (wl[i] != XtWindow(w))
+ n_wl[n_nw++] = wl[i];
+
+ XSetWMColormapWindows (w->gterm.display, window, n_wl, n_nw);
+ }
+}
+
+
+/* restore_colormap_focus -- Reset WM_COLORMAP_WINDOWS. Retain the window
+ * that had the focus in the list, but drop its priority one notch. This
+ * should follow a prior call to request_colormap_focus.
+ */
+static
+restore_colormap_focus (w)
+ GtermWidget w;
+{
+ register int nw, n_nw, i;
+ Window *wl, n_wl[MAX_WMWIN+1], old;
+
+ if (!w || !XtIsRealized ((Widget)w))
+ return;
+
+ old = XtWindow(w);
+ wl = w->gterm.wmWindows;
+ if ((nw = w->gterm.n_wmWindows) == 0 || (nw == 1 && wl[0] == old))
+ return;
+
+ n_nw = 0;
+ if (wl[0] != old)
+ n_wl[n_nw++] = wl[0];
+ n_wl[n_nw++] = old;
+
+ for (i=1; i < nw; i++)
+ if (wl[i] != old)
+ n_wl[n_nw++] = wl[i];
+
+ XSetWMColormapWindows (w->gterm.display, w->gterm.wmTop, n_wl, n_nw);
+}
+
+
+/* inherit_default_colormap -- Set any unused cells of the custom colormap
+ * to the colors defined for the corresponding cells of the default colormap.
+ * This minimizes colormap flashing when using a custom colormap, but only
+ * works if a few unused cells can be reserved, e.g., at the beginning of
+ * the colormap (which is usually where X allocates its colors).
+ */
+static
+inherit_default_colormap (w)
+ GtermWidget w;
+{
+ register XColor *cp, *ap;
+ register int ncolors, i;
+ Display *display = w->gterm.display;
+ Screen *screen = w->gterm.screen;
+ Window root = w->gterm.root;
+ Atom atom = w->gterm.cmapAtom;
+ XColor colors[MAX_SZCMAP];
+ XStandardColormap *cm;
+ int first, nitems, ncmap;
+
+
+
+ if (DBG_TRACE)
+ fprintf (stderr, "inherit_default_cmap: ncols=%d maxcols=%d base=%d\n",
+ w->gterm.ncolors, w->gterm.maxColors, w->gterm.base_pixel);
+
+ if (!w || !XtIsRealized ((Widget)w))
+ return;
+ if (w->gterm.useDefaultCM || !w->gterm.haveColormap)
+ return;
+ if (w->gterm.base_pixel <= 0)
+ return; /* fully allocated colormap */
+
+ /* We have to read the colormap property again as another client could
+ * have reserved more static colors (i.e.,changed red_max), and we don't
+ * want to clobber these colors.
+ */
+ if (XGetRGBColormaps (display, root, &cm, &ncmap, atom)) {
+ /* Make sure we have the right colormap. */
+ if (w->core.colormap != cm->colormap)
+ XtVaSetValues ((Widget)w,XtNcolormap,(XtArgVal)cm->colormap,NULL);
+
+ /* Get lower part of default colormap. */
+ ncolors = cm->base_pixel - cm->red_max;
+ for (cp=colors, i=0; i < ncolors; i++, cp++) {
+ cp->flags = (DoRed | DoGreen | DoBlue);
+ cp->pixel = i;
+ }
+
+ /* Get upper part of default colormap. */
+ first = cm->base_pixel + w->gterm.ncolors - SZ_STATIC_CMAP;
+ ncolors = min (MAX_SZCMAP, CellsOfScreen(screen)) - first;
+ for (i=0; i < ncolors; i++, cp++) {
+ cp->flags = (DoRed | DoGreen | DoBlue);
+ cp->pixel = first + i;
+ }
+
+ /* Inherit values from default colormap. */
+ ncolors = cp - colors;
+ XQueryColors (display, DefaultColormapOfScreen(screen),
+ colors, ncolors);
+ XStoreColors (display, w->core.colormap, colors, ncolors);
+
+ /* The global gterm colormap may have changed. Compare widget's
+ * version of color table with the global colortable and update
+ * the widget's state if the global colortable has changed.
+ */
+ ncolors = w->gterm.ncolors;
+ memmove (colors, w->gterm.color, ncolors * sizeof(*cp));
+ XQueryColors (display, w->core.colormap, colors, ncolors);
+ for (i=ncolors, cp=colors, ap=w->gterm.color; --i >= 0; cp++, ap++)
+ if (cp->red != ap->red || cp->green != ap->green ||
+ cp->blue != ap->blue) {
+ memmove (w->gterm.color, colors, ncolors * sizeof(*cp));
+ invalidate_cmap (w);
+ }
+
+ } else {
+ if (DBG_TRACE)
+ fprintf (stderr, "inherit_default_cmap: else XGetRGBColormaps\n");
+ }
+}
+
+
+/* update_default_colormap -- Update the default colormap so that any
+ * unallocated cells mirror the widget's custom colormap. This increases
+ * the chance that the widget's contents will be visible when the window
+ * does not have the colormap focus, and minimizes flashing when the
+ * colormap focus changes.
+ */
+static
+update_default_colormap (w)
+ GtermWidget w;
+{
+ register XColor *ip, *op;
+ register int j, n;
+ register Pixel v;
+
+ XColor colors[MAX_SZCMAP];
+ Pixel pixels[MAX_SZCMAP];
+ char allocated[MAX_SZCMAP];
+ int overflow, req, need, first, nelem, i;
+ unsigned long plane_masks[1];
+ Colormap defcmap;
+
+
+ if (!w || !XtIsRealized ((Widget)w))
+ return;
+ if (w->gterm.useDefaultCM || !w->gterm.haveColormap)
+ return;
+ if (w->gterm.useGlobalCmap) /* 24-bit */
+ return;
+
+ if (DBG_TRACE)
+ fprintf (stderr, "update_def_colormap: ENTER\n");
+
+ first = SZ_STATIC_CMAP;
+ nelem = w->gterm.ncolors;
+
+ defcmap = DefaultColormapOfScreen (w->gterm.screen);
+ /* need = min (MAX_SZCMAP, first + nelem - SZ_STATIC_CMAP); */
+ need = MAX_SZCMAP;
+
+ /* Get the colormap cells. */
+ for (req=need, n=0; req > 0 && n < need; )
+ if (XAllocColorCells (w->gterm.display, defcmap, False,
+ plane_masks, 0, &pixels[n], req)) {
+ n += req;
+ } else
+ req /= 2;
+
+ /* Perform the color matching. This is awkward as the pixel value
+ * assignments may be different in the two colormaps. We have to look
+ * up each pixel before attempting to assign a color, or XStoreColors
+ * below will result in a server error.
+ */
+ memset (allocated, 0, sizeof(allocated));
+ overflow = 0;
+
+ for (i=0; i < n; i++) {
+ v = pixels[i];
+ if (v < MAX_SZCMAP)
+ allocated[v] = 1;
+ else {
+ overflow++;
+ break;
+ }
+ }
+
+ ip = &w->gterm.color[first];
+ op = colors;
+ if (overflow) {
+ for (i=0; i < nelem; i++, ip++) {
+ for (j=0, v = ip->pixel; j < n; j++) {
+ if (pixels[j] == v) {
+ *op++ = *ip;
+ break;
+ }
+ }
+ }
+ } else {
+ for (j=0; j < nelem; j++, ip++) {
+ if (allocated[ip->pixel]) {
+ allocated[ip->pixel] = 0;
+ *op++ = *ip;
+ }
+ }
+ }
+
+ if (op > colors)
+ XStoreColors (w->gterm.display, defcmap, colors, op - colors);
+
+ if (!w->gterm.useGlobalCmap)
+ XFreeColors (w->gterm.display, defcmap, pixels, n, 0);
+
+done:
+ if (DBG_TRACE)
+ fprintf (stderr, "update_def_colormap: LEAVING\n");
+}
+
+
+
+
+/* Global Colormap routines.
+ */
+static int SetGlobalCmap(w)
+ GtermWidget w;
+{
+ static int init=0;
+
+ if( !init ){
+ strcpy (global_cmapname, XtNcmapName);
+ global_ncolors = 0;
+ global_mincolors = 0;
+ init = 1;
+ }
+ if( !w->gterm.useGlobalCmap ){
+ w->gterm.cmap = (Pixel *)XtCalloc(MAX_SZCMAP, sizeof(Pixel));
+ w->gterm.color = (XColor *)XtCalloc(MAX_SZCMAP, sizeof(XColor));
+
+ return(0);
+
+ } else{
+ w->gterm.cmap = global_cmap;
+ w->gterm.color = global_color;
+
+ return(global_ncolors);
+ }
+}
+
+
+static int ParseGlobalCmap(w)
+ GtermWidget w;
+{
+ char *s;
+ char *t;
+ char *cmapname;
+ int colors;
+ int usedefault=0;
+
+ /* process a directive such as "default[n:m,name]", where
+ * n = min number of colors that must be allocated or else
+ * use a private map called "name". m is the max colors to
+ * allocate (same as maxColors). Either or both can be omitted
+ */
+ cmapname = w->gterm.cmapName;
+ if( !strncmp (cmapname, "default", 7) ){
+ usedefault = 1;
+ if( (s=strchr(cmapname,'[')) != NULL ){
+ /* skip open bracket */
+ s++;
+ /* get min number of colors */
+ global_mincolors = strtol(s, &t, 10);
+ /* for n:m syntax, get max colors */
+ if( *t == ':' ){
+ s = ++t;
+ colors = strtol(s, &t, 10);
+ if( colors > 0 )
+ w->gterm.maxColors = colors;
+ }
+ /* look for default name */
+ if( *t == ',' ){
+ t++;
+ }
+ s = t;
+ /* this is the new name of the cmap -- but it can't be "default"! */
+ if( (strncmp(s, "default", 7)) && (*s != ']') ){
+ strcpy(global_cmapname, s);
+ /* null out closing bracket */
+ if( (s = strchr(global_cmapname, ']')) != NULL )
+ *s = '\0';
+ }
+ /* now make sure we can grab the min number of colors,
+ or else set up to use a private color map */
+ colors = GetMaxCmapColors(w);
+ if( colors < global_mincolors ){
+ usedefault = 0;
+ w->gterm.haveColormap = 0;
+ strcpy(w->gterm.cmapName, global_cmapname);
+ }
+ else{
+ w->gterm.maxColors = min(w->gterm.maxColors, colors);
+ }
+ }
+ }
+ return(usedefault);
+}
+
+/*
+ *
+ * GetMaxCmapColors -- try to determine how many colors we can alloc in the
+ * default colormap. We do this now in order set maxColors to this number,
+ * to avoid the situation where a larger colormap is used that repeats
+ * the actually-allocated colormap -- very ugly ...
+ *
+ */
+static int GetMaxCmapColors(w)
+ GtermWidget w;
+{
+ register int n;
+ unsigned long plane_masks[1];
+ int req;
+ int first, nelem, maxelem;
+ Pixel cmap[MAX_SZCMAP];
+ Display *dpy;
+ Colormap colormap;
+ Visual *visual;
+ int screen;
+
+
+ dpy = XtDisplay(w);
+ screen = XDefaultScreen(dpy);
+ visual = XDefaultVisual(dpy, screen);
+ colormap = XDefaultColormap(dpy, screen);
+
+ /* Make sure we have the right sort of visual.
+ */
+ if (visual->class == TrueColor)
+ return (global_ncolors);
+
+ if ((visual->class != PseudoColor) && (visual->class != GrayScale))
+ return (0);
+
+ /* Get current colormap specs.
+ */
+ GtQueryColormap (w, 0, &first, &nelem, &maxelem);
+
+ /* Try to alloc the max size colormap.
+ */
+ if (maxelem > 0) {
+ req = min(MAX_SZCMAP, maxelem);
+ for (n=0; req > 0 && n < maxelem; ){
+ if (XAllocColorCells (dpy, colormap,
+ False, plane_masks, 0, &cmap[n], req)) {
+ n += req;
+ } else
+ req /= 2;
+ }
+
+ /* just wondering ... don't really need this.
+ */
+ if (! w->gterm.useGlobalCmap)
+ XFreeColors (dpy, colormap, cmap, n, 0);
+
+ } else
+ n = 0;
+
+ return (n);
+}
+
+
+static int
+GetGlobalColors()
+{
+ return (global_ncolors);
+}
+
+
+static void
+SetGlobalColors(n)
+ int n;
+{
+ global_ncolors = n;
+}
+
+
+/*
+ * This routine will search the STATIC colors of w->core.colormap to find an
+ * exact match for the color name. If no match is found, the foreground is
+ * returned.
+ */
+
+static Pixel
+ColorNameToPixel (w, str)
+GtermWidget w;
+String str;
+{
+ int i;
+ XColor color;
+ XColor cmap[SZ_STATIC_CMAP];
+ char *ip, *op, name[32];
+ unsigned long r, g, b;
+ unsigned long val = 0;
+
+
+
+ bzero (cmap, (SZ_STATIC_CMAP * sizeof(XColor)));
+ if (!str)
+ return (0);
+
+ if (w->gterm.w_depth > ColormapDepth && w->gterm.useGlobalCmap) {
+ bzero (name, 32);
+ for (ip=str, op=name; ip && *ip; )
+ *op++ = (char) tolower ((int)*ip++);
+
+
+ for (i=0; i < (SZ_STATIC_CMAP + SZ_OVERLAY_CMAP); i++) {
+ if (strcmp (name, static_colors[i].name) == 0) {
+ r = ((uchar)static_colors[i].r & 0xff) << 16;
+ g = ((uchar)static_colors[i].g & 0xff) << 8;
+ b = ((uchar)static_colors[i].b & 0xff);
+ val = static_colors[i].value;
+ break;
+ }
+ }
+ return (val);
+
+ } else {
+ /* Find what colors are available... */
+ for (i=0; i < SZ_STATIC_CMAP; i++) {
+ memset (&cmap[i], 0, sizeof(XColor));
+ cmap[i].pixel = i;
+ cmap[i].flags = DoRed | DoGreen | DoBlue;
+ }
+
+ XQueryColors(w->gterm.display, w->core.colormap, cmap, SZ_STATIC_CMAP);
+
+ /* ...and find a match */
+ if (XParseColor(w->gterm.display, w->core.colormap, str, &color)) {
+ for (i=0; i<SZ_STATIC_CMAP; i++) {
+ if ((color.red == cmap[i].red) &&
+ (color.green == cmap[i].green) &&
+ (color.blue == cmap[i].blue)) {
+ return i;
+ }
+ }
+ }
+
+ }
+
+ return 1;
+}
+