10bbfda8aSnia/*
20bbfda8aSnia * XPM image handling functions
30bbfda8aSnia */
40bbfda8aSnia
50bbfda8aSnia#include "ctwm.h"
60bbfda8aSnia
70bbfda8aSnia#include <stdio.h>
80bbfda8aSnia#include <stdlib.h>
90bbfda8aSnia#include <string.h>
100bbfda8aSnia
110bbfda8aSnia#include <X11/xpm.h>
120bbfda8aSnia
130bbfda8aSnia#include "screen.h"
140bbfda8aSnia
150bbfda8aSnia#include "image.h"
160bbfda8aSnia#include "image_xpm.h"
170bbfda8aSnia
180bbfda8aSniastatic Image *LoadXpmImage(const char  *name, ColorPair cp);
190bbfda8aSniastatic void xpmErrorMessage(int status, const char *name, const char *fullname);
200bbfda8aSnia
210bbfda8aSniastatic int reportxpmerror = 1;
220bbfda8aSnia
230bbfda8aSnia
240bbfda8aSnia/*
250bbfda8aSnia * External entry point
260bbfda8aSnia */
270bbfda8aSniaImage *
280bbfda8aSniaGetXpmImage(const char *name, ColorPair cp)
290bbfda8aSnia{
300bbfda8aSnia	/* For non-animated requests, just load the file */
310bbfda8aSnia	if(! strchr(name, '%')) {
320bbfda8aSnia		return LoadXpmImage(name, cp);
330bbfda8aSnia	}
340bbfda8aSnia
350bbfda8aSnia	/* Else it's animated, so load/return the series */
360bbfda8aSnia	return get_image_anim_cp(name, cp, LoadXpmImage);
370bbfda8aSnia}
380bbfda8aSnia
390bbfda8aSnia
400bbfda8aSnia
410bbfda8aSnia/*
420bbfda8aSnia * Internal backend
430bbfda8aSnia */
440bbfda8aSniastatic Image *
450bbfda8aSniaLoadXpmImage(const char *name, ColorPair cp)
460bbfda8aSnia{
470bbfda8aSnia	char        *fullname;
480bbfda8aSnia	Image       *image;
490bbfda8aSnia	int         status;
500bbfda8aSnia	Colormap    stdcmap = Scr->RootColormaps.cwins[0]->colormap->c;
510bbfda8aSnia	XpmAttributes attributes;
520bbfda8aSnia	static XpmColorSymbol overrides[] = {
530bbfda8aSnia		{"Foreground", NULL, 0},
540bbfda8aSnia		{"Background", NULL, 0},
550bbfda8aSnia		{"HiShadow", NULL, 0},
560bbfda8aSnia		{"LoShadow", NULL, 0}
570bbfda8aSnia	};
580bbfda8aSnia
590bbfda8aSnia	fullname = ExpandPixmapPath(name);
600bbfda8aSnia	if(! fullname) {
610bbfda8aSnia		return NULL;
620bbfda8aSnia	}
630bbfda8aSnia
640bbfda8aSnia	image = AllocImage();
650bbfda8aSnia	if(image == NULL) {
660bbfda8aSnia		free(fullname);
670bbfda8aSnia		return NULL;
680bbfda8aSnia	}
690bbfda8aSnia
700bbfda8aSnia	attributes.valuemask  = 0;
710bbfda8aSnia	attributes.valuemask |= XpmSize;
720bbfda8aSnia	attributes.valuemask |= XpmReturnPixels;
730bbfda8aSnia	attributes.valuemask |= XpmColormap;
740bbfda8aSnia	attributes.valuemask |= XpmDepth;
750bbfda8aSnia	attributes.valuemask |= XpmVisual;
760bbfda8aSnia	attributes.valuemask |= XpmCloseness;
770bbfda8aSnia	attributes.valuemask |= XpmColorSymbols;
780bbfda8aSnia
790bbfda8aSnia	attributes.numsymbols = 4;
800bbfda8aSnia	attributes.colorsymbols = overrides;
810bbfda8aSnia	overrides[0].pixel = cp.fore;
820bbfda8aSnia	overrides[1].pixel = cp.back;
830bbfda8aSnia	overrides[2].pixel = cp.shadd;
840bbfda8aSnia	overrides[3].pixel = cp.shadc;
850bbfda8aSnia
860bbfda8aSnia
870bbfda8aSnia	attributes.colormap  = AlternateCmap ? AlternateCmap : stdcmap;
880bbfda8aSnia	attributes.depth     = Scr->d_depth;
890bbfda8aSnia	attributes.visual    = Scr->d_visual;
900bbfda8aSnia	attributes.closeness = 65535; /* Never fail */
910bbfda8aSnia	status = XpmReadFileToPixmap(dpy, Scr->Root, fullname,
920bbfda8aSnia	                             &(image->pixmap), &(image->mask), &attributes);
930bbfda8aSnia	if(status != XpmSuccess) {
940bbfda8aSnia		xpmErrorMessage(status, name, fullname);
950bbfda8aSnia		free(fullname);
960bbfda8aSnia		free(image);
970bbfda8aSnia		return NULL;
980bbfda8aSnia	}
990bbfda8aSnia	free(fullname);
1000bbfda8aSnia	image->width  = attributes.width;
1010bbfda8aSnia	image->height = attributes.height;
1020bbfda8aSnia	return image;
1030bbfda8aSnia}
1040bbfda8aSnia
1050bbfda8aSniastatic void
1060bbfda8aSniaxpmErrorMessage(int status, const char *name, const char *fullname)
1070bbfda8aSnia{
1080bbfda8aSnia	switch(status) {
1090bbfda8aSnia		case XpmSuccess:
1100bbfda8aSnia			/* No error */
1110bbfda8aSnia			return;
1120bbfda8aSnia
1130bbfda8aSnia		case XpmColorError:
1140bbfda8aSnia			if(reportxpmerror)
1150bbfda8aSnia				fprintf(stderr,
1160bbfda8aSnia				        "Could not parse or alloc requested color : %s\n",
1170bbfda8aSnia				        fullname);
1180bbfda8aSnia			return;
1190bbfda8aSnia
1200bbfda8aSnia		case XpmOpenFailed:
1210bbfda8aSnia			if(reportxpmerror && reportfilenotfound) {
1220bbfda8aSnia				fprintf(stderr, "unable to locate XPM file : %s\n", fullname);
1230bbfda8aSnia			}
1240bbfda8aSnia			return;
1250bbfda8aSnia
1260bbfda8aSnia		case XpmFileInvalid:
1270bbfda8aSnia			fprintf(stderr, "invalid XPM file : %s\n", fullname);
1280bbfda8aSnia			return;
1290bbfda8aSnia
1300bbfda8aSnia		case XpmNoMemory:
1310bbfda8aSnia			if(reportxpmerror) {
1320bbfda8aSnia				fprintf(stderr, "Not enough memory for XPM file : %s\n", fullname);
1330bbfda8aSnia			}
1340bbfda8aSnia			return;
1350bbfda8aSnia
1360bbfda8aSnia		case XpmColorFailed:
1370bbfda8aSnia			if(reportxpmerror) {
1380bbfda8aSnia				fprintf(stderr, "Color not found in : %s\n", fullname);
1390bbfda8aSnia			}
1400bbfda8aSnia			return;
1410bbfda8aSnia
1420bbfda8aSnia		default :
1430bbfda8aSnia			fprintf(stderr, "Unknown error in : %s\n", fullname);
1440bbfda8aSnia			return;
1450bbfda8aSnia	}
1460bbfda8aSnia}
147