1/* 2 * XPM image handling functions 3 */ 4 5#include "ctwm.h" 6 7#include <stdio.h> 8#include <stdlib.h> 9#include <string.h> 10 11#include <X11/xpm.h> 12 13#include "screen.h" 14 15#include "image.h" 16#include "image_xpm.h" 17 18static Image *LoadXpmImage(const char *name, ColorPair cp); 19static void xpmErrorMessage(int status, const char *name, const char *fullname); 20 21static int reportxpmerror = 1; 22 23 24/* 25 * External entry point 26 */ 27Image * 28GetXpmImage(const char *name, ColorPair cp) 29{ 30 /* For non-animated requests, just load the file */ 31 if(! strchr(name, '%')) { 32 return LoadXpmImage(name, cp); 33 } 34 35 /* Else it's animated, so load/return the series */ 36 return get_image_anim_cp(name, cp, LoadXpmImage); 37} 38 39 40 41/* 42 * Internal backend 43 */ 44static Image * 45LoadXpmImage(const char *name, ColorPair cp) 46{ 47 char *fullname; 48 Image *image; 49 int status; 50 Colormap stdcmap = Scr->RootColormaps.cwins[0]->colormap->c; 51 XpmAttributes attributes; 52 static XpmColorSymbol overrides[] = { 53 {"Foreground", NULL, 0}, 54 {"Background", NULL, 0}, 55 {"HiShadow", NULL, 0}, 56 {"LoShadow", NULL, 0} 57 }; 58 59 fullname = ExpandPixmapPath(name); 60 if(! fullname) { 61 return NULL; 62 } 63 64 image = AllocImage(); 65 if(image == NULL) { 66 free(fullname); 67 return NULL; 68 } 69 70 attributes.valuemask = 0; 71 attributes.valuemask |= XpmSize; 72 attributes.valuemask |= XpmReturnPixels; 73 attributes.valuemask |= XpmColormap; 74 attributes.valuemask |= XpmDepth; 75 attributes.valuemask |= XpmVisual; 76 attributes.valuemask |= XpmCloseness; 77 attributes.valuemask |= XpmColorSymbols; 78 79 attributes.numsymbols = 4; 80 attributes.colorsymbols = overrides; 81 overrides[0].pixel = cp.fore; 82 overrides[1].pixel = cp.back; 83 overrides[2].pixel = cp.shadd; 84 overrides[3].pixel = cp.shadc; 85 86 87 attributes.colormap = AlternateCmap ? AlternateCmap : stdcmap; 88 attributes.depth = Scr->d_depth; 89 attributes.visual = Scr->d_visual; 90 attributes.closeness = 65535; /* Never fail */ 91 status = XpmReadFileToPixmap(dpy, Scr->Root, fullname, 92 &(image->pixmap), &(image->mask), &attributes); 93 if(status != XpmSuccess) { 94 xpmErrorMessage(status, name, fullname); 95 free(fullname); 96 free(image); 97 return NULL; 98 } 99 free(fullname); 100 image->width = attributes.width; 101 image->height = attributes.height; 102 return image; 103} 104 105static void 106xpmErrorMessage(int status, const char *name, const char *fullname) 107{ 108 switch(status) { 109 case XpmSuccess: 110 /* No error */ 111 return; 112 113 case XpmColorError: 114 if(reportxpmerror) 115 fprintf(stderr, 116 "Could not parse or alloc requested color : %s\n", 117 fullname); 118 return; 119 120 case XpmOpenFailed: 121 if(reportxpmerror && reportfilenotfound) { 122 fprintf(stderr, "unable to locate XPM file : %s\n", fullname); 123 } 124 return; 125 126 case XpmFileInvalid: 127 fprintf(stderr, "invalid XPM file : %s\n", fullname); 128 return; 129 130 case XpmNoMemory: 131 if(reportxpmerror) { 132 fprintf(stderr, "Not enough memory for XPM file : %s\n", fullname); 133 } 134 return; 135 136 case XpmColorFailed: 137 if(reportxpmerror) { 138 fprintf(stderr, "Color not found in : %s\n", fullname); 139 } 140 return; 141 142 default : 143 fprintf(stderr, "Unknown error in : %s\n", fullname); 144 return; 145 } 146} 147