add: } else { rcolor.red = 0; rcolor.green = 0; rcolor.blue = 0; }  if (image->data[3]) { RCombineImageWithColor(image, &rcolor);
context: parseTexture(RContext *rc, char *text){    BackgroundTexture *texture = NULL;    proplist_t texarray;    proplist_t val;    int count;    char *tmp;    char *type;#define GETSTRORGOTO(val, str, i, label) \		val = PLGetArrayElement(texarray, i);\		if (!PLIsString(val)) {\			wwarning("could not parse texture %s", text);\			goto label;\		}\		str = PLGetString(val)    texarray = PLGetProplistWithDescription(text);    if (!texarray || !PLIsArray(texarray) 	|| (count = PLGetNumberOfElements(texarray)) < 2) {	wwarning("could not parse texture %s", text);	if (texarray)	    PLRelease(texarray);	return NULL;    }    texture = wmalloc(sizeof(BackgroundTexture));    memset(texture, 0, sizeof(BackgroundTexture));    GETSTRORGOTO(val, type, 0, error);    if (strcasecmp(type, "solid")==0) {	XColor color;	Pixmap pixmap;	texture->solid = 1;		GETSTRORGOTO(val, tmp, 1, error);	if (!XParseColor(dpy, DefaultColormap(dpy, scr), tmp, &color)) {	    wwarning("could not parse color %s in texture %s", tmp, text);	    goto error;	}	XAllocColor(dpy, DefaultColormap(dpy, scr), &color);	pixmap = XCreatePixmap(dpy, root, 8, 8, DefaultDepth(dpy, scr));	XSetForeground(dpy, DefaultGC(dpy, scr), color.pixel);	XFillRectangle(dpy, pixmap, DefaultGC(dpy, scr), 0, 0, 8, 8);	texture->pixmap = pixmap;	texture->color = color;	texture->width = 8;	texture->height = 8;    } else if (strcasecmp(type, "vgradient")==0	       || strcasecmp(type, "dgradient")==0	       || strcasecmp(type, "hgradient")==0) {	XColor color;	RColor color1, color2;	RImage *image;	Pixmap pixmap;	int gtype;	int iwidth, iheight;	GETSTRORGOTO(val, tmp, 1, error);	if (!XParseColor(dpy, DefaultColormap(dpy, scr), tmp, &color)) {	    wwarning("could not parse color %s in texture %s", tmp, text);	    goto error;	}	color1.red = color.red >> 8;	color1.green = color.green >> 8;	color1.blue = color.blue >> 8;	GETSTRORGOTO(val, tmp, 2, error);	if (!XParseColor(dpy, DefaultColormap(dpy, scr), tmp, &color)) {	    wwarning("could not parse color %s in texture %s", tmp, text);	    goto error;	}	color2.red = color.red >> 8;	color2.green = color.green >> 8;	color2.blue = color.blue >> 8;	switch (type[0]) {	 case 'h':	 case 'H':	    gtype = RHorizontalGradient;	    iwidth = scrWidth;	    iheight = 8;	    break;	 case 'V':	 case 'v':	    gtype = RVerticalGradient;	    iwidth = 8;	    iheight = scrHeight;	    break;	 default:	    gtype = RDiagonalGradient;	    iwidth = scrWidth;	    iheight = scrHeight;	    break;	}	image = RRenderGradient(iwidth, iheight, &color1, &color2, gtype);	if (!image) {	    wwarning("could not render gradient texture:%s",		     RMessageForError(RErrorCode));	    goto error;	}	if (!RConvertImage(rc, image, &pixmap)) {	    wwarning("could not convert texture:%s", 		     RMessageForError(RErrorCode));	    RDestroyImage(image);	    goto error;	}	texture->width = image->width;	texture->height = image->height;	RDestroyImage(image);	texture->pixmap = pixmap;    } else if (strcasecmp(type, "mvgradient")==0	       || strcasecmp(type, "mdgradient")==0	       || strcasecmp(type, "mhgradient")==0) {	XColor color;	RColor **colors;	RImage *image;	Pixmap pixmap;	int i, j;	int gtype;	int iwidth, iheight;	colors = malloc(sizeof(RColor*)*(count-1));	if (!colors) {	    wwarning("out of memory while parsing texture");	    goto error;	}	memset(colors, 0, sizeof(RColor*)*(count-1));	for (i = 2; i < count; i++) {	    val = PLGetArrayElement(texarray, i);	    if (!PLIsString(val)) {		wwarning("could not parse texture %s", text);		for (j = 0; colors[j]!=NULL; j++)		    free(colors[j]);		free(colors);		goto error;	    }	    tmp = PLGetString(val);	    if (!XParseColor(dpy, DefaultColormap(dpy, scr), tmp, &color)) {		wwarning("could not parse color %s in texture %s",			 tmp, text);		for (j = 0; colors[j]!=NULL; j++)		    free(colors[j]);		free(colors);		goto error;	    }	    if (!(colors[i-2] = malloc(sizeof(RColor)))) {		wwarning("out of memory while parsing texture");		for (j = 0; colors[j]!=NULL; j++)		    free(colors[j]);		free(colors);		goto error;	    }	    colors[i-2]->red = color.red >> 8;	    colors[i-2]->green = color.green >> 8;	    colors[i-2]->blue = color.blue >> 8;	}	switch (type[1]) {	 case 'h':	 case 'H':	    gtype = RHorizontalGradient;	    iwidth = scrWidth;	    iheight = 8;	    break;	 case 'V':	 case 'v':	    gtype = RVerticalGradient;	    iwidth = 8;	    iheight = scrHeight;	    break;	 default:	    gtype = RDiagonalGradient;	    iwidth = scrWidth;	    iheight = scrHeight;	    break;	}	image = RRenderMultiGradient(iwidth, iheight, colors, gtype);		for (j = 0; colors[j]!=NULL; j++)	    free(colors[j]);	free(colors);	if (!image) {	    wwarning("could not render gradient texture:%s",		     RMessageForError(RErrorCode));	    goto error;	}	if (!RConvertImage(rc, image, &pixmap)) {	    wwarning("could not convert texture:%s", 		     RMessageForError(RErrorCode));	    RDestroyImage(image);	    goto error;	}	texture->width = image->width;	texture->height = image->height;	RDestroyImage(image);	texture->pixmap = pixmap;    } else if (strcasecmp(type, "cpixmap")==0	  || strcasecmp(type, "spixmap")==0	  || strcasecmp(type, "mpixmap")==0	  || strcasecmp(type, "tpixmap")==0) {	XColor color;	Pixmap pixmap = None;	RImage *image = NULL;	int w, h;	int iwidth, iheight;	GETSTRORGOTO(val, tmp, 1, error);/*	if (toupper(type[0]) == 'T' || toupper(type[0]) == 'C')	    pixmap = LoadJPEG(rc, tmp, &iwidth, &iheight); */	if (!pixmap) {	    image = loadImage(rc, tmp);	    if (!image) {		goto error;	    }	    iwidth = image->width;	    iheight = image->height;	}	GETSTRORGOTO(val, tmp, 2, error);	if (!XParseColor(dpy, DefaultColormap(dpy, scr), tmp, &color)) {	    wwarning("could not parse color %s in texture %s\n", tmp, text);	    RDestroyImage(image);	    goto error;	}	if (!XAllocColor(dpy, DefaultColormap(dpy, scr), &color)) {	    RColor rcolor;	    rcolor.red = color.red >> 8;	    rcolor.green = color.green >> 8;	    rcolor.blue = color.blue >> 8;	    RGetClosestXColor(rc, &rcolor, &color);	}	switch (toupper(type[0])) {	 case 'T':	    texture->width = iwidth;	    texture->height = iheight;	    if (!pixmap && !RConvertImage(rc, image, &pixmap)) {		wwarning("could not convert texture:%s", 			 RMessageForError(RErrorCode));		RDestroyImage(image);		goto error;	    }	    if (image)		RDestroyImage(image);	    break;	 case 'S':	 case 'M':	    if (toupper(type[0])=='S') {		w = scrWidth;		h = scrHeight;	    } else {		if (iwidth*scrHeight > iheight*scrWidth) {		    w = scrWidth;		    h = (scrWidth*iheight)/iwidth;		} else {		    h = scrHeight;		    w = (scrHeight*iwidth)/iheight;		}	    }	    {		RImage *simage;		if (smooth)		    simage = RSmoothScaleImage(image, w, h);		else		    simage = RScaleImage(image, w, h);		if (!simage) {		    wwarning("could not scale image:%s", 			     RMessageForError(RErrorCode));		    RDestroyImage(image);		    goto error;		}		RDestroyImage(image);		image = simage;		iwidth = image->width;		iheight = image->height;	    }	    /* fall through */	 case 'C':	    {		Pixmap cpixmap;		if (!pixmap && !RConvertImage(rc, image, &pixmap)) {		    wwarning("could not convert texture:%s", 			     RMessageForError(RErrorCode));		    RDestroyImage(image);		    goto error;		}		if (iwidth != scrWidth || iheight != scrHeight) {		    int x, y, sx, sy, w, h;		    cpixmap = XCreatePixmap(dpy, root, scrWidth, scrHeight,					    DefaultDepth(dpy, scr));		    XSetForeground(dpy, DefaultGC(dpy, scr), color.pixel);		    XFillRectangle(dpy, cpixmap, DefaultGC(dpy, scr),				   0, 0, scrWidth, scrHeight);		    if (iheight < scrHeight) {			h = iheight;			y = (scrHeight - h)/2;			sy = 0;		    } else {			sy = (iheight - scrHeight)/2;			y = 0;			h = scrHeight;		    }		    if (iwidth < scrWidth) {			w = iwidth;			x = (scrWidth - w)/2;			sx = 0;		    } else {			sx = (iwidth - scrWidth)/2;			x = 0;			w = scrWidth;		    }		    XCopyArea(dpy, pixmap, cpixmap, DefaultGC(dpy, scr),			      sx, sy, w, h, x, y);		    XFreePixmap(dpy, pixmap);		    pixmap = cpixmap;		}		if (image)		    RDestroyImage(image);		texture->width = scrWidth;		texture->height = scrHeight;	    }	    break;	}	texture->pixmap = pixmap;	texture->color = color;    } else if (strcasecmp(type, "thgradient")==0	       || strcasecmp(type, "tvgradient")==0	       || strcasecmp(type, "tdgradient")==0) {	XColor color;	RColor color1, color2;	RImage *image;	RImage *gradient;	RImage *tiled;	Pixmap pixmap;	int opaq;	char *file;	int gtype;	int twidth, theight;	GETSTRORGOTO(val, file, 1, error);	GETSTRORGOTO(val, tmp, 2, error);	opaq = atoi(tmp);	GETSTRORGOTO(val, tmp, 3, error);	if (!XParseColor(dpy, DefaultColormap(dpy, scr), tmp, &color)) {	    wwarning("could not parse color %s in texture %s", tmp, text);	    goto error;	}	color1.red = color.red >> 8;	color1.green = color.green >> 8;	color1.blue = color.blue >> 8;	GETSTRORGOTO(val, tmp, 4, error);	if (!XParseColor(dpy, DefaultColormap(dpy, scr), tmp, &color)) {	    wwarning("could not parse color %s in texture %s", tmp, text);	    goto error;	}	color2.red = color.red >> 8;	color2.green = color.green >> 8;	color2.blue = color.blue >> 8;	image = loadImage(rc, file);	if (!image) {	    goto error;	}	switch (type[1]) {	 case 'h':	 case 'H':	    gtype = RHorizontalGradient;	    twidth = scrWidth;	    theight = image->height > scrHeight ? scrHeight : image->height;	    break;	 case 'V':	 case 'v':	    gtype = RVerticalGradient;	    twidth = image->width > scrWidth ? scrWidth : image->width;	    theight = scrHeight;	    break;	 default:	    gtype = RDiagonalGradient;	    twidth = scrWidth;	    theight = scrHeight;	    break;	}	gradient = RRenderGradient(twidth, theight, &color1, &color2, gtype);	if (!gradient) {	    wwarning("could not render texture:%s",		     RMessageForError(RErrorCode));            RDestroyImage(gradient);            RDestroyImage(image);	    goto error;	}	tiled = RMakeTiledImage(image, twidth, theight);	if (!tiled) {	    wwarning("could not render texture:%s",		     RMessageForError(RErrorCode));	    RDestroyImage(gradient);	    RDestroyImage(image);	    goto error;	}	RDestroyImage(image);	RCombineImagesWithOpaqueness(tiled, gradient, opaq);	RDestroyImage(gradient);	if (!RConvertImage(rc, tiled, &pixmap)) {	    wwarning("could not convert texture:%s", 		     RMessageForError(RErrorCode));	    RDestroyImage(tiled);	    goto error;	}	texture->width = tiled->width;	texture->height = tiled->height;	RDestroyImage(tiled);	texture->pixmap = pixmap;	    } else if (strcasecmp(type, "function")==0) {#ifdef HAVE_DLFCN_H	void (*initFunc) (Display*, Colormap);	RImage* (*mainFunc) (int, char**, int, int, int);	Pixmap pixmap;	RImage *image = 0;	int success = 0;	char *lib, *func, **argv = 0;	void *handle = 0;	int i, argc;        if (count < 3)	    goto function_cleanup;	/* get the library name */	GETSTRORGOTO(val, lib, 1, function_cleanup);	/* get the function name */	GETSTRORGOTO(val, func, 2, function_cleanup);	argc = count - 2;	argv = (char**)wmalloc(argc * sizeof(char*));	/* get the parameters */	argv[0] = func;	for (i=0; i<argc-1; i++) {	    GETSTRORGOTO(val, tmp, 3+i, function_cleanup);	    argv[i+1] = wstrdup(tmp);	}	handle = dlopen(lib, RTLD_LAZY);	if (!handle) {            wwarning("could not find library %s", lib);	    goto function_cleanup;	}	initFunc = dlsym(handle, "initWindowMaker");        if (!initFunc) {	    wwarning("could not initialize library %s", lib);	    goto function_cleanup;        }        initFunc(dpy, DefaultColormap(dpy, scr));        mainFunc = dlsym(handle, func);        if (!mainFunc) {            wwarning("could not find function %s::%s", lib, func);	    goto function_cleanup;        }        image = mainFunc(argc, argv, scrWidth, scrHeight, 0);        if (!RConvertImage(rc, image, &pixmap)) {	    wwarning("could not convert texture:%s", 	        RMessageForError(RErrorCode));	    goto function_cleanup;	}	texture->width = scrWidth;        texture->height = scrHeight;	texture->pixmap = pixmap;	        success = 1;function_cleanup:        if (argv) {	    int i;	    for (i=0; i<argc; i++) {	        free(argv[i]);	    }	}	if (handle) {	    dlclose(handle);	}	if (image) {            RDestroyImage(image);	}	if (!success) {	    goto error;	}#else	wwarning("function textures not supported");	goto error;#endif    } else {	wwarning("invalid texture type %s", text);	goto error;    }    texture->spec = wstrdup(text);    return texture;error:    if (texture)	free(texture);    if (texarray)	PLRelease(texarray);    return NULL;}