fvwm-workers@fvwm.org wrote:

On Wed, Apr 17, 2002 at 01:02:25PM +0000, Mikhael Goikhman wrote:

Why not to have one "if (Pdepth < 2)" when defining colorset 0 or any
unused/deleted colorset? The default for normal depths could be as it is
now, 4 colors: black on rgb:be/be/be and its shadow/hilight.

Good idea.

OK here's a patch that does the following:

   * Replaces FvwmTheme with a dummy module that just sends the
     Colorset and ReadWriteColors commands to fvwm
   * Adds the new commands Colorset and ReadWriteColors to fvwm
   * Initializes colorsets to black on gray for color screens and black
     on white for mono

There's two files attached as well that need to go in the fvwm directory. I haven't updated any man pages, could someone else do this please?

Cheers,
Tim.

/* This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
#define FVWMTHEME_PRIVATE
#include "libs/Colorset.h"
#undef FVWMTHEME_PRIVATE

void set_readwrite_colors();
void parse_colorset(int n, char *line);
void cleanup_colorsets();
void alloc_colorset(int n);

/* Copyright (C) 2002 the late Joey Shutup.
 *
 * http://www.streetmap.co.uk/streetmap.dll?postcode2map?BS24+9TZ
 *
 * No guarantees or warranties or anything are provided or implied in any way
 * whatsoever.  Use this program at your own risk.  Permission to use this
 * program for any purpose is given, as long as the copyright is kept intact.
 */
/*
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
#define FVWMTHEME_PRIVATE

#include "config.h"
#include "libs/fvwmlib.h"
#include "externs.h"
#include "fvwm.h"
#include "cursor.h"
#include "functions.h"
#include "misc.h"
#include "screen.h"
#include "colorset.h"
#include "module_interface.h"
#include "commands.h"
#include "libs/FShape.h"
#include "libs/Picture.h"

extern int nColorsets;  /* in libs/Colorset.c */

/* Globals */
static Bool privateCells = False;       /* set when read/write colors used */
static Bool sharedCells = False;        /* set after a shared color is used */
static char *black = "black";
static char *white = "white";
static char *gray = "gray";

/* When fvwm destroys pixmaps it puts them on a list and only destroys them
 * after some period of inactivity. This is necessary because changing colorset
 * options rapidly may result in a module redrawing itself due to the first
 * change while the second change is happening. If the module renders something
 * with the colorset affected by the second change there is a chance it may
 * reference pixmaps that FvwmTheme has destroyed, bad things would happen */
struct junklist {
  struct junklist *prev;
  Pixmap pixmap;
};
static struct junklist *junk = NULL;
static Bool cleanup_scheduled = False;
static void add_to_junk(Pixmap pixmap)
{
  struct junklist *oldjunk = junk;

  junk = (struct junklist *)safemalloc(sizeof(struct junklist));
  junk->prev = oldjunk;
  junk->pixmap = pixmap;
  if (!cleanup_scheduled) {
    CMD_Schedule(NULL, NULL, 0, NULL, 0, "3000 CleanupColorsets", NULL);
    cleanup_scheduled = True;
  }
}
void cleanup_colorsets()
{
  struct junklist *oldjunk = junk;

  while (junk)
  {
    XFreePixmap(dpy, junk->pixmap);
    oldjunk = junk;
    junk = junk->prev;
    free(oldjunk);
  }
  cleanup_scheduled = False;
}

static void MyXParseColor(
  char *spec, XColor *exact_def_return)
{
  if (!XParseColor(dpy, Pcmap, spec, exact_def_return))
  {
    fvwm_msg(ERR, "MyXParseColor", "can't parse color \"%s\"",
             (spec) ? spec : "");
    exact_def_return->red = 0;
    exact_def_return->green = 0;
    exact_def_return->blue = 0;
    exact_def_return->flags |= DoRed | DoGreen | DoBlue;
  }

  return;
}

void CMD_ReadWriteColors(F_CMD_ARGS) {
  static char *name = "ReadWriteColors";

  if (sharedCells)
    fvwm_msg(ERR, name, "%s must come first, already allocated shared pixels", 
name);
  else if (Pvisual->class != PseudoColor)
    fvwm_msg(ERR, name, "%s only works with PseudoColor visuals", name);
  else
    privateCells = True;
}

static char *get_simple_color(
  char *string, char **color, colorset_struct *cs, int supplied_color,
  int special_flag, char *special_string)
{
  char *rest;

  if (*color)
  {
    free(*color);
    *color = NULL;
  }
  rest = GetNextToken(string, color);
  if (*color)
  {
    if (special_string && StrEquals(*color, special_string))
    {
      free(*color);
      *color = NULL;
      cs->color_flags |= special_flag;
      cs->color_flags &= ~supplied_color;
    }
    else
    {
      cs->color_flags |= supplied_color;
      cs->color_flags &= ~special_flag;
    }
  }
  else
    cs->color_flags &= ~(supplied_color | special_flag);

  return rest;
}

static void SafeDestroyPicture(Display *dpy, Picture *picture)
{
  /* have to subvert destroy picture so that it doesn't free pixmaps,
   * these are added to the junk list to be cleaned up after a timeout */
  if (picture->count < 2)
  {
    if (picture->picture)
    {
      add_to_junk(picture->picture);
      picture->picture = None;
    }
    if (picture->mask)
    {
      add_to_junk(picture->mask);
      picture->mask = None;
    }
  }
  /* all that this will now do is free the colors and the name */
  DestroyPicture(dpy, picture);
}

static void free_colorset_background(colorset_struct *cs)
{
  if (cs->picture) {
    SafeDestroyPicture(dpy, cs->picture);
    cs->picture = None;
    cs->pixmap = None;
  }
  if (cs->pixmap && cs->pixmap != ParentRelative)
  {
    add_to_junk(cs->pixmap);
  }
  cs->pixmap = None;
  if (cs->mask)
  {
    add_to_junk(cs->mask);
    cs->mask = None;
  }
  if (cs->pixels && cs->nalloc_pixels)
  {
    XFreeColors(dpy, Pcmap, cs->pixels, cs->nalloc_pixels, 0);
    free(cs->pixels);
    cs->pixels = NULL;
    cs->nalloc_pixels = 0;
  }
}

static char *csetopts[] =
{
  "Foreground",
  "Fore",
  "fg",

  "Background",
  "Back",
  "bg",

  "Hilight",
  "Hilite",
  "hi",

  "Shadow",
  "Shade",
  "sh",

  /* these strings are used inside the cases in the switch below! */
  "Pixmap",
  "TiledPixmap",
  "AspectPixmap",

  /* these strings are used inside the cases in the switch below! */
  "Shape",
  "TiledShape",
  "AspectShape",

  /* switch off pixmaps and gradients */
  "Plain",
  /* switch off shape */
  "NoShape",

  /* Make the background transparent, it copies the root window background */
  "Transparent",

  NULL
};

/* translate a colorset spec into a colorset structure */
void parse_colorset(int n, char *line)
{
  int i;
  int w;
  int h;
  colorset_struct *cs;
  char *token;
  char *optstring;
  char *args;
  char *option;
  char type;
  char *fg = NULL;
  char *bg = NULL;
  char *hi = NULL;
  char *sh = NULL;
  Bool do_remove_shape;
  Bool have_pixels_changed = False;
  Bool has_fg_changed = False;
  Bool has_bg_changed = False;
  Bool has_sh_changed = False;
  Bool has_hi_changed = False;
  Bool has_pixmap_changed = False;
  Bool has_shape_changed = False;
  XColor color;
  XGCValues xgcv;
  static char *name = "parse_colorset";
  Window win = Scr.SizeWindow;
  static GC gc = None;

  /* make sure it exists and has sensible contents */
  if (nColorsets <= n) {
    Colorset =
      (colorset_struct *)saferealloc((char *)Colorset,
                                     (n + 1) * sizeof(colorset_struct));
    memset(&Colorset[nColorsets], 0,
           (n + 1 - nColorsets) * sizeof(colorset_struct));
  }

  /* initialize new colorsets to black on gray */
  while (nColorsets <= n)
  {
    colorset_struct *ncs = &Colorset[nColorsets];
    have_pixels_changed = True;
    if (privateCells &&
        /* grab four writeable cells */
        XAllocColorCells(dpy, Pcmap, False, NULL, 0, &(ncs->fg), 4)) {
      XColor *colorp;

      /* set the fg color */
      MyXParseColor(black, &color);
      color.pixel = ncs->fg;
      XStoreColor(dpy, Pcmap, &color);
      /* set the bg */
      MyXParseColor(gray, &color);
      color.pixel = ncs->bg;
      XStoreColor(dpy, Pcmap, &color);
      /* calculate and set the hilite */
      colorp = GetHiliteColor(ncs->bg);
      colorp->pixel = ncs->hilite;
      XStoreColor(dpy, Pcmap, colorp);
      /* calculate and set the shadow */
      colorp = GetShadowColor(ncs->bg);
      colorp->pixel = ncs->shadow;
      XStoreColor(dpy, Pcmap, colorp);
    } else {
      /* grab four shareable colors */
      if (Pdepth < 2) {
        /* monochrome monitors get black on white */
        /* FIXME: add a gray pixmap background */
        Colorset[nColorsets].fg = GetColor(black);
        Colorset[nColorsets].bg = GetColor(white);
        Colorset[nColorsets].hilite = GetColor(white);
        Colorset[nColorsets].shadow = GetColor(black);
      } else {
        Colorset[nColorsets].fg = GetColor(black);
        Colorset[nColorsets].bg = GetColor(gray);
        Colorset[nColorsets].hilite = GetHilite(Colorset[nColorsets].bg);
        Colorset[nColorsets].shadow = GetShadow(Colorset[nColorsets].bg);
      }
      /* set flags for fg contrast, bg average in case just a pixmap is given */
      Colorset[nColorsets].color_flags = FG_CONTRAST | BG_AVERAGE;
    }
    nColorsets++;
  }

  cs = &Colorset[n];
  if (gc == None)
  {
    gc = fvwmlib_XCreateGC(dpy, win, 0, &xgcv);
  }

  /* ---------- Parse the options ---------- */
  while (line && *line)
  {
    /* Read next option specification (delimited by a comma or \0). */
    line = GetQuotedString(line, &optstring, ",", NULL, NULL, NULL);
    if (!optstring)
      break;
    args = GetNextToken(optstring, &option);
    if (!option)
    {
      free(optstring);
      break;
    }

    do_remove_shape = False;
    switch((i = GetTokenIndex(option, csetopts, 0, NULL)))
    {
    case 0: /* Foreground */
    case 1: /* Fore */
    case 2: /* fg */
      get_simple_color(args, &fg, cs, FG_SUPPLIED, FG_CONTRAST, "contrast");
      has_fg_changed = True;
      break;
    case 3: /* Background */
    case 4: /* Back */
    case 5: /* bg */
      get_simple_color(args, &bg, cs, BG_SUPPLIED, BG_AVERAGE, "average");
      has_bg_changed = True;
      break;
    case 6: /* Hilight */
    case 7: /* Hilite */
    case 8: /* hi */
      get_simple_color(args, &hi, cs, HI_SUPPLIED, 0, NULL);
      has_hi_changed = True;
      break;
    case 9: /* Shadow */
    case 10: /* Shade */
    case 11: /* sh */
      get_simple_color(args, &sh, cs, SH_SUPPLIED, 0, NULL);
      has_sh_changed = True;
      break;
    case 12: /* TiledPixmap */
    case 13: /* Pixmap */
    case 14: /* AspectPixmap */
      has_pixmap_changed = True;
      free_colorset_background(cs);
      /* set the flags */
      if (csetopts[i][0] == 'T')
        cs->pixmap_type = PIXMAP_TILED;
      else if (csetopts[i][0] == 'A')
        cs->pixmap_type = PIXMAP_STRETCH_ASPECT;
      else
        cs->pixmap_type = PIXMAP_STRETCH;

      /* read filename */
      token = PeekToken(args, &args);
      if (!token)
        break;
      /* load the file using the color reduction routines in Picture.c */
      cs->picture = CachePicture(dpy, win, NULL, token, Scr.ColorLimit);
      if (!cs->picture)
      {
        fvwm_msg(ERR, name, "can't load picture %s", token);
        break;
      }
      /* don't try to be smart with bitmaps */
      if (cs->picture->depth != Pdepth)
      {
        fvwm_msg(ERR, name, "bitmaps not supported");
        SafeDestroyPicture(dpy, cs->picture);
        cs->picture = None;
        break;
      }
      /* copy the picture pixmap into the public colorset structure */
      cs->width = cs->picture->width;
      cs->height = cs->picture->height;
      cs->pixmap = cs->picture->picture;

      if (cs->pixmap)
      {
        if (cs->picture->mask != None)
        {
          /* make an inverted copy of the mask */
          cs->mask = XCreatePixmap(dpy, win, cs->width, cs->height, 1);
          if (cs->mask)
          {
            XCopyArea(dpy, cs->picture->mask, cs->mask, Scr.MonoGC, 0, 0,
                      cs->width, cs->height, 0, 0);
            /* Invert the mask. We use it to draw the background. */
            XSetFunction(dpy, Scr.MonoGC, GXinvert);
            XFillRectangle(dpy, cs->mask, Scr.MonoGC, 0, 0,
                           cs->width, cs->height);
            XSetFunction(dpy, Scr.MonoGC, GXcopy);
          }
        }
      }
      break;
    case 15: /* Shape */
    case 16: /* TiledShape */
    case 17: /* AspectShape */
      if (FHaveShapeExtension)
      {
        /* read filename */
        token = PeekToken(args, &args);
        has_shape_changed = True;
        if (cs->shape_mask)
        {
          add_to_junk(cs->shape_mask);
          cs->shape_mask = None;
        }
        if (do_remove_shape == True)
          break;
        /* set the flags */
        if (csetopts[i][0] == 'T')
          cs->shape_type = SHAPE_TILED;
        else if (csetopts[i][0] == 'A')
          cs->shape_type = SHAPE_STRETCH_ASPECT;
        else
          cs->shape_type = SHAPE_STRETCH;

        /* try to load the shape mask */
        if (token)
        {
          Picture *picture;

          /* load the shape mask */
          picture = CachePicture(dpy, win, NULL, token, Scr.ColorLimit);
          if (!picture)
            fvwm_msg(ERR, name, "can't load picture %s", token);
          else if (picture->depth != 1 && picture->mask == None)
          {
            fvwm_msg(ERR, name, "shape pixmap must be of depth 1");
            SafeDestroyPicture(dpy, picture);
          }
          else
          {
            Pixmap mask;

            /* okay, we have what we want */
            if (picture->mask != None)
              mask = picture->mask;
            else
              mask = picture->picture;
            cs->shape_width = picture->width;
            cs->shape_height = picture->height;

            if (mask != None)
            {
              cs->shape_mask = XCreatePixmap(
                dpy, mask, picture->width, picture->height, 1);
              if (cs->shape_mask != None)
              {
                XCopyPlane(dpy, mask, cs->shape_mask, Scr.MonoGC, 0, 0,
                           picture->width, picture->height, 0, 0, 1);
              }
            }
          }
          if (picture)
          {
            SafeDestroyPicture(dpy, picture);
            picture = None;
          }
        }
      }
      else
      {
        cs->shape_mask = None;
      }
      break;
    case 18: /* Plain */
      has_pixmap_changed = True;
      free_colorset_background(cs);
      break;
    case 19: /* NoShape */
      has_shape_changed = True;
      if (cs->shape_mask)
      {
        add_to_junk(cs->shape_mask);
        cs->shape_mask = None;
      }
      break;
    case 20: /* Transparent */
      /* this is only allowable when the root depth == fvwm visual depth
       * otherwise bad match errors happen, it may be even more restrictive
       * but my tests (on exceed 6.2) show that only == depth is necessary */
      if (Pdepth != DefaultDepth(dpy, (DefaultScreen(dpy))))
      {
        fvwm_msg(ERR, name, "can't do Transparent when root_depth!=fvwm_depth");
        break;
      }
      has_pixmap_changed = True;
      free_colorset_background(cs);
      cs->pixmap = ParentRelative;
      cs->pixmap_type = PIXMAP_STRETCH;
      break;
    default:
      /* test for ?Gradient */
      if (option[0] && StrEquals(&option[1], "Gradient"))
      {
        type = toupper(option[0]);
        if (!IsGradientTypeSupported(type))
          break;
        has_pixmap_changed = True;
        free_colorset_background(cs);
        /* create a pixmap of the gradient type */
        cs->pixmap = CreateGradientPixmapFromString(dpy, win, gc, type, args,
                                                    &w, &h, &cs->pixels,
                                                    &cs->nalloc_pixels);
        cs->width = w;
        cs->height = h;
        if (type == V_GRADIENT)
          cs->pixmap_type = PIXMAP_STRETCH_Y;
        else if (type == H_GRADIENT)
          cs->pixmap_type = PIXMAP_STRETCH_X;
        else
          cs->pixmap_type = PIXMAP_STRETCH;
      }
      else
      {
        fvwm_msg(WARN, name, "bad colorset pixmap specifier %s %s",
                 option, line);
      }
      break;
    } /* switch */

    if (option)
    {
      free(option);
      option = NULL;
    }
    free(optstring);
    optstring = NULL;
  } /* while (line && *line) */

  /*
   * ---------- change the background colour ----------
   */
  if (has_bg_changed || has_pixmap_changed)
  {
    Bool do_set_default_background = False;

    if ((cs->color_flags & BG_AVERAGE) && cs->pixmap != None &&
        cs->pixmap != ParentRelative)
    {
      /* calculate average background color */
      XColor *colors;
      XImage *image;
      XImage *mask_image = None;
      unsigned int i, j, k = 0;
      unsigned long red = 0, blue = 0, green = 0;

      /* create an array to store all the pixmap colors in */
      colors = (XColor *)safemalloc(cs->width * cs->height * sizeof(XColor));
      /* get the pixmap and mask into an image */
      image = XGetImage(dpy, cs->pixmap, 0, 0, cs->width, cs->height,
                        AllPlanes, ZPixmap);
      if (cs->mask != None)
        mask_image = XGetImage(dpy, cs->mask, 0, 0, cs->width, cs->height,
                               AllPlanes, ZPixmap);
      /* only fetch the pixels that are not masked out */
      for (i = 0; i < cs->width; i++)
        for (j = 0; j < cs->height; j++)
          if ((cs->mask == None) || (XGetPixel(mask_image, i, j) == 0))
            colors[k++].pixel = XGetPixel(image, i, j);

      XDestroyImage(image);
      if (mask_image != None)
        XDestroyImage(mask_image);
      if (k == 0)
      {
        do_set_default_background = True;
      }
      else
      {
        /* look them all up, XQueryColors() can't handle more than 256 */
        for (i = 0; i < k; i += 256)
          XQueryColors(dpy, Pcmap, &colors[i], min(k - i, 256));
        /* calculate average, ignore overflow: .red is short, red is long */
        for (i = 0; i < k; i++) {
          red += colors[i].red;
          green += colors[i].green;
          blue += colors[i].blue;
        }
        free(colors);
        /* get it */
        color.red = red / k;
        color.green = green / k;
        color.blue = blue / k;
        if (privateCells) {
          color.pixel = cs->bg;
          XStoreColor(dpy, Pcmap, &color);
        } else {
          Pixel old_bg = cs->bg;

          XFreeColors(dpy, Pcmap, &cs->bg, 1, 0);
          XAllocColor(dpy, Pcmap, &color);
          cs->bg = color.pixel;
          if (old_bg != cs->bg)
            have_pixels_changed = True;
        }
      }
    } /* average */
    else if ((cs->color_flags & BG_SUPPLIED) && bg != NULL)
    {
      /* user specified colour */
      if (privateCells) {
        unsigned short red, green, blue;

        MyXParseColor(bg, &color);
        red = color.red;
        green = color.green;
        blue = color.blue;
        color.pixel = cs->bg;
        XStoreColor(dpy, Pcmap, &color);
      } else {
        Pixel old_bg = cs->bg;

        XFreeColors(dpy, Pcmap, &cs->bg, 1, 0);
        cs->bg = GetColor(bg);
        if (old_bg != cs->bg)
          have_pixels_changed = True;
      }
    } /* user specified */
    else if ((bg == NULL && has_bg_changed) ||
             ((cs->color_flags & BG_AVERAGE) && cs->pixmap == ParentRelative))
    {
      /* default */
      do_set_default_background = True;
    } /* default */
    if (do_set_default_background)
    {
      if (privateCells) {
        MyXParseColor(white, &color);
        color.pixel = cs->bg;
        XStoreColor(dpy, Pcmap, &color);
      } else {
        Pixel old_bg = cs->bg;

        XFreeColors(dpy, Pcmap, &cs->bg, 1, 0);
        cs->bg = GetColor(white);
        if (old_bg != cs->bg)
          have_pixels_changed = True;
      }
    }
    has_bg_changed = True;
  } /* has_bg_changed */

  /*
   * ---------- change the foreground colour ----------
   */
  if (has_fg_changed || (has_bg_changed && (cs->color_flags & FG_CONTRAST)))
  {
    has_fg_changed = 1;
    if (cs->color_flags & FG_CONTRAST)
    {
      /* calculate contrasting foreground color */
      color.pixel = cs->bg;
      XQueryColor(dpy, Pcmap, &color);
      color.red = (color.red > 32767) ? 0 : 65535;
      color.green = (color.green > 32767) ? 0 : 65535;
      color.blue = (color.blue > 32767) ? 0 : 65535;
      if (privateCells) {
        color.pixel = cs->fg;
        XStoreColor(dpy, Pcmap, &color);
      } else {
        Pixel old_fg = cs->fg;

        XFreeColors(dpy, Pcmap, &cs->fg, 1, 0);
        XAllocColor(dpy, Pcmap, &color);
        cs->fg = color.pixel;
        if (old_fg != cs->fg)
          have_pixels_changed = True;
      }
    } /* contrast */
    else if ((cs->color_flags & FG_SUPPLIED) && fg != NULL)
    {
      /* user specified colour */
      if (privateCells) {
        MyXParseColor(fg, &color);
        color.pixel = cs->fg;
        XStoreColor(dpy, Pcmap, &color);
      } else {
        Pixel old_fg = cs->fg;

        XFreeColors(dpy, Pcmap, &cs->fg, 1, 0);
        cs->fg = GetColor(fg);
        if (old_fg != cs->fg)
          have_pixels_changed = True;
      }
    } /* user specified */
    else if (fg == NULL)
    {
      /* default */
      if (privateCells) {
        /* query it */
        MyXParseColor(black, &color);
        color.pixel = cs->fg;
        XStoreColor(dpy, Pcmap, &color);
      } else {
        Pixel old_fg = cs->fg;

        XFreeColors(dpy, Pcmap, &cs->fg, 1, 0);
        cs->fg = GetColor(black);
        if (old_fg != cs->fg)
          have_pixels_changed = True;
      }
    }
  } /* has_fg_changed */

  /*
   * ---------- change the hilight colour ----------
   */
  if (has_hi_changed || has_bg_changed)
  {
    has_hi_changed = 1;
    if ((cs->color_flags & HI_SUPPLIED) && hi != NULL)
    {
      /* user specified colour */
      if (privateCells) {
        MyXParseColor(hi, &color);
        color.pixel = cs->hilite;
        XStoreColor(dpy, Pcmap, &color);
      } else {
        Pixel old_hilite = cs->hilite;

        XFreeColors(dpy, Pcmap, &cs->hilite, 1, 0);
        cs->hilite = GetColor(hi);
        if (old_hilite != cs->hilite)
          have_pixels_changed = True;
      }
    } /* user specified */
    else if (hi == NULL)
    {
      if (privateCells) {
        XColor *colorp;

        colorp = GetHiliteColor(cs->bg);
        colorp->pixel = cs->hilite;
        XStoreColor(dpy, Pcmap, colorp);
      } else {
        Pixel old_hilite = cs->hilite;

        XFreeColors(dpy, Pcmap, &cs->hilite, 1, 0);
        cs->hilite = GetHilite(cs->bg);
        if (old_hilite != cs->hilite)
          have_pixels_changed = True;
      }
    }
  } /* has_hi_changed */

  /*
   * ---------- change the shadow colour ----------
   */
  if (has_sh_changed || has_bg_changed)
  {
    has_sh_changed = 1;
    if ((cs->color_flags & SH_SUPPLIED) && sh != NULL)
    {
      /* user specified colour */
      if (privateCells) {
        MyXParseColor(sh, &color);
        color.pixel = cs->shadow;
        XStoreColor(dpy, Pcmap, &color);
      } else {
        Pixel old_shadow = cs->shadow;

        XFreeColors(dpy, Pcmap, &cs->shadow, 1, 0);
        cs->shadow = GetColor(sh);
        if (old_shadow != cs->shadow)
          have_pixels_changed = True;
      }
    } /* user specified */
    else if (sh == NULL)
    {
      if (privateCells) {
        XColor *colorp;

        colorp = GetShadowColor(cs->bg);
        colorp->pixel = cs->shadow;
        XStoreColor(dpy, Pcmap, colorp);
      } else {
        Pixel old_shadow = cs->shadow;

        XFreeColors(dpy, Pcmap, &cs->shadow, 1, 0);
        cs->shadow = GetShadow(cs->bg);
        if (old_shadow != cs->shadow)
          have_pixels_changed = True;
      }
    }
  } /* has_sh_changed */

  /*
   * ---------- change the masked out parts of the background pixmap ----------
   */
  if ((cs->mask != None) && (has_pixmap_changed || has_bg_changed))
  {
    /* Now that we know the background colour we can update the pixmap
     * background. */
    XSetForeground(dpy, gc, cs->bg);
    XSetClipMask(dpy, gc, cs->mask);
    XFillRectangle(dpy, cs->pixmap, gc, 0, 0, cs->width, cs->height);
    XSetClipMask(dpy, gc, None);
    has_pixmap_changed = True;
  } /* has_pixmap_changed */

  /*
   * ---------- send new colorset to fvwm and clean up ----------
   */
  /* make sure the server has this to avoid races */
  XSync(dpy, False);

  /* inform modules of the change */
  if (have_pixels_changed || has_pixmap_changed || has_shape_changed)
    BroadcastColorset(n);

  if (fg)
    free(fg);
  if (bg)
    free(bg);
  if (hi)
    free(hi);
  if (sh)
    free(sh);

  /* if privateCells are not being used and XAllocColor has been used
   * we are stuck in sharedCells behaviour forever */
  /* have_pixels_changed will be set if a new colorset has been made */
  if (!privateCells && have_pixels_changed)
    sharedCells = True;
}

/*****************************************************************************
 * alloc_colorset() grows the size of the Colorset array to include set n
 * Colorset_struct *Colorset will be altered
 * returns the address of the member
 *****************************************************************************/
void alloc_colorset(int n)
{
  /* do nothing if it already exists */
  if (n < nColorsets)
    return;

  /* increment n to get the required array size, get a new array */
  Colorset = (colorset_struct *)saferealloc((char *)Colorset,
                                            ++n * sizeof(colorset_struct));

  /* zero out the new members */
  memset(&Colorset[nColorsets], 0, (n - nColorsets) * sizeof(colorset_struct));

  /* copy colorset 0 pixels into new members so that if undefined ones are
   * referenced at least they don't give black on black */
  if (n > 1)
  {
    for ( ; nColorsets < n; nColorsets++)
    {
      Colorset[nColorsets].fg = Colorset[0].fg;
      Colorset[nColorsets].bg = Colorset[0].bg;
      Colorset[nColorsets].hilite = Colorset[0].hilite;
      Colorset[nColorsets].shadow = Colorset[0].shadow;
    }
  }

  nColorsets = n;
}
Index: ChangeLog
===================================================================
RCS file: /u/phippst/share/cvsroot/fvwm/ChangeLog,v
retrieving revision 1.137
diff -u -r1.137 ChangeLog
--- ChangeLog   2002/04/16 07:10:22     1.137
+++ ChangeLog   2002/04/17 16:04:43
@@ -1,3 +1,7 @@
+2002-04016  Hippo
+
+       * fvwm/*.[ch]: Moved FvwmTheme functionality into fvwm
+
 2002-04-15  Dominik Vogt  <[EMAIL PROTECTED]>
 
        * libs/Bindings.c (CheckBinding):
Index: fvwm/ConfigFvwmDefaults
===================================================================
RCS file: /u/phippst/share/cvsroot/fvwm/fvwm/ConfigFvwmDefaults,v
retrieving revision 1.8
diff -u -r1.8 ConfigFvwmDefaults
--- fvwm/ConfigFvwmDefaults     2002/03/20 14:07:02     1.8
+++ fvwm/ConfigFvwmDefaults     2002/04/16 22:48:45
@@ -6,12 +6,12 @@
 #  Created on 03/21/99 by DanEspen (dje):
 #  - FvwmDefaults file.  Contains fvwm defaults, and enough to help out
 #  the new user with no configuration file.
-#  This picks up from where the builtin table in fvwm.c SetUpRCDefaults ends.
+#  This picks up from where the builtin table in fvwm.c SetRCDefaults ends.
 
 # Set at least 2 root keys to bring up the builtin menu:
 Silent Key Help R A Popup MenuFvwmRoot
 Key F1 R A Popup MenuFvwmRoot
-# Ctrl-Alt-Escape for aboring Wait pause and ModuleSynchronous command
+# Ctrl-Alt-Escape for aborting Wait pause and ModuleSynchronous command
 Key Escape A MC EscapeFunc
 
 # Needed by the builtin WindowList command, this should match the manpage.
Index: fvwm/Makefile.am
===================================================================
RCS file: /u/phippst/share/cvsroot/fvwm/fvwm/Makefile.am,v
retrieving revision 1.17
diff -u -r1.17 Makefile.am
--- fvwm/Makefile.am    2002/04/16 07:10:23     1.17
+++ fvwm/Makefile.am    2002/04/17 13:09:04
@@ -16,7 +16,8 @@
        gnome.h icccm2.h icons.h menuitem.h menus.h menustyle.h menudim.h \
        misc.h modconf.h module_interface.h move_resize.h placement.h \
        read.h repeat.h schedule.h screen.h session.h stack.h style.h \
-       update.h virtual.h window_flags.h windowlist.h frame.h menus.c \
+       update.h virtual.h window_flags.h windowlist.h frame.h colorset.h \
+       menus.c colorset.c \
        style.c borders.c move_resize.c builtins.c events.c add_window.c \
        module_interface.c icons.c stack.c functions.c virtual.c session.c \
        fvwm.c placement.c focus.c read.c misc.c conditional.c colormaps.c \
Index: fvwm/borders.c
===================================================================
RCS file: /u/phippst/share/cvsroot/fvwm/fvwm/borders.c,v
retrieving revision 1.28
diff -u -r1.28 borders.c
--- fvwm/borders.c      2002/04/02 08:59:39     1.28
+++ fvwm/borders.c      2002/04/17 14:10:10
@@ -48,7 +48,7 @@
 #include "builtins.h"
 #include "icons.h"
 #include "module_interface.h"
-#include "libs/Colorset.h"
+#include "colorset.h"
 #include "add_window.h"
 #include "frame.h"
 
Index: fvwm/builtins.c
===================================================================
RCS file: /u/phippst/share/cvsroot/fvwm/fvwm/builtins.c,v
retrieving revision 1.37
diff -u -r1.37 builtins.c
--- fvwm/builtins.c     2002/04/08 10:43:29     1.37
+++ fvwm/builtins.c     2002/04/17 14:47:36
@@ -40,7 +40,7 @@
 #include "libs/Picture.h"
 #include "fvwm.h"
 #include "externs.h"
-#include "libs/Colorset.h"
+#include "colorset.h"
 #include "bindings.h"
 #include "misc.h"
 #include "cursor.h"
@@ -2226,18 +2226,17 @@
 
 void CMD_Colorset(F_CMD_ARGS)
 {
-       int n = -1, ret;
+       int n;
        char *token;
 
-       token = PeekToken(action, NULL);
-       if (token == NULL)
+       if (GetIntegerArguments(action, &token, &n, 1) != 1)
                return;
-       ret = sscanf(token, "%x", &n);
-
-       if ((ret == 0) || (n < 0))
+       if (n < 0)
+               return;
+       if (token == NULL)
                return;
 
-       LoadColorset(action);
+       parse_colorset(n, token);
        BroadcastColorset(n);
 
        if (n == Scr.DefaultColorset)
@@ -2252,6 +2251,11 @@
        return;
 }
 
+void CMD_CleanupColorsets(F_CMD_ARGS)
+{
+       cleanup_colorsets();
+}
+
 void CMD_PropertyChange(F_CMD_ARGS)
 {
        char string[256] = "\0";
@@ -2290,7 +2294,7 @@
        Scr.DefaultColorset = cset;
        if (Scr.DefaultColorset < 0)
                Scr.DefaultColorset = -1;
-       AllocColorset(Scr.DefaultColorset);
+       alloc_colorset(Scr.DefaultColorset);
        Scr.flags.do_need_window_update = 1;
        Scr.flags.has_default_color_changed = 1;
 
Index: fvwm/commands.h
===================================================================
RCS file: /u/phippst/share/cvsroot/fvwm/fvwm/commands.h,v
retrieving revision 1.12
diff -u -r1.12 commands.h
--- fvwm/commands.h     2002/04/12 11:43:16     1.12
+++ fvwm/commands.h     2002/04/17 15:41:56
@@ -39,6 +39,7 @@
 void CMD_ChangeDecor(F_CMD_ARGS);
 #endif /* USEDECOR */
 void CMD_ChangeMenuStyle(F_CMD_ARGS);
+void CMD_CleanupColorsets(F_CMD_ARGS);
 void CMD_ClickTime(F_CMD_ARGS);
 void CMD_Close(F_CMD_ARGS);
 void CMD_ColorLimit(F_CMD_ARGS);
@@ -135,6 +136,7 @@
 void CMD_Raise(F_CMD_ARGS);
 void CMD_RaiseLower(F_CMD_ARGS);
 void CMD_Read(F_CMD_ARGS);
+void CMD_ReadWriteColors(F_CMD_ARGS);
 void CMD_Recapture(F_CMD_ARGS);
 void CMD_RecaptureWindow(F_CMD_ARGS);
 void CMD_Refresh(F_CMD_ARGS);
Index: fvwm/events.c
===================================================================
RCS file: /u/phippst/share/cvsroot/fvwm/fvwm/events.c,v
retrieving revision 1.52
diff -u -r1.52 events.c
--- fvwm/events.c       2002/04/15 08:25:56     1.52
+++ fvwm/events.c       2002/04/17 14:10:34
@@ -71,7 +71,7 @@
 #include "screen.h"
 #include "defaults.h"
 #include "events.h"
-#include "libs/Colorset.h"
+#include "colorset.h"
 #include "fvwmsignal.h"
 #include "module_interface.h"
 #include "session.h"
Index: fvwm/functions.c
===================================================================
RCS file: /u/phippst/share/cvsroot/fvwm/fvwm/functions.c,v
retrieving revision 1.28
diff -u -r1.28 functions.c
--- fvwm/functions.c    2002/04/12 11:43:16     1.28
+++ fvwm/functions.c    2002/04/17 15:41:03
@@ -51,7 +51,7 @@
 #include "repeat.h"
 #include "read.h"
 #include "virtual.h"
-#include "libs/Colorset.h"
+#include "colorset.h"
 #include "ewmh.h"
 #include "schedule.h"
 
@@ -121,6 +121,7 @@
   CMD_ENTRY("changedecor", CMD_ChangeDecor, F_CHANGE_DECOR, FUNC_NEEDS_WINDOW),
 #endif /* USEDECOR */
   CMD_ENTRY("changemenustyle", CMD_ChangeMenuStyle, F_CHANGE_MENUSTYLE, 0),
+  CMD_ENTRY("cleanupcolorsets", CMD_CleanupColorsets, F_NOP, 0),
   CMD_ENTRY("clicktime", CMD_ClickTime, F_CLICK, 0),
   CMD_ENTRY("close", CMD_Close, F_CLOSE, FUNC_NEEDS_WINDOW),
   CMD_ENTRY("colorlimit", CMD_ColorLimit, F_COLOR_LIMIT, 0),
@@ -221,6 +222,7 @@
   CMD_ENTRY("raise", CMD_Raise, F_RAISE, FUNC_NEEDS_WINDOW),
   CMD_ENTRY("raiselower", CMD_RaiseLower, F_RAISELOWER, FUNC_NEEDS_WINDOW),
   CMD_ENTRY("read", CMD_Read, F_READ, 0),
+  CMD_ENTRY("readwritecolors", CMD_ReadWriteColors, F_NOP, 0),
   CMD_ENTRY("recapture", CMD_Recapture, F_RECAPTURE, 0),
   CMD_ENTRY("recapturewindow", CMD_RecaptureWindow, F_RECAPTURE_WINDOW, 0),
   CMD_ENTRY("refresh", CMD_Refresh, F_REFRESH, 0),
@@ -406,7 +408,7 @@
       return 0;
     if (cs < 0)
       return 0;
-    AllocColorset(cs);
+    alloc_colorset(cs);
     switch (i)
     {
     case 0:
Index: fvwm/fvwm.c
===================================================================
RCS file: /u/phippst/share/cvsroot/fvwm/fvwm/fvwm.c,v
retrieving revision 1.29
diff -u -r1.29 fvwm.c
--- fvwm/fvwm.c 2002/04/12 11:43:17     1.29
+++ fvwm/fvwm.c 2002/04/17 14:14:15
@@ -54,7 +54,7 @@
 #include "builtins.h"
 #include "menus.h"
 #include "module_interface.h"
-#include "libs/Colorset.h"
+#include "colorset.h"
 #include "icccm2.h"
 #include "gnome.h"
 #include "ewmh.h"
@@ -1390,7 +1390,7 @@
   Scr.DefaultIcon = NULL;
 
   Scr.DefaultColorset = -1;
-  AllocColorset(0);
+  alloc_colorset(0);
   /* set up colorset 0 so that if FvwmTheme fails to start any modules
    * using colorsets don't appear black on black */
   Colorset[0].fg = Scr.StdFore = GetColor(DEFAULT_FORE_COLOR);
Index: fvwm/icons.c
===================================================================
RCS file: /u/phippst/share/cvsroot/fvwm/fvwm/icons.c,v
retrieving revision 1.42
diff -u -r1.42 icons.c
--- fvwm/icons.c        2002/04/08 10:43:31     1.42
+++ fvwm/icons.c        2002/04/17 14:12:18
@@ -57,7 +57,7 @@
 #include "virtual.h"
 #include "decorations.h"
 #include "module_interface.h"
-#include "libs/Colorset.h"
+#include "colorset.h"
 #include "libs/FImageLoader.h"
 #include "gnome.h"
 #include "ewmh.h"
Index: fvwm/menucmd.c
===================================================================
RCS file: /u/phippst/share/cvsroot/fvwm/fvwm/menucmd.c,v
retrieving revision 1.3
diff -u -r1.3 menucmd.c
--- fvwm/menucmd.c      2002/03/26 14:36:49     1.3
+++ fvwm/menucmd.c      2002/04/17 14:12:23
@@ -50,7 +50,7 @@
 #include "colors.h"
 #include "colormaps.h"
 #include "decorations.h"
-#include "libs/Colorset.h"
+#include "colorset.h"
 #include "defaults.h"
 #include "libs/FScreen.h"
 #include "libs/Flocale.h"
Index: fvwm/menus.c
===================================================================
RCS file: /u/phippst/share/cvsroot/fvwm/fvwm/menus.c,v
retrieving revision 1.32
diff -u -r1.32 menus.c
--- fvwm/menus.c        2002/04/08 10:43:31     1.32
+++ fvwm/menus.c        2002/04/17 14:12:29
@@ -49,7 +49,7 @@
 #include "colors.h"
 #include "colormaps.h"
 #include "decorations.h"
-#include "libs/Colorset.h"
+#include "colorset.h"
 #include "defaults.h"
 #include "libs/FScreen.h"
 #include "libs/Flocale.h"
Index: fvwm/menustyle.c
===================================================================
RCS file: /u/phippst/share/cvsroot/fvwm/fvwm/menustyle.c,v
retrieving revision 1.4
diff -u -r1.4 menustyle.c
--- fvwm/menustyle.c    2002/04/08 10:43:31     1.4
+++ fvwm/menustyle.c    2002/04/17 14:14:20
@@ -42,7 +42,7 @@
 #include "colors.h"
 #include "colormaps.h"
 #include "decorations.h"
-#include "libs/Colorset.h"
+#include "colorset.h"
 #include "defaults.h"
 #include "libs/FScreen.h"
 #include "libs/Flocale.h"
@@ -1229,7 +1229,7 @@
                        {
                                ST_HAS_MENU_CSET(tmpms) = 1;
                                ST_CSET_MENU(tmpms) = *val;
-                               AllocColorset(*val);
+                               alloc_colorset(*val);
                        }
                        has_gc_changed = True;
                        break;
@@ -1243,7 +1243,7 @@
                        {
                                ST_HAS_ACTIVE_CSET(tmpms) = 1;
                                ST_CSET_ACTIVE(tmpms) = *val;
-                               AllocColorset(*val);
+                               alloc_colorset(*val);
                        }
                        has_gc_changed = True;
                        break;
@@ -1258,7 +1258,7 @@
                        {
                                ST_HAS_GREYED_CSET(tmpms) = 1;
                                ST_CSET_GREYED(tmpms) = *val;
-                               AllocColorset(*val);
+                               alloc_colorset(*val);
                        }
                        has_gc_changed = True;
                        break;
Index: fvwm/modconf.c
===================================================================
RCS file: /u/phippst/share/cvsroot/fvwm/fvwm/modconf.c,v
retrieving revision 1.11
diff -u -r1.11 modconf.c
--- fvwm/modconf.c      2002/04/08 10:43:31     1.11
+++ fvwm/modconf.c      2002/04/17 14:12:43
@@ -52,7 +52,7 @@
 #include "misc.h"
 #include "screen.h"
 #include "module_interface.h"
-#include "libs/Colorset.h"
+#include "colorset.h"
 #include "libs/FScreen.h"
 
 extern int nColorsets; /* in libs/Colorset.c */
Index: fvwm/module_interface.c
===================================================================
RCS file: /u/phippst/share/cvsroot/fvwm/fvwm/module_interface.c,v
retrieving revision 1.24
diff -u -r1.24 module_interface.c
--- fvwm/module_interface.c     2002/03/26 14:36:49     1.24
+++ fvwm/module_interface.c     2002/04/17 14:16:46
@@ -38,7 +38,6 @@
 #endif
 
 #include "libs/fvwmlib.h"
-#include "libs/Colorset.h"
 #include "libs/FScreen.h"
 #include "libs/Module.h"
 #include "libs/queue.h"
@@ -50,6 +49,7 @@
 #include "bindings.h"
 #include "misc.h"
 #include "screen.h"
+#include "colorset.h"
 #include "module_interface.h"
 #include "read.h"
 #include "events.h"
Index: fvwm/move_resize.c
===================================================================
RCS file: /u/phippst/share/cvsroot/fvwm/fvwm/move_resize.c,v
retrieving revision 1.39
diff -u -r1.39 move_resize.c
--- fvwm/move_resize.c  2002/04/08 10:43:31     1.39
+++ fvwm/move_resize.c  2002/04/17 14:16:06
@@ -32,7 +32,6 @@
 #include <stdio.h>
 
 #include "libs/fvwmlib.h"
-#include "libs/Colorset.h"
 #include "libs/FScreen.h"
 #include "libs/Flocale.h"
 #include <libs/gravity.h>
@@ -44,6 +43,7 @@
 #include "bindings.h"
 #include "misc.h"
 #include "screen.h"
+#include "colorset.h"
 #include "defaults.h"
 #include "move_resize.h"
 #include "module_interface.h"
Index: fvwm/schedule.c
===================================================================
RCS file: /u/phippst/share/cvsroot/fvwm/fvwm/schedule.c,v
retrieving revision 1.3
diff -u -r1.3 schedule.c
--- fvwm/schedule.c     2002/03/18 12:47:12     1.3
+++ fvwm/schedule.c     2002/04/17 14:13:00
@@ -21,7 +21,7 @@
 #include "libs/queue.h"
 #include "fvwm.h"
 #include "externs.h"
-#include "libs/Colorset.h"
+#include "colorset.h"
 #include "bindings.h"
 #include "misc.h"
 #include "cursor.h"
Index: fvwm/style.c
===================================================================
RCS file: /u/phippst/share/cvsroot/fvwm/fvwm/style.c,v
retrieving revision 1.27
diff -u -r1.27 style.c
--- fvwm/style.c        2002/04/09 11:38:01     1.27
+++ fvwm/style.c        2002/04/17 14:14:24
@@ -41,7 +41,7 @@
 #include "defaults.h"
 #include "update.h"
 #include "style.h"
-#include "libs/Colorset.h"
+#include "colorset.h"
 #include "ewmh.h"
 #include "gnome.h"
 #include "icons.h"
@@ -991,7 +991,7 @@
           *val = -1;
          GetIntegerArguments(rest, NULL, val, 1);
          SSET_BORDER_COLORSET(*ptmpstyle, *val);
-         AllocColorset(*val);
+         alloc_colorset(*val);
          ptmpstyle->flags.use_border_colorset = (*val >= 0);
          ptmpstyle->flag_mask.use_border_colorset = 1;
          ptmpstyle->change_mask.use_border_colorset = 1;
@@ -1056,7 +1056,7 @@
          if (*val < 0)
            *val = -1;
          SSET_COLORSET(*ptmpstyle, *val);
-         AllocColorset(*val);
+         alloc_colorset(*val);
          ptmpstyle->flags.use_colorset = (*val >= 0);
          ptmpstyle->flag_mask.use_colorset = 1;
          ptmpstyle->change_mask.use_colorset = 1;
@@ -1505,7 +1505,7 @@
           *val = -1;
          GetIntegerArguments(rest, NULL, val, 1);
          SSET_COLORSET_HI(*ptmpstyle, *val);
-         AllocColorset(*val);
+         alloc_colorset(*val);
          ptmpstyle->flags.use_colorset_hi = (*val >= 0);
          ptmpstyle->flag_mask.use_colorset_hi = 1;
          ptmpstyle->change_mask.use_colorset_hi = 1;
@@ -1516,7 +1516,7 @@
           *val = -1;
          GetIntegerArguments(rest, NULL, val, 1);
          SSET_BORDER_COLORSET_HI(*ptmpstyle, *val);
-         AllocColorset(*val);
+         alloc_colorset(*val);
          ptmpstyle->flags.use_border_colorset_hi = (*val >= 0);
          ptmpstyle->flag_mask.use_border_colorset_hi = 1;
          ptmpstyle->change_mask.use_border_colorset_hi = 1;
Index: fvwm/update.c
===================================================================
RCS file: /u/phippst/share/cvsroot/fvwm/fvwm/update.c,v
retrieving revision 1.27
diff -u -r1.27 update.c
--- fvwm/update.c       2002/03/26 14:36:50     1.27
+++ fvwm/update.c       2002/04/17 14:13:10
@@ -32,7 +32,7 @@
 #include "update.h"
 #include "style.h"
 #include "builtins.h"
-#include "libs/Colorset.h"
+#include "colorset.h"
 #include "borders.h"
 #include "frame.h"
 #include "gnome.h"
@@ -459,8 +459,6 @@
        {
                if (Scr.Hilite != NULL && t == Scr.Hilite)
                {
-                       fprintf(stderr, "fc broadcast 0x%08x '%s'\n",
-                               (int)Scr.Hilite, Scr.Hilite->name.name);
                        BroadcastPacket(
                                M_FOCUS_CHANGE, 5, FW_W(Scr.Hilite),
                                FW_W_FRAME(Scr.Hilite), 0,
Index: modules/ChangeLog
===================================================================
RCS file: /u/phippst/share/cvsroot/fvwm/modules/ChangeLog,v
retrieving revision 1.86
diff -u -r1.86 ChangeLog
--- modules/ChangeLog   2002/04/16 07:10:24     1.86
+++ modules/ChangeLog   2002/04/17 16:06:40
@@ -1,3 +1,8 @@
+2002-04-16  Hippo
+
+       * FvwmTheme/FvwmTheme.c: FvwmTheme printf a warning and 
+         and sends the command back to fvwm
+
 2002-04-15  Dominik Vogt  <[EMAIL PROTECTED]>
 
        * FvwmIconMan/readconfig.h:
Index: modules/FvwmTheme/FvwmTheme.c
===================================================================
RCS file: /u/phippst/share/cvsroot/fvwm/modules/FvwmTheme/FvwmTheme.c,v
retrieving revision 1.4
diff -u -r1.4 FvwmTheme.c
--- modules/FvwmTheme/FvwmTheme.c       2002/04/08 10:43:43     1.4
+++ modules/FvwmTheme/FvwmTheme.c       2002/04/17 15:37:48
@@ -1,4 +1,4 @@
-/* Copyright (C) 1999 Joey Shutup.
+/* Copyright (C) 2002 the late Joey Shutup.
  *
  * http://www.streetmap.co.uk/streetmap.dll?postcode2map?BS24+9TZ
  *
@@ -21,85 +21,37 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-#define FVWMTHEME_PRIVATE
-
 #include "config.h"
 
 #include <stdio.h>
 #include <signal.h>
 
-#include <X11/Xlib.h>
-#include <X11/Xproto.h>
-#include <X11/Intrinsic.h>
-
 #include "libs/fvwmlib.h"
-#include "libs/FShape.h"
 #include "libs/Module.h"
-#include "libs/InitPicture.h"
-#include "libs/Picture.h"
-#include "libs/Colorset.h"
 #include "libs/fvwmsignal.h"
 
 /* Globals */
-static Display *dpy;
-static Window win;                     /* need a window to create pixmaps */
-static GC gc;                          /* ditto */
 static char *name;
 static int namelen;
-static int color_limit = 0;
 static int fd[2];                      /* communication pipes */
-static Bool privateCells = False;      /* set when read/write colors used */
-static Bool sharedCells = False;       /* set after a shared color is used */
-static char *black = "black";
-static char *gray = "gray";
 
 /* forward declarations */
 static RETSIGTYPE signal_handler(int signal);
 static void set_signals(void);
-static int error_handler(Display *dpy, XErrorEvent *e);
 static void parse_config(void);
 static void parse_config_line(char *line);
 static void parse_message_line(char *line);
 static void main_loop(void) __attribute__((__noreturn__));
 static void parse_colorset(char *line);
-static void add_to_junk(Pixmap pixmap);
-static void feng_shui();
 
-/* When FvemTheme destroys pixmaps it puts them on a list and only destoys them
- * after some period of inactivity. This is necessary because changing colorset
- * options rapidly may result in a module redrawing itself due to the first
- * change whie the second change is happening. If the module renders something
- * with the colorset affected by the second change there is a chance it may
- * reference pixmaps that FvwmTheme has destroyed */
-struct junklist {
-  struct junklist *prev;
-  Pixmap pixmap;
-};
-static struct junklist *junk = NULL;
-
-void MyXParseColor(
-  Display *display, Colormap colormap, char *spec, XColor *exact_def_return)
-{
-  if (!XParseColor(display, colormap, spec, exact_def_return))
-  {
-    fprintf(stderr,"%s: can't parse color \"%s\"\n", name, (spec) ? spec : "");
-    exact_def_return->red = 0;
-    exact_def_return->green = 0;
-    exact_def_return->blue = 0;
-    exact_def_return->flags |= DoRed | DoGreen | DoBlue;
-  }
-
-  return;
-}
-
 int main(int argc, char **argv)
 {
-  XSetWindowAttributes xswa;
-  XGCValues xgcv;
-
   name = GetFileNameFromPath(argv[0]);
   namelen = strlen(name);
 
+  fprintf(stderr,
+          "%s is obsolete, see the Colorset section of the fvwm(1) man page\n",
+          name);
   set_signals();
 
   /* try to make sure it is fvwm that spawned this module */
@@ -112,52 +64,12 @@
   fd[0] = atoi(argv[1]);
   fd[1] = atoi(argv[2]);
 
-  /* open the display and initialize the picture library */
-  dpy = XOpenDisplay(NULL);
-  if (!dpy) {
-    fprintf(stderr,"%s: can't open display %s", name, XDisplayName(NULL));
-    exit (1);
-  }
-  InitPictureCMap(dpy);
-
-  /* This module allocates resouces that othe rmodules may rely on.
-   * Set the closedown mode so that the pixmaps and colors are not freed
-   * by the server if this module dies
-   */
-  XSetCloseDownMode(dpy, RetainTemporary);
-
-  /* create a window to work in */
-  xswa.background_pixmap = None;
-  xswa.border_pixel = 0;
-  xswa.colormap = Pcmap;
-  win = XCreateWindow(dpy, RootWindow(dpy, DefaultScreen(dpy)), -2, -2, 2, 2,
-                     0, Pdepth, InputOutput, Pvisual,
-                     CWBackPixmap | CWBorderPixel | CWColormap, &xswa);
-
-  /* create a GC */
-  gc = fvwmlib_XCreateGC(dpy, win, 0, &xgcv);
-
-  /* die horribly if either win or gc could not be created */
-  XSync(dpy, False);
-
-  /* install a non-fatal error handler */
-  XSetErrorHandler(error_handler);
-
   /* get the initial configuration options */
   parse_config();
 
   /* tell fvwm we're running */
   SendFinishedStartupNotification(fd);
 
-  /* garbage collect */
-  alloca(0);
-
-  /* just in case any previous FvwmTheme has died and left pixmaps dangling.
-   * This might be overkill but any other method must ensure that fvwm doesn't
-   * get killed (it can be the owner of the pixels in colorset 0)
-   */
-  XKillClient(dpy, AllTemporary);
-
   /* sit around waiting for something to do */
   main_loop();
 }
@@ -167,12 +79,9 @@
   FvwmPacket *packet;
   fd_set_size_t fd_width;
   fd_set in_fdset;
-  struct timeval delay;
 
   fd_width = fd[1] + 1;
   FD_ZERO(&in_fdset);
-  delay.tv_sec = 5;
-  delay.tv_usec = 0;
 
   while (True) {
     /* garbage collect */
@@ -180,18 +89,12 @@
 
     FD_SET(fd[1], &in_fdset);
     /* wait for an instruction from fvwm or a timeout */
-    if (fvwmSelect(fd_width, &in_fdset, NULL, NULL, junk ? &delay : NULL) < 0)
+    if (fvwmSelect(fd_width, &in_fdset, NULL, NULL, NULL) < 0)
     {
       fprintf(stderr, "%s: select error!\n", name);
       exit(-1);
     }
 
-    if (!FD_ISSET(fd[1], &in_fdset))
-    { /* have a timeout, tidy up */
-      feng_shui();
-      continue;
-    }
-
     packet = ReadFvwmPacket(fd[1]);
     if (!packet)
       exit(0);
@@ -229,781 +132,22 @@
   switch(GetTokenIndex(line, config_options, -1, &rest))
   {
   case 0: /* ImagePath */
-    SetImagePath(rest);
     break;
   case 1: /* ColorLimit */
-    sscanf(rest, "%d", &color_limit);
     break;
   case 2: /* *FvwmThemColorset */
     parse_colorset(rest);
     break;
   case 3: /* *FvwmThemeReadWriteColors */
-    if (sharedCells)
-      fprintf(stderr, "%s: must come first, already allocated shared pixels\n",
-             config_options[3]);
-    else if (Pvisual->class != PseudoColor)
-      fprintf(stderr, "%s: only works with PseudoColor visuals\n",
-             config_options[3]);
-    else
-      privateCells = True;
-  }
-}
-
-static char *get_simple_color(
-  char *string, char **color, colorset_struct *cs, int supplied_color,
-  int special_flag, char *special_string)
-{
-  char *rest;
-
-  if (*color)
-  {
-    free(*color);
-    *color = NULL;
-  }
-  rest = GetNextToken(string, color);
-  if (*color)
-  {
-    if (special_string && StrEquals(*color, special_string))
-    {
-      free(*color);
-      *color = NULL;
-      cs->color_flags |= special_flag;
-      cs->color_flags &= ~supplied_color;
-    }
-    else
-    {
-      cs->color_flags |= supplied_color;
-      cs->color_flags &= ~special_flag;
-    }
-  }
-  else
-    cs->color_flags &= ~(supplied_color | special_flag);
-
-  return rest;
-}
-
-static void SafeDestroyPicture(Display *dpy, Picture *picture)
-{
-    /* have to subvert destroy picture so that it doesn't free pixmaps
-     * these are added to the junk list to be cleaned up after a timeout */
-    if (picture->count < 2)
-    {
-      if (picture->picture)
-      {
-        add_to_junk(picture->picture);
-        picture->picture = None;
-      }
-      if (picture->mask)
-      {
-        add_to_junk(picture->mask);
-        picture->mask = None;
-      }
-    }
-    /* all that this will now do is free the colors and the name */
-    DestroyPicture(dpy, picture);
-}
-
-static void free_colorset_background(colorset_struct *cs)
-{
-  if (cs->picture) {
-    if (cs->picture->picture != cs->pixmap)
-      fprintf(stderr, "FvwmTheme warning: cs->picture != cs->pixmap\n");
-    SafeDestroyPicture(dpy, cs->picture);
-    cs->picture = None;
-    cs->pixmap = None;
-  }
-  if (cs->pixmap && cs->pixmap != ParentRelative)
-  {
-    add_to_junk(cs->pixmap);
-  }
-  cs->pixmap = None;
-  if (cs->mask)
-  {
-    add_to_junk(cs->mask);
-    cs->mask = None;
-  }
-  if (cs->pixels && cs->nalloc_pixels)
-  {
-    XFreeColors(dpy, Pcmap, cs->pixels, cs->nalloc_pixels, 0);
-    free(cs->pixels);
-    cs->pixels = NULL;
-    cs->nalloc_pixels = 0;
+    SendText(fd, "ReadWriteColors", 0);
+    break;
   }
 }
 
-static char *csetopts[] =
-{
-  "Foreground",
-  "Fore",
-  "fg",
-
-  "Background",
-  "Back",
-  "bg",
-
-  "Hilight",
-  "Hilite",
-  "hi",
-
-  "Shadow",
-  "Shade",
-  "sh",
-
-  /* these strings are used inside the cases in the switch below! */
-  "Pixmap",
-  "TiledPixmap",
-  "AspectPixmap",
-
-  /* these strings are used inside the cases in the switch below! */
-  "Shape",
-  "TiledShape",
-  "AspectShape",
-
-  /* switch off pixmaps and gradients */
-  "Plain",
-  /* switch off shape */
-  "NoShape",
-
-  /* Make the background transparent, it copies the root window background */
-  "Transparent",
-
-  NULL
-};
-
 /* translate a colorset spec into a colorset structure */
 static void parse_colorset(char *line)
 {
-  int n;
-  int i;
-  int w;
-  int h;
-  colorset_struct *cs;
-  char *token;
-  char *optstring;
-  char *args;
-  char *option;
-  char type;
-  char *fg = NULL;
-  char *bg = NULL;
-  char *hi = NULL;
-  char *sh = NULL;
-  Bool do_remove_shape;
-  Bool have_pixels_changed = False;
-  Bool has_fg_changed = False;
-  Bool has_bg_changed = False;
-  Bool has_sh_changed = False;
-  Bool has_hi_changed = False;
-  Bool has_pixmap_changed = False;
-  Bool has_shape_changed = False;
-  XColor color;
-  XGCValues xgcv;
-  static GC mono_gc = None;
-  static int nColorsets = 0;
-
-  /* find out which colorset */
-  if (GetIntegerArguments(line, &line, &n, 1) != 1)
-    return;
-  if (n < 0)
-  {
-    fprintf(stderr, "%s: colorset number must be zero or positive\n", name);
-    return;
-  }
-
-  /* make sure it exists and has sensible contents */
-  if (nColorsets <= n) {
-    Colorset =
-      (colorset_struct *)saferealloc((char *)Colorset,
-                                    (n + 1) * sizeof(colorset_struct));
-    memset(&Colorset[nColorsets], 0,
-          (n + 1 - nColorsets) * sizeof(colorset_struct));
-  }
-
-  /* initialize new colorsets to black on gray */
-  while (nColorsets <= n)
-  {
-    colorset_struct *ncs = &Colorset[nColorsets];
-    have_pixels_changed = True;
-    if (privateCells &&
-       /* grab four writeable cells */
-       XAllocColorCells(dpy, Pcmap, False, NULL, 0, &(ncs->fg), 4)) {
-      XColor *colorp;
-
-      /* set the fg color */
-      MyXParseColor(dpy, Pcmap, black, &color);
-      color.pixel = ncs->fg;
-      XStoreColor(dpy, Pcmap, &color);
-      /* set the bg */
-      MyXParseColor(dpy, Pcmap, gray, &color);
-      color.pixel = ncs->bg;
-      XStoreColor(dpy, Pcmap, &color);
-      /* calculate and set the hilite */
-      colorp = GetHiliteColor(ncs->bg);
-      colorp->pixel = ncs->hilite;
-      XStoreColor(dpy, Pcmap, colorp);
-      /* calculate and set the shadow */
-      colorp = GetShadowColor(ncs->bg);
-      colorp->pixel = ncs->shadow;
-      XStoreColor(dpy, Pcmap, colorp);
-    } else {
-      /* grab four shareable colors */
-      Colorset[nColorsets].fg = GetColor(black);
-      Colorset[nColorsets].bg = GetColor(gray);
-      Colorset[nColorsets].hilite = GetHilite(Colorset[nColorsets].bg);
-      Colorset[nColorsets].shadow = GetShadow(Colorset[nColorsets].bg);
-      /* set flags for fg contrast, bg average in case just a pixmap is given 
*/
-      Colorset[nColorsets].color_flags = FG_CONTRAST | BG_AVERAGE;
-    }
-    nColorsets++;
-  }
-
-  cs = &Colorset[n];
-
-  /* ---------- Parse the options ---------- */
-  while (line && *line)
-  {
-    /* Read next option specification (delimited by a comma or \0). */
-    line = GetQuotedString(line, &optstring, ",", NULL, NULL, NULL);
-    if (!optstring)
-      break;
-    args = GetNextToken(optstring, &option);
-    if (!option)
-    {
-      free(optstring);
-      break;
-    }
-
-    do_remove_shape = False;
-    switch((i = GetTokenIndex(option, csetopts, 0, NULL)))
-    {
-    case 0: /* Foreground */
-    case 1: /* Fore */
-    case 2: /* fg */
-      get_simple_color(args, &fg, cs, FG_SUPPLIED, FG_CONTRAST, "contrast");
-      has_fg_changed = True;
-      break;
-    case 3: /* Background */
-    case 4: /* Back */
-    case 5: /* bg */
-      get_simple_color(args, &bg, cs, BG_SUPPLIED, BG_AVERAGE, "average");
-      has_bg_changed = True;
-      break;
-    case 6: /* Hilight */
-    case 7: /* Hilite */
-    case 8: /* hi */
-      get_simple_color(args, &hi, cs, HI_SUPPLIED, 0, NULL);
-      has_hi_changed = True;
-      break;
-    case 9: /* Shadow */
-    case 10: /* Shade */
-    case 11: /* sh */
-      get_simple_color(args, &sh, cs, SH_SUPPLIED, 0, NULL);
-      has_sh_changed = True;
-      break;
-    case 12: /* TiledPixmap */
-    case 13: /* Pixmap */
-    case 14: /* AspectPixmap */
-      has_pixmap_changed = True;
-      free_colorset_background(cs);
-      /* set the flags */
-      if (csetopts[i][0] == 'T')
-       cs->pixmap_type = PIXMAP_TILED;
-      else if (csetopts[i][0] == 'A')
-       cs->pixmap_type = PIXMAP_STRETCH_ASPECT;
-      else
-       cs->pixmap_type = PIXMAP_STRETCH;
-
-      /* read filename */
-      token = PeekToken(args, &args);
-      if (!token)
-       break;
-      /* load the file using the color reduction routines in Picture.c */
-      cs->picture = CachePicture(dpy, win, NULL, token, color_limit);
-      if (!cs->picture)
-      {
-       fprintf(stderr, "%s: can't load picture %s\n", name, token);
-       break;
-      }
-      /* don't try to be smart with bitmaps */
-      if (cs->picture->depth != Pdepth)
-      {
-       fprintf(stderr, "%s: bitmaps not supported\n", name);
-       SafeDestroyPicture(dpy, cs->picture);
-       cs->picture = None;
-       break;
-      }
-      /* copy the picture pixmap into the public colorset structure */
-      cs->width = cs->picture->width;
-      cs->height = cs->picture->height;
-      cs->pixmap = cs->picture->picture;
-
-      if (cs->pixmap)
-      {
-       if (cs->picture->mask != None)
-       {
-         /* make an inverted copy of the mask */
-         cs->mask = XCreatePixmap(dpy, win, cs->width, cs->height, 1);
-         if (cs->mask)
-         {
-           if (mono_gc == None)
-           {
-             xgcv.foreground = 1;
-             xgcv.background = 0;
-             /* create a gc for 1 bit depth */
-             mono_gc = fvwmlib_XCreateGC(
-               dpy, cs->mask, GCForeground | GCBackground, &xgcv);
-           }
-           XCopyArea(dpy, cs->picture->mask, cs->mask, mono_gc, 0, 0,
-                     cs->width, cs->height, 0, 0);
-           /* Invert the mask. We use it to draw the background. */
-           XSetFunction(dpy, mono_gc, GXinvert);
-           XFillRectangle(dpy, cs->mask, mono_gc, 0, 0, cs->width, cs->height);
-           XSetFunction(dpy, mono_gc, GXcopy);
-         }
-       }
-      }
-      break;
-    case 15: /* Shape */
-    case 16: /* TiledShape */
-    case 17: /* AspectShape */
-      if (FHaveShapeExtension)
-      {
-       /* read filename */
-       token = PeekToken(args, &args);
-       has_shape_changed = True;
-       if (cs->shape_mask)
-       {
-         add_to_junk(cs->shape_mask);
-         cs->shape_mask = None;
-       }
-       if (do_remove_shape == True)
-         break;
-       /* set the flags */
-       if (csetopts[i][0] == 'T')
-         cs->shape_type = SHAPE_TILED;
-       else if (csetopts[i][0] == 'A')
-         cs->shape_type = SHAPE_STRETCH_ASPECT;
-       else
-         cs->shape_type = SHAPE_STRETCH;
-
-       /* try to load the shape mask */
-       if (token)
-       {
-         Picture *picture;
-
-         /* load the shape mask */
-         picture = CachePicture(dpy, win, NULL, token, color_limit);
-         if (!picture)
-           fprintf(stderr, "%s: can't load picture %s\n", name, token);
-         else if (picture->depth != 1 && picture->mask == None)
-         {
-           fprintf(stderr, "%s: shape pixmap must be of depth 1\n", name);
-           SafeDestroyPicture(dpy, picture);
-         }
-         else
-         {
-           Pixmap mask;
-
-           /* okay, we have what we want */
-           if (picture->mask != None)
-             mask = picture->mask;
-           else
-             mask = picture->picture;
-           cs->shape_width = picture->width;
-           cs->shape_height = picture->height;
-
-           if (mask != None)
-           {
-             cs->shape_mask = XCreatePixmap(
-               dpy, mask, picture->width, picture->height, 1);
-             if (cs->shape_mask != None)
-             {
-               if (mono_gc == None)
-               {
-                 xgcv.foreground = 1;
-                 xgcv.background = 0;
-                 /* create a gc for 1 bit depth */
-                 mono_gc = fvwmlib_XCreateGC(
-                   dpy, picture->mask, GCForeground|GCBackground, &xgcv);
-               }
-               XCopyPlane(dpy, mask, cs->shape_mask, mono_gc, 0, 0,
-                          picture->width, picture->height, 0, 0, 1);
-             }
-           }
-         }
-         if (picture)
-         {
-           SafeDestroyPicture(dpy, picture);
-           picture = None;
-         }
-       }
-      }
-      else
-      {
-       cs->shape_mask = None;
-      }
-      break;
-    case 18: /* Plain */
-      has_pixmap_changed = True;
-      free_colorset_background(cs);
-      break;
-    case 19: /* NoShape */
-      has_shape_changed = True;
-      if (cs->shape_mask)
-      {
-       add_to_junk(cs->shape_mask);
-       cs->shape_mask = None;
-      }
-      break;
-    case 20: /* Transparent */
-      /* this is only allowable when the root depth == fvwm visual depth
-       * otherwise bad match errors happen, it may be even more restrictive
-       * but my tests (on exceed 6.2) show that only == depth is necessary */
-      if (Pdepth != DefaultDepth(dpy, (DefaultScreen(dpy))))
-      {
-       fprintf(stderr,
-               "%s: can't do Transparent when root_depth != fvwm_depth\n",
-               name);
-       break;
-      }
-      has_pixmap_changed = True;
-      free_colorset_background(cs);
-      cs->pixmap = ParentRelative;
-      cs->pixmap_type = PIXMAP_STRETCH;
-      break;
-    default:
-      /* test for ?Gradient */
-      if (option[0] && StrEquals(&option[1], "Gradient"))
-      {
-       type = toupper(option[0]);
-       if (!IsGradientTypeSupported(type))
-         break;
-       has_pixmap_changed = True;
-       free_colorset_background(cs);
-       /* create a pixmap of the gradient type */
-       cs->pixmap = CreateGradientPixmapFromString(dpy, win, gc, type, args,
-                                                   &w, &h, &cs->pixels,
-                                                   &cs->nalloc_pixels);
-       cs->width = w;
-       cs->height = h;
-       if (type == V_GRADIENT)
-         cs->pixmap_type = PIXMAP_STRETCH_Y;
-       else if (type == H_GRADIENT)
-         cs->pixmap_type = PIXMAP_STRETCH_X;
-       else
-         cs->pixmap_type = PIXMAP_STRETCH;
-      }
-      else
-      {
-       fprintf(stderr, "%s: bad colorset pixmap specifier %s %s\n", name,
-               option, line);
-      }
-      break;
-    } /* switch */
-
-    if (option)
-    {
-      free(option);
-      option = NULL;
-    }
-    free(optstring);
-    optstring = NULL;
-  } /* while (line && *line) */
-
-  /*
-   * ---------- change the background colour ----------
-   */
-  if (has_bg_changed || has_pixmap_changed)
-  {
-    Bool do_set_default_background = False;
-
-    if ((cs->color_flags & BG_AVERAGE) && cs->pixmap != None &&
-        cs->pixmap != ParentRelative)
-    {
-      /* calculate average background color */
-      XColor *colors;
-      XImage *image;
-      XImage *mask_image = None;
-      unsigned int i, j, k = 0;
-      unsigned long red = 0, blue = 0, green = 0;
-
-      /* create an array to store all the pixmap colors in */
-      colors = (XColor *)safemalloc(cs->width * cs->height * sizeof(XColor));
-      /* get the pixmap and mask into an image */
-      image = XGetImage(dpy, cs->pixmap, 0, 0, cs->width, cs->height,
-                       AllPlanes, ZPixmap);
-      if (cs->mask != None)
-       mask_image = XGetImage(dpy, cs->mask, 0, 0, cs->width, cs->height,
-                              AllPlanes, ZPixmap);
-      /* only fetch the pixels that are not masked out */
-      for (i = 0; i < cs->width; i++)
-       for (j = 0; j < cs->height; j++)
-         if ((cs->mask == None) || (XGetPixel(mask_image, i, j) == 0))
-           colors[k++].pixel = XGetPixel(image, i, j);
-
-      XDestroyImage(image);
-      if (mask_image != None)
-       XDestroyImage(mask_image);
-      if (k == 0)
-      {
-       do_set_default_background = True;
-      }
-      else
-      {
-       /* look them all up, XQueryColors() can't handle more than 256 */
-       for (i = 0; i < k; i += 256)
-         XQueryColors(dpy, Pcmap, &colors[i], min(k - i, 256));
-       /* calculate average, ignore overflow: .red is short, red is long */
-       for (i = 0; i < k; i++) {
-         red += colors[i].red;
-         green += colors[i].green;
-         blue += colors[i].blue;
-       }
-       free(colors);
-       /* get it */
-       color.red = red / k;
-       color.green = green / k;
-       color.blue = blue / k;
-       if (privateCells) {
-         color.pixel = cs->bg;
-         XStoreColor(dpy, Pcmap, &color);
-       } else {
-         Pixel old_bg = cs->bg;
-
-         XFreeColors(dpy, Pcmap, &cs->bg, 1, 0);
-         XAllocColor(dpy, Pcmap, &color);
-         cs->bg = color.pixel;
-         if (old_bg != cs->bg)
-           have_pixels_changed = True;
-       }
-      }
-    } /* average */
-    else if ((cs->color_flags & BG_SUPPLIED) && bg != NULL)
-    {
-      /* user specified colour */
-      if (privateCells) {
-       unsigned short red, green, blue;
-
-       MyXParseColor(dpy, Pcmap, bg, &color);
-       red = color.red;
-       green = color.green;
-       blue = color.blue;
-       color.pixel = cs->bg;
-       XStoreColor(dpy, Pcmap, &color);
-      } else {
-       Pixel old_bg = cs->bg;
-
-       XFreeColors(dpy, Pcmap, &cs->bg, 1, 0);
-       cs->bg = GetColor(bg);
-       if (old_bg != cs->bg)
-         have_pixels_changed = True;
-      }
-    } /* user specified */
-    else if ((bg == NULL && has_bg_changed) ||
-             ((cs->color_flags & BG_AVERAGE) && cs->pixmap == ParentRelative))
-    {
-      /* default */
-      do_set_default_background = True;
-    } /* default */
-    if (do_set_default_background)
-    {
-      if (privateCells) {
-        MyXParseColor(dpy, Pcmap, gray, &color);
-        color.pixel = cs->bg;
-        XStoreColor(dpy, Pcmap, &color);
-      } else {
-       Pixel old_bg = cs->bg;
-
-       XFreeColors(dpy, Pcmap, &cs->bg, 1, 0);
-       cs->bg = GetColor(gray);
-       if (old_bg != cs->bg)
-         have_pixels_changed = True;
-      }
-    }
-    has_bg_changed = True;
-  } /* has_bg_changed */
-
-  /*
-   * ---------- change the foreground colour ----------
-   */
-  if (has_fg_changed || (has_bg_changed && (cs->color_flags & FG_CONTRAST)))
-  {
-    has_fg_changed = 1;
-    if (cs->color_flags & FG_CONTRAST)
-    {
-      /* calculate contrasting foreground color */
-      color.pixel = cs->bg;
-      XQueryColor(dpy, Pcmap, &color);
-      color.red = (color.red > 32767) ? 0 : 65535;
-      color.green = (color.green > 32767) ? 0 : 65535;
-      color.blue = (color.blue > 32767) ? 0 : 65535;
-      if (privateCells) {
-       color.pixel = cs->fg;
-       XStoreColor(dpy, Pcmap, &color);
-      } else {
-       Pixel old_fg = cs->fg;
-
-       XFreeColors(dpy, Pcmap, &cs->fg, 1, 0);
-       XAllocColor(dpy, Pcmap, &color);
-       cs->fg = color.pixel;
-       if (old_fg != cs->fg)
-         have_pixels_changed = True;
-      }
-    } /* contrast */
-    else if ((cs->color_flags & FG_SUPPLIED) && fg != NULL)
-    {
-      /* user specified colour */
-      if (privateCells) {
-       MyXParseColor(dpy, Pcmap, fg, &color);
-       color.pixel = cs->fg;
-       XStoreColor(dpy, Pcmap, &color);
-      } else {
-       Pixel old_fg = cs->fg;
-
-       XFreeColors(dpy, Pcmap, &cs->fg, 1, 0);
-       cs->fg = GetColor(fg);
-       if (old_fg != cs->fg)
-         have_pixels_changed = True;
-      }
-    } /* user specified */
-    else if (fg == NULL)
-    {
-      /* default */
-      if (privateCells) {
-        /* query it */
-        MyXParseColor(dpy, Pcmap, black, &color);
-        color.pixel = cs->fg;
-        XStoreColor(dpy, Pcmap, &color);
-      } else {
-       Pixel old_fg = cs->fg;
-
-       XFreeColors(dpy, Pcmap, &cs->fg, 1, 0);
-       cs->fg = GetColor(black);
-       if (old_fg != cs->fg)
-         have_pixels_changed = True;
-      }
-    }
-  } /* has_fg_changed */
-
-  /*
-   * ---------- change the hilight colour ----------
-   */
-  if (has_hi_changed || has_bg_changed)
-  {
-    has_hi_changed = 1;
-    if ((cs->color_flags & HI_SUPPLIED) && hi != NULL)
-    {
-      /* user specified colour */
-      if (privateCells) {
-       MyXParseColor(dpy, Pcmap, hi, &color);
-       color.pixel = cs->hilite;
-       XStoreColor(dpy, Pcmap, &color);
-      } else {
-       Pixel old_hilite = cs->hilite;
-
-       XFreeColors(dpy, Pcmap, &cs->hilite, 1, 0);
-       cs->hilite = GetColor(hi);
-       if (old_hilite != cs->hilite)
-         have_pixels_changed = True;
-      }
-    } /* user specified */
-    else if (hi == NULL)
-    {
-      if (privateCells) {
-       XColor *colorp;
-
-       colorp = GetHiliteColor(cs->bg);
-       colorp->pixel = cs->hilite;
-       XStoreColor(dpy, Pcmap, colorp);
-      } else {
-       Pixel old_hilite = cs->hilite;
-
-       XFreeColors(dpy, Pcmap, &cs->hilite, 1, 0);
-       cs->hilite = GetHilite(cs->bg);
-       if (old_hilite != cs->hilite)
-         have_pixels_changed = True;
-      }
-    }
-  } /* has_hi_changed */
-
-  /*
-   * ---------- change the shadow colour ----------
-   */
-  if (has_sh_changed || has_bg_changed)
-  {
-    has_sh_changed = 1;
-    if ((cs->color_flags & SH_SUPPLIED) && sh != NULL)
-    {
-      /* user specified colour */
-      if (privateCells) {
-       MyXParseColor(dpy, Pcmap, sh, &color);
-       color.pixel = cs->shadow;
-       XStoreColor(dpy, Pcmap, &color);
-      } else {
-       Pixel old_shadow = cs->shadow;
-
-       XFreeColors(dpy, Pcmap, &cs->shadow, 1, 0);
-       cs->shadow = GetColor(sh);
-       if (old_shadow != cs->shadow)
-         have_pixels_changed = True;
-      }
-    } /* user specified */
-    else if (sh == NULL)
-    {
-      if (privateCells) {
-       XColor *colorp;
-
-       colorp = GetShadowColor(cs->bg);
-       colorp->pixel = cs->shadow;
-       XStoreColor(dpy, Pcmap, colorp);
-      } else {
-       Pixel old_shadow = cs->shadow;
-
-       XFreeColors(dpy, Pcmap, &cs->shadow, 1, 0);
-       cs->shadow = GetShadow(cs->bg);
-       if (old_shadow != cs->shadow)
-         have_pixels_changed = True;
-      }
-    }
-  } /* has_sh_changed */
-
-  /*
-   * ---------- change the masked out parts of the background pixmap ----------
-   */
-  if ((cs->mask != None) && (has_pixmap_changed || has_bg_changed))
-  {
-    /* Now that we know the background colour we can update the pixmap
-     * background. */
-    XSetForeground(dpy, gc, cs->bg);
-    XSetClipMask(dpy, gc, cs->mask);
-    XFillRectangle(dpy, cs->pixmap, gc, 0, 0, cs->width, cs->height);
-    XSetClipMask(dpy, gc, None);
-    has_pixmap_changed = True;
-  } /* has_pixmap_changed */
-
-  /*
-   * ---------- send new colorset to fvwm and clean up ----------
-   */
-  /* make sure the server has this to avoid races */
-  XSync(dpy, False);
-
-  /* inform fvwm of the change */
-  if (have_pixels_changed || has_pixmap_changed || has_shape_changed)
-    SendText(fd, DumpColorset(n, &Colorset[n]), 0);
-
-  if (fg)
-    free(fg);
-  if (bg)
-    free(bg);
-  if (hi)
-    free(hi);
-  if (sh)
-    free(sh);
-
-  /* if privateCells are not being used and XAllocColor has been used
-   * we are stuck in sharedCells behaviour forever */
-  /* have_pixels_changed will be set if a new colorset has been made */
-  if (!privateCells && have_pixels_changed)
-    sharedCells = True;
+  SendText(fd, CatString2("Colorset ", line), 0);
 }
 
 /* SendToModule options */
@@ -1048,21 +192,6 @@
   SetSyncMask(fd, M_CONFIG_INFO | M_STRING);
 }
 
-static int error_handler(Display *d, XErrorEvent *e)
-{
-  /* Since GetColor() doesn't return a status it is possible that FvwmTheme
-   * will try to free a color that it hasn't XAlloc()'d. Allow this error */
-  if (e->error_code == BadAccess && e->request_code == X_FreeColors)
-  {
-    fprintf(stderr, "%s: couldn't free a pixel, may have run out of colors\n",
-           name);
-    return 0;
-  }
-  /* All other errors cause diagnostic output and stop execution */
-  PrintXErrorAndCoredump(d, e, name);
-  return 0;
-}
-
 static void set_signals(void) {
 #ifdef HAVE_SIGACTION
   struct sigaction  sigact;
@@ -1106,27 +235,4 @@
 static RETSIGTYPE signal_handler(int signal) {
   fprintf(stderr, "%s quiting on signal %d\n", name, signal);
   exit(signal);
-}
-
-static void add_to_junk(Pixmap pixmap)
-{
-  struct junklist *oldjunk = junk;
-
-  junk = (struct junklist *)safemalloc(sizeof(struct junklist));
-  junk->prev = oldjunk;
-  junk->pixmap = pixmap;
-}
-
-static void feng_shui()
-{
-  struct junklist *oldjunk = junk;
-
-  while (junk)
-  {
-    XFreePixmap(dpy, junk->pixmap);
-    oldjunk = junk;
-    junk = junk->prev;
-    free(oldjunk);
-  }
-  XFlush(dpy);
 }

Reply via email to