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