/*
 * Copyright (c) 1998, 1999 Ethan Fischer <allanon@crystaltokyo.com>
 *
 * 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.
 *
 */

#include "../configure.h"
#ifdef NEWLOOK

#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include <X11/Xproto.h>
#include <X11/Xatom.h>

#include "../include/aftersteplib.h"
#include "../include/loadimg.h"
#include "../include/parse.h"
#include "../include/mystyle.h"
#include "../include/stepgfx.h"

/*
 * if you add a member to this list, or to the MyStyle structure, 
 * remember to update new_style(), delete_style(), merge_styles(), and 
 * ParseMyStyle()
 */
struct config mystyle_config[] =
{
  {"~MyStyle", set_func_arg, (char **) F_DONE},
  {"Inherit", set_func_arg, (char **) F_INHERIT},
  {"Font", set_func_arg, (char **) F_FONT},
  {"ForeColor", set_func_arg, (char **) F_FORECOLOR},
  {"BackColor", set_func_arg, (char **) F_BACKCOLOR},
  {"TextStyle", set_func_arg, (char **) F_TEXTSTYLE},
#ifndef NO_TEXTURE
  {"MaxColors", set_func_arg, (char **) F_MAXCOLORS},
  {"BackGradient", set_func_arg, (char **) F_BACKGRADIENT},
  {"BackPixmap", set_func_arg, (char **) F_BACKPIXMAP},
#endif
  {"", NULL, NULL}
};

MyStyle *mystyle_first;

/* the GCs are static, but they are still used outside mystyle.c */
static GC ForeGC = None;
static GC BackGC = None;
static GC ReliefGC = None;
static GC ShadowGC = None;

static int style_func;
static char *style_arg;

/* create the default style if necessary, and fill in the unset fields 
 * of the other styles from the default */
void
fix_styles (void)
{
  MyStyle *dflt;
  MyStyle *style;

/* 
 * the user may not have set the default style, so set it here
 * all we need are reasonable defaults, and most defaults have been set 
 *  by new_style() already
 * we need FONT, FORECOLOR, and BACKCOLOR, at a minimum
 */
  if ((dflt = find_style ("default")) == NULL)
    dflt = new_style_with_name ("default");
  if ((dflt->set_flags & F_FORECOLOR) == 0)
    dflt->user_flags |= F_FORECOLOR;
  if ((dflt->set_flags & F_BACKCOLOR) == 0)
    {
      dflt->relief.fore = GetHilite (dflt->colors.back);
      dflt->relief.back = GetShadow (dflt->colors.back);
      dflt->user_flags |= F_BACKCOLOR;
    }
  if ((dflt->set_flags & F_FONT) == 0)
    {
      if (load_font (NULL, &dflt->font) == False)
	{
	  fprintf (stderr, "%s: couldn't load default font", MyName);
	  exit (1);
	}
      dflt->user_flags |= F_FONT;
    }
  dflt->set_flags = dflt->inherit_flags | dflt->user_flags;

/* fix up the styles, using the default style */
  for (style = mystyle_first; style != NULL; style = style->next)
    merge_styles (dflt, style, False, False);
}


void
draw_styled_text (Window w, MyStyle * style, char *text, int x, int y)
{
  int len = strlen (text);
  change_style (style);
  switch (style->text_style)
    {
#ifdef I18N
#undef FONTSET
#define FONTSET (*style).font.fontset
#endif
/* 3d look #1 */
    case 1:
      XDrawString (dpy, w, ReliefGC, x - 2, y - 2, text, len);
      XDrawString (dpy, w, ReliefGC, x - 1, y - 2, text, len);
      XDrawString (dpy, w, ReliefGC, x + 0, y - 2, text, len);
      XDrawString (dpy, w, ReliefGC, x + 1, y - 2, text, len);
      XDrawString (dpy, w, ReliefGC, x + 2, y - 2, text, len);

      XDrawString (dpy, w, ReliefGC, x - 2, y - 1, text, len);
      XDrawString (dpy, w, ReliefGC, x - 2, y + 0, text, len);
      XDrawString (dpy, w, ReliefGC, x - 2, y + 1, text, len);
      XDrawString (dpy, w, ReliefGC, x - 2, y + 2, text, len);

      XDrawString (dpy, w, ShadowGC, x + 2, y + 0, text, len);
      XDrawString (dpy, w, ShadowGC, x + 2, y + 1, text, len);
      XDrawString (dpy, w, ShadowGC, x + 2, y + 2, text, len);
      XDrawString (dpy, w, ShadowGC, x + 1, y + 2, text, len);
      XDrawString (dpy, w, ShadowGC, x + 0, y + 2, text, len);

      XDrawString (dpy, w, ForeGC, x + 0, y + 0, text, len);
      break;
/* 3d look #2 */
    case 2:
      XDrawString (dpy, w, ShadowGC, x - 1, y - 1, text, len);
      XDrawString (dpy, w, ReliefGC, x + 0, y + 0, text, len);
      XDrawString (dpy, w, ForeGC, x + 1, y + 1, text, len);
      break;
/* normal text */
    default:
    case 0:
      XDrawString (dpy, w, ForeGC, x + 0, y + 0, text, len);
      break;
    }
}

icon_t
make_styled_icon (MyStyle * style, int width, int height, Pixmap cache)
{
  icon_t icon =
  {None, None, 0, 0};
#ifndef NO_TEXTURE
  GC gc, mgc = None;
  XGCValues gcv;
  unsigned long gcm;

  icon.pix = XCreatePixmap (dpy, RootWindow (dpy, screen), width, height, DefaultDepth (dpy, screen));
  gcv.foreground = style->colors.fore;
  gcv.background = style->colors.back;
  gcv.fill_style = FillSolid;
  gcv.graphics_exposures = False;
  gcm = GCForeground | GCBackground | GCFillStyle | GCGraphicsExposures;
  if (style->texture_type == 128)
    {
      gcv.fill_style = FillTiled;
      gcv.tile = style->back_icon.pix;
      gcm |= GCTile;
      if (style->back_icon.mask != None)
	icon.mask = XCreatePixmap (dpy, RootWindow (dpy, screen), width, height, 1);
    }
  gc = XCreateGC (dpy, icon.pix, gcm, &gcv);
  if (icon.mask != None)
    {
      gcv.tile = style->back_icon.mask;
      gcm = GCFillStyle | GCGraphicsExposures | GCTile;
      mgc = XCreateGC (dpy, style->back_icon.mask, gcm, &gcv);
    }
  switch (style->texture_type)
    {
    case 128:
      if (icon.mask != None)
	XFillRectangle (dpy, icon.mask, mgc, 0, 0, width, height);
      /* fall through to case 0 */
    case 0:
      XFillRectangle (dpy, icon.pix, gc, 0, 0, width, height);
      break;
    case 1:
      if (!DrawDegradeRelief (dpy, icon.pix, 0, 0, width, height,
			      style->gradient.from,
			      style->gradient.to, 0,
			      style->max_colors))
	{
	  XFreePixmap (dpy, icon.pix);
	  icon.pix = None;
	}
      break;
    case 2:
    case 3:
      /* use the cache if we can */
      if (cache != None && width < DisplayWidth (dpy, screen))
	{
	  XCopyArea (dpy, cache, icon.pix, gc, 0, 0, width, height, 0, 0);
	}
      else if (!DrawHGradient (dpy, icon.pix, 0, 0, width, height,
			       style->gradient.from,
			       style->gradient.to, 0,
			       style->max_colors,
			       style->texture_type - 2))
	{
	  XFreePixmap (dpy, icon.pix);
	  icon.pix = None;
	}
      break;
    case 4:
    case 5:
      if (!DrawVGradient (dpy, icon.pix, 0, 0, width, height,
			  style->gradient.from,
			  style->gradient.to, 0,
			  style->max_colors,
			  style->texture_type - 4))
	{
	  XFreePixmap (dpy, icon.pix);
	  icon.pix = None;
	}
      break;
    case 129:
    default:
      XFreePixmap (dpy, icon.pix);
      icon.pix = None;
      break;
    }
  XFreeGC (dpy, gc);
  if (mgc != None)
    XFreeGC (dpy, mgc);
  if (icon.pix != None)
    {
      icon.width = width;
      icon.height = height;
    }
#endif /* NO_TEXTURE */
  return icon;
}

Pixmap
make_styled_pixmap (MyStyle * style, int width, int height, Pixmap cache)
{
  icon_t icon = make_styled_icon (style, width, height, cache);
  if (icon.mask != None)
    XFreePixmap (dpy, icon.mask);
  return icon.pix;
}

/* set a window's background for XClearArea */
void
change_styled_background (Window w, MyStyle * style)
{
#ifndef NO_TEXTURE
  if (style->texture_type == 128 && style->set_flags & F_BACKPIXMAP)
    XSetWindowBackgroundPixmap (dpy, w, style->back_icon.pix);
  else if (style->texture_type == 129)
    XSetWindowBackgroundPixmap (dpy, w, ParentRelative);
  else
#endif /* NO_TEXTURE */
    XSetWindowBackground (dpy, w, style->colors.back);
}

/*
 * set the standard global drawing GCs
 * avoids resetting the GCs when possible
 * WARNING: the GCs are invalid until this function is called
 */
void
change_style (MyStyle * style)
{
  static MyStyle *old_style = NULL;
  static int make_GCs = 1;

/* make the drawing GCs if necessary */
  if (make_GCs)
    {
      XGCValues gcv;
      unsigned long gcm;

      gcv.graphics_exposures = False;
      gcm = GCGraphicsExposures;
      ForeGC = XCreateGC (dpy, RootWindow (dpy, screen), gcm, &gcv);
      BackGC = XCreateGC (dpy, RootWindow (dpy, screen), gcm, &gcv);
      ReliefGC = XCreateGC (dpy, RootWindow (dpy, screen), gcm, &gcv);
      ShadowGC = XCreateGC (dpy, RootWindow (dpy, screen), gcm, &gcv);

      make_GCs = 0;
    }

/* set the GCs if the style is different */
  if (old_style != style)
    {
      old_style = style;
      change_styled_gc (style, ForeGC, BackGC, ReliefGC, ShadowGC);
    }
}

void
change_styled_gc (MyStyle * style, GC foreGC, GC backGC, GC reliefGC, GC shadowGC)
{
  XGCValues gcv;
  unsigned long gcm;

/* set the drawing GC */
  gcv.foreground = style->colors.fore;
  gcv.background = style->colors.back;
  gcv.font = style->font.font->fid;
  gcv.fill_style = FillSolid;
  gcm = GCForeground | GCBackground | GCFont | GCFillStyle;
  XChangeGC (dpy, foreGC, gcm, &gcv);

#ifndef NO_TEXTURE
  if ((style->texture_type != 0) && (style->back_icon.pix != None))
    {
      gcv.fill_style = FillTiled;
      gcv.tile = style->back_icon.pix;
      gcm |= GCTile;
    }
#endif /* NO_TEXTURE */
  XChangeGC (dpy, backGC, gcm, &gcv);

/* set the relief GC */
  gcv.foreground = style->relief.fore;
  gcv.background = style->relief.back;
  gcv.fill_style = FillSolid;
  gcm = GCForeground | GCBackground | GCFont | GCFillStyle;
  XChangeGC (dpy, reliefGC, gcm, &gcv);

/* set the shadow GC */
  gcv.foreground = style->relief.back;
  gcv.background = style->relief.fore;
  gcv.fill_style = FillSolid;
  gcm = GCForeground | GCBackground | GCFont | GCFillStyle;
  XChangeGC (dpy, shadowGC, gcm, &gcv);
}

void
get_styled_gcs (MyStyle * style, GC * foreGC, GC * backGC, GC * reliefGC, GC * shadowGC)
{
  change_style (style);
  if (foreGC != NULL)
    *foreGC = ForeGC;
  if (backGC != NULL)
    *backGC = BackGC;
  if (reliefGC != NULL)
    *reliefGC = ReliefGC;
  if (shadowGC != NULL)
    *shadowGC = ShadowGC;
}

MyStyle *
new_style (void)
{
  MyStyle *style = (MyStyle *) safemalloc (sizeof (MyStyle));

  style->next = mystyle_first;
  mystyle_first = style;

  style->user_flags = 0;
  style->inherit_flags = 0;
  style->set_flags = 0;
  style->name = NULL;
  style->text_style = 0;
  style->font.name = NULL;
  style->font.font = NULL;
#ifdef I18N
  style->font.fontset = NULL;
#endif
  style->colors.fore = GetColor ("white");
  style->colors.back = GetColor ("black");
  style->relief.fore = style->colors.back;
  style->relief.back = style->colors.fore;
  style->texture_type = 0;
#ifndef NO_TEXTURE
  {
    int i;
    for (i = 0; i < 3; i++)
      {
	style->gradient.from[i] = style->colors.fore;
	style->gradient.to[i] = style->colors.fore;
      }
  }
  style->back_icon.pix = None;
  style->back_icon.mask = None;
  if (DefaultDepth (dpy, screen) > 16)
    style->max_colors = 128;
  else if (DefaultDepth (dpy, screen) > 8)
    style->max_colors = 32;
  else
    style->max_colors = 10;
  style->tint.red = style->tint.green = style->tint.blue = 0xc000;
#endif
  return style;
}

MyStyle *
new_style_with_name (char *name)
{
  MyStyle *style = new_style ();

  if (name != NULL)
    {
      style->name = (char *) safemalloc (strlen (name) + 1);
      strcpy (style->name, name);
    }
  return style;
}

/*
 * deletes memory alloc'd for style (including members)
 */

void
delete_style (MyStyle * style)
{
  MyStyle *s1;
  MyStyle *s2;

  /* remove ourself from the list */
  for (s1 = s2 = mystyle_first; s1 != NULL; s2 = s1, s1 = s1->next)
    if (s1 == style)
      break;
  if (s1 != NULL)
    {
      if (mystyle_first == s1)
	mystyle_first = s1->next;
      else
	s2->next = s1->next;
    }
  /* delete members */
  if (style->name != NULL);
  free (style->name);
  if (style->user_flags & F_FONT)
    {
      if (style->font.name != NULL);
      free (style->font.name);
      XFreeFont (dpy, style->font.font);
    }
#ifndef NO_TEXTURE
  if (style->user_flags & F_BACKPIXMAP)
    {
      XFreePixmap (dpy, style->back_icon.pix);
      if (style->back_icon.mask != None)
	XFreePixmap (dpy, style->back_icon.mask);
    }
#endif

  /* free our own mem */
  free (style);
}

/* find a style by name */
MyStyle *
find_style (char *name)
{
  MyStyle *style;
  for (style = mystyle_first; style != NULL; style = style->next)
    if (!mystrcasecmp (style->name, name))
      break;
  return style;
}

/*
 * merges two styles, with the result in child
 * if override == False, will not override fields already set
 * if copy == True, copies instead of inheriting; this is important, because 
 *   inherited members are deleted when their real parent is deleted; don't 
 *   inherit if the parent style could go away before the child
 */
void
merge_styles (MyStyle * parent, MyStyle * child, Bool override, Bool copy)
{
  if (parent->set_flags & F_FONT)
    {
      if ((override == True) && (child->user_flags & F_FONT))
	unload_font (&child->font);
      if ((override == True) || !(child->set_flags & F_FONT))
	{
	  if (copy == False)
	    {
	      child->font = parent->font;
	      child->user_flags &= ~F_FONT;
	      child->inherit_flags |= F_FONT;
	    }
	  else
	    {
	      if (load_font (parent->font.name, &child->font) == True)
		{
		  child->user_flags |= F_FONT;
		  child->inherit_flags &= ~F_FONT;
		}
	    }
	}
    }
  if (parent->set_flags & F_TEXTSTYLE)
    {
      if ((override == True) || !(child->set_flags & F_TEXTSTYLE))
	{
	  child->text_style = parent->text_style;

	  if (copy == False)
	    {
	      child->user_flags &= ~F_TEXTSTYLE;
	      child->inherit_flags |= F_TEXTSTYLE;
	    }
	  else
	    {
	      child->user_flags |= F_TEXTSTYLE;
	      child->inherit_flags &= ~F_TEXTSTYLE;
	    }
	}
    }
  if (parent->set_flags & F_FORECOLOR)
    {
      if ((override == True) || !(child->set_flags & F_FORECOLOR))
	{
	  if (override == True)
	    child->texture_type = parent->texture_type;
	  child->colors.fore = parent->colors.fore;
	  if (copy == False)
	    {
	      child->user_flags &= ~F_FORECOLOR;
	      child->inherit_flags |= F_FORECOLOR;
	    }
	  else
	    {
	      child->user_flags |= F_FORECOLOR;
	      child->inherit_flags &= ~F_FORECOLOR;
	    }
	}
    }
  if (parent->set_flags & F_BACKCOLOR)
    {
      if ((override == True) || !(child->set_flags & F_BACKCOLOR))
	{
	  child->colors.back = parent->colors.back;
	  child->relief = parent->relief;
	  if (copy == False)
	    {
	      child->user_flags &= ~F_BACKCOLOR;
	      child->inherit_flags |= F_BACKCOLOR;
	    }
	  else
	    {
	      child->user_flags |= F_BACKCOLOR;
	      child->inherit_flags &= ~F_BACKCOLOR;
	    }
	}
    }
#ifndef NO_TEXTURE
  if (parent->set_flags & F_MAXCOLORS)
    {
      if ((override == True) || !(child->set_flags & F_MAXCOLORS))
	{
	  child->max_colors = parent->max_colors;
	  if (copy == False)
	    {
	      child->user_flags &= ~F_MAXCOLORS;
	      child->inherit_flags |= F_MAXCOLORS;
	    }
	  else
	    {
	      child->user_flags |= F_MAXCOLORS;
	      child->inherit_flags &= ~F_MAXCOLORS;
	    }
	}
    }
  if (parent->set_flags & F_BACKGRADIENT)
    {
      if ((override == True) || !(child->set_flags & F_BACKGRADIENT))
	{
	  if (override == True)
	    child->texture_type = parent->texture_type;
	  child->gradient = parent->gradient;
	  if (copy == False)
	    {
	      child->user_flags &= ~F_BACKGRADIENT;
	      child->inherit_flags |= F_BACKGRADIENT;
	    }
	  else
	    {
	      child->user_flags |= F_BACKGRADIENT;
	      child->inherit_flags &= ~F_BACKGRADIENT;
	    }
	}
    }
  if (parent->set_flags & F_BACKPIXMAP)
    {
      if ((override == True) && (child->user_flags & F_BACKPIXMAP))
	{
	  XFreePixmap (dpy, child->back_icon.pix);
	  if (child->back_icon.mask != None)
	    XFreePixmap (dpy, child->back_icon.mask);
	}
      if ((override == True) || !(child->set_flags & F_BACKPIXMAP))
	{
	  if (override == True)
	    child->texture_type = parent->texture_type;
	  if (copy == False)
	    {
	      child->back_icon = parent->back_icon;
	      child->user_flags &= ~F_BACKPIXMAP;
	      child->inherit_flags |= F_BACKPIXMAP;
	    }
	  else
	    {
	      GC gc = DefaultGC (dpy, screen);
	      child->back_icon.pix = XCreatePixmap (dpy, RootWindow (dpy, screen), parent->back_icon.width, parent->back_icon.height, DefaultDepth (dpy, screen));
	      XCopyArea (dpy, parent->back_icon.pix, child->back_icon.pix, gc,
	      0, 0, parent->back_icon.width, parent->back_icon.height, 0, 0);
	      if (parent->back_icon.mask != None)
		{
		  GC mgc = XCreateGC (dpy, parent->back_icon.mask, 0, NULL);
		  child->back_icon.pix = XCreatePixmap (dpy, RootWindow (dpy, screen), parent->back_icon.width, parent->back_icon.height, 1);
		  XCopyArea (dpy, parent->back_icon.pix, child->back_icon.pix, mgc,
			     0, 0, parent->back_icon.width, parent->back_icon.height, 0, 0);
		  XFreeGC (dpy, mgc);
		}
	      child->back_icon.width = parent->back_icon.width;
	      child->back_icon.height = parent->back_icon.height;
	      child->user_flags |= F_BACKPIXMAP;
	      child->inherit_flags &= ~F_BACKPIXMAP;
	    }
	}
    }
  if (parent->texture_type == 129 && (override == True || child->texture_type != 129))
    {
      child->tint = parent->tint;
    }
#endif /* NO_TEXTURE */
  child->set_flags = child->user_flags | child->inherit_flags;
}

void
ParseMyStyle (char *tline, FILE * fd, char **ppath, int *junk2)
{
  MyStyle *style;
  char *newline = safemalloc (MAXLINELENGTH + 1);
  int i;
  Bool done = False;
  char *name = stripcpy2 (tline, 0);

  if (name == NULL)
    {
      fprintf (stderr, "%s: bad style name '%s'", MyName, tline);
      return;
    }
/* if this style was already defined, find it */
  if ((style = find_style (name)) != NULL)
    {
      free (name);
      name = style->name;
    }
  else
    {
      style = new_style ();
      style->name = name;
    }

  while (done == False)
    {
      char *p, *tempstring;
      p = fgets (newline, MAXLINELENGTH, fd);
      if (p == NULL)
	break;
      while (isspace (*p))
	p++;
      /* remove comments from the line */
      tempstring = p;
      while (*tempstring != '\0' && (tempstring = strchr (tempstring, '#')) != NULL)
	{
	  i = 1;
	  /* make sure it's not color */
	  while (isxdigit (*(tempstring + i)))
	    i++;
	  /* the minimum color definition is '#000' or similar */
	  if (i < 4)
	    *tempstring = '\0';
	  else
	    tempstring += i;
	}
      if (*p != '\0')
	done = parse_style_member (style, p, *ppath);
    }

  free (newline);
}

/*
 * parse a style member, for example:
 *   parse_style_member(find_style("default"), "BackColor black");
 * this function will likely modify the string argument
 * returns 1 when a "~MyStyle" is parsed
 */
int 
parse_style_member (MyStyle * style, char *str, const char *PixmapPath)
{
  int done = 0;
  struct config *config = find_config (mystyle_config, str);
  style_func = F_ERROR;
  style_arg = NULL;
  if (config != NULL)
    config->action (str + strlen (config->keyword), NULL, config->arg, config->arg2);
  else
    fprintf (stderr, "%s: unknown style command: %s", MyName, str);
  if (style_arg == NULL)
    {
      fprintf (stderr, "%s: bad style arg: %s", MyName, str);
    }
  else
    {
      style->inherit_flags &= ~style_func;
      switch (style_func)
	{
	case F_INHERIT:
	  {
	    MyStyle *parent = find_style (style_arg);
	    if (parent != NULL)
	      merge_styles (parent, style, True, False);
	  }
	  break;
	case F_FONT:
	  if (style->user_flags & style_func)
	    unload_font (&style->font);
	  style->user_flags &= ~style_func;
	  if (load_font (style_arg, &style->font) == True)
	    style->user_flags |= style_func;
	  break;
	case F_TEXTSTYLE:
	  style->text_style = strtol (style_arg, NULL, 10);
	  style->user_flags |= style_func;
	  break;
	case F_FORECOLOR:
	  style->colors.fore = GetColor (style_arg);
	  style->user_flags |= style_func;
	  break;
	case F_BACKCOLOR:
	  style->texture_type = 0;
	  style->colors.back = GetColor (style_arg);
	  style->relief.fore = GetHilite (style->colors.back);
	  style->relief.back = GetShadow (style->colors.back);
	  style->user_flags |= style_func;
	  break;
#ifndef NO_TEXTURE
	case F_MAXCOLORS:
	  style->max_colors = strtol (style_arg, NULL, 10);
	  style->user_flags |= style_func;
	  break;
	case F_BACKGRADIENT:
	  {
	    char *ptr;
	    int type = strtol (style_arg, &ptr, 10);
	    XColor color1, color2;
	    if (XParseColor (dpy, DefaultColormap (dpy, screen), strtok (ptr, " \t\v\r\n\f"), &color1) &&
		XParseColor (dpy, DefaultColormap (dpy, screen), strtok (NULL, " \t\v\r\n\f"), &color2))
	      {
		style->gradient.from[0] = color1.red;
		style->gradient.from[1] = color1.green;
		style->gradient.from[2] = color1.blue;
		style->gradient.to[0] = color2.red;
		style->gradient.to[1] = color2.green;
		style->gradient.to[2] = color2.blue;
		style->texture_type = type;
		style->user_flags |= style_func;
	      }
	    else
	      fprintf (stderr, "%s: bad gradient: %s", MyName, style_arg);
	  }
	  break;
	case F_BACKPIXMAP:
	  {
	    char *ptr;
	    int type = strtol (style_arg, &ptr, 10);
	    char *tmp = stripcpy (ptr);
	    int colors = -1;
	    if (style->set_flags & F_MAXCOLORS)
	      colors = style->max_colors;
	    if (type == 129)
	      {
		style->texture_type = type;
		style->tint.pixel = GetColor (tmp);
		XQueryColor (dpy, DefaultColormap (dpy, screen), &style->tint);
	      }
	    else
	      {
		char *path;
		Pixmap pix, mask;
		if ((path = findIconFile (tmp, PixmapPath, R_OK)) != NULL &&
		    (pix = LoadImageWithMask (dpy, RootWindow (dpy, screen), colors, path, &mask)) != None)
		  {
		    Window r;
		    int d;
		    XGetGeometry (dpy, pix, &r, &d, &d, &style->back_icon.width, &style->back_icon.height, &d, &d);
		    if (style->user_flags & style_func)
		      {
			XFreePixmap (dpy, style->back_icon.pix);
			if (style->back_icon.mask != None)
			  XFreePixmap (dpy, style->back_icon.mask);
		      }
		    style->back_icon.pix = pix;
		    style->back_icon.mask = mask;
		    style->texture_type = type;
		    style->user_flags |= style_func;
		  }
		else
		  {
		    if (path != NULL)
		      free (path);
		    fprintf (stderr, "%s: unable to load pixmap: '%s'", MyName, tmp);
		  }
	      }
	    free (tmp);
	  }
	  break;
#endif
	case F_DONE:
	  done = 1;
	  break;

	case F_ERROR:
	default:
	  fprintf (stderr, "%s: unknown style command: %s", MyName, str);
	  break;
	}
    }
  style->set_flags = style->inherit_flags | style->user_flags;
  free (style_arg);
  return done;
}

void
set_style (char *text, FILE * fd, char **style, int *junk2)
{
  char *name = stripcpy2 (text, 0);
  if (name != NULL)
    {
      *(MyStyle **) style = find_style (name);
      if (*style == NULL)
	fprintf (stderr, "%s: unknown style name: '%s'", MyName, name);
      free (name);
    }
}

void
set_func_arg (char *text, FILE * fd, char **value, int *junk)
{
  style_arg = stripcpy (text);
  style_func = (unsigned long) value;
}

#endif /* NEWLOOK */
