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