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