Home | History | Annotate | Line # | Download | only in src
      1 /*
      2  * Copyright (c) 1998 by The XFree86 Project, Inc.
      3  *
      4  * Permission is hereby granted, free of charge, to any person obtaining a
      5  * copy of this software and associated documentation files (the "Software"),
      6  * to deal in the Software without restriction, including without limitation
      7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      8  * and/or sell copies of the Software, and to permit persons to whom the
      9  * Software is furnished to do so, subject to the following conditions:
     10  *
     11  * The above copyright notice and this permission notice shall be included in
     12  * all copies or substantial portions of the Software.
     13  *
     14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     17  * THE XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
     18  * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
     19  * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
     20  * SOFTWARE.
     21  *
     22  * Except as contained in this notice, the name of the XFree86 Project shall
     23  * not be used in advertising or otherwise to promote the sale, use or other
     24  * dealings in this Software without prior written authorization from the
     25  * XFree86 Project.
     26  */
     27 
     28 #ifdef HAVE_CONFIG_H
     29 #include <config.h>
     30 #endif
     31 #include <string.h>
     32 #include <stdio.h>
     33 #include <stdlib.h>
     34 #include <X11/IntrinsicP.h>
     35 #include <X11/Xmu/CharSet.h>
     36 #include <X11/Xfuncs.h>
     37 #include <X11/extensions/shape.h>
     38 #ifndef OLDXAW
     39 #include <X11/xpm.h>
     40 #endif
     41 #include "Private.h"
     42 
     43 
     44 #ifndef OLDXAW
     45 
     46 /*
     47  * Types
     48  */
     49 typedef struct _XawCache {
     50   long value;
     51   XtPointer *elems;
     52   unsigned int num_elems;
     53 } XawCache;
     54 
     55 typedef struct _XawPixmapLoaderInfo {
     56   XawPixmapLoader loader;
     57   String type;
     58   String ext;
     59 } XawPixmapLoaderInfo;
     60 
     61 /*
     62  * Private Methods
     63  */
     64 static Bool BitmapLoader(XawParams*, Screen*, Colormap, int,
     65 			    Pixmap*, Pixmap*, Dimension*, Dimension*);
     66 static Bool GradientLoader(XawParams*, Screen*, Colormap, int,
     67 			      Pixmap*, Pixmap*, Dimension*, Dimension*);
     68 static Bool XPixmapLoader(XawParams*, Screen*, Colormap, int,
     69 			  Pixmap*, Pixmap*, Dimension*, Dimension*);
     70 static XawPixmap *_XawFindPixmap(String, Screen*, Colormap, int);
     71 static void _XawCachePixmap(XawPixmap*, Screen*, Colormap, int);
     72 static int _XawFindPixmapLoaderIndex(String, String);
     73 static int qcmp_long(register _Xconst void*, register _Xconst void *);
     74 static int bcmp_long(register _Xconst void*, register _Xconst void *);
     75 static int qcmp_string(register _Xconst void*, register _Xconst void *);
     76 static int bcmp_string(register _Xconst void*, register _Xconst void *);
     77 static void GetResourcePixmapPath(Display*);
     78 
     79 /*
     80  * Initialization
     81  */
     82 static XawCache xaw_pixmaps;
     83 static XawCache x_pixmaps;   /* for fast reverse search */
     84 static XawPixmapLoaderInfo **loader_info;
     85 static Cardinal num_loader_info;
     86 
     87 /*
     88  * Implementation
     89  */
     90 Bool
     91 XawPixmapsInitialize(void)
     92 {
     93   static Boolean first_time = True;
     94 
     95   if (!first_time)
     96     return (False);
     97 
     98   (void)XawAddPixmapLoader(NULL, NULL, BitmapLoader);
     99   (void)XawAddPixmapLoader("bitmap", NULL, BitmapLoader);
    100   (void)XawAddPixmapLoader("gradient", NULL, GradientLoader);
    101   (void)XawAddPixmapLoader("xpm", "xpm", XPixmapLoader);
    102 
    103   return (True);
    104 }
    105 
    106 XawParams *
    107 XawParseParamsString(String name)
    108 {
    109   XawParams *xaw_params;
    110   char *tok, *str, *type = NULL, *ext = NULL, *params = NULL;
    111 
    112   if (!name)
    113     return (NULL);
    114 
    115   xaw_params = (XawParams *)XtMalloc(sizeof(XawParams));
    116 
    117   str = XtNewString(name);
    118 
    119   /* Find type */
    120   tok = str;
    121   while (tok = strchr(tok, ':'), tok)
    122     {
    123       if (tok == str || tok[-1] != '\\')
    124 	break;
    125       memmove(&tok[-1], tok, strlen(tok) + 1);
    126     }
    127   if (tok)
    128     {
    129       *tok = '\0';
    130       if (strchr(str, '?'))
    131 	{
    132 	  *tok = ':';
    133 	}
    134       else
    135 	{
    136 	  ++tok;
    137 	  type = XtNewString(str);
    138 	  memmove(str, tok, strlen(tok) + 1);
    139 	}
    140     }
    141 
    142   /* Find params */
    143   tok = str;
    144   while (tok = strchr(tok, '?'), tok)
    145     {
    146       if (tok == str || tok[-1] != '\\')
    147 	params = tok;
    148       if (tok != str && tok[-1] == '\\')
    149 	memmove(&tok[-1], tok, strlen(tok) + 1);
    150       else
    151 	break;
    152     }
    153   if (params)
    154     {
    155       *params = '\0';
    156       ++params;
    157     }
    158 
    159   /* Find ext */
    160   tok = str;
    161   while (tok = strchr(tok, '.'), tok)
    162     {
    163       if (tok == str || tok[-1] != '\\')
    164 	ext = tok;
    165       if (tok != str && tok[-1] == '\\')
    166 	memmove(&tok[-1], tok, strlen(tok) + 1);
    167       else
    168 	break;
    169     }
    170   if (ext)
    171     {
    172       ++ext;
    173       if (strchr(ext, '/'))
    174 	ext = NULL;
    175     }
    176 
    177   xaw_params->name = XtNewString(str);
    178   xaw_params->type = type;
    179   xaw_params->ext = ext ? XtNewString(ext) : ext;
    180   xaw_params->args = NULL;
    181   xaw_params->num_args = 0;
    182 
    183   /* Parse params */
    184   if (params)
    185     {
    186       char *arg, *val;
    187       XawArgVal *xaw_arg;
    188 
    189       for (tok = strtok(params, "&"); tok; tok = strtok(NULL, "&"))
    190 	{
    191 	  val = strchr(tok, '=');
    192 	  if (val)
    193 	    {
    194 	      *val = '\0';
    195 	      ++val;
    196 	      if (*val != '\0')
    197 		val = XtNewString(val);
    198 	      else
    199 		val = NULL;
    200 	    }
    201 	  arg = XtNewString(tok);
    202 	  xaw_arg = (XawArgVal *)XtMalloc(sizeof(XawArgVal));
    203 	  xaw_arg->name = arg;
    204 	  xaw_arg->value = val;
    205 	  if (!xaw_params->num_args)
    206 	    {
    207 	      xaw_params->num_args = 1;
    208 	      xaw_params->args = (XawArgVal **)
    209 		XtMalloc(sizeof(XawArgVal*));
    210 	    }
    211 	  else
    212 	    {
    213 	      ++xaw_params->num_args;
    214 	      xaw_params->args = (XawArgVal **)
    215 		XtRealloc((char *)xaw_params->args,
    216 			  (Cardinal)(sizeof(XawArgVal*) * (size_t)xaw_params->num_args));
    217 	    }
    218 	  xaw_params->args[xaw_params->num_args - 1] = xaw_arg;
    219 	}
    220     }
    221 
    222   if (xaw_params->num_args > 1)
    223     qsort(xaw_params->args, xaw_params->num_args, sizeof(XtPointer),
    224 	  qcmp_string);
    225 
    226   XtFree(str);
    227 
    228   return (xaw_params);
    229 }
    230 
    231 void
    232 XawFreeParamsStruct(XawParams *params)
    233 {
    234   unsigned int i;
    235 
    236   if (!params)
    237     return;
    238 
    239   for (i = 0; i < params->num_args; i++)
    240     {
    241       XtFree((char *)params->args[i]->name);
    242       if (params->args[i]->value)
    243 	XtFree((char *)params->args[i]->value);
    244       XtFree((char *)params->args[i]);
    245     }
    246 
    247   if (params->args)
    248     XtFree((char *)params->args);
    249   XtFree((char *)params);
    250 }
    251 
    252 XawArgVal *
    253 XawFindArgVal(XawParams *params, String name)
    254 {
    255   XawArgVal **arg_val;
    256 
    257   if (!params->args)
    258     return (NULL);
    259 
    260   arg_val = (XawArgVal **)bsearch((void *)name, params->args,
    261 				  params->num_args, sizeof(XtPointer*),
    262 				  bcmp_string);
    263   if (!arg_val)
    264     return (NULL);
    265 
    266   return (*arg_val);
    267 }
    268 
    269 XawPixmap *
    270 XawLoadPixmap(String name, Screen *screen, Colormap colormap, int depth)
    271 {
    272   int idx;
    273   Bool success;
    274   XawPixmap *xaw_pixmap;
    275   Pixmap pixmap, mask;
    276   Dimension width, height;
    277   XawParams *xaw_params;
    278 
    279   if (!name)
    280     return (NULL);
    281 
    282   xaw_pixmap = _XawFindPixmap(name, screen, colormap, depth);
    283 
    284   if (xaw_pixmap)
    285     return (xaw_pixmap);
    286 
    287   if ((xaw_params = XawParseParamsString(name)) == NULL)
    288     return (NULL);
    289 
    290   idx = _XawFindPixmapLoaderIndex(xaw_params->type, xaw_params->ext);
    291   if (idx < 0)
    292     return (NULL);
    293 
    294 #ifdef DIAGNOSTIC
    295   fprintf(stderr, "(*) Loading pixmap \"%s\": ", name);
    296 #endif
    297 
    298   success = loader_info[idx]->loader(xaw_params, screen, colormap, depth,
    299 				       &pixmap, &mask, &width, &height);
    300   if (success)
    301     {
    302       xaw_pixmap = (XawPixmap *)XtMalloc(sizeof(XawPixmap));
    303       xaw_pixmap->name = XtNewString(name);
    304       xaw_pixmap->pixmap = pixmap;
    305       xaw_pixmap->mask = mask;
    306       xaw_pixmap->width = width;
    307       xaw_pixmap->height = height;
    308       _XawCachePixmap(xaw_pixmap, screen, colormap, depth);
    309     }
    310 
    311   XawFreeParamsStruct(xaw_params);
    312 
    313 #ifdef DIAGNOSTIC
    314   fprintf(stderr, "%s", success ? "success\n" : "failed\n");
    315 #endif
    316 
    317   return (success ? xaw_pixmap : NULL);
    318 }
    319 
    320 Bool
    321 XawAddPixmapLoader(String type, String ext, XawPixmapLoader loader)
    322 {
    323   XawPixmapLoaderInfo *info;
    324   int i;
    325 
    326   if (!loader)
    327     return (False);
    328 
    329   i = _XawFindPixmapLoaderIndex(type, ext);
    330 
    331   if (i >= 0)
    332     {
    333       loader_info[i]->loader = loader;
    334       if (loader_info[i]->type)
    335 	XtFree((char *)loader_info[i]->type);
    336       if (loader_info[i]->ext)
    337 	XtFree((char *)loader_info[i]->ext);
    338       loader_info[i]->type = type ? XtNewString(type) : NULL;
    339       loader_info[i]->ext = ext ? XtNewString(ext) : NULL;
    340       return (True);
    341     }
    342 
    343   if ((info = (XawPixmapLoaderInfo *)XtMalloc(sizeof(XawPixmapLoaderInfo)))
    344       == NULL)
    345     return (False);
    346 
    347   info->loader = loader;
    348   info->type = type ? XtNewString(type) : NULL;
    349   info->ext = ext ? XtNewString(ext) : NULL;
    350 
    351   if (!loader_info)
    352     {
    353       num_loader_info = 1;
    354       loader_info = (XawPixmapLoaderInfo**)
    355 	XtMalloc(sizeof(XawPixmapLoaderInfo*));
    356     }
    357   else
    358     {
    359       ++num_loader_info;
    360       loader_info = (XawPixmapLoaderInfo**)
    361 	XtRealloc((char *)loader_info,
    362 		  (Cardinal)(sizeof(XawPixmapLoaderInfo) * (size_t)num_loader_info));
    363     }
    364   loader_info[num_loader_info - 1] = info;
    365 
    366   return (True);
    367 }
    368 
    369 static int
    370 _XawFindPixmapLoaderIndex(String type, String ext)
    371 {
    372   Cardinal i;
    373 
    374   if (!loader_info)
    375     return (-1);
    376 
    377   for (i = 0; i < num_loader_info; i++)
    378     if ((type && loader_info[i]->type && strcmp(type, loader_info[i]->type) == 0)
    379 	|| (ext && loader_info[i]->ext && strcmp(ext, loader_info[i]->ext) == 0))
    380       return ((int)i);
    381 
    382   if (!type)
    383     return (0);	/* try a bitmap */
    384 
    385   return (-1);
    386 }
    387 
    388 static int
    389 qcmp_x_cache(register _Xconst void *left, register _Xconst void *right)
    390 {
    391   return ((int)((*(XawPixmap **)left)->pixmap) -
    392 	  (int)((*(XawPixmap **)right)->pixmap));
    393 }
    394 
    395 static int
    396 bcmp_x_cache(register _Xconst void *pixmap, register _Xconst void *xaw)
    397 {
    398   return (int)((long)pixmap - (long)((*(XawPixmap **)xaw)->pixmap));
    399 }
    400 
    401 static int
    402 qcmp_long(register _Xconst void *left, register _Xconst void *right)
    403 {
    404   return (int)((long)((*(XawCache **)left)->value) -
    405 	       (long)((*(XawCache **)right)->value));
    406 }
    407 
    408 static int
    409 qcmp_string(register _Xconst void *left, register _Xconst void *right)
    410 {
    411   return (strcmp((String)((*(XawCache **)left)->value),
    412 		 (String)((*(XawCache **)right)->value)));
    413 }
    414 
    415 static int
    416 bcmp_long(register _Xconst void *value, register _Xconst void *cache)
    417 {
    418   return (int)((long)value - (long)((*(XawCache **)cache)->value));
    419 }
    420 
    421 static int
    422 bcmp_string(register _Xconst void *string,
    423 	    register _Xconst void *cache)
    424 {
    425   return (strcmp((String)string, (String)((*(XawCache **)cache)->value)));
    426 }
    427 
    428 #define FIND_ALL      0
    429 #define FIND_SCREEN   1
    430 #define FIND_COLORMAP 2
    431 #define FIND_DEPTH    3
    432 static XawCache *
    433 _XawFindCache(XawCache *xaw,
    434 	      Screen *screen, Colormap colormap, int depth, int flags)
    435 {
    436   XawCache **cache;
    437 
    438   if (!xaw->num_elems)
    439     return (NULL);
    440 
    441   /* Screen */
    442   cache = (XawCache **)bsearch(screen, xaw->elems,
    443 			       xaw->num_elems, sizeof(XtPointer),
    444 			       bcmp_long);
    445   if (!cache || !(*cache)->num_elems)
    446     return (NULL);
    447   if (flags == FIND_SCREEN)
    448     return (*cache);
    449 
    450   /* Colormap */
    451   cache = (XawCache **)bsearch((void *)colormap, (*cache)->elems,
    452 			       (*cache)->num_elems, sizeof(XtPointer),
    453 			       bcmp_long);
    454   if (!cache || !(*cache)->num_elems)
    455     return (NULL);
    456   if (flags == FIND_COLORMAP)
    457     return (*cache);
    458 
    459   /* Depth */
    460   cache = (XawCache **)bsearch((void *)(long)depth, (*cache)->elems,
    461 			       (*cache)->num_elems, sizeof(XtPointer),
    462 			       bcmp_long);
    463 
    464   if (!cache || !(*cache)->num_elems)
    465     return (NULL);
    466   return (*cache);
    467 }
    468 
    469 static XawCache *
    470 _XawGetCache(XawCache *xaw, Screen *screen, Colormap colormap, int depth)
    471 {
    472   XawCache *cache;
    473 
    474   cache = _XawFindCache(xaw, screen, colormap, depth, FIND_ALL);
    475 
    476   if (!cache)
    477     {
    478       XawCache *c_cache, *d_cache, *pcache;
    479       XawCache *s_cache = _XawFindCache(xaw,
    480 					screen, colormap, depth, FIND_SCREEN);
    481       if (!s_cache)
    482 	{
    483 	  pcache = (XawCache *)XtMalloc(sizeof(XawCache));
    484 	  if (!xaw->num_elems)
    485 	    {
    486 	      xaw->num_elems = 1;
    487 	      xaw->elems = (XtPointer*)XtMalloc(sizeof(XtPointer));
    488 	    }
    489 	  else
    490 	    {
    491 	      ++xaw->num_elems;
    492 	      xaw->elems = (XtPointer*)
    493 		XtRealloc((char *)xaw->elems,
    494 			  (Cardinal)(sizeof(XtPointer) * (size_t)xaw->num_elems));
    495 	    }
    496 	  pcache->value = (long)screen;
    497 	  pcache->elems = NULL;
    498 	  pcache->num_elems = 0;
    499 	  xaw->elems[xaw->num_elems - 1] = (XtPointer)pcache;
    500 	  s_cache = (XawCache *)xaw->elems[xaw->num_elems - 1];
    501 	  if (xaw->num_elems > 1)
    502 	    qsort(xaw->elems, xaw->num_elems, sizeof(XtPointer), qcmp_long);
    503 	}
    504 
    505       c_cache = _XawFindCache(xaw,
    506 			      screen, colormap, depth, FIND_COLORMAP);
    507       if (!c_cache)
    508 	{
    509 	  pcache = (XawCache *)XtMalloc(sizeof(XawCache));
    510 	  if (!s_cache->num_elems)
    511 	    {
    512 	      s_cache->num_elems = 1;
    513 	      s_cache->elems = (XtPointer*)XtMalloc(sizeof(XtPointer));
    514 	    }
    515 	  else
    516 	    {
    517 	      ++s_cache->num_elems;
    518 	      s_cache->elems = (XtPointer*)
    519 		XtRealloc((char *)s_cache->elems,
    520 			  (Cardinal)(sizeof(XtPointer) * s_cache->num_elems));
    521 	    }
    522 	  pcache->value = (long)colormap;
    523 	  pcache->elems = NULL;
    524 	  pcache->num_elems = 0;
    525 	  s_cache->elems[s_cache->num_elems - 1] = (XtPointer)pcache;
    526 	  c_cache = (XawCache *)s_cache->elems[s_cache->num_elems - 1];
    527 	  if (s_cache->num_elems > 1)
    528 	    qsort(s_cache->elems, s_cache->num_elems,
    529 		  sizeof(XtPointer), qcmp_long);
    530 	}
    531 
    532       d_cache = _XawFindCache(xaw,
    533 			      screen, colormap, depth, FIND_DEPTH);
    534       if (!d_cache)
    535 	{
    536 	  pcache = (XawCache *)XtMalloc(sizeof(XawCache));
    537 	  if (!c_cache->num_elems)
    538 	    {
    539 	      c_cache->num_elems = 1;
    540 	      c_cache->elems = (XtPointer*)XtMalloc(sizeof(XtPointer));
    541 	    }
    542 	  else
    543 	    {
    544 	      ++c_cache->num_elems;
    545 	      c_cache->elems = (XtPointer*)
    546 		XtRealloc((char *)c_cache->elems,
    547 			  (Cardinal)(sizeof(XtPointer) * c_cache->num_elems));
    548 	    }
    549 	  pcache->value = (long)depth;
    550 	  pcache->elems = NULL;
    551 	  pcache->num_elems = 0;
    552 	  c_cache->elems[c_cache->num_elems - 1] = (XtPointer)pcache;
    553 	  d_cache = (XawCache *)c_cache->elems[c_cache->num_elems - 1];
    554 	  if (c_cache->num_elems > 1)
    555 	    qsort(c_cache->elems, c_cache->num_elems,
    556 		  sizeof(XtPointer), qcmp_long);
    557 	}
    558 
    559       cache = d_cache;
    560     }
    561 
    562   return (cache);
    563 }
    564 
    565 static XawPixmap *
    566 _XawFindPixmap(String name, Screen *screen, Colormap colormap, int depth)
    567 {
    568   XawCache *cache;
    569   XawPixmap **pixmap;
    570 
    571   cache = _XawFindCache(&xaw_pixmaps, screen, colormap, depth, FIND_ALL);
    572 
    573   if (!cache)
    574     return (NULL);
    575 
    576   /* Name */
    577   pixmap = (XawPixmap **)bsearch((void *)name, cache->elems,
    578 				 cache->num_elems, sizeof(XtPointer),
    579 				 bcmp_string);
    580   if (!pixmap)
    581     return (NULL);
    582 
    583   return (*pixmap);
    584 }
    585 
    586 XawPixmap *
    587 XawPixmapFromXPixmap(Pixmap pixmap,
    588 		     Screen *screen, Colormap colormap, int depth)
    589 {
    590   XawCache *cache;
    591   XawPixmap **x_pixmap;
    592 
    593   cache = _XawFindCache(&x_pixmaps, screen, colormap, depth, FIND_ALL);
    594 
    595   if (!cache)
    596     return (NULL);
    597 
    598   /* Pixmap */
    599   x_pixmap = (XawPixmap **)bsearch((void *)pixmap, cache->elems,
    600 				   cache->num_elems, sizeof(XtPointer),
    601 				   bcmp_x_cache);
    602   if (!x_pixmap)
    603     return (NULL);
    604 
    605   return (*x_pixmap);
    606 }
    607 
    608 static void
    609 _XawCachePixmap(XawPixmap *pixmap,
    610 		Screen *screen, Colormap colormap, int depth)
    611 {
    612   XawCache *xaw_cache, *x_cache;
    613 
    614   xaw_cache = _XawGetCache(&xaw_pixmaps, screen, colormap, depth);
    615   x_cache = _XawGetCache(&x_pixmaps, screen, colormap, depth);
    616 
    617   if (!xaw_cache->num_elems)
    618     {
    619       xaw_cache->num_elems = 1;
    620       xaw_cache->elems = (XtPointer*)XtMalloc(sizeof(XtPointer));
    621     }
    622   else
    623     {
    624       ++xaw_cache->num_elems;
    625       xaw_cache->elems = (XtPointer*)XtRealloc((char *)xaw_cache->elems,
    626 					       (Cardinal)(sizeof(XtPointer) *
    627 							  xaw_cache->num_elems));
    628     }
    629 
    630   xaw_cache->elems[xaw_cache->num_elems - 1] = (XtPointer)pixmap;
    631   if (xaw_cache->num_elems > 1)
    632     qsort(xaw_cache->elems, xaw_cache->num_elems,
    633 	  sizeof(XtPointer), qcmp_string);
    634 
    635 
    636   if (!x_cache->num_elems)
    637     {
    638       x_cache->num_elems = 1;
    639       x_cache->elems = (XtPointer*)XtMalloc(sizeof(XtPointer));
    640     }
    641   else
    642     {
    643       ++x_cache->num_elems;
    644       x_cache->elems = (XtPointer*)XtRealloc((char *)x_cache->elems,
    645 					     (Cardinal)(sizeof(XtPointer) *
    646 							x_cache->num_elems));
    647     }
    648 
    649   x_cache->elems[x_cache->num_elems - 1] = (XtPointer)pixmap;
    650   if (x_cache->num_elems > 1)
    651     qsort(x_cache->elems, x_cache->num_elems, sizeof(XtPointer), qcmp_x_cache);
    652 }
    653 
    654 #ifndef PROJECT_ROOT
    655 #define PROJECT_ROOT	"/usr/X11R6"
    656 #endif
    657 
    658 static char *pixmap_path = NULL;
    659 
    660 static void
    661 GetResourcePixmapPath(Display *display)
    662 {
    663     XrmName xrm_name[2];
    664     XrmClass xrm_class[2];
    665     XrmRepresentation rep_type;
    666     XrmValue value;
    667     static char *default_path =
    668 	(char*)"%H/%T/%N:%P/include/X11/%T/%N:/usr/X11R6/include/X11/%T/%N:/usr/include/X11/%T/%N:%N";
    669 
    670     xrm_name[0] = XrmPermStringToQuark("pixmapFilePath");
    671     xrm_name[1] = NULLQUARK;
    672     xrm_class[0] = XrmPermStringToQuark("PixmapFilePath");
    673     xrm_class[1] = NULLQUARK;
    674     if (!XrmGetDatabase(display))
    675 	(void) XGetDefault(display, "", "");
    676     if (XrmQGetResource(XrmGetDatabase(display), xrm_name, xrm_class,
    677 			&rep_type, &value) &&
    678 			rep_type == XrmPermStringToQuark("String")) {
    679 	int length = 0;
    680 	char *tok, *buffer = XtNewString(value.addr);
    681 
    682 	for (tok = strtok(buffer, ":"); tok; tok = strtok(NULL, ":")) {
    683 	    int toklen = (int)strlen(tok);
    684 
    685 	    if (toklen) {
    686 		pixmap_path = XtRealloc(pixmap_path, (Cardinal)(length + toklen + 5));
    687 		strcpy(pixmap_path + length, tok);
    688 		if (length)
    689 		    pixmap_path[length++] = ':';
    690 		sprintf(pixmap_path + length, "%s/%%N", tok);
    691 		length = (length + (int)strlen(tok) + 3);
    692 	    }
    693 	}
    694 	XtFree(buffer);
    695 	pixmap_path = XtRealloc(pixmap_path, (Cardinal)((size_t)length + strlen(default_path) + 2));
    696 	if (length)
    697 	    pixmap_path[length++] = ':';
    698 	strcpy(pixmap_path + length, default_path);
    699     }
    700     else
    701 	pixmap_path = default_path;
    702 }
    703 
    704 static const char *
    705 GetFileName(XawParams *params, Screen *screen)
    706 {
    707   static SubstitutionRec sub[] = {
    708     {'H',   NULL},
    709     {'N',   NULL},
    710     {'T',   "pixmaps"},
    711     {'P',   PROJECT_ROOT},
    712   };
    713   if (params->name[0] != '/' && params->name[0] != '.')
    714     {
    715       if (!sub[0].substitution)
    716 	sub[0].substitution = getenv("HOME");
    717       sub[1].substitution = (_XtString)params->name;
    718       if (pixmap_path == NULL)
    719 	GetResourcePixmapPath(DisplayOfScreen(screen));
    720       return XtFindFile(pixmap_path, sub, XtNumber(sub), NULL);
    721     }
    722    return params->name;
    723 }
    724 
    725 static Bool
    726 BitmapLoader(XawParams *params, Screen *screen, Colormap colormap, int depth,
    727 	     Pixmap *pixmap_return, Pixmap *mask_return,
    728 	     Dimension *width_return, Dimension *height_return)
    729 {
    730   Pixel fg, bg;
    731   XColor color, exact;
    732   unsigned int width, height;
    733   unsigned char *data = NULL;
    734   int hotX, hotY;
    735   XawArgVal *argval;
    736   Bool retval = False;
    737   const char *filename;
    738 
    739   fg = BlackPixelOfScreen(screen);
    740   bg = WhitePixelOfScreen(screen);
    741 
    742   if ((argval = XawFindArgVal(params, "foreground")) != NULL
    743       && argval->value)
    744     {
    745       if (XAllocNamedColor(DisplayOfScreen(screen), colormap, argval->value,
    746 			   &color, &exact))
    747 	fg = color.pixel;
    748       else
    749 	return (False);
    750     }
    751   if ((argval = XawFindArgVal(params, "background")) != NULL
    752       && argval->value)
    753     {
    754       if (XAllocNamedColor(DisplayOfScreen(screen), colormap, argval->value,
    755 			   &color, &exact))
    756 	bg = color.pixel;
    757       else
    758 	return (False);
    759     }
    760 
    761   filename = GetFileName(params, screen);
    762   if (!filename)
    763     return (FALSE);
    764 
    765   if (XReadBitmapFileData(filename, &width, &height, &data,
    766 			  &hotX, &hotY) == BitmapSuccess)
    767     {
    768       Pixmap pixmap =
    769 	  XCreatePixmapFromBitmapData(DisplayOfScreen(screen),
    770 				      RootWindowOfScreen(screen),
    771 				      (char *)data,
    772 				      width, height, fg, bg, (unsigned)depth);
    773       if (data)
    774 	XFree(data);
    775       *pixmap_return = pixmap;
    776       *mask_return = None;
    777       *width_return = (Dimension)width;
    778       *height_return = (Dimension)height;
    779 
    780       retval = True;
    781     }
    782 
    783   if (filename != params->name)
    784     XtFree((char *)filename);
    785 
    786   return (retval);
    787 }
    788 
    789 #define VERTICAL   1
    790 #define HORIZONTAL 2
    791 static Bool
    792 GradientLoader(XawParams *params, Screen *screen, Colormap colormap, int depth,
    793 	       Pixmap *pixmap_return, Pixmap *mask_return,
    794 	       Dimension *width_return, Dimension *height_return)
    795 {
    796   double ired, igreen, iblue, red, green, blue;
    797   XColor start, end, color;
    798   XGCValues values;
    799   GC gc;
    800   double i, inc, x, y, xend, yend;
    801   Pixmap pixmap;
    802   XawArgVal *argval;
    803   int orientation, dimension, steps;
    804   char *value;
    805 
    806   if (XmuCompareISOLatin1(params->name, "vertical") == 0)
    807     orientation = VERTICAL;
    808   else if (XmuCompareISOLatin1(params->name, "horizontal") == 0)
    809     orientation = HORIZONTAL;
    810   else
    811     return (False);
    812 
    813   if ((argval = XawFindArgVal(params, "dimension")) != NULL
    814       && argval->value)
    815     {
    816       dimension = atoi(argval->value);
    817       if (dimension <= 0)
    818 	return (False);
    819     }
    820   else
    821     dimension = 50;
    822 
    823   if ((argval = XawFindArgVal(params, "steps")) != NULL
    824       && argval->value)
    825     {
    826       steps = atoi(argval->value);
    827       if (steps <= 0)
    828 	return (False);
    829     }
    830   else
    831       steps = dimension;
    832 
    833   steps = XawMin(steps, dimension);
    834 
    835   value = NULL;
    836   if ((argval = XawFindArgVal(params, "start")) != NULL)
    837     value = (char*)argval->value;
    838   if (value && !XAllocNamedColor(DisplayOfScreen(screen), colormap, value,
    839 			    &start, &color))
    840     return (False);
    841   else if (!value)
    842     {
    843       start.pixel = WhitePixelOfScreen(screen);
    844       XQueryColor(DisplayOfScreen(screen), colormap, &start);
    845     }
    846   value = NULL;
    847   if ((argval = XawFindArgVal(params, "end")) != NULL)
    848     value = (char*)argval->value;
    849   if (value && !XAllocNamedColor(DisplayOfScreen(screen), colormap, value,
    850 			    &end, &color))
    851     return (False);
    852   else if (!value)
    853     {
    854       end.pixel = BlackPixelOfScreen(screen);
    855       XQueryColor(DisplayOfScreen(screen), colormap, &end);
    856     }
    857 
    858   if ((pixmap = XCreatePixmap(DisplayOfScreen(screen),
    859 			      RootWindowOfScreen(screen),
    860 			      (unsigned)(orientation == VERTICAL ? 1 : dimension),
    861 			      (unsigned)(orientation == VERTICAL ? dimension : 1), (unsigned)depth))
    862       == 0)
    863     return (False);
    864 
    865   ired   = (double)(end.red   - start.red)   / (double)steps;
    866   igreen = (double)(end.green - start.green) / (double)steps;
    867   iblue  = (double)(end.blue  - start.blue)  / (double)steps;
    868 
    869   red   = color.red   = start.red;
    870   green = color.green = start.green;
    871   blue  = color.blue  = start.blue;
    872 
    873   inc = (double)dimension / (double)steps;
    874 
    875   gc = XCreateGC(DisplayOfScreen(screen), pixmap, 0, &values);
    876 
    877   x = y = 0.0;
    878   if (orientation == VERTICAL)
    879     {
    880       xend = 1;
    881       yend = 0;
    882     }
    883   else
    884     {
    885       xend = 0;
    886       yend = 1;
    887     }
    888 
    889   color.flags = DoRed | DoGreen | DoBlue;
    890 
    891   XSetForeground(DisplayOfScreen(screen), gc, start.pixel);
    892   for (i = 0.0; i < dimension; i += inc)
    893     {
    894       if ((int)color.red != (int)red || (int)color.green != (int)green
    895 	  || (int)color.blue != (int)blue)
    896 	{
    897 	  XFillRectangle(DisplayOfScreen(screen), pixmap, gc, (int)x, (int)y,
    898 			 (unsigned int)xend, (unsigned int)yend);
    899 	  color.red   = (unsigned short)red;
    900 	  color.green = (unsigned short)green;
    901 	  color.blue  = (unsigned short)blue;
    902 	  if (!XAllocColor(DisplayOfScreen(screen), colormap, &color))
    903 	    {
    904 	      XFreePixmap(DisplayOfScreen(screen), pixmap);
    905 	      return (False);
    906 	    }
    907 	  XSetForeground(DisplayOfScreen(screen), gc, color.pixel);
    908 	  if (orientation == VERTICAL)
    909 	    y = yend;
    910 	  else
    911 	    x = xend;
    912 	}
    913       red   += ired;
    914       green += igreen;
    915       blue  += iblue;
    916       if (orientation == VERTICAL)
    917 	yend += inc;
    918       else
    919 	xend += inc;
    920     }
    921   XFillRectangle(DisplayOfScreen(screen), pixmap, gc, (int)x, (int)y,
    922 		 (unsigned int)xend, (unsigned int)yend);
    923 
    924   *pixmap_return = pixmap;
    925   *mask_return = None;
    926   *width_return = (Dimension)(orientation == VERTICAL ? 1 : dimension);
    927   *height_return = (Dimension)(orientation == VERTICAL ? dimension : 1);
    928 
    929   XFreeGC(DisplayOfScreen(screen), gc);
    930 
    931   return (True);
    932 }
    933 
    934 static Bool
    935 XPixmapLoader(XawParams *params, Screen *screen, Colormap colormap, int depth _X_UNUSED,
    936 	      Pixmap *pixmap_return, Pixmap *mask_return,
    937 	      Dimension *width_return, Dimension *height_return)
    938 {
    939   XpmAttributes xpm_attributes;
    940   XawArgVal *argval;
    941   unsigned int closeness = 4000;
    942   Bool retval = False;
    943   const char *filename;
    944 
    945   if ((argval = XawFindArgVal(params, "closeness")) != NULL
    946       && argval->value)
    947     closeness = (unsigned)atoi(argval->value);
    948 
    949   filename = GetFileName(params, screen);
    950   if (!filename)
    951     return (FALSE);
    952 
    953   xpm_attributes.colormap = colormap;
    954   xpm_attributes.closeness = closeness;
    955   xpm_attributes.valuemask = XpmSize | XpmColormap | XpmCloseness;
    956   if (XpmReadFileToPixmap(DisplayOfScreen(screen),
    957 			  RootWindowOfScreen(screen), filename, pixmap_return,
    958 			  mask_return, &xpm_attributes) == XpmSuccess)
    959     {
    960       *width_return = (Dimension)xpm_attributes.width;
    961       *height_return = (Dimension)xpm_attributes.height;
    962 
    963       retval = True;
    964     }
    965 
    966   if (filename != params->name)
    967     XtFree((char *)filename);
    968   return (retval);
    969 }
    970 
    971 void
    972 XawReshapeWidget(Widget w, XawPixmap *pixmap)
    973 {
    974   if (!pixmap || pixmap->mask == None)
    975     XShapeCombineMask(XtDisplay(w), XtWindow(w), ShapeBounding, 0, 0,
    976 		      None, ShapeSet);
    977   else
    978     XShapeCombineMask(XtDisplay(w), XtWindow(w), ShapeBounding, 0, 0,
    979 		      pixmap->mask, ShapeSet);
    980 }
    981 
    982 #endif /* OLDXAW */
    983