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++) { 1539d0b5e55Smrg const char *fn = filename; 1546c321187Smrg Pixmap pixmap; 1556c321187Smrg unsigned char *data; 1566c321187Smrg 1576c321187Smrg switch (i) { 1586c321187Smrg case 1: 1596c321187Smrg if (!(name[0] == '/' || ((name[0] == '.') && name[1] == '/'))) 1606c321187Smrg continue; 1619d0b5e55Smrg fn = name; 1626c321187Smrg try_plain_name = False; 1636c321187Smrg break; 1646c321187Smrg case 2: 1656c321187Smrg if (file_paths && *file_paths) { 1666c321187Smrg XmuSnprintf(filename, sizeof(filename), 1676c321187Smrg "%s/%s", *file_paths, name); 1686c321187Smrg file_paths++; 1696c321187Smrg i--; 1706c321187Smrg break; 1716c321187Smrg } 1726c321187Smrg continue; 1736c321187Smrg case 3: 1746c321187Smrg XmuSnprintf(filename, sizeof(filename), "%s/%s", BITMAPDIR, name); 1756c321187Smrg break; 1766c321187Smrg case 4: 1776c321187Smrg if (!try_plain_name) continue; 1789d0b5e55Smrg fn = name; 1796c321187Smrg break; 1806c321187Smrg } 1816c321187Smrg 1826c321187Smrg data = NULL; 1836c321187Smrg pixmap = None; 1846c321187Smrg if (XmuReadBitmapDataFromFile (fn, &width, &height, &data, 1856c321187Smrg &xhot, &yhot) == BitmapSuccess) { 1866c321187Smrg pixmap = XCreatePixmapFromBitmapData (dpy, root, (char *) data, 1876c321187Smrg width, height, 1886c321187Smrg fore, back, depth); 1896c321187Smrg XFree ((char *)data); 1906c321187Smrg } 1916c321187Smrg 1926c321187Smrg if (pixmap) { 1936c321187Smrg if (widthp) *widthp = (int)width; 1946c321187Smrg if (heightp) *heightp = (int)height; 1956c321187Smrg if (xhotp) *xhotp = xhot; 1966c321187Smrg if (yhotp) *yhotp = yhot; 1976c321187Smrg if (srcname && srcnamelen > 0) { 1986c321187Smrg strncpy (srcname, fn, srcnamelen - 1); 1996c321187Smrg srcname[srcnamelen - 1] = '\0'; 2006c321187Smrg } 2016c321187Smrg return pixmap; 2026c321187Smrg } 2036c321187Smrg } 2046c321187Smrg 2056c321187Smrg return None; 2066c321187Smrg} 2076c321187Smrg 2086c321187Smrg 2096c321187Smrg/* 2106c321187Smrg * split_path_string - split a colon-separated list into its constituent 2116c321187Smrg * parts; to release, free list[0] and list. 2126c321187Smrg */ 2136c321187Smrgstatic char ** 2146c321187Smrgsplit_path_string(register char *src) 2156c321187Smrg{ 2166c321187Smrg int nelems = 1; 2176c321187Smrg register char *dst; 2186c321187Smrg char **elemlist, **elem; 2196c321187Smrg 2206c321187Smrg /* count the number of elements */ 2216c321187Smrg for (dst = src; *dst; dst++) if (*dst == ':') nelems++; 2226c321187Smrg 2236c321187Smrg /* get memory for everything */ 2249dedec0cSmrg dst = malloc (dst - src + 1); 2256c321187Smrg if (!dst) return NULL; 2269dedec0cSmrg elemlist = calloc ((nelems + 1), sizeof (char *)); 2276c321187Smrg if (!elemlist) { 2286c321187Smrg free (dst); 2296c321187Smrg return NULL; 2306c321187Smrg } 2316c321187Smrg 2326c321187Smrg /* copy to new list and walk up nulling colons and setting list pointers */ 2336c321187Smrg strcpy (dst, src); 2346c321187Smrg for (elem = elemlist, src = dst; *src; src++) { 2356c321187Smrg if (*src == ':') { 2366c321187Smrg *elem++ = dst; 2376c321187Smrg *src = '\0'; 2386c321187Smrg dst = src + 1; 2396c321187Smrg } 2406c321187Smrg } 2416c321187Smrg *elem = dst; 2426c321187Smrg 2436c321187Smrg return elemlist; 2446c321187Smrg} 2456c321187Smrg 2466c321187Smrg 2476c321187Smrgvoid 2486c321187Smrg_XmuStringToBitmapInitCache(register XmuCvtCache *c) 2496c321187Smrg{ 2506c321187Smrg c->string_to_bitmap.bitmapFilePath = NULL; 2516c321187Smrg} 2526c321187Smrg 2536c321187Smrgvoid 2546c321187Smrg_XmuStringToBitmapFreeCache(register XmuCvtCache *c) 2556c321187Smrg{ 2566c321187Smrg if (c->string_to_bitmap.bitmapFilePath) { 2570cc2eac3Smrg if (c->string_to_bitmap.bitmapFilePath[0]) 2586c321187Smrg free (c->string_to_bitmap.bitmapFilePath[0]); 2599dedec0cSmrg free (c->string_to_bitmap.bitmapFilePath); 2606c321187Smrg } 2616c321187Smrg} 262