Imported Upstream version 1.1.1
[platform/upstream/libXmu.git] / src / LocBitmap.c
1 /*
2
3 Copyright 1989, 1998  The Open Group
4
5 Permission to use, copy, modify, distribute, and sell this software and its
6 documentation for any purpose is hereby granted without fee, provided that
7 the above copyright notice appear in all copies and that both that
8 copyright notice and this permission notice appear in supporting
9 documentation.
10
11 The above copyright notice and this permission notice shall be included in
12 all copies or substantial portions of the Software.
13
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
17 OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20
21 Except as contained in this notice, the name of The Open Group shall not be
22 used in advertising or otherwise to promote the sale, use or other dealings
23 in 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  */
70 static char **split_path_string(char*);
71
72 /*
73  * XmuLocateBitmapFile - read a bitmap file using the normal defaults
74  */
75
76 Pixmap
77 XmuLocateBitmapFile(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  */
91 Pixmap
92 XmuLocatePixmapFile(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  */
221 static char **
222 split_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
255 void
256 _XmuStringToBitmapInitCache(register XmuCvtCache *c)
257 {
258     c->string_to_bitmap.bitmapFilePath = NULL;
259 }
260
261 void
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 }