From dafebc5bb70303f0b5baf0b087cf4d9a64b5c7f0 Mon Sep 17 00:00:00 2001 From: marha Date: Mon, 12 Sep 2011 11:27:51 +0200 Subject: Synchronised line endinge with release branch --- libXaw/src/Pixmap.c | 1990 +++++++++++++++++++++++++-------------------------- 1 file changed, 995 insertions(+), 995 deletions(-) (limited to 'libXaw/src/Pixmap.c') diff --git a/libXaw/src/Pixmap.c b/libXaw/src/Pixmap.c index 92880c247..b1718b50f 100644 --- a/libXaw/src/Pixmap.c +++ b/libXaw/src/Pixmap.c @@ -1,995 +1,995 @@ -/* - * 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. - */ - -#ifdef HAVE_CONFIG_H -#include -#endif -#include -#include -#include -#include -#include -#include -#include -#ifndef OLDXAW -#include -#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 (NULL); - - 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) - #ifdef _MSC_VER - sub[0].substitution = "."; - #else - sub[0].substitution = getenv("HOME"); - #endif - 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 */ +/* + * 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. + */ + +#ifdef HAVE_CONFIG_H +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#ifndef OLDXAW +#include +#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 (NULL); + + 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) + #ifdef _MSC_VER + sub[0].substitution = "."; + #else + sub[0].substitution = getenv("HOME"); + #endif + 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 */ -- cgit v1.2.3