/*
* 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.17 2002/05/18 02:05:39 paulo Exp $ */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#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>
#ifndef OLDXAW
#include <X11/xpm.h>
#endif
#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 */
|