source: trunk/third/mwm/WmImage.c @ 9757

Revision 9757, 21.3 KB checked in by ghudson, 28 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r9756, which included commits to RCS files with non-trunk default branches.
Line 
1/*
2 * (c) Copyright 1989, 1990, 1991, 1992, 1993 OPEN SOFTWARE FOUNDATION, INC.
3 * ALL RIGHTS RESERVED
4*/
5/*
6 * Motif Release 1.2.3
7*/
8#ifdef REV_INFO
9#ifndef lint
10static char rcsid[] = "$RCSfile: WmImage.c,v $ $Revision: 1.1.1.1 $ $Date: 1997-03-25 09:12:21 $"
11#endif
12#endif
13/*
14 * (c) Copyright 1987, 1988, 1989, 1990 HEWLETT-PACKARD COMPANY */
15
16/*
17 * Included Files:
18 */
19
20#include "WmGlobal.h"
21
22#define MWM_NEED_IIMAGE
23#include "WmIBitmap.h"
24
25#ifdef MOTIF_ONE_DOT_ONE
26#include <stdio.h>
27#include <pwd.h>
28#define MATCH_CHAR 'P'          /* Default match character - defined in Xmos.p */
29#else
30#include <Xm/XmosP.h>
31#endif
32
33#define MAXPATH 1023
34#define MATCH_XBM 'B'           /* .xbm character: see XmGetPixmap */
35#define MATCH_PATH "XBMLANGPATH"
36
37/*
38 * include extern functions
39 */
40
41#include "WmImage.h"
42#include "WmGraphics.h"
43#include "WmResource.h"
44#include "WmResParse.h"
45#include "WmMenu.h"
46#include "WmError.h"
47
48#ifdef MOTIF_ONE_DOT_ONE
49extern char    *getenv ();
50#endif
51
52
53/******************************<->*************************************
54 *
55 *  MakeClientIconPixmap (pCD, iconBitmap)
56 *
57 *
58 *  Description:
59 *  -----------
60 *  This function takes a client supplied icon image bitmap and makes it
61 *  into a colored pixmap suitable for use as an icon image.
62 *
63 *
64 *  Inputs:
65 *  ------
66 *  pCD = pointer to client data (icon colors and tiles)
67 *
68 *  iconBitmap = uncolored and formated icon bitmap
69 *
70 *
71 *  Outputs:
72 *  -------
73 *  RETURN = icon pixmap (NULL if error)
74 *
75 ******************************<->***********************************/
76
77#ifdef _NO_PROTO
78Pixmap MakeClientIconPixmap (pCD, iconBitmap)
79
80    ClientData *pCD;
81    Pixmap iconBitmap;
82
83#else /* _NO_PROTO */
84Pixmap MakeClientIconPixmap (ClientData *pCD, Pixmap iconBitmap)
85#endif /* _NO_PROTO */
86{
87    Window root;
88    int x;
89    int y;
90    unsigned int bitmapWidth;
91    unsigned int bitmapHeight;
92    unsigned int border;
93    unsigned int depth;
94
95   
96    /*
97     * Check out the attributes of the bitmap to insure that it is usable.
98     */
99
100    if (!XGetGeometry (DISPLAY, iconBitmap, &root, &x, &y,
101             &bitmapWidth, &bitmapHeight, &border, &depth))
102    {
103        Warning ("Invalid icon bitmap");
104        return ((Pixmap)NULL);
105    }
106
107    if (ROOT_FOR_CLIENT(pCD) != root)
108    {
109        /*
110         * The bitmap was not made with usable parameters.
111         */
112        Warning ("Invalid root for icon bitmap");
113        return ((Pixmap)NULL);
114    }
115
116#ifdef DISALLOW_DEEP_ICONS
117    if (depth != 1)
118    {
119        Warning ("Warning color icon pixmap not supported");
120        return ((Pixmap)NULL);
121    }
122#endif
123
124    /*
125     * Color the bitmap, center it in a pixmap ....
126     */
127
128    return (MakeIconPixmap (pCD, iconBitmap, (Pixmap)NULL,
129            bitmapWidth, bitmapHeight, depth));
130
131
132} /* END OF FUNCTION MakeClientIconPixmap */
133
134
135
136/*************************************<->*************************************
137 *
138 *  MakeNamedIconPixmap (pCD, iconName)
139 *
140 *
141 *  Description:
142 *  -----------
143 *  This function makes an icon pixmap for a particular client given the
144 *  name of a bitmap file.
145 *
146 *
147 *  Inputs:
148 *  ------
149 *  pCD      = (nonNULL) pointer to client data
150 *  iconName = pointer to the icon name (bitmap file path name or NULL)
151 *
152 *
153 *  Outputs:
154 *  -------
155 *  RETURN = icon pixmap or NULL
156 *
157 *************************************<->***********************************/
158
159#ifdef _NO_PROTO
160Pixmap MakeNamedIconPixmap (pCD, iconName)
161
162    ClientData *pCD;
163    String      iconName;
164
165#else /* _NO_PROTO */
166Pixmap MakeNamedIconPixmap (ClientData *pCD, String iconName)
167#endif /* _NO_PROTO */
168{
169    int          bitmapIndex;
170
171    /*
172     * Get the bitmap cache entry (will read data from file if necessary).
173     * If unable to find the iconName file return NULL.
174     */
175
176    if ((bitmapIndex = GetBitmapIndex (PSD_FOR_CLIENT(pCD), iconName)) < 0)
177    {
178        return ((Pixmap)NULL);
179    }
180
181    /*
182     * Color the bitmap, center it in a pixmap ....
183     */
184
185    return (MakeCachedIconPixmap (pCD, bitmapIndex, (Pixmap)NULL));
186
187} /* END OF FUNCTION MakeNamedIconPixmap */
188
189
190
191
192/*************************************<->*************************************
193 *
194 *  Pixmap
195 *  MakeCachedIconPixmap (pCD, bitmapIndex, mask)
196 *
197 *
198 *  Description:
199 *  -----------
200 *  Convert the cached bitmap and mask into an icon pixmap.
201 *
202 *
203 *  Inputs:
204 *  ------
205 *  pCD         - (nonNULL) pointer to client data (icon colors and tiles)
206 *  bitmapIndex - bitmap cache index of image to be converted
207 *  mask        - bitmap mask, 1 for bits of "bitmap" to be kept
208 *
209 *
210 *  Outputs:
211 *  -------
212 *  RETURN      - icon pixmap or NULL
213 *
214 *
215 *  Comments:
216 *  --------
217 *  o "mask" is not used.
218 *
219 *************************************<->***********************************/
220#ifdef _NO_PROTO
221Pixmap MakeCachedIconPixmap (pCD, bitmapIndex, mask)
222
223    ClientData *pCD;
224    int         bitmapIndex;
225    Pixmap      mask;
226
227#else /* _NO_PROTO */
228Pixmap MakeCachedIconPixmap (ClientData *pCD, int bitmapIndex, Pixmap mask)
229#endif /* _NO_PROTO */
230{
231    BitmapCache  *bitmapc;
232    PixmapCache  *pixmapc;
233    Pixmap        pixmap = (Pixmap)NULL;
234    WmScreenData *pSD = PSD_FOR_CLIENT(pCD);
235
236    if (bitmapIndex < 0)
237    {
238        return ((Pixmap)NULL);
239    }
240    bitmapc = &(pSD->bitmapCache[bitmapIndex]);
241
242    /*
243     * Search for an icon pixmap matching the client icon colors.
244     */
245
246    pixmapc = bitmapc->pixmapCache;
247    while (pixmapc)
248    {
249        if ((pixmapc->pixmapType == ICON_PIXMAP) &&
250            (pixmapc->foreground == pCD->iconImageForeground) &&
251            (pixmapc->background == pCD->iconImageBackground))
252        {
253            pixmap = pixmapc->pixmap;
254            break;
255        }
256        pixmapc = pixmapc->next;
257    }
258
259    /*
260     * If a matching pixmap was not found in the pixmap cache for this bitmap
261     *   then create the icon pixmap with the appropriate colors.
262     * If have sufficient memory, save the pixmap info in the pixmapCache.
263     */
264
265    if (!pixmap &&
266        (pixmap = MakeIconPixmap (pCD, bitmapc->bitmap, mask,
267                                     bitmapc->width, bitmapc->height, 1)) &&
268        (pixmapc = (PixmapCache *) XtMalloc (sizeof (PixmapCache))))
269    {
270
271        pixmapc->pixmapType = ICON_PIXMAP;
272        pixmapc->foreground = pCD->iconImageForeground;
273        pixmapc->background = pCD->iconImageBackground;
274        pixmapc->pixmap = pixmap;
275        pixmapc->next = bitmapc->pixmapCache;
276        bitmapc->pixmapCache = pixmapc;
277    }
278
279    return (pixmap);
280
281} /* END OF FUNCTION MakeCachedIconPixmap */
282
283
284
285/*************************************<->*************************************
286 *
287 *  MakeIconPixmap (pCD, bitmap, mask, width, height, depth)
288 *
289 *
290 *  Description:
291 *  -----------
292 *  Convert the bitmap and mask into an icon pixmap.
293 *
294 *
295 *  Inputs:
296 *  ------
297 *  pCD         - pointer to client data (icon colors and tiles)
298 *  pWS         - pointer to workspace data
299 *  bitmap      - bitmap image to be converted
300 *  mask        - bitmap mask, 1 for bits of "bitmap" to be kept
301 *  width       - pixel width of bitmap
302 *  height      - pixel height of bitmap
303 *  depth       - depth of bitmap (pixmap, really)
304 *
305 *
306 *  Outputs:
307 *  -------
308 *  RETURN      - icon pixmap or NULL
309 *
310 *
311 *  Comments:
312 *  --------
313 *  o "mask" is not used.
314 *
315 *************************************<->***********************************/
316#ifdef _NO_PROTO
317Pixmap MakeIconPixmap (pCD, bitmap, mask, width, height, depth)
318
319    ClientData  *pCD;
320    Pixmap       bitmap;
321    Pixmap       mask;
322    unsigned int width;
323    unsigned int height;
324    unsigned int depth;
325
326#else /* _NO_PROTO */
327Pixmap MakeIconPixmap (ClientData *pCD, Pixmap bitmap, Pixmap mask, unsigned int width, unsigned int height, unsigned int depth)
328#endif /* _NO_PROTO */
329{
330    Pixmap       iconPixmap;
331    GC           imageGC, topGC, botGC;
332    XGCValues    gcv;
333    unsigned int imageWidth;
334    unsigned int imageHeight;
335    int          dest_x, dest_y;
336    Pixel        fg;
337    Pixel        bg;
338    RList       *top_rects = NULL;
339    RList       *bot_rects = NULL;
340    WmScreenData        *pSD;
341
342 /*
343  *  CR5208 - Allocate a new RList each time this routine is entered.
344  *           If the RList is static, then each time this routine is
345  *           entered the RList size is increased by BevelRectangle,
346  *           causing a pseudo memory leak.
347  */
348     if ((top_rects = AllocateRList
349         ((unsigned)2 * ICON_INTERNAL_SHADOW_WIDTH)) == NULL)
350    {
351        /* Out of memory! */
352        Warning ("Insufficient memory to bevel icon image");
353        return ((Pixmap)NULL);
354    }
355
356    if ((bot_rects = AllocateRList
357        ((unsigned)2 * ICON_INTERNAL_SHADOW_WIDTH)) == NULL)
358    {
359        /* Out of memory! */
360        Warning ("Insufficient memory to bevel icon image");
361        return ((Pixmap)NULL);
362    }
363
364    if (pCD)
365    {
366        pSD = pCD->pSD;
367    }
368    else
369    {
370        pSD = wmGD.pActiveSD;
371    }
372
373    /* don't make icon pixmap if bitmap is too small */
374
375    if ((width < pSD->iconImageMinimum.width) ||
376        (height < pSD->iconImageMinimum.height))
377    {
378        /* bitmap is too small */
379        return ((Pixmap)NULL);
380    }
381
382    imageWidth = pSD->iconImageMaximum.width +
383                  2 * ICON_INTERNAL_SHADOW_WIDTH;
384    imageHeight = pSD->iconImageMaximum.height +
385                  2 * ICON_INTERNAL_SHADOW_WIDTH;
386
387    /* create a pixmap (to be returned) */
388
389    iconPixmap = XCreatePixmap (DISPLAY, pSD->rootWindow,
390                     imageWidth, imageHeight,
391                     DefaultDepth(DISPLAY, pSD->screen));
392
393    /*
394     * If a client is not specified use icon component colors, otherwise
395     * use the client-specific icon colors.
396     */
397
398    if (pCD)
399    {
400        bg = pCD->iconImageBackground;
401        fg = pCD->iconImageForeground;
402    }
403    else
404    {
405        bg = pSD->iconAppearance.background;
406        fg = pSD->iconAppearance.foreground;
407    }
408
409    /* create a GC to use */
410    gcv.foreground = bg;        /* clear it first! */
411    gcv.background = bg;
412    gcv.graphics_exposures = False;
413
414    imageGC = XCreateGC (DISPLAY, iconPixmap, (GCForeground|GCBackground),
415                  &gcv);
416
417    /*
418     * Format the image.
419     */
420
421    /* fill in background */
422
423    XFillRectangle(DISPLAY, iconPixmap, imageGC, 0, 0,
424                   imageWidth, imageHeight);
425
426    /* center the image */
427
428    if (width > pSD->iconImageMaximum.width)
429    {
430        width = pSD->iconImageMaximum.width;
431    }
432    if (height > pSD->iconImageMaximum.height)
433    {
434        height = pSD->iconImageMaximum.height;
435    }
436    /* center the image */
437
438    dest_x = (imageWidth - width) / 2;
439    dest_y = (imageHeight - height) / 2;
440
441    /* set the foreground */
442    XSetForeground (DISPLAY, imageGC, fg);
443
444    /* copy the bitmap to the pixmap */
445#ifndef DISALLOW_DEEP_ICONS
446    if ((depth > 1) &&
447        (depth == DefaultDepth(DISPLAY, pSD->screen)))
448    {
449        XCopyArea (DISPLAY, bitmap, iconPixmap, imageGC, 0, 0,
450                width, height, dest_x, dest_y);
451    }
452    else
453#endif /* DISALLOW_DEEP_ICONS */
454    XCopyPlane (DISPLAY, bitmap, iconPixmap, imageGC, 0, 0, width, height,
455                dest_x, dest_y, 1L);
456
457    /* free resources */
458    XFreeGC (DISPLAY, imageGC);
459
460    if (pCD)
461    {
462        /*
463         * Shadowing
464         */
465
466        topGC = GetHighlightGC (pSD, pCD->iconImageTopShadowColor,
467                                  pCD->iconImageBackground,
468                                  pCD->iconImageTopShadowPixmap);
469
470        botGC = GetHighlightGC (pSD, pCD->iconImageBottomShadowColor,
471                                  pCD->iconImageBackground,
472                                  pCD->iconImageBottomShadowPixmap);
473
474        top_rects->used = 0;    /* reset count */
475        bot_rects->used = 0;
476
477        BevelRectangle (top_rects,
478                        bot_rects,
479                        0, 0,
480                        imageWidth, imageHeight,
481                        ICON_INTERNAL_SHADOW_WIDTH,
482                        ICON_INTERNAL_SHADOW_WIDTH,
483                        ICON_INTERNAL_SHADOW_WIDTH,
484                        ICON_INTERNAL_SHADOW_WIDTH);
485
486        XFillRectangles (DISPLAY, iconPixmap, topGC, top_rects->prect,
487                                                        top_rects->used);
488        XFillRectangles (DISPLAY, iconPixmap, botGC, bot_rects->prect,
489                                                        bot_rects->used);
490    }
491
492    /*
493     * CR5208, Part 2 - Free the RList structures.
494     */
495    FreeRList(top_rects);
496    FreeRList(bot_rects);
497
498
499    return (iconPixmap);
500
501} /* END OF FUNCTION MakeIconPixmap */
502
503
504
505/*************************************<->*************************************
506 *
507 *  Pixmap
508 *  MakeCachedLabelPixmap (pSD, menuW, bitmapIndex)
509 *
510 *
511 *  Description:
512 *  -----------
513 *  Creates and returns a label pixmap.
514 *
515 *
516 *  Inputs:
517 *  ------
518 *  pSD = pointer to screen data
519 *  menuW = menu widget (for foreground and background colors)
520 *  bitmapIndex = bitmap cache index
521 *
522 *
523 *  Outputs:
524 *  -------
525 *  Return = label pixmap or NULL.
526 *
527 *
528 *  Comments:
529 *  --------
530 *  Assumes bitmapIndex is valid.
531 *
532 *************************************<->***********************************/
533
534#ifdef _NO_PROTO
535Pixmap MakeCachedLabelPixmap (pSD, menuW, bitmapIndex)
536
537    WmScreenData  *pSD;
538    Widget        menuW;
539    int           bitmapIndex;
540
541#else /* _NO_PROTO */
542Pixmap MakeCachedLabelPixmap (WmScreenData *pSD, Widget menuW, int bitmapIndex)
543#endif /* _NO_PROTO */
544{
545    BitmapCache  *bitmapc;
546    PixmapCache  *pixmapc;
547    int           i;
548    Arg           args[5];
549    Pixel         fg, bg;
550    Pixmap        pixmap = (Pixmap)NULL;
551    GC            gc;
552    XGCValues     gcv;
553
554    if (bitmapIndex < 0)
555    {
556        return ((Pixmap)NULL);
557    }
558    bitmapc = &(pSD->bitmapCache[bitmapIndex]);
559
560    /*
561     * Get the foreground and background colors from the menu widget.
562     * Search for a label pixmap matching those colors.
563     */
564
565    i = 0;
566    XtSetArg (args[i], XtNforeground, &fg); i++;
567    XtSetArg (args[i], XtNbackground, &bg); i++;
568    XtGetValues (menuW, (ArgList)args, i);
569
570    pixmapc = bitmapc->pixmapCache;
571    while (pixmapc)
572    {
573        if ((pixmapc->pixmapType == LABEL_PIXMAP) &&
574            (pixmapc->foreground == fg) &&
575            (pixmapc->background == bg))
576        {
577            pixmap = pixmapc->pixmap;
578            break;
579        }
580        pixmapc = pixmapc->next;
581    }
582
583    if (!pixmap)
584    /*
585     * A matching pixmap was not found in the pixmap cache for this bitmap.
586     * Create and save the label pixmap with appropriate colors.
587     */
588    {
589        /*
590         * Create a pixmap of the appropriate size, root, and depth.
591         * Only BadAlloc error possible; BadDrawable and BadValue are avoided.
592         */
593
594        pixmap = XCreatePixmap (DISPLAY, pSD->rootWindow,
595                                bitmapc->width, bitmapc->height,
596                                DefaultDepth (DISPLAY, pSD->screen));
597
598        /*
599         * Create a GC and copy the bitmap to the pixmap.
600         * Only BadAlloc and BadDrawable errors are possible; others are avoided
601         */
602
603        gcv.foreground = bg;
604        gcv.background = bg;
605        gcv.graphics_exposures = False;
606        gc = XCreateGC(DISPLAY, pixmap, (GCForeground|GCBackground), &gcv);
607   
608        /*
609         * Fill in the background, set the foreground, copy the bitmap to the
610         * pixmap, and free the gc.
611         */
612
613        XFillRectangle (DISPLAY, pixmap, gc, 0, 0,
614                        bitmapc->width, bitmapc->height);
615        XSetForeground (DISPLAY, gc, fg);
616        XCopyPlane (DISPLAY, bitmapc->bitmap, pixmap, gc, 0, 0,
617                    bitmapc->width, bitmapc->height, 0, 0, 1L);
618        XFreeGC (DISPLAY, gc);
619
620        /*
621         * If have sufficient memory, save the pixmap info in the pixmapCache.
622         */
623
624        if ((pixmapc = (PixmapCache *) XtMalloc(sizeof(PixmapCache))) != NULL)
625        {
626            pixmapc->pixmapType = LABEL_PIXMAP;
627            pixmapc->foreground = fg;
628            pixmapc->background = bg;
629            pixmapc->pixmap = pixmap;
630            pixmapc->next = bitmapc->pixmapCache;
631            bitmapc->pixmapCache = pixmapc;
632        }
633    }
634
635    return (pixmap);
636
637} /* END OF FUNCTION MakeCachedLabelPixmap */
638
639
640
641/*************************************<->*************************************
642 *
643 *  int
644 *  GetBitmapIndex (pSD, name)
645 *
646 *
647 *  Description:
648 *  -----------
649 *  Retrieve bitmap from cache.
650 *
651 *
652 *  Inputs:
653 *  ------
654 *  pSD = pointer to screen data
655 *  name = bitmap file name or NULL pointer
656 *  bitmapCache[]
657 *  bitmapCacheSize
658 *  bitmapCacheCount
659 *
660 *
661 *  Outputs:
662 *  -------
663 *  bitmapCache[]
664 *  bitmapCacheSize
665 *  bitmapCacheCount
666 *  Return   = bitmap cache index or -1
667 *
668 *
669 *  Comments:
670 *  --------
671 *  None
672 *
673 *************************************<->***********************************/
674
675#define BITMAP_CACHE_INC 5
676
677#ifdef _NO_PROTO
678int GetBitmapIndex (pSD, name)
679
680    WmScreenData *pSD;
681    char         *name;
682#else /* _NO_PROTO */
683int GetBitmapIndex (WmScreenData *pSD, char *name)
684#endif /* _NO_PROTO */
685{
686    char         *path;
687    BitmapCache  *bitmapc;
688    unsigned int  n;
689    int           x, y;
690
691    /*
692     * Search a nonempty bitmap cache for a pathname match.
693     */
694    path = BitmapPathName (name);
695    for (n = 0, bitmapc = pSD->bitmapCache;
696         n < pSD->bitmapCacheCount;
697         n++, bitmapc++)
698    {
699        if ((!path && !bitmapc->path) ||
700            (path && bitmapc->path &&
701             !strcmp (path, bitmapc->path)))
702        {
703            return (n);
704        }
705    }
706
707    /*
708     * The bitmap path name was not found in bitmapCache.
709     * Find the next BitmapCache entry, creating or enlarging bitmapCache if
710     * necessary.
711     */
712    if (pSD->bitmapCacheSize == 0)
713    /* create */
714    {
715        pSD->bitmapCacheSize = BITMAP_CACHE_INC;
716        pSD->bitmapCache =
717            (BitmapCache *) XtMalloc (BITMAP_CACHE_INC * sizeof (BitmapCache));
718    }
719    else if (pSD->bitmapCacheCount == pSD->bitmapCacheSize)
720    /* enlarge */
721    {
722        pSD->bitmapCacheSize += BITMAP_CACHE_INC;
723        pSD->bitmapCache = (BitmapCache *)
724            XtRealloc ((char*)pSD->bitmapCache,
725                     pSD->bitmapCacheSize * sizeof (BitmapCache));
726    }
727
728    if (pSD->bitmapCache == NULL)
729    {
730        MWarning ("Insufficient memory for bitmap %s\n", name);
731        pSD->bitmapCacheSize = 0;
732        pSD->bitmapCacheCount = 0;
733        return (-1);
734    }
735
736    bitmapc = &(pSD->bitmapCache[pSD->bitmapCacheCount]);
737
738    /*
739     * Fill the entry with the bitmap info.
740     * A NULL path indicates the builtin icon bitmap.
741     * Indicate that no pixmapCache exists yet.
742     */
743
744    if (path)
745    {
746        if ((bitmapc->path = (String)
747                 XtMalloc ((unsigned int)(strlen (path) + 1))) == NULL)
748        {
749            MWarning ("Insufficient memory for bitmap %s\n", name);
750            return (-1);
751        }
752        strcpy (bitmapc->path, path);
753
754        if (XReadBitmapFile (DISPLAY, pSD->rootWindow, path,
755                             &bitmapc->width, &bitmapc->height,
756                             &bitmapc->bitmap, &x, &y)
757            != BitmapSuccess)
758        {
759            MWarning ("Unable to read bitmap file %s\n", path);
760            XtFree ((char *)bitmapc->path);
761            return (-1);
762        }
763
764        if (bitmapc->width == 0 || bitmapc->height == 0)
765        {
766            MWarning ("Invalid bitmap file %s\n", path);
767            XtFree ((char *)bitmapc->path);
768            return (-1);
769        }
770    }
771    else
772    /* builtin icon bitmap */
773    {
774        bitmapc->path   = NULL;
775        bitmapc->bitmap = pSD->builtinIconPixmap;
776        bitmapc->width  = iImage_width;
777        bitmapc->height = iImage_height;
778    }
779
780    bitmapc->pixmapCache = NULL;
781
782    return (pSD->bitmapCacheCount++);
783
784} /* END OF FUNCTION GetBitmapIndex */
785
786
787
788/*************************************<->*************************************
789 *
790 *  BitmapPathName (string)
791 *
792 *
793 *  Description:
794 *  -----------
795 *  Constructs a bitmap file pathname from the bitmap file name and the
796 *  bitmapDirectory resource value.
797 *
798 *
799 *  Inputs:
800 *  ------
801 *  string = bitmap file name or NULL
802 *  wmGD.bitmapDirectory = bitmapDirectory resource value
803 *  HOME = environment variable for home directory
804 *  XBMLANGPATH
805 *  XAPPLRESDIR
806 *
807 *
808 *  Outputs:
809 *  -------
810 *  Return = string containing the bitmap file pathname or NULL.
811 *
812 *
813 *  Comments:
814 *  --------
815 *  If the bitmap file does not exist, searches using XBMLANGPATH.
816 *  Returns NULL path name for a NULL file name.
817 *
818 *************************************<->***********************************/
819
820char *BitmapPathName (string)
821    char *string;
822
823{
824    static char  fileName[MAXPATH+1];
825    char *retname;
826    SubstitutionRec subs[1];
827#ifndef MOTIF_ONE_DOT_ONE
828    char *homeDir = _XmOSGetHomeDirName();
829#endif
830
831    if (!string || !*string)
832    {
833        return (NULL);
834    }
835
836    /*
837     * Interpret "~/.." as relative to the user's home directory.
838     * Interpret "/.." as an absolute pathname.
839     * If the bitmapDirectory resource is nonNULL, interpret path as relative
840     *   to it.
841     * Else, or if bitmapDirectory has no such file, use a XBMLANGPATH lookup.
842     */
843
844    if ((string[0] == '~') && (string[1] == '/'))
845    /*
846     * Handle "~/.."
847     */
848    {
849#ifdef MOTIF_ONE_DOT_ONE
850        GetHomeDirName(fileName);
851#else
852        strcpy (fileName, homeDir);
853#endif
854        strncat (fileName, &(string[1]), MAXPATH - strlen (fileName));
855        return (fileName);
856    }
857
858    if (string[0] == '/')
859    {
860      return(string);
861    }
862
863    if (wmGD.bitmapDirectory && *wmGD.bitmapDirectory)
864    /*
865     * Relative to nonNULL bitmapDirectory (which may have relative to HOME)
866     */
867    {
868        if ((wmGD.bitmapDirectory[0] == '~') &&
869            (wmGD.bitmapDirectory[1] == '/'))
870        {
871#ifdef MOTIF_ONE_DOT_ONE
872            GetHomeDirName(fileName);
873#else
874            strcpy (fileName, homeDir);
875#endif
876            strncat (fileName, &wmGD.bitmapDirectory[1],
877                     MAXPATH - strlen (fileName));
878        } else {
879            strcpy (fileName, wmGD.bitmapDirectory);
880        }
881        strncat (fileName, "/", MAXPATH - strlen (fileName));
882        strncat (fileName, string, MAXPATH - strlen (fileName));
883
884/* Test file for existence. */
885
886        subs[0].substitution = "";
887        if ((retname = XtFindFile(fileName, subs, 0,
888                                  (XtFilePredicate) NULL)) != NULL) {
889          XtFree(retname);
890          return (fileName);
891        }
892    }
893
894    /* Fall back on a path search */
895
896#ifdef MOTIF_ONE_DOT_ONE
897    return (NULL);
898#else
899    {
900        char *search_path;
901        Boolean user_path;
902
903        search_path = _XmOSInitPath(string, MATCH_PATH, &user_path);
904        subs[0].match = user_path ? MATCH_XBM : MATCH_CHAR;
905        subs[0].substitution = string;
906        retname = XtResolvePathname(DISPLAY, "bitmaps", NULL, NULL,
907                                    search_path, subs, XtNumber(subs),
908                                        (XtFilePredicate)NULL);
909        XtFree(search_path);
910
911        if (!retname)
912          return (string);
913
914        strncpy(fileName, retname, MAXPATH);
915        XtFree(retname);
916        return (fileName);
917    }
918#endif
919
920} /* END OF FUNCTION BitmapPathName */
Note: See TracBrowser for help on using the repository browser.