/*
* $XConsortium: LocBitmap.c,v 1.16 91/07/02 09:09:59 rws Exp $
*
* Copyright 1989 Massachusetts Institute of Technology
*
* Portions Copyright 1991 by the University of Maryland
* College Park, Maryland
* $Id: LocPixmap.c,v 1.7 1991/10/05 08:39:16 cross Exp $
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose and without fee is hereby granted, provided
* that the above copyright notice appear in all copies and that both that
* copyright notice and this permission notice appear in supporting
* documentation, and that the name of M.I.T. not be used in advertising
* or publicity pertaining to distribution of the software without specific,
* written prior permission. M.I.T. makes no representations about the
* suitability of this software for any purpose. It is provided "as is"
* without express or implied warranty.
*
* M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL M.I.T.
* BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* Author: Jim Fulton, MIT X Consortium
*/
/*
* This file is a modified version of mit/lib/Xmu/LocBitmap.c designed to
* work with tvtwm and the additions of Xpm support. This will work when
* compiled with Xpm v3.0 (as distributes on the R5 contrib tape) or higher.
*
* Chris P. Ross
*/
#include <stdlib.h>
#include "twm.h"
#include <X11/Xlib.h>
#include <X11/Xresource.h>
#include <X11/Xutil.h>
#include <X11/Xmu/CvtCache.h>
#include <X11/Xmu/Drawing.h>
#include <X11/xpm.h>
#ifndef X_NOT_POSIX
# ifdef _POSIX_SOURCE
# include <limits.h>
# else
# define _POSIX_SOURCE
# include <limits.h>
# undef _POSIX_SOURCE
# endif
#endif /* X_NOT_POSIX */
#ifndef PATH_MAX
# include <sys/param.h>
# ifdef MAXPATHLEN
# define PATH_MAX MAXPATHLEN
# else
# define PATH_MAX 1024
# endif
#endif /* PATH_MAX */
static char **split_path_string();
/*
* version that reads pixmap data as well as bitmap data
*/
Pixmap XcprLocatePixmapFile (Screen *screen, _Xconst char *name,
unsigned long fore, unsigned long back,
unsigned int depth,
char *srcname, int srcnamelen,
int *widthp, int *heightp, int *xhotp, int *yhotp,
Bool *isXpm, XpmAttributes *attribs, Pixmap *mask)
{
Display *dpy = DisplayOfScreen (screen);
Window root = RootWindowOfScreen (screen);
Bool try_plain_name = True;
XmuCvtCache *cache = _XmuCCLookupDisplay (dpy);
char **file_paths = (char **) NULL;
char filename[PATH_MAX];
unsigned int width, height;
int xhot, yhot;
int i;
int XPMret;
XpmAttributes localAttribs;
/*
* We need to use the attribs...
*/
localAttribs.valuemask = 0;
if (!attribs) {
attribs = &localAttribs;
attribs->valuemask = 0;
}
/*
* Assume a Bitmap...
*/
*isXpm = False; /* xxxmask */
if (mask)
*mask = None;
/*
* look in cache for bitmap path
*/
if (cache) {
if (!cache->string_to_bitmap.bitmapFilePath) {
XrmName xrm_name[2];
XrmClass xrm_class[2];
XrmRepresentation rep_type;
XrmValue value;
/* xrm_name[0] = XrmPermStringToQuark ("bitmapFilePath"); */
xrm_name[0] = XrmStringToQuark ("bitmapFilePath");
xrm_name[1] = NULLQUARK;
/* xrm_class[0] = XrmPermStringToQuark ("BitmapFilePath"); */
xrm_class[0] = XrmStringToQuark ("BitmapFilePath");
xrm_class[1] = NULLQUARK;
if (!XrmGetDatabase(dpy)) {
/* what a hack; need to initialize it */
(void) XGetDefault (dpy, "", "");
}
if (XrmQGetResource (XrmGetDatabase(dpy),
xrm_name, xrm_class,
&rep_type, &value) &&
/* rep_type == XrmPermStringToQuark("String") */
rep_type == XrmStringToQuark("String")
) {
cache->string_to_bitmap.bitmapFilePath =
split_path_string (value.addr);
}
}
file_paths = cache->string_to_bitmap.bitmapFilePath;
}
/*
* Search order:
* 1. name if it begins with / or ./
* 2. "each prefix in file_paths"/name
* 3. BITMAPDIR/name
* 4. name if didn't begin with / or .
*/
#ifndef BITMAPDIR
#define BITMAPDIR "/usr/include/X11/bitmaps"
#endif
for (i = 1; i <= 4; i++) {
char *fn = filename;
Pixmap pixmap;
unsigned char *data;
switch (i) {
case 1:
if (!((name[0] == '/') || ((name[0] == '.') && (name[1] == '/'))))
continue;
fn = (char *) name;
try_plain_name = False;
break;
case 2:
if (file_paths && *file_paths) {
sprintf (filename, "%s/%s", *file_paths, name);
file_paths++;
i--;
break;
}
continue;
case 3:
sprintf (filename, "%s/%s", BITMAPDIR, name);
break;
case 4:
if (!try_plain_name) continue;
fn = (char *) name;
break;
}
XPMret = XpmReadFileToPixmap(dpy, root, fn, &pixmap, mask, attribs);
switch (XPMret) {
case XpmSuccess:
case XpmColorError:
*isXpm = True;
if (widthp) *widthp = (int)attribs->width;
if (heightp) *heightp = (int)attribs->height;
if (attribs->valuemask & XpmHotspot) {
if (xhotp) *xhotp = (int)attribs->x_hotspot;
if (yhotp) *yhotp = (int)attribs->y_hotspot;
}
if (srcname && srcnamelen > 0) {
strncpy (srcname, fn, srcnamelen - 1);
srcname[srcnamelen - 1] = '\0';
}
if (XPMret == XpmColorError)
fprintf(stderr, "%s: Color substitution performed for file \"%s\"\n", ProgramName, fn);
XpmFreeAttributes(&localAttribs);
return pixmap;
break;
case XpmColorFailed:
fprintf(stderr, "%s: Color allocation failed on file \"%s\"\n", ProgramName, fn);
pixmap = None;
if (mask)
*mask = None;
break;
case XpmNoMemory:
fprintf(stderr, "%s: Color allocation failed on file \"%s\"\n", ProgramName, fn);
pixmap = None;
if (mask)
*mask = None;
break;
case XpmOpenFailed:
case XpmFileInvalid:
default:
/* XpmFreeAttributes(&localAttribs); */
data = NULL;
pixmap = None;
if (mask)
*mask = None;
if (XmuReadBitmapDataFromFile (fn, &width, &height,
&data, &xhot, &yhot) == BitmapSuccess) {
pixmap = XCreatePixmapFromBitmapData (dpy, root,
(char *) data, width, height,
fore, back, depth);
XFree ((char *)data);
}
if (pixmap) {
if (widthp) *widthp = (int)width;
if (heightp) *heightp = (int)height;
if (xhotp) *xhotp = xhot;
if (yhotp) *yhotp = yhot;
if (srcname && srcnamelen > 0) {
strncpy (srcname, fn, srcnamelen - 1);
srcname[srcnamelen - 1] = '\0';
}
XpmFreeAttributes(&localAttribs);
return pixmap;
}
break;
}
}
XpmFreeAttributes(&localAttribs);
return None;
}
/*
* split_path_string - split a colon-separated list into its constituent
* parts; to release, free list[0] and list.
*/
static char **split_path_string (src)
register char *src;
{
int nelems = 1;
register char *dst;
char **elemlist, **elem;
/* count the number of elements */
for (dst = src; *dst; dst++) if (*dst == ':') nelems++;
/* get memory for everything */
dst = (char *) malloc (dst - src + 1);
if (!dst) return NULL;
elemlist = (char **) calloc ((nelems + 1), sizeof (char *));
if (!elemlist) {
free (dst);
return NULL;
}
/* copy to new list and walk up nulling colons and setting list pointers */
strcpy (dst, src);
for (elem = elemlist, src = dst; *src; src++) {
if (*src == ':') {
*elem++ = dst;
*src = '\0';
dst = src + 1;
}
}
*elem = dst;
return elemlist;
}
void _XmuStringToBitmapInitCache (c)
register XmuCvtCache *c;
{
c->string_to_bitmap.bitmapFilePath = NULL;
}
void _XmuStringToBitmapFreeCache (c)
register XmuCvtCache *c;
{
if (c->string_to_bitmap.bitmapFilePath) {
if (c->string_to_bitmap.bitmapFilePath[0])
free (c->string_to_bitmap.bitmapFilePath[0]);
free ((char *) (c->string_to_bitmap.bitmapFilePath));
}
}
syntax highlighted by Code2HTML, v. 0.9.1