1 /* Change for xpbiff by Yoshikazu Yamamoto(y-yamamt@ics.es.osaka-u.ac.jp) at Oct 19, 1993 */ 2 3 /* * Last edited: Sep 17 14:39 1991 (mallet) */ 4 /* 5 * Copyright 1991 Lionel Mallet 6 * 7 * Permission to use, copy, modify, and distribute this software and its 8 * documentation for any purpose and without fee is hereby granted, provided 9 * that the above copyright notice appear in all copies and that both that 10 * copyright notice and this permission notice appear in supporting 11 * documentation, and that the name of Lionel MALLET not be used in advertising 12 * or publicity pertaining to distribution of the software without specific, 13 * written prior permission. Lionel MALLET makes no representations about the 14 * suitability of this software for any purpose. It is provided "as is" 15 * without express or implied warranty. 16 * 17 * Lionel MALLET DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS 18 * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND 19 * FITNESS, IN NO EVENT SHALL Lionel MALLET BE LIABLE FOR ANY SPECIAL, 20 * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER 21 * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION 22 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR 23 * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 24 * 25 * Author: Lionel Mallet - SIMULOG 26 */ 27 28 #include <X11/Xlib.h> 29 #include <X11/Xresource.h> 30 #include <X11/Xutil.h> 31 #include <X11/StringDefs.h> 32 #include <sys/param.h> /* get MAXPATHLEN if possible */ 33 #ifndef MAXPATHLEN 34 #define MAXPATHLEN 256 35 #endif 36 37 #include <X11/Xmu/CvtCache.h> 38 #include <X11/xpm.h> 39 #include <X11/Xmu/Drawing.h> 40 41 42 /* 43 * LocatePixmapFile - read a pixmap file using the normal defaults 44 */ 45 46 static char **split_path_string(); 47 48 Pixmap LocatePixmapFile (screen, name, srcname, srcnamelen, 49 widthp, heightp, mask) 50 Screen *screen; 51 char *name; 52 char *srcname; /* RETURN */ 53 int srcnamelen; 54 int *widthp, *heightp; /* RETURN */ 55 Pixmap *mask; /* RETURN */ 56 { 57 Display *dpy = DisplayOfScreen (screen); 58 Window root = RootWindowOfScreen (screen); 59 Bool try_plain_name = True; 60 XmuCvtCache *cache = _XmuCCLookupDisplay (dpy); 61 char **file_paths; 62 char filename[MAXPATHLEN]; 63 unsigned int width, height; 64 int xhot, yhot; 65 int i; 66 67 68 /* 69 * look in cache for pixmap path 70 */ 71 if (cache) { 72 if (!cache->string_to_bitmap.bitmapFilePath) { 73 XrmName xrm_name[2]; 74 XrmClass xrm_class[2]; 75 XrmRepresentation rep_type; 76 XrmValue value; 77 78 xrm_name[0] = XrmStringToName ("bitmapFilePath"); 79 xrm_name[1] = NULL; 80 xrm_class[0] = XrmStringToClass ("BitmapFilePath"); 81 xrm_class[1] = NULL; 82 /* 83 * XXX - warning, derefing Display * until XDisplayDatabase 84 */ 85 if (!XrmGetDatabase(dpy)) { 86 /* what a hack; need to initialize dpy->db */ 87 (void) XGetDefault (dpy, "", ""); 88 } 89 if (XrmQGetResource (XrmGetDatabase(dpy), xrm_name, xrm_class, 90 &rep_type, &value) && 91 rep_type == XrmStringToQuark(XtRString)) { 92 cache->string_to_bitmap.bitmapFilePath = 93 split_path_string (value.addr); 94 } 95 } 96 file_paths = cache->string_to_bitmap.bitmapFilePath; 97 } 98 99 100 /* 101 * Search order: 102 * 1. name if it begins with / or ./ 103 * 2. "each prefix in file_paths"/name 104 * 3. BITMAPDIR/name 105 * 4. name if didn't begin with / or . 106 */ 107 108 #ifndef BITMAPDIR 109 #define BITMAPDIR "/usr/include/X11/bitmaps" 110 #endif 111 112 for (i = 1; i <= 4; i++) { 113 char *fn = filename; 114 Pixmap pixmap; 115 XpmAttributes attributes; 116 unsigned char *data; 117 118 switch (i) { 119 case 1: 120 if (!(name[0] == '/' || (name[0] == '.') && name[1] == '/')) 121 continue; 122 fn = name; 123 try_plain_name = False; 124 break; 125 case 2: 126 if (file_paths && *file_paths) { 127 sprintf (filename, "%s/%s", *file_paths, name); 128 file_paths++; 129 i--; 130 break; 131 } 132 continue; 133 case 3: 134 sprintf (filename, "%s/%s", BITMAPDIR, name); 135 break; 136 case 4: 137 if (!try_plain_name) continue; 138 fn = name; 139 break; 140 } 141 142 data = NULL; 143 pixmap = None; 144 if (XmuReadBitmapDataFromFile (fn, &width, &height, &data, 145 &xhot, &yhot) == BitmapSuccess) { 146 pixmap = XCreatePixmapFromBitmapData (dpy, root, (char *) data, 147 width, height, 148 (unsigned long) 1, 149 (unsigned long) 0, 150 (unsigned int) 1); 151 XFree ((char *)data); 152 if (pixmap != None) { 153 if (widthp) *widthp = (int)width; 154 if (heightp) *heightp = (int)height; 155 if (srcname && srcnamelen > 0) { 156 strncpy (srcname, fn, srcnamelen - 1); 157 srcname[srcnamelen - 1] = '\0'; 158 } 159 *mask = None; 160 return pixmap; 161 } 162 } 163 attributes.visual = DefaultVisualOfScreen (screen); 164 attributes.colormap = DefaultColormapOfScreen (screen); 165 attributes.depth = DefaultDepthOfScreen (screen); 166 attributes.colorsymbols = (ColorSymbol *)NULL; 167 attributes.numsymbols = 0; 168 attributes.valuemask = XpmVisual | XpmColormap | XpmDepth; 169 if (pixmap == None && 170 XpmReadPixmapFile (dpy, root, fn, &pixmap, mask, 171 &attributes) == XpmPixmapSuccess) { 172 if (widthp) *widthp = (int)attributes.width; 173 if (heightp) *heightp = (int)attributes.height; 174 if (srcname && srcnamelen > 0) { 175 strncpy (srcname, fn, srcnamelen - 1); 176 srcname[srcnamelen - 1] = '\0'; 177 } 178 XpmFreeAttributes(&attributes); 179 return pixmap; 180 } 181 } 182 *mask = None; 183 return None; 184 } 185 186 187 /* 188 * split_path_string - split a colon-separated list into its constituent 189 * parts; to release, free list[0] and list. 190 */ 191 static char **split_path_string (src) 192 register char *src; 193 { 194 int nelems = 1; 195 register char *dst; 196 char **elemlist, **elem; 197 198 /* count the number of elements */ 199 for (dst = src; *dst; dst++) if (*dst == ':') nelems++; 200 201 /* get memory for everything */ 202 dst = (char *) malloc (dst - src + 1); 203 if (!dst) return NULL; 204 elemlist = (char **) calloc ((nelems + 1), sizeof (char *)); 205 if (!elemlist) { 206 free (dst); 207 return NULL; 208 } 209 210 /* copy to new list and walk up nulling colons and setting list pointers */ 211 strcpy (dst, src); 212 for (elem = elemlist, src = dst; *src; src++) { 213 if (*src == ':') { 214 *elem++ = dst; 215 *src = '\0'; 216 dst = src + 1; 217 } 218 } 219 *elem = dst; 220 221 return elemlist; 222 } 223 224 /* 225 void _XmuStringToBitmapInitCache (c) 226 register XmuCvtCache *c; 227 { 228 c->string_to_bitmap.bitmapFilePath = NULL; 229 } 230 231 void _XmuStringToBitmapFreeCache (c) 232 register XmuCvtCache *c; 233 { 234 if (c->string_to_bitmap.bitmapFilePath) { 235 if (c->string_to_bitmap.bitmapFilePath[0]) 236 free (c->string_to_bitmap.bitmapFilePath[0]); 237 free ((char *) (c->string_to_bitmap.bitmapFilePath)); 238 } 239 } 240 */ 241