LocBitmap.c revision 0cc2eac3
16c321187Smrg/*
20cc2eac3Smrg
36c321187SmrgCopyright 1989, 1998  The Open Group
46c321187Smrg
56c321187SmrgPermission to use, copy, modify, distribute, and sell this software and its
66c321187Smrgdocumentation for any purpose is hereby granted without fee, provided that
76c321187Smrgthe above copyright notice appear in all copies and that both that
86c321187Smrgcopyright notice and this permission notice appear in supporting
96c321187Smrgdocumentation.
106c321187Smrg
116c321187SmrgThe above copyright notice and this permission notice shall be included in
126c321187Smrgall copies or substantial portions of the Software.
136c321187Smrg
146c321187SmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
156c321187SmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
166c321187SmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
176c321187SmrgOPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
186c321187SmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
196c321187SmrgCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
206c321187Smrg
216c321187SmrgExcept as contained in this notice, the name of The Open Group shall not be
226c321187Smrgused in advertising or otherwise to promote the sale, use or other dealings
236c321187Smrgin this Software without prior written authorization from The Open Group.
246c321187Smrg
256c321187Smrg*/
266c321187Smrg
276c321187Smrg/*
286c321187Smrg * Author:  Jim Fulton, MIT X Consortium
296c321187Smrg */
306c321187Smrg
316c321187Smrg#ifdef HAVE_CONFIG_H
326c321187Smrg#include <config.h>
336c321187Smrg#endif
346c321187Smrg#include <X11/Xlib.h>
356c321187Smrg#include <stdlib.h>
366c321187Smrg#include <string.h>
376c321187Smrg#include <X11/Xresource.h>
386c321187Smrg#include <X11/Xutil.h>
396c321187Smrg#include <X11/Xmu/CvtCache.h>
406c321187Smrg#include <X11/Xmu/Drawing.h>
416c321187Smrg#include <X11/Xmu/SysUtil.h>
426c321187Smrg
436c321187Smrg#ifndef X_NOT_POSIX
446c321187Smrg#ifdef _POSIX_SOURCE
456c321187Smrg#include <limits.h>
466c321187Smrg#else
476c321187Smrg#define _POSIX_SOURCE
486c321187Smrg#include <limits.h>
496c321187Smrg#undef _POSIX_SOURCE
506c321187Smrg#endif
516c321187Smrg#endif /* X_NOT_POSIX */
526c321187Smrg#ifndef PATH_MAX
536c321187Smrg#ifdef WIN32
546c321187Smrg#define PATH_MAX 512
556c321187Smrg#else
566c321187Smrg#include <sys/param.h>
576c321187Smrg#endif
586c321187Smrg#ifndef PATH_MAX
596c321187Smrg#ifdef MAXPATHLEN
606c321187Smrg#define PATH_MAX MAXPATHLEN
616c321187Smrg#else
626c321187Smrg#define PATH_MAX 1024
636c321187Smrg#endif
646c321187Smrg#endif
656c321187Smrg#endif /* PATH_MAX */
666c321187Smrg
676c321187Smrg/*
686c321187Smrg * Prototypes
696c321187Smrg */
706c321187Smrgstatic char **split_path_string(char*);
716c321187Smrg
726c321187Smrg/*
736c321187Smrg * XmuLocateBitmapFile - read a bitmap file using the normal defaults
746c321187Smrg */
756c321187Smrg
766c321187SmrgPixmap
776c321187SmrgXmuLocateBitmapFile(Screen *screen, _Xconst char *name, char *srcname,
780cc2eac3Smrg			    int srcnamelen, int *widthp, int *heightp,
796c321187Smrg			    int *xhotp, int *yhotp)
806c321187Smrg{
810cc2eac3Smrg    return XmuLocatePixmapFile (screen, name,
826c321187Smrg				(unsigned long) 1, (unsigned long) 0,
836c321187Smrg				(unsigned int) 1, srcname, srcnamelen,
846c321187Smrg				widthp, heightp, xhotp, yhotp);
856c321187Smrg}
866c321187Smrg
876c321187Smrg
886c321187Smrg/*
896c321187Smrg * version that reads pixmap data as well as bitmap data
906c321187Smrg */
916c321187SmrgPixmap
920cc2eac3SmrgXmuLocatePixmapFile(Screen *screen, _Xconst char *name,
930cc2eac3Smrg			    unsigned long fore, unsigned long back,
940cc2eac3Smrg			    unsigned int depth,
956c321187Smrg			    char *srcname, int srcnamelen,
966c321187Smrg			    int *widthp, int *heightp, int *xhotp, int *yhotp)
976c321187Smrg{
986c321187Smrg
996c321187Smrg#ifndef BITMAPDIR
1006c321187Smrg#define BITMAPDIR "/usr/include/X11/bitmaps"
1016c321187Smrg#endif
1026c321187Smrg
1036c321187Smrg    Display *dpy = DisplayOfScreen (screen);
1046c321187Smrg    Window root = RootWindowOfScreen (screen);
1056c321187Smrg    Bool try_plain_name = True;
1066c321187Smrg    XmuCvtCache *cache = _XmuCCLookupDisplay (dpy);
1076c321187Smrg    char **file_paths = (char **) NULL;
1086c321187Smrg    char filename[PATH_MAX];
1096c321187Smrg#if 0
1106c321187Smrg    char* bitmapdir = BITMAPDIR;
1116c321187Smrg#endif
1126c321187Smrg    unsigned int width, height;
1136c321187Smrg    int xhot, yhot;
1146c321187Smrg    int i;
1156c321187Smrg
1166c321187Smrg    /*
1176c321187Smrg     * look in cache for bitmap path
1186c321187Smrg     */
1196c321187Smrg    if (cache) {
1206c321187Smrg	if (!cache->string_to_bitmap.bitmapFilePath) {
1216c321187Smrg	    XrmName xrm_name[2];
1226c321187Smrg	    XrmClass xrm_class[2];
1236c321187Smrg	    XrmRepresentation rep_type;
1246c321187Smrg	    XrmValue value;
1256c321187Smrg
1266c321187Smrg	    xrm_name[0] = XrmPermStringToQuark ("bitmapFilePath");
1276c321187Smrg	    xrm_name[1] = NULLQUARK;
1286c321187Smrg	    xrm_class[0] = XrmPermStringToQuark ("BitmapFilePath");
1296c321187Smrg	    xrm_class[1] = NULLQUARK;
1306c321187Smrg	    if (!XrmGetDatabase(dpy)) {
1316c321187Smrg		/* what a hack; need to initialize it */
1326c321187Smrg		(void) XGetDefault (dpy, "", "");
1336c321187Smrg	    }
1340cc2eac3Smrg	    if (XrmQGetResource (XrmGetDatabase(dpy), xrm_name, xrm_class,
1356c321187Smrg				 &rep_type, &value) &&
1366c321187Smrg		rep_type == XrmPermStringToQuark("String")) {
1370cc2eac3Smrg		cache->string_to_bitmap.bitmapFilePath =
1386c321187Smrg		  split_path_string (value.addr);
1396c321187Smrg	    }
1406c321187Smrg	}
1416c321187Smrg	file_paths = cache->string_to_bitmap.bitmapFilePath;
1426c321187Smrg    }
1436c321187Smrg
1446c321187Smrg    /*
1456c321187Smrg     * Search order:
1466c321187Smrg     *    1.  name if it begins with / or ./
1476c321187Smrg     *    2.  "each prefix in file_paths"/name
1486c321187Smrg     *    3.  BITMAPDIR/name
1496c321187Smrg     *    4.  name if didn't begin with / or .
1506c321187Smrg     */
1516c321187Smrg
1526c321187Smrg    for (i = 1; i <= 4; i++) {
1536c321187Smrg	char *fn = filename;
1546c321187Smrg	Pixmap pixmap;
1556c321187Smrg	unsigned char *data;
1566c321187Smrg
1576c321187Smrg	switch (i) {
1586c321187Smrg	  case 1:
1596c321187Smrg#ifndef __UNIXOS2__
1606c321187Smrg	    if (!(name[0] == '/' || ((name[0] == '.') && name[1] == '/')))
1616c321187Smrg#else
1626c321187Smrg	    if (!(name[0] == '/' || (name[0] == '.' && name[1] == '/') ||
1636c321187Smrg		  (isalpha(name[0]) && name[1] == ':')))
1646c321187Smrg#endif
1656c321187Smrg	      continue;
1666c321187Smrg	    fn = (char *) name;
1676c321187Smrg	    try_plain_name = False;
1686c321187Smrg	    break;
1696c321187Smrg	  case 2:
1706c321187Smrg	    if (file_paths && *file_paths) {
1716c321187Smrg		XmuSnprintf(filename, sizeof(filename),
1726c321187Smrg			    "%s/%s", *file_paths, name);
1736c321187Smrg		file_paths++;
1746c321187Smrg		i--;
1756c321187Smrg		break;
1766c321187Smrg	    }
1776c321187Smrg	    continue;
1786c321187Smrg	  case 3:
1796c321187Smrg	    XmuSnprintf(filename, sizeof(filename), "%s/%s", BITMAPDIR, name);
1806c321187Smrg	    break;
1816c321187Smrg	  case 4:
1826c321187Smrg	    if (!try_plain_name) continue;
1836c321187Smrg	    fn = (char *) name;
1846c321187Smrg	    break;
1856c321187Smrg	}
1866c321187Smrg
1876c321187Smrg	data = NULL;
1886c321187Smrg	pixmap = None;
1896c321187Smrg#ifdef __UNIXOS2__
1906c321187Smrg	fn = (char*)__XOS2RedirRoot(fn);
1916c321187Smrg#endif
1926c321187Smrg	if (XmuReadBitmapDataFromFile (fn, &width, &height, &data,
1936c321187Smrg				       &xhot, &yhot) == BitmapSuccess) {
1946c321187Smrg	    pixmap = XCreatePixmapFromBitmapData (dpy, root, (char *) data,
1956c321187Smrg						  width, height,
1966c321187Smrg						  fore, back, depth);
1976c321187Smrg	    XFree ((char *)data);
1986c321187Smrg	}
1996c321187Smrg
2006c321187Smrg	if (pixmap) {
2016c321187Smrg	    if (widthp) *widthp = (int)width;
2026c321187Smrg	    if (heightp) *heightp = (int)height;
2036c321187Smrg	    if (xhotp) *xhotp = xhot;
2046c321187Smrg	    if (yhotp) *yhotp = yhot;
2056c321187Smrg	    if (srcname && srcnamelen > 0) {
2066c321187Smrg		strncpy (srcname, fn, srcnamelen - 1);
2076c321187Smrg		srcname[srcnamelen - 1] = '\0';
2086c321187Smrg	    }
2096c321187Smrg	    return pixmap;
2106c321187Smrg	}
2116c321187Smrg    }
2126c321187Smrg
2136c321187Smrg    return None;
2146c321187Smrg}
2156c321187Smrg
2166c321187Smrg
2176c321187Smrg/*
2186c321187Smrg * split_path_string - split a colon-separated list into its constituent
2196c321187Smrg * parts; to release, free list[0] and list.
2206c321187Smrg */
2216c321187Smrgstatic char **
2226c321187Smrgsplit_path_string(register char *src)
2236c321187Smrg{
2246c321187Smrg    int nelems = 1;
2256c321187Smrg    register char *dst;
2266c321187Smrg    char **elemlist, **elem;
2276c321187Smrg
2286c321187Smrg    /* count the number of elements */
2296c321187Smrg    for (dst = src; *dst; dst++) if (*dst == ':') nelems++;
2306c321187Smrg
2316c321187Smrg    /* get memory for everything */
2326c321187Smrg    dst = (char *) malloc (dst - src + 1);
2336c321187Smrg    if (!dst) return NULL;
2346c321187Smrg    elemlist = (char **) calloc ((nelems + 1), sizeof (char *));
2356c321187Smrg    if (!elemlist) {
2366c321187Smrg	free (dst);
2376c321187Smrg	return NULL;
2386c321187Smrg    }
2396c321187Smrg
2406c321187Smrg    /* copy to new list and walk up nulling colons and setting list pointers */
2416c321187Smrg    strcpy (dst, src);
2426c321187Smrg    for (elem = elemlist, src = dst; *src; src++) {
2436c321187Smrg	if (*src == ':') {
2446c321187Smrg	    *elem++ = dst;
2456c321187Smrg	    *src = '\0';
2466c321187Smrg	    dst = src + 1;
2476c321187Smrg	}
2486c321187Smrg    }
2496c321187Smrg    *elem = dst;
2506c321187Smrg
2516c321187Smrg    return elemlist;
2526c321187Smrg}
2536c321187Smrg
2546c321187Smrg
2556c321187Smrgvoid
2566c321187Smrg_XmuStringToBitmapInitCache(register XmuCvtCache *c)
2576c321187Smrg{
2586c321187Smrg    c->string_to_bitmap.bitmapFilePath = NULL;
2596c321187Smrg}
2606c321187Smrg
2616c321187Smrgvoid
2626c321187Smrg_XmuStringToBitmapFreeCache(register XmuCvtCache *c)
2636c321187Smrg{
2646c321187Smrg    if (c->string_to_bitmap.bitmapFilePath) {
2650cc2eac3Smrg	if (c->string_to_bitmap.bitmapFilePath[0])
2666c321187Smrg	  free (c->string_to_bitmap.bitmapFilePath[0]);
2676c321187Smrg	free ((char *) (c->string_to_bitmap.bitmapFilePath));
2686c321187Smrg    }
2696c321187Smrg}
270