mirror of
https://github.com/Stichting-MINIX-Research-Foundation/xsrc.git
synced 2025-09-17 16:44:45 -04:00
989 lines
25 KiB
C
989 lines
25 KiB
C
/*
|
|
* Copyright (c) 1998 by The XFree86 Project, Inc.
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
* copy of this software and associated documentation files (the "Software"),
|
|
* to deal in the Software without restriction, including without limitation
|
|
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
* and/or sell copies of the Software, and to permit persons to whom the
|
|
* Software is furnished to do so, subject to the following conditions:
|
|
*
|
|
* The above copyright notice and this permission notice shall be included in
|
|
* all copies or substantial portions of the Software.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
* THE XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
|
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
* SOFTWARE.
|
|
*
|
|
* Except as contained in this notice, the name of the XFree86 Project shall
|
|
* not be used in advertising or otherwise to promote the sale, use or other
|
|
* dealings in this Software without prior written authorization from the
|
|
* XFree86 Project.
|
|
*/
|
|
|
|
/* $XFree86: xc/lib/Xaw/Pixmap.c,v 3.18 2003/03/25 04:18:10 dawes Exp $ */
|
|
|
|
#include <string.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <X11/IntrinsicP.h>
|
|
#include <X11/Xmu/CharSet.h>
|
|
#include <X11/Xfuncs.h>
|
|
#include <X11/extensions/shape.h>
|
|
#include <X11/xpm.h>
|
|
#include "Private.h"
|
|
|
|
#ifdef __UNIXOS2__
|
|
static char dummy;
|
|
#endif
|
|
|
|
#ifndef OLDXAW
|
|
|
|
/*
|
|
* Types
|
|
*/
|
|
typedef struct _XawCache {
|
|
long value;
|
|
XtPointer *elems;
|
|
unsigned int num_elems;
|
|
} XawCache;
|
|
|
|
typedef struct _XawPixmapLoaderInfo {
|
|
XawPixmapLoader loader;
|
|
String type;
|
|
String ext;
|
|
} XawPixmapLoaderInfo;
|
|
|
|
/*
|
|
* Private Methods
|
|
*/
|
|
static Bool BitmapLoader(XawParams*, Screen*, Colormap, int,
|
|
Pixmap*, Pixmap*, Dimension*, Dimension*);
|
|
static Bool GradientLoader(XawParams*, Screen*, Colormap, int,
|
|
Pixmap*, Pixmap*, Dimension*, Dimension*);
|
|
static Bool XPixmapLoader(XawParams*, Screen*, Colormap, int,
|
|
Pixmap*, Pixmap*, Dimension*, Dimension*);
|
|
static XawPixmap *_XawFindPixmap(String, Screen*, Colormap, int);
|
|
static void _XawCachePixmap(XawPixmap*, Screen*, Colormap, int);
|
|
static int _XawFindPixmapLoaderIndex(String, String);
|
|
static int qcmp_long(register _Xconst void*, register _Xconst void *);
|
|
static int bcmp_long(register _Xconst void*, register _Xconst void *);
|
|
static int qcmp_string(register _Xconst void*, register _Xconst void *);
|
|
static int bcmp_string(register _Xconst void*, register _Xconst void *);
|
|
static void GetResourcePixmapPath(Display*);
|
|
|
|
/*
|
|
* Initialization
|
|
*/
|
|
static XawCache xaw_pixmaps;
|
|
static XawCache x_pixmaps; /* for fast reverse search */
|
|
static XawPixmapLoaderInfo **loader_info;
|
|
static Cardinal num_loader_info;
|
|
|
|
/*
|
|
* Implementation
|
|
*/
|
|
Bool
|
|
XawPixmapsInitialize(void)
|
|
{
|
|
static Boolean first_time = True;
|
|
|
|
if (!first_time)
|
|
return (False);
|
|
|
|
(void)XawAddPixmapLoader(NULL, NULL, BitmapLoader);
|
|
(void)XawAddPixmapLoader("bitmap", NULL, BitmapLoader);
|
|
(void)XawAddPixmapLoader("gradient", NULL, GradientLoader);
|
|
(void)XawAddPixmapLoader("xpm", "xpm", XPixmapLoader);
|
|
|
|
return (True);
|
|
}
|
|
|
|
XawParams *
|
|
XawParseParamsString(String name)
|
|
{
|
|
XawParams *xaw_params;
|
|
char *tok, *str, *type = NULL, *ext = NULL, *params = NULL;
|
|
|
|
if (!name)
|
|
return (NULL);
|
|
|
|
xaw_params = (XawParams *)XtMalloc(sizeof(XawParams));
|
|
|
|
str = XtNewString(name);
|
|
|
|
/* Find type */
|
|
tok = str;
|
|
while (tok = strchr(tok, ':'), tok)
|
|
{
|
|
if (tok == str || tok[-1] != '\\')
|
|
break;
|
|
memmove(&tok[-1], tok, strlen(tok) + 1);
|
|
}
|
|
if (tok)
|
|
{
|
|
*tok = '\0';
|
|
if (strchr(str, '?'))
|
|
{
|
|
*tok = ':';
|
|
}
|
|
else
|
|
{
|
|
++tok;
|
|
type = XtNewString(str);
|
|
memmove(str, tok, strlen(tok) + 1);
|
|
}
|
|
}
|
|
|
|
/* Find params */
|
|
tok = str;
|
|
while (tok = strchr(tok, '?'), tok)
|
|
{
|
|
if (tok == str || tok[-1] != '\\')
|
|
params = tok;
|
|
if (tok != str && tok[-1] == '\\')
|
|
memmove(&tok[-1], tok, strlen(tok) + 1);
|
|
else
|
|
break;
|
|
}
|
|
if (params)
|
|
{
|
|
*params = '\0';
|
|
++params;
|
|
}
|
|
|
|
/* Find ext */
|
|
tok = str;
|
|
while (tok = strchr(tok, '.'), tok)
|
|
{
|
|
if (tok == str || tok[-1] != '\\')
|
|
ext = tok;
|
|
if (tok != str && tok[-1] == '\\')
|
|
memmove(&tok[-1], tok, strlen(tok) + 1);
|
|
else
|
|
break;
|
|
}
|
|
if (ext)
|
|
{
|
|
++ext;
|
|
if (strchr(ext, '/'))
|
|
ext = NULL;
|
|
}
|
|
|
|
xaw_params->name = XtNewString(str);
|
|
xaw_params->type = type;
|
|
xaw_params->ext = ext ? XtNewString(ext) : ext;
|
|
xaw_params->args = NULL;
|
|
xaw_params->num_args = 0;
|
|
|
|
/* Parse params */
|
|
if (params)
|
|
{
|
|
char *arg, *val;
|
|
XawArgVal *xaw_arg;
|
|
|
|
for (tok = strtok(params, "&"); tok; tok = strtok(NULL, "&"))
|
|
{
|
|
val = strchr(tok, '=');
|
|
if (val)
|
|
{
|
|
*val = '\0';
|
|
++val;
|
|
if (*val != '\0')
|
|
val = XtNewString(val);
|
|
else
|
|
val = NULL;
|
|
}
|
|
arg = XtNewString(tok);
|
|
xaw_arg = (XawArgVal *)XtMalloc(sizeof(XawArgVal));
|
|
xaw_arg->name = arg;
|
|
xaw_arg->value = val;
|
|
if (!xaw_params->num_args)
|
|
{
|
|
xaw_params->num_args = 1;
|
|
xaw_params->args = (XawArgVal **)
|
|
XtMalloc(sizeof(XawArgVal*));
|
|
}
|
|
else
|
|
{
|
|
++xaw_params->num_args;
|
|
xaw_params->args = (XawArgVal **)
|
|
XtRealloc((char *)xaw_params->args,
|
|
sizeof(XawArgVal*) * xaw_params->num_args);
|
|
}
|
|
xaw_params->args[xaw_params->num_args - 1] = xaw_arg;
|
|
}
|
|
}
|
|
|
|
if (xaw_params->num_args > 1)
|
|
qsort(xaw_params->args, xaw_params->num_args, sizeof(XtPointer),
|
|
qcmp_string);
|
|
|
|
XtFree(str);
|
|
|
|
return (xaw_params);
|
|
}
|
|
|
|
void
|
|
XawFreeParamsStruct(XawParams *params)
|
|
{
|
|
unsigned int i;
|
|
|
|
if (!params)
|
|
return;
|
|
|
|
for (i = 0; i < params->num_args; i++)
|
|
{
|
|
XtFree(params->args[i]->name);
|
|
if (params->args[i]->value)
|
|
XtFree(params->args[i]->value);
|
|
XtFree((char *)params->args[i]);
|
|
}
|
|
|
|
if (params->args)
|
|
XtFree((char *)params->args);
|
|
XtFree((char *)params);
|
|
}
|
|
|
|
XawArgVal *
|
|
XawFindArgVal(XawParams *params, String name)
|
|
{
|
|
XawArgVal **arg_val;
|
|
|
|
if (!params->args)
|
|
return (NULL);
|
|
|
|
arg_val = (XawArgVal **)bsearch((void *)name, params->args,
|
|
params->num_args, sizeof(XtPointer*),
|
|
bcmp_string);
|
|
if (!arg_val)
|
|
return (NULL);
|
|
|
|
return (*arg_val);
|
|
}
|
|
|
|
XawPixmap *
|
|
XawLoadPixmap(String name, Screen *screen, Colormap colormap, int depth)
|
|
{
|
|
int idx;
|
|
Bool success;
|
|
XawPixmap *xaw_pixmap;
|
|
Pixmap pixmap, mask;
|
|
Dimension width, height;
|
|
XawParams *xaw_params;
|
|
|
|
if (!name)
|
|
return (False);
|
|
|
|
xaw_pixmap = _XawFindPixmap(name, screen, colormap, depth);
|
|
|
|
if (xaw_pixmap)
|
|
return (xaw_pixmap);
|
|
|
|
if ((xaw_params = XawParseParamsString(name)) == NULL)
|
|
return (NULL);
|
|
|
|
idx = _XawFindPixmapLoaderIndex(xaw_params->type, xaw_params->ext);
|
|
if (idx < 0)
|
|
return (NULL);
|
|
|
|
#ifdef DIAGNOSTIC
|
|
fprintf(stderr, "(*) Loading pixmap \"%s\": ", name);
|
|
#endif
|
|
|
|
success = loader_info[idx]->loader(xaw_params, screen, colormap, depth,
|
|
&pixmap, &mask, &width, &height);
|
|
if (success)
|
|
{
|
|
xaw_pixmap = (XawPixmap *)XtMalloc(sizeof(XawPixmap));
|
|
xaw_pixmap->name = XtNewString(name);
|
|
xaw_pixmap->pixmap = pixmap;
|
|
xaw_pixmap->mask = mask;
|
|
xaw_pixmap->width = width;
|
|
xaw_pixmap->height = height;
|
|
_XawCachePixmap(xaw_pixmap, screen, colormap, depth);
|
|
}
|
|
|
|
XawFreeParamsStruct(xaw_params);
|
|
|
|
#ifdef DIAGNOSTIC
|
|
fprintf(stderr, "%s", success ? "success\n" : "failed\n");
|
|
#endif
|
|
|
|
return (success ? xaw_pixmap : NULL);
|
|
}
|
|
|
|
Bool
|
|
XawAddPixmapLoader(String type, String ext, XawPixmapLoader loader)
|
|
{
|
|
XawPixmapLoaderInfo *info;
|
|
int i;
|
|
|
|
if (!loader)
|
|
return (False);
|
|
|
|
i = _XawFindPixmapLoaderIndex(type, ext);
|
|
|
|
if (i >= 0)
|
|
{
|
|
loader_info[i]->loader = loader;
|
|
if (loader_info[i]->type)
|
|
XtFree(loader_info[i]->type);
|
|
if (loader_info[i]->ext)
|
|
XtFree(loader_info[i]->ext);
|
|
loader_info[i]->type = type ? XtNewString(type) : NULL;
|
|
loader_info[i]->ext = ext ? XtNewString(ext) : NULL;
|
|
return (True);
|
|
}
|
|
|
|
if ((info = (XawPixmapLoaderInfo *)XtMalloc(sizeof(XawPixmapLoaderInfo)))
|
|
== NULL)
|
|
return (False);
|
|
|
|
info->loader = loader;
|
|
info->type = type ? XtNewString(type) : NULL;
|
|
info->ext = ext ? XtNewString(ext) : NULL;
|
|
|
|
if (!loader_info)
|
|
{
|
|
num_loader_info = 1;
|
|
loader_info = (XawPixmapLoaderInfo**)
|
|
XtMalloc(sizeof(XawPixmapLoaderInfo*));
|
|
}
|
|
else
|
|
{
|
|
++num_loader_info;
|
|
loader_info = (XawPixmapLoaderInfo**)
|
|
XtRealloc((char *)loader_info,
|
|
sizeof(XawPixmapLoaderInfo) * num_loader_info);
|
|
}
|
|
loader_info[num_loader_info - 1] = info;
|
|
|
|
return (True);
|
|
}
|
|
|
|
static int
|
|
_XawFindPixmapLoaderIndex(String type, String ext)
|
|
{
|
|
Cardinal i;
|
|
|
|
if (!loader_info)
|
|
return (-1);
|
|
|
|
for (i = 0; i < num_loader_info; i++)
|
|
if ((type && loader_info[i]->type && strcmp(type, loader_info[i]->type) == 0)
|
|
|| (ext && loader_info[i]->ext && strcmp(ext, loader_info[i]->ext) == 0))
|
|
return ((int)i);
|
|
|
|
if (!type)
|
|
return (0); /* try a bitmap */
|
|
|
|
return (-1);
|
|
}
|
|
|
|
static int
|
|
qcmp_x_cache(register _Xconst void *left, register _Xconst void *right)
|
|
{
|
|
return ((int)((*(XawPixmap **)left)->pixmap) -
|
|
(int)((*(XawPixmap **)right)->pixmap));
|
|
}
|
|
|
|
static int
|
|
bcmp_x_cache(register _Xconst void *pixmap, register _Xconst void *xaw)
|
|
{
|
|
return (int)((long)pixmap - (long)((*(XawPixmap **)xaw)->pixmap));
|
|
}
|
|
|
|
static int
|
|
qcmp_long(register _Xconst void *left, register _Xconst void *right)
|
|
{
|
|
return ((long)((*(XawCache **)left)->value) -
|
|
(long)((*(XawCache **)right)->value));
|
|
}
|
|
|
|
static int
|
|
qcmp_string(register _Xconst void *left, register _Xconst void *right)
|
|
{
|
|
return (strcmp((String)((*(XawCache **)left)->value),
|
|
(String)((*(XawCache **)right)->value)));
|
|
}
|
|
|
|
static int
|
|
bcmp_long(register _Xconst void *value, register _Xconst void *cache)
|
|
{
|
|
return ((long)value - (long)((*(XawCache **)cache)->value));
|
|
}
|
|
|
|
static int
|
|
bcmp_string(register _Xconst void *string,
|
|
register _Xconst void *cache)
|
|
{
|
|
return (strcmp((String)string, (String)((*(XawCache **)cache)->value)));
|
|
}
|
|
|
|
#define FIND_ALL 0
|
|
#define FIND_SCREEN 1
|
|
#define FIND_COLORMAP 2
|
|
#define FIND_DEPTH 3
|
|
static XawCache *
|
|
_XawFindCache(XawCache *xaw,
|
|
Screen *screen, Colormap colormap, int depth, int flags)
|
|
{
|
|
XawCache **cache;
|
|
|
|
if (!xaw->num_elems)
|
|
return (NULL);
|
|
|
|
/* Screen */
|
|
cache = (XawCache **)bsearch(screen, xaw->elems,
|
|
xaw->num_elems, sizeof(XtPointer),
|
|
bcmp_long);
|
|
if (!cache || !(*cache)->num_elems)
|
|
return (NULL);
|
|
if (flags == FIND_SCREEN)
|
|
return (*cache);
|
|
|
|
/* Colormap */
|
|
cache = (XawCache **)bsearch((void *)colormap, (*cache)->elems,
|
|
(*cache)->num_elems, sizeof(XtPointer),
|
|
bcmp_long);
|
|
if (!cache || !(*cache)->num_elems)
|
|
return (NULL);
|
|
if (flags == FIND_COLORMAP)
|
|
return (*cache);
|
|
|
|
/* Depth */
|
|
cache = (XawCache **)bsearch((void *)(long)depth, (*cache)->elems,
|
|
(*cache)->num_elems, sizeof(XtPointer),
|
|
bcmp_long);
|
|
|
|
if (!cache || !(*cache)->num_elems)
|
|
return (NULL);
|
|
return (*cache);
|
|
}
|
|
|
|
static XawCache *
|
|
_XawGetCache(XawCache *xaw, Screen *screen, Colormap colormap, int depth)
|
|
{
|
|
XawCache *s_cache, *c_cache, *d_cache, *cache, *pcache;
|
|
|
|
cache = _XawFindCache(xaw, screen, colormap, depth, FIND_ALL);
|
|
|
|
if (!cache)
|
|
{
|
|
s_cache = _XawFindCache(xaw,
|
|
screen, colormap, depth, FIND_SCREEN);
|
|
if (!s_cache)
|
|
{
|
|
pcache = (XawCache *)XtMalloc(sizeof(XawCache));
|
|
if (!xaw->num_elems)
|
|
{
|
|
xaw->num_elems = 1;
|
|
xaw->elems = (XtPointer*)XtMalloc(sizeof(XtPointer));
|
|
}
|
|
else
|
|
{
|
|
++xaw->num_elems;
|
|
xaw->elems = (XtPointer*)
|
|
XtRealloc((char *)xaw->elems,
|
|
sizeof(XtPointer) * xaw->num_elems);
|
|
}
|
|
pcache->value = (long)screen;
|
|
pcache->elems = NULL;
|
|
pcache->num_elems = 0;
|
|
xaw->elems[xaw->num_elems - 1] = (XtPointer)pcache;
|
|
s_cache = (XawCache *)xaw->elems[xaw->num_elems - 1];
|
|
if (xaw->num_elems > 1)
|
|
qsort(xaw->elems, xaw->num_elems, sizeof(XtPointer), qcmp_long);
|
|
}
|
|
|
|
c_cache = _XawFindCache(xaw,
|
|
screen, colormap, depth, FIND_COLORMAP);
|
|
if (!c_cache)
|
|
{
|
|
pcache = (XawCache *)XtMalloc(sizeof(XawCache));
|
|
if (!s_cache->num_elems)
|
|
{
|
|
s_cache->num_elems = 1;
|
|
s_cache->elems = (XtPointer*)XtMalloc(sizeof(XtPointer));
|
|
}
|
|
else
|
|
{
|
|
++s_cache->num_elems;
|
|
s_cache->elems = (XtPointer*)
|
|
XtRealloc((char *)s_cache->elems,
|
|
sizeof(XtPointer) * s_cache->num_elems);
|
|
}
|
|
pcache->value = (long)colormap;
|
|
pcache->elems = NULL;
|
|
pcache->num_elems = 0;
|
|
s_cache->elems[s_cache->num_elems - 1] = (XtPointer)pcache;
|
|
c_cache = (XawCache *)s_cache->elems[s_cache->num_elems - 1];
|
|
if (s_cache->num_elems > 1)
|
|
qsort(s_cache->elems, s_cache->num_elems,
|
|
sizeof(XtPointer), qcmp_long);
|
|
}
|
|
|
|
d_cache = _XawFindCache(xaw,
|
|
screen, colormap, depth, FIND_DEPTH);
|
|
if (!d_cache)
|
|
{
|
|
pcache = (XawCache *)XtMalloc(sizeof(XawCache));
|
|
if (!c_cache->num_elems)
|
|
{
|
|
c_cache->num_elems = 1;
|
|
c_cache->elems = (XtPointer*)XtMalloc(sizeof(XtPointer));
|
|
}
|
|
else
|
|
{
|
|
++c_cache->num_elems;
|
|
c_cache->elems = (XtPointer*)
|
|
XtRealloc((char *)c_cache->elems,
|
|
sizeof(XtPointer) * c_cache->num_elems);
|
|
}
|
|
pcache->value = (long)depth;
|
|
pcache->elems = NULL;
|
|
pcache->num_elems = 0;
|
|
c_cache->elems[c_cache->num_elems - 1] = (XtPointer)pcache;
|
|
d_cache = (XawCache *)c_cache->elems[c_cache->num_elems - 1];
|
|
if (c_cache->num_elems > 1)
|
|
qsort(c_cache->elems, c_cache->num_elems,
|
|
sizeof(XtPointer), qcmp_long);
|
|
}
|
|
|
|
cache = d_cache;
|
|
}
|
|
|
|
return (cache);
|
|
}
|
|
|
|
static XawPixmap *
|
|
_XawFindPixmap(String name, Screen *screen, Colormap colormap, int depth)
|
|
{
|
|
XawCache *cache;
|
|
XawPixmap **pixmap;
|
|
|
|
cache = _XawFindCache(&xaw_pixmaps, screen, colormap, depth, FIND_ALL);
|
|
|
|
if (!cache)
|
|
return (NULL);
|
|
|
|
/* Name */
|
|
pixmap = (XawPixmap **)bsearch((void *)name, cache->elems,
|
|
cache->num_elems, sizeof(XtPointer),
|
|
bcmp_string);
|
|
if (!pixmap)
|
|
return (NULL);
|
|
|
|
return (*pixmap);
|
|
}
|
|
|
|
XawPixmap *
|
|
XawPixmapFromXPixmap(Pixmap pixmap,
|
|
Screen *screen, Colormap colormap, int depth)
|
|
{
|
|
XawCache *cache;
|
|
XawPixmap **x_pixmap;
|
|
|
|
cache = _XawFindCache(&x_pixmaps, screen, colormap, depth, FIND_ALL);
|
|
|
|
if (!cache)
|
|
return (NULL);
|
|
|
|
/* Pixmap */
|
|
x_pixmap = (XawPixmap **)bsearch((void *)pixmap, cache->elems,
|
|
cache->num_elems, sizeof(XtPointer),
|
|
bcmp_x_cache);
|
|
if (!x_pixmap)
|
|
return (NULL);
|
|
|
|
return (*x_pixmap);
|
|
}
|
|
|
|
static void
|
|
_XawCachePixmap(XawPixmap *pixmap,
|
|
Screen *screen, Colormap colormap, int depth)
|
|
{
|
|
XawCache *xaw_cache, *x_cache;
|
|
|
|
xaw_cache = _XawGetCache(&xaw_pixmaps, screen, colormap, depth);
|
|
x_cache = _XawGetCache(&x_pixmaps, screen, colormap, depth);
|
|
|
|
if (!xaw_cache->num_elems)
|
|
{
|
|
xaw_cache->num_elems = 1;
|
|
xaw_cache->elems = (XtPointer*)XtMalloc(sizeof(XtPointer));
|
|
}
|
|
else
|
|
{
|
|
++xaw_cache->num_elems;
|
|
xaw_cache->elems = (XtPointer*)XtRealloc((char *)xaw_cache->elems,
|
|
sizeof(XtPointer) *
|
|
xaw_cache->num_elems);
|
|
}
|
|
|
|
xaw_cache->elems[xaw_cache->num_elems - 1] = (XtPointer)pixmap;
|
|
if (xaw_cache->num_elems > 1)
|
|
qsort(xaw_cache->elems, xaw_cache->num_elems,
|
|
sizeof(XtPointer), qcmp_string);
|
|
|
|
|
|
if (!x_cache->num_elems)
|
|
{
|
|
x_cache->num_elems = 1;
|
|
x_cache->elems = (XtPointer*)XtMalloc(sizeof(XtPointer));
|
|
}
|
|
else
|
|
{
|
|
++x_cache->num_elems;
|
|
x_cache->elems = (XtPointer*)XtRealloc((char *)x_cache->elems,
|
|
sizeof(XtPointer) *
|
|
x_cache->num_elems);
|
|
}
|
|
|
|
x_cache->elems[x_cache->num_elems - 1] = (XtPointer)pixmap;
|
|
if (x_cache->num_elems > 1)
|
|
qsort(x_cache->elems, x_cache->num_elems, sizeof(XtPointer), qcmp_x_cache);
|
|
}
|
|
|
|
#ifndef PROJECT_ROOT
|
|
#define PROJECT_ROOT "/usr/X11R6"
|
|
#endif
|
|
|
|
static char *pixmap_path = NULL;
|
|
|
|
static void
|
|
GetResourcePixmapPath(Display *display)
|
|
{
|
|
XrmName xrm_name[2];
|
|
XrmClass xrm_class[2];
|
|
XrmRepresentation rep_type;
|
|
XrmValue value;
|
|
static char *default_path =
|
|
"%H/%T/%N:%P/include/X11/%T/%N:/usr/X11R6/include/X11/%T/%N:/usr/include/X11/%T/%N:%N";
|
|
|
|
xrm_name[0] = XrmPermStringToQuark("pixmapFilePath");
|
|
xrm_name[1] = NULLQUARK;
|
|
xrm_class[0] = XrmPermStringToQuark("PixmapFilePath");
|
|
xrm_class[1] = NULLQUARK;
|
|
if (!XrmGetDatabase(display))
|
|
(void) XGetDefault(display, "", "");
|
|
if (XrmQGetResource(XrmGetDatabase(display), xrm_name, xrm_class,
|
|
&rep_type, &value) &&
|
|
rep_type == XrmPermStringToQuark("String")) {
|
|
int length = 0;
|
|
char *tok, *buffer = XtNewString(value.addr);
|
|
|
|
for (tok = strtok(buffer, ":"); tok; tok = strtok(NULL, ":")) {
|
|
int toklen = strlen(tok);
|
|
|
|
if (toklen) {
|
|
pixmap_path = XtRealloc(pixmap_path, length + toklen + 5);
|
|
strcpy(pixmap_path + length, tok);
|
|
if (length)
|
|
pixmap_path[length++] = ':';
|
|
sprintf(pixmap_path + length, "%s/%%N", tok);
|
|
length += strlen(tok) + 3;
|
|
}
|
|
}
|
|
pixmap_path = XtRealloc(pixmap_path, length + strlen(default_path) + 2);
|
|
if (length)
|
|
pixmap_path[length++] = ':';
|
|
strcpy(pixmap_path + length, default_path);
|
|
}
|
|
else
|
|
pixmap_path = default_path;
|
|
}
|
|
|
|
static Bool
|
|
BitmapLoader(XawParams *params, Screen *screen, Colormap colormap, int depth,
|
|
Pixmap *pixmap_return, Pixmap *mask_return,
|
|
Dimension *width_return, Dimension *height_return)
|
|
{
|
|
Pixel fg, bg;
|
|
XColor color, exact;
|
|
Pixmap pixmap;
|
|
unsigned int width, height;
|
|
unsigned char *data = NULL;
|
|
int hotX, hotY;
|
|
XawArgVal *argval;
|
|
Bool retval = False;
|
|
static SubstitutionRec sub[] = {
|
|
{'H', NULL},
|
|
{'N', NULL},
|
|
{'T', "bitmaps"},
|
|
{'P', PROJECT_ROOT},
|
|
};
|
|
char *filename;
|
|
|
|
fg = BlackPixelOfScreen(screen);
|
|
bg = WhitePixelOfScreen(screen);
|
|
|
|
if ((argval = XawFindArgVal(params, "foreground")) != NULL
|
|
&& argval->value)
|
|
{
|
|
if (XAllocNamedColor(DisplayOfScreen(screen), colormap, argval->value,
|
|
&color, &exact))
|
|
fg = color.pixel;
|
|
else
|
|
return (False);
|
|
}
|
|
if ((argval = XawFindArgVal(params, "background")) != NULL
|
|
&& argval->value)
|
|
{
|
|
if (XAllocNamedColor(DisplayOfScreen(screen), colormap, argval->value,
|
|
&color, &exact))
|
|
bg = color.pixel;
|
|
else
|
|
return (False);
|
|
}
|
|
|
|
if (params->name[0] != '/' && params->name[0] != '.')
|
|
{
|
|
if (!sub[0].substitution)
|
|
sub[0].substitution = getenv("HOME");
|
|
sub[1].substitution = params->name;
|
|
if (pixmap_path == NULL)
|
|
GetResourcePixmapPath(DisplayOfScreen(screen));
|
|
filename = XtFindFile(pixmap_path, sub, XtNumber(sub), NULL);
|
|
if (!filename)
|
|
return (FALSE);
|
|
}
|
|
else
|
|
filename = params->name;
|
|
|
|
if (XReadBitmapFileData(filename, &width, &height, &data,
|
|
&hotX, &hotY) == BitmapSuccess)
|
|
{
|
|
pixmap = XCreatePixmapFromBitmapData(DisplayOfScreen(screen),
|
|
RootWindowOfScreen(screen),
|
|
(char *)data,
|
|
width, height, fg, bg, depth);
|
|
if (data)
|
|
XFree(data);
|
|
*pixmap_return = pixmap;
|
|
*mask_return = None;
|
|
*width_return = width;
|
|
*height_return = height;
|
|
|
|
retval = True;
|
|
}
|
|
|
|
if (filename != params->name)
|
|
XtFree(filename);
|
|
|
|
return (retval);
|
|
}
|
|
|
|
#define VERTICAL 1
|
|
#define HORIZONTAL 2
|
|
static Bool
|
|
GradientLoader(XawParams *params, Screen *screen, Colormap colormap, int depth,
|
|
Pixmap *pixmap_return, Pixmap *mask_return,
|
|
Dimension *width_return, Dimension *height_return)
|
|
{
|
|
double ired, igreen, iblue, red, green, blue;
|
|
XColor start, end, color;
|
|
XGCValues values;
|
|
GC gc;
|
|
double i, inc, x, y, xend, yend;
|
|
Pixmap pixmap;
|
|
XawArgVal *argval;
|
|
int orientation, dimension, steps;
|
|
char *value;
|
|
|
|
if (XmuCompareISOLatin1(params->name, "vertical") == 0)
|
|
orientation = VERTICAL;
|
|
else if (XmuCompareISOLatin1(params->name, "horizontal") == 0)
|
|
orientation = HORIZONTAL;
|
|
else
|
|
return (False);
|
|
|
|
if ((argval = XawFindArgVal(params, "dimension")) != NULL
|
|
&& argval->value)
|
|
{
|
|
dimension = atoi(argval->value);
|
|
if (dimension <= 0)
|
|
return (False);
|
|
}
|
|
else
|
|
dimension = 50;
|
|
|
|
if ((argval = XawFindArgVal(params, "steps")) != NULL
|
|
&& argval->value)
|
|
{
|
|
steps = atoi(argval->value);
|
|
if (steps <= 0)
|
|
return (False);
|
|
}
|
|
else
|
|
steps = dimension;
|
|
|
|
steps = XawMin(steps, dimension);
|
|
|
|
value = NULL;
|
|
if ((argval = XawFindArgVal(params, "start")) != NULL)
|
|
value = argval->value;
|
|
if (value && !XAllocNamedColor(DisplayOfScreen(screen), colormap, value,
|
|
&start, &color))
|
|
return (False);
|
|
else if (!value)
|
|
{
|
|
start.pixel = WhitePixelOfScreen(screen);
|
|
XQueryColor(DisplayOfScreen(screen), colormap, &start);
|
|
}
|
|
value = NULL;
|
|
if ((argval = XawFindArgVal(params, "end")) != NULL)
|
|
value = argval->value;
|
|
if (value && !XAllocNamedColor(DisplayOfScreen(screen), colormap, value,
|
|
&end, &color))
|
|
return (False);
|
|
else if (!value)
|
|
{
|
|
end.pixel = BlackPixelOfScreen(screen);
|
|
XQueryColor(DisplayOfScreen(screen), colormap, &end);
|
|
}
|
|
|
|
if ((pixmap = XCreatePixmap(DisplayOfScreen(screen),
|
|
RootWindowOfScreen(screen),
|
|
orientation == VERTICAL ? 1 : dimension,
|
|
orientation == VERTICAL ? dimension : 1, depth))
|
|
== 0)
|
|
return (False);
|
|
|
|
ired = (double)(end.red - start.red) / (double)steps;
|
|
igreen = (double)(end.green - start.green) / (double)steps;
|
|
iblue = (double)(end.blue - start.blue) / (double)steps;
|
|
|
|
red = color.red = start.red;
|
|
green = color.green = start.green;
|
|
blue = color.blue = start.blue;
|
|
|
|
inc = (double)dimension / (double)steps;
|
|
|
|
gc = XCreateGC(DisplayOfScreen(screen), pixmap, 0, &values);
|
|
|
|
x = y = 0.0;
|
|
if (orientation == VERTICAL)
|
|
{
|
|
xend = 1;
|
|
yend = 0;
|
|
}
|
|
else
|
|
{
|
|
xend = 0;
|
|
yend = 1;
|
|
}
|
|
|
|
color.flags = DoRed | DoGreen | DoBlue;
|
|
|
|
XSetForeground(DisplayOfScreen(screen), gc, start.pixel);
|
|
for (i = 0.0; i < dimension; i += inc)
|
|
{
|
|
if ((int)color.red != (int)red || (int)color.green != (int)green
|
|
|| (int)color.blue != (int)blue)
|
|
{
|
|
XFillRectangle(DisplayOfScreen(screen), pixmap, gc, (int)x, (int)y,
|
|
(unsigned int)xend, (unsigned int)yend);
|
|
color.red = (unsigned short)red;
|
|
color.green = (unsigned short)green;
|
|
color.blue = (unsigned short)blue;
|
|
if (!XAllocColor(DisplayOfScreen(screen), colormap, &color))
|
|
{
|
|
XFreePixmap(DisplayOfScreen(screen), pixmap);
|
|
return (False);
|
|
}
|
|
XSetForeground(DisplayOfScreen(screen), gc, color.pixel);
|
|
if (orientation == VERTICAL)
|
|
y = yend;
|
|
else
|
|
x = xend;
|
|
}
|
|
red += ired;
|
|
green += igreen;
|
|
blue += iblue;
|
|
if (orientation == VERTICAL)
|
|
yend += inc;
|
|
else
|
|
xend += inc;
|
|
}
|
|
XFillRectangle(DisplayOfScreen(screen), pixmap, gc, (int)x, (int)y,
|
|
(unsigned int)xend, (unsigned int)yend);
|
|
|
|
*pixmap_return = pixmap;
|
|
*mask_return = None;
|
|
*width_return = orientation == VERTICAL ? 1 : dimension;
|
|
*height_return = orientation == VERTICAL ? dimension : 1;
|
|
|
|
XFreeGC(DisplayOfScreen(screen), gc);
|
|
|
|
return (True);
|
|
}
|
|
|
|
static Bool
|
|
XPixmapLoader(XawParams *params, Screen *screen, Colormap colormap, int depth,
|
|
Pixmap *pixmap_return, Pixmap *mask_return,
|
|
Dimension *width_return, Dimension *height_return)
|
|
{
|
|
XpmAttributes xpm_attributes;
|
|
XawArgVal *argval;
|
|
unsigned int closeness = 4000;
|
|
static SubstitutionRec sub[] = {
|
|
{'H', NULL},
|
|
{'N', NULL},
|
|
{'T', "pixmaps"},
|
|
{'P', PROJECT_ROOT},
|
|
};
|
|
char *filename;
|
|
|
|
if ((argval = XawFindArgVal(params, "closeness")) != NULL
|
|
&& argval->value)
|
|
closeness = atoi(argval->value);
|
|
|
|
if (params->name[0] != '/' && params->name[0] != '.')
|
|
{
|
|
if (!sub[0].substitution)
|
|
sub[0].substitution = getenv("HOME");
|
|
sub[1].substitution = params->name;
|
|
if (pixmap_path == NULL)
|
|
GetResourcePixmapPath(DisplayOfScreen(screen));
|
|
filename = XtFindFile(pixmap_path, sub, XtNumber(sub), NULL);
|
|
if (!filename)
|
|
return (False);
|
|
}
|
|
else
|
|
filename = params->name;
|
|
|
|
xpm_attributes.colormap = colormap;
|
|
xpm_attributes.closeness = closeness;
|
|
xpm_attributes.valuemask = XpmSize | XpmColormap | XpmCloseness;
|
|
if (XpmReadFileToPixmap(DisplayOfScreen(screen),
|
|
RootWindowOfScreen(screen), filename, pixmap_return,
|
|
mask_return, &xpm_attributes) == XpmSuccess)
|
|
{
|
|
*width_return = xpm_attributes.width;
|
|
*height_return = xpm_attributes.height;
|
|
|
|
return (True);
|
|
}
|
|
|
|
return (False);
|
|
}
|
|
|
|
void
|
|
XawReshapeWidget(Widget w, XawPixmap *pixmap)
|
|
{
|
|
if (!pixmap || pixmap->mask == None)
|
|
XShapeCombineMask(XtDisplay(w), XtWindow(w), ShapeBounding, 0, 0,
|
|
None, ShapeSet);
|
|
else
|
|
XShapeCombineMask(XtDisplay(w), XtWindow(w), ShapeBounding, 0, 0,
|
|
pixmap->mask, ShapeSet);
|
|
}
|
|
|
|
#endif /* OLDXAW */
|