LocBitmap.c revision 0cc2eac3
1/* 2 3Copyright 1989, 1998 The Open Group 4 5Permission to use, copy, modify, distribute, and sell this software and its 6documentation for any purpose is hereby granted without fee, provided that 7the above copyright notice appear in all copies and that both that 8copyright notice and this permission notice appear in supporting 9documentation. 10 11The above copyright notice and this permission notice shall be included in 12all copies or substantial portions of the Software. 13 14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 18AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 19CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 20 21Except as contained in this notice, the name of The Open Group shall not be 22used in advertising or otherwise to promote the sale, use or other dealings 23in this Software without prior written authorization from The Open Group. 24 25*/ 26 27/* 28 * Author: Jim Fulton, MIT X Consortium 29 */ 30 31#ifdef HAVE_CONFIG_H 32#include <config.h> 33#endif 34#include <X11/Xlib.h> 35#include <stdlib.h> 36#include <string.h> 37#include <X11/Xresource.h> 38#include <X11/Xutil.h> 39#include <X11/Xmu/CvtCache.h> 40#include <X11/Xmu/Drawing.h> 41#include <X11/Xmu/SysUtil.h> 42 43#ifndef X_NOT_POSIX 44#ifdef _POSIX_SOURCE 45#include <limits.h> 46#else 47#define _POSIX_SOURCE 48#include <limits.h> 49#undef _POSIX_SOURCE 50#endif 51#endif /* X_NOT_POSIX */ 52#ifndef PATH_MAX 53#ifdef WIN32 54#define PATH_MAX 512 55#else 56#include <sys/param.h> 57#endif 58#ifndef PATH_MAX 59#ifdef MAXPATHLEN 60#define PATH_MAX MAXPATHLEN 61#else 62#define PATH_MAX 1024 63#endif 64#endif 65#endif /* PATH_MAX */ 66 67/* 68 * Prototypes 69 */ 70static char **split_path_string(char*); 71 72/* 73 * XmuLocateBitmapFile - read a bitmap file using the normal defaults 74 */ 75 76Pixmap 77XmuLocateBitmapFile(Screen *screen, _Xconst char *name, char *srcname, 78 int srcnamelen, int *widthp, int *heightp, 79 int *xhotp, int *yhotp) 80{ 81 return XmuLocatePixmapFile (screen, name, 82 (unsigned long) 1, (unsigned long) 0, 83 (unsigned int) 1, srcname, srcnamelen, 84 widthp, heightp, xhotp, yhotp); 85} 86 87 88/* 89 * version that reads pixmap data as well as bitmap data 90 */ 91Pixmap 92XmuLocatePixmapFile(Screen *screen, _Xconst char *name, 93 unsigned long fore, unsigned long back, 94 unsigned int depth, 95 char *srcname, int srcnamelen, 96 int *widthp, int *heightp, int *xhotp, int *yhotp) 97{ 98 99#ifndef BITMAPDIR 100#define BITMAPDIR "/usr/include/X11/bitmaps" 101#endif 102 103 Display *dpy = DisplayOfScreen (screen); 104 Window root = RootWindowOfScreen (screen); 105 Bool try_plain_name = True; 106 XmuCvtCache *cache = _XmuCCLookupDisplay (dpy); 107 char **file_paths = (char **) NULL; 108 char filename[PATH_MAX]; 109#if 0 110 char* bitmapdir = BITMAPDIR; 111#endif 112 unsigned int width, height; 113 int xhot, yhot; 114 int i; 115 116 /* 117 * look in cache for bitmap path 118 */ 119 if (cache) { 120 if (!cache->string_to_bitmap.bitmapFilePath) { 121 XrmName xrm_name[2]; 122 XrmClass xrm_class[2]; 123 XrmRepresentation rep_type; 124 XrmValue value; 125 126 xrm_name[0] = XrmPermStringToQuark ("bitmapFilePath"); 127 xrm_name[1] = NULLQUARK; 128 xrm_class[0] = XrmPermStringToQuark ("BitmapFilePath"); 129 xrm_class[1] = NULLQUARK; 130 if (!XrmGetDatabase(dpy)) { 131 /* what a hack; need to initialize it */ 132 (void) XGetDefault (dpy, "", ""); 133 } 134 if (XrmQGetResource (XrmGetDatabase(dpy), xrm_name, xrm_class, 135 &rep_type, &value) && 136 rep_type == XrmPermStringToQuark("String")) { 137 cache->string_to_bitmap.bitmapFilePath = 138 split_path_string (value.addr); 139 } 140 } 141 file_paths = cache->string_to_bitmap.bitmapFilePath; 142 } 143 144 /* 145 * Search order: 146 * 1. name if it begins with / or ./ 147 * 2. "each prefix in file_paths"/name 148 * 3. BITMAPDIR/name 149 * 4. name if didn't begin with / or . 150 */ 151 152 for (i = 1; i <= 4; i++) { 153 char *fn = filename; 154 Pixmap pixmap; 155 unsigned char *data; 156 157 switch (i) { 158 case 1: 159#ifndef __UNIXOS2__ 160 if (!(name[0] == '/' || ((name[0] == '.') && name[1] == '/'))) 161#else 162 if (!(name[0] == '/' || (name[0] == '.' && name[1] == '/') || 163 (isalpha(name[0]) && name[1] == ':'))) 164#endif 165 continue; 166 fn = (char *) name; 167 try_plain_name = False; 168 break; 169 case 2: 170 if (file_paths && *file_paths) { 171 XmuSnprintf(filename, sizeof(filename), 172 "%s/%s", *file_paths, name); 173 file_paths++; 174 i--; 175 break; 176 } 177 continue; 178 case 3: 179 XmuSnprintf(filename, sizeof(filename), "%s/%s", BITMAPDIR, name); 180 break; 181 case 4: 182 if (!try_plain_name) continue; 183 fn = (char *) name; 184 break; 185 } 186 187 data = NULL; 188 pixmap = None; 189#ifdef __UNIXOS2__ 190 fn = (char*)__XOS2RedirRoot(fn); 191#endif 192 if (XmuReadBitmapDataFromFile (fn, &width, &height, &data, 193 &xhot, &yhot) == BitmapSuccess) { 194 pixmap = XCreatePixmapFromBitmapData (dpy, root, (char *) data, 195 width, height, 196 fore, back, depth); 197 XFree ((char *)data); 198 } 199 200 if (pixmap) { 201 if (widthp) *widthp = (int)width; 202 if (heightp) *heightp = (int)height; 203 if (xhotp) *xhotp = xhot; 204 if (yhotp) *yhotp = yhot; 205 if (srcname && srcnamelen > 0) { 206 strncpy (srcname, fn, srcnamelen - 1); 207 srcname[srcnamelen - 1] = '\0'; 208 } 209 return pixmap; 210 } 211 } 212 213 return None; 214} 215 216 217/* 218 * split_path_string - split a colon-separated list into its constituent 219 * parts; to release, free list[0] and list. 220 */ 221static char ** 222split_path_string(register char *src) 223{ 224 int nelems = 1; 225 register char *dst; 226 char **elemlist, **elem; 227 228 /* count the number of elements */ 229 for (dst = src; *dst; dst++) if (*dst == ':') nelems++; 230 231 /* get memory for everything */ 232 dst = (char *) malloc (dst - src + 1); 233 if (!dst) return NULL; 234 elemlist = (char **) calloc ((nelems + 1), sizeof (char *)); 235 if (!elemlist) { 236 free (dst); 237 return NULL; 238 } 239 240 /* copy to new list and walk up nulling colons and setting list pointers */ 241 strcpy (dst, src); 242 for (elem = elemlist, src = dst; *src; src++) { 243 if (*src == ':') { 244 *elem++ = dst; 245 *src = '\0'; 246 dst = src + 1; 247 } 248 } 249 *elem = dst; 250 251 return elemlist; 252} 253 254 255void 256_XmuStringToBitmapInitCache(register XmuCvtCache *c) 257{ 258 c->string_to_bitmap.bitmapFilePath = NULL; 259} 260 261void 262_XmuStringToBitmapFreeCache(register XmuCvtCache *c) 263{ 264 if (c->string_to_bitmap.bitmapFilePath) { 265 if (c->string_to_bitmap.bitmapFilePath[0]) 266 free (c->string_to_bitmap.bitmapFilePath[0]); 267 free ((char *) (c->string_to_bitmap.bitmapFilePath)); 268 } 269} 270