2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
6 * These libraries and programs are free software; you can
7 * redistribute them and/or modify them under the terms of the GNU
8 * Lesser General Public License as published by the Free Software
9 * Foundation; either version 2 of the License, or (at your option)
12 * These libraries and programs are distributed in the hope that
13 * they will be useful, but WITHOUT ANY WARRANTY; without even the
14 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU Lesser General Public License for more
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with these librararies and programs; if not, write
20 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21 * Floor, Boston, MA 02110-1301 USA
24 * (c) Copyright 1989, 1990, 1991, 1992, 1993 OPEN SOFTWARE FOUNDATION, INC.
32 static char rcsid[] = "$XConsortium: WmImage.c /main/7 1996/11/14 13:50:30 rswiston $"
36 * (c) Copyright 1987, 1988, 1989, 1990 HEWLETT-PACKARD COMPANY */
44 #define MWM_NEED_IIMAGE
45 #include "WmIBitmap.h"
47 #ifdef MOTIF_ONE_DOT_ONE
50 #define MATCH_CHAR 'P' /* Default match character - defined in Xmos.p */
53 /* Copied from XmosI.h */
54 extern String _XmOSInitPath(
60 #include <Xm/IconFile.h>
61 #include <Dt/GetDispRes.h>
64 #define MATCH_XBM 'B' /* .xbm character: see XmGetPixmap */
65 #define MATCH_PATH "XBMLANGPATH"
68 * include extern functions
72 #include "WmGraphics.h"
73 #include "WmResource.h"
74 #include "WmResParse.h"
78 #ifdef MOTIF_ONE_DOT_ONE
79 extern char *getenv ();
83 /******************************<->*************************************
85 * MakeClientIconPixmap (pCD, iconBitmap, iconMask)
90 * This function takes a client supplied icon image pixmap and mask
91 * bitmap and makes it into a colored pixmap suitable for use as an
97 * pCD = pointer to client data (icon colors and tiles)
99 * iconBitmap = icon bitmap
100 * iconMask = mask bitmap
105 * RETURN = icon pixmap (NULL if error)
107 ******************************<->***********************************/
109 Pixmap MakeClientIconPixmap (
117 unsigned int bitmapWidth;
118 unsigned int bitmapHeight;
124 * Check out the attributes of the bitmap to insure that it is usable.
127 if (!XGetGeometry (DISPLAY, iconBitmap, &root, &x, &y,
128 &bitmapWidth, &bitmapHeight, &border, &depth))
130 Warning (((char *)GETMESSAGE(38, 1, "Invalid icon bitmap")));
131 return ((Pixmap)NULL);
134 if (ROOT_FOR_CLIENT(pCD) != root)
137 * The bitmap was not made with usable parameters.
140 Warning (((char *)GETMESSAGE(38, 9, "Icon bitmap cannot be used on this screen")));
142 Warning ("Invalid root for icon bitmap");
144 return ((Pixmap)NULL);
147 #ifdef DISALLOW_DEEP_ICONS
150 Warning (((char *)GETMESSAGE(38, 10, "Color icon pixmap not supported")));
151 return ((Pixmap)NULL);
156 * Color the bitmap, center it in a pixmap ....
159 return (MakeIconPixmap (pCD, iconBitmap, (Pixmap)iconMask,
160 bitmapWidth, bitmapHeight, depth));
163 } /* END OF FUNCTION MakeClientIconPixmap */
167 /*************************************<->*************************************
169 * MakeNamedIconPixmap (pCD, iconName)
174 * This function makes an icon pixmap for a particular client given the
175 * name of a bitmap file.
180 * pCD = (nonNULL) pointer to client data
181 * iconName = pointer to the icon name (bitmap file path name or NULL)
186 * RETURN = icon pixmap or NULL
188 *************************************<->***********************************/
190 Pixmap MakeNamedIconPixmap (ClientData *pCD, String iconName)
194 Pixmap pixmap, pixmap_r, mask;
197 unsigned int width, height, border_width, depth;
198 String sIconFileName;
203 * Get the bitmap cache entry (will read data from file if necessary).
204 * If unable to find the iconName file return NULL.
208 if ((bitmapIndex = GetBitmapIndex (PSD_FOR_CLIENT(pCD), iconName,
211 if ((bitmapIndex = GetBitmapIndex (PSD_FOR_CLIENT(pCD), iconName)) < 0)
215 if ((PSD_FOR_CLIENT(pCD)->displayResolutionType == LOW_RES_DISPLAY) ||
216 (PSD_FOR_CLIENT(pCD)->displayResolutionType == VGA_RES_DISPLAY))
218 iconSizeDesired = XmMEDIUM_ICON_SIZE;
222 iconSizeDesired = XmLARGE_ICON_SIZE;
225 pixmap = XmUNSPECIFIED_PIXMAP;
227 sIconFileName = XmGetIconFileName(
228 XtScreen(PSD_FOR_CLIENT(pCD)->screenTopLevelW1),
234 if (sIconFileName != NULL)
236 pixmap = XmGetPixmap (
237 XtScreen (PSD_FOR_CLIENT(pCD)->screenTopLevelW1),
239 pCD->iconImageForeground,
240 pCD->iconImageBackground);
243 if (pixmap == XmUNSPECIFIED_PIXMAP)
245 pixmap = XmGetPixmap (
246 XtScreen (PSD_FOR_CLIENT(pCD)->screenTopLevelW1),
248 pCD->iconImageForeground,
249 pCD->iconImageBackground);
252 if (pixmap == XmUNSPECIFIED_PIXMAP)
254 MWarning (((char *)GETMESSAGE(38, 7, "Unable to read bitmap file %s\n")), iconName);
258 mask = _DtGetMask (XtScreen(PSD_FOR_CLIENT(pCD)->screenTopLevelW1),
259 (sIconFileName == NULL) ? iconName : sIconFileName);
260 if (mask == XmUNSPECIFIED_PIXMAP)
262 mask = (Pixmap) NULL;
265 if (sIconFileName != NULL)
266 XtFree(sIconFileName);
269 * We need to synchronize DISPLAY1 here because the pixmap and mask
270 * were created on that display connection, and we must ensure that
271 * the server has processed those requests before we attempt to use
272 * the pixmap and mask on DISPLAY. We thus assume that the
273 * subsequent XGetGeometry() call is successful.
275 XSync(DISPLAY1, False);
277 (void) XGetGeometry (DISPLAY, pixmap, &root, &x, &y, &width,
278 &height, &border_width, &depth);
280 pixmap_r = MakeIconPixmap (pCD, pixmap, mask,
281 width, height, depth);
283 XmDestroyPixmap (XtScreen (PSD_FOR_CLIENT(pCD)->screenTopLevelW1),
287 XtScreen (PSD_FOR_CLIENT(pCD)->screenTopLevelW1), mask);
292 if (sIconFileName != NULL)
293 XtFree (sIconFileName);
295 return ((Pixmap)NULL);
299 * Color the bitmap, center it in a pixmap ....
302 return (MakeCachedIconPixmap (pCD, bitmapIndex, (Pixmap)NULL));
304 } /* END OF FUNCTION MakeNamedIconPixmap */
309 /*************************************<->*************************************
312 * MakeCachedIconPixmap (pCD, bitmapIndex, mask)
317 * Convert the cached bitmap and mask into an icon pixmap.
322 * pCD - (nonNULL) pointer to client data (icon colors and tiles)
323 * bitmapIndex - bitmap cache index of image to be converted
324 * mask - bitmap mask, 1 for bits of "bitmap" to be kept
329 * RETURN - icon pixmap or NULL
334 * o "mask" is not used.
336 *************************************<->***********************************/
337 Pixmap MakeCachedIconPixmap (ClientData *pCD, int bitmapIndex, Pixmap mask)
339 BitmapCache *bitmapc;
340 PixmapCache *pixmapc;
341 Pixmap pixmap = (Pixmap)NULL;
342 WmScreenData *pSD = PSD_FOR_CLIENT(pCD);
346 return ((Pixmap)NULL);
348 bitmapc = &(pSD->bitmapCache[bitmapIndex]);
351 * Search for an icon pixmap matching the client icon colors.
354 pixmapc = bitmapc->pixmapCache;
357 if ((pixmapc->pixmapType == ICON_PIXMAP) &&
358 (pixmapc->foreground == pCD->iconImageForeground) &&
359 (pixmapc->background == pCD->iconImageBackground))
361 pixmap = pixmapc->pixmap;
364 pixmapc = pixmapc->next;
368 * If a matching pixmap was not found in the pixmap cache for this bitmap
369 * then create the icon pixmap with the appropriate colors.
370 * If have sufficient memory, save the pixmap info in the pixmapCache.
374 (pixmap = MakeIconPixmap (pCD, bitmapc->bitmap, mask,
375 bitmapc->width, bitmapc->height, 1)) &&
376 (pixmapc = (PixmapCache *) XtMalloc (sizeof (PixmapCache))))
379 pixmapc->pixmapType = ICON_PIXMAP;
380 pixmapc->foreground = pCD->iconImageForeground;
381 pixmapc->background = pCD->iconImageBackground;
382 pixmapc->pixmap = pixmap;
383 pixmapc->next = bitmapc->pixmapCache;
384 bitmapc->pixmapCache = pixmapc;
389 } /* END OF FUNCTION MakeCachedIconPixmap */
393 /*************************************<->*************************************
395 * MakeIconPixmap (pCD, bitmap, mask, width, height, depth)
400 * Convert the bitmap and mask into an icon pixmap.
405 * pCD - pointer to client data (icon colors and tiles)
406 * pWS - pointer to workspace data
407 * bitmap - bitmap image to be converted
408 * mask - bitmap mask, 1 for bits of "bitmap" to be kept
409 * width - pixel width of bitmap
410 * height - pixel height of bitmap
411 * depth - depth of bitmap (pixmap, really)
416 * RETURN - icon pixmap or NULL
421 * o "mask" is not used.
423 *************************************<->***********************************/
424 Pixmap MakeIconPixmap (ClientData *pCD, Pixmap bitmap, Pixmap mask, unsigned int width, unsigned int height, unsigned int depth)
427 GC imageGC, topGC, botGC;
430 unsigned long gc_mask;
431 XmPixelSet *pPS = NULL;
433 unsigned int imageWidth;
434 unsigned int imageHeight;
436 #ifndef NO_CLIP_CENTER
438 #endif /* NO_CLIP_CENTER */
441 static RList *top_rects = NULL;
442 static RList *bot_rects = NULL;
445 if ((top_rects == NULL) &&
446 (top_rects = AllocateRList
447 ((unsigned)2 * ICON_INTERNAL_SHADOW_WIDTH)) == NULL)
450 Warning (((char *)GETMESSAGE(38, 3, "Insufficient memory to bevel icon image")));
451 return ((Pixmap)NULL);
454 if ((bot_rects == NULL) &&
455 (bot_rects = AllocateRList
456 ((unsigned)2 * ICON_INTERNAL_SHADOW_WIDTH)) == NULL)
459 Warning (((char *)GETMESSAGE(38, 4, "Insufficient memory to bevel icon image")));
460 return ((Pixmap)NULL);
469 pSD = wmGD.pActiveSD;
472 /* don't make icon pixmap if bitmap is too small */
474 if ((width < pSD->iconImageMinimum.width) ||
475 (height < pSD->iconImageMinimum.height))
477 /* bitmap is too small */
478 return ((Pixmap)NULL);
480 #ifndef NO_CLIP_CENTER
482 /* copy the center of the icon if too big */
483 if (width > pSD->iconImageMaximum.width)
485 src_x = (width - pSD->iconImageMaximum.width)/2;
491 if (height > pSD->iconImageMaximum.height)
493 src_y = (height - pSD->iconImageMaximum.height)/2;
499 #endif /* NO_CLIP_CENTER */
502 * SLAB frameStyle adds a single pixel of background color around
503 * the image to set it off from the beveling.
505 imageWidth = pSD->iconImageMaximum.width +
506 2 * ICON_INTERNAL_SHADOW_WIDTH +
507 ((wmGD.frameStyle == WmSLAB) ? 2 : 0);
508 imageHeight = pSD->iconImageMaximum.height +
509 2 * ICON_INTERNAL_SHADOW_WIDTH +
510 ((wmGD.frameStyle == WmSLAB) ? 2 : 0);
512 /* create a pixmap (to be returned) */
514 iconPixmap = XCreatePixmap (DISPLAY, pSD->rootWindow,
515 imageWidth, imageHeight,
516 DefaultDepth(DISPLAY, pSD->screen));
519 * If a client is not specified use icon component colors, otherwise
520 * use the client-specific icon colors.
525 bg = pCD->iconImageBackground;
526 fg = pCD->iconImageForeground;
530 bg = pSD->iconAppearance.background;
531 fg = pSD->iconAppearance.foreground;
534 /* create a GC to use */
536 gc_mask = GCForeground | GCBackground | GCGraphicsExposures;
539 if (pSD->pPrimaryPixelSet != NULL)
541 pPS = pSD->pPrimaryPixelSet;
542 gcv.background = pPS->bg;
543 /* set fg to bg color to clear it first */
544 gcv.foreground = pPS->bg;
548 gcv.background = ICON_APPEARANCE(pCD).background;
549 /* set fg to bg color to clear it first */
550 gcv.foreground = ICON_APPEARANCE(pCD).background;
555 gcv.foreground = bg; /* clear it first! */
558 gcv.graphics_exposures = False;
560 imageGC = XCreateGC (DISPLAY, iconPixmap, gc_mask, &gcv);
562 gcv.foreground = bg; /* clear it first! */
564 gcv.graphics_exposures = False;
566 imageGC = XCreateGC (DISPLAY, iconPixmap, (GCForeground|GCBackground),
574 /* fill in background */
576 XFillRectangle(DISPLAY, iconPixmap, imageGC, 0, 0,
577 imageWidth, imageHeight);
579 /* center the image */
581 if (width > pSD->iconImageMaximum.width)
583 width = pSD->iconImageMaximum.width;
585 if (height > pSD->iconImageMaximum.height)
587 height = pSD->iconImageMaximum.height;
589 /* center the image */
591 dest_x = (imageWidth - width) / 2;
592 dest_y = (imageHeight - height) / 2;
599 gcv.foreground = pPS->fg;
603 gcv.foreground = ICON_APPEARANCE(pCD).foreground;
610 gc_mask = GCForeground;
613 gcv.clip_mask = mask;
614 #ifndef NO_CLIP_CENTER
615 gcv.clip_x_origin = dest_x - src_x;
616 gcv.clip_y_origin = dest_y - src_y;
617 #else /* NO_CLIP_CENTER */
618 gcv.clip_x_origin = dest_x;
619 gcv.clip_y_origin = dest_y;
620 #endif /* NO_CLIP_CENTER */
621 gc_mask |= GCClipXOrigin | GCClipYOrigin | GCClipMask;
624 XChangeGC (DISPLAY, imageGC, gc_mask, &gcv);
626 /* set the foreground */
627 XSetForeground (DISPLAY, imageGC, fg);
630 /* copy the bitmap to the pixmap */
631 #ifndef DISALLOW_DEEP_ICONS
633 (depth == DefaultDepth(DISPLAY, pSD->screen)))
635 #ifndef NO_CLIP_CENTER
636 XCopyArea (DISPLAY, bitmap, iconPixmap, imageGC, src_x, src_y,
637 width, height, dest_x, dest_y);
638 #else /* NO_CLIP_CENTER */
639 XCopyArea (DISPLAY, bitmap, iconPixmap, imageGC, 0, 0,
640 width, height, dest_x, dest_y);
641 #endif /* NO_CLIP_CENTER */
644 #endif /* DISALLOW_DEEP_ICONS */
645 #ifndef NO_CLIP_CENTER
646 XCopyPlane (DISPLAY, bitmap, iconPixmap, imageGC, src_x, src_y, width,
647 height, dest_x, dest_y, 1L);
648 #else /* NO_CLIP_CENTER */
649 XCopyPlane (DISPLAY, bitmap, iconPixmap, imageGC, 0, 0, width, height,
651 #endif /* NO_CLIP_CENTER */
654 XFreeGC (DISPLAY, imageGC);
663 if (mask && (pPS != NULL))
665 topGC = GetHighlightGC (pSD, pPS->ts, pPS->bg,
666 pCD->iconImageTopShadowPixmap);
668 botGC = GetHighlightGC (pSD, pPS->bs, pPS->bg,
669 pCD->iconImageBottomShadowPixmap);
674 topGC = GetHighlightGC (pSD, pCD->iconImageTopShadowColor,
675 pCD->iconImageBackground,
676 pCD->iconImageTopShadowPixmap);
678 botGC = GetHighlightGC (pSD, pCD->iconImageBottomShadowColor,
679 pCD->iconImageBackground,
680 pCD->iconImageBottomShadowPixmap);
686 * CR5208 - Better fix than from OSF!
687 * Zero out the rectangle count in our
688 * static structures so that BevelRectangle
689 * won't extend the RList causing a memory leak.
690 * Old fix allocated and freed rectangle structure
693 top_rects->used = 0; /* reset count */
696 BevelRectangle (top_rects,
699 imageWidth, imageHeight,
700 ICON_INTERNAL_SHADOW_WIDTH,
701 ICON_INTERNAL_SHADOW_WIDTH,
702 ICON_INTERNAL_SHADOW_WIDTH,
703 ICON_INTERNAL_SHADOW_WIDTH);
705 XFillRectangles (DISPLAY, iconPixmap, topGC, top_rects->prect,
707 XFillRectangles (DISPLAY, iconPixmap, botGC, bot_rects->prect,
712 } /* END OF FUNCTION MakeIconPixmap */
716 /*************************************<->*************************************
719 * MakeCachedLabelPixmap (pSD, menuW, bitmapIndex)
724 * Creates and returns a label pixmap.
729 * pSD = pointer to screen data
730 * menuW = menu widget (for foreground and background colors)
731 * bitmapIndex = bitmap cache index
736 * Return = label pixmap or NULL.
741 * Assumes bitmapIndex is valid.
743 *************************************<->***********************************/
745 Pixmap MakeCachedLabelPixmap (WmScreenData *pSD, Widget menuW, int bitmapIndex)
747 BitmapCache *bitmapc;
748 PixmapCache *pixmapc;
752 Pixmap pixmap = (Pixmap)NULL;
758 return ((Pixmap)NULL);
760 bitmapc = &(pSD->bitmapCache[bitmapIndex]);
763 * Get the foreground and background colors from the menu widget.
764 * Search for a label pixmap matching those colors.
768 XtSetArg (args[i], XtNforeground, &fg); i++;
769 XtSetArg (args[i], XtNbackground, &bg); i++;
770 XtGetValues (menuW, (ArgList)args, i);
772 pixmapc = bitmapc->pixmapCache;
775 if ((pixmapc->pixmapType == LABEL_PIXMAP) &&
776 (pixmapc->foreground == fg) &&
777 (pixmapc->background == bg))
779 pixmap = pixmapc->pixmap;
782 pixmapc = pixmapc->next;
787 * A matching pixmap was not found in the pixmap cache for this bitmap.
788 * Create and save the label pixmap with appropriate colors.
792 * Create a pixmap of the appropriate size, root, and depth.
793 * Only BadAlloc error possible; BadDrawable and BadValue are avoided.
796 pixmap = XCreatePixmap (DISPLAY, pSD->rootWindow,
797 bitmapc->width, bitmapc->height,
798 DefaultDepth (DISPLAY, pSD->screen));
801 * Create a GC and copy the bitmap to the pixmap.
802 * Only BadAlloc and BadDrawable errors are possible; others are avoided
807 gcv.graphics_exposures = False;
808 gc = XCreateGC(DISPLAY, pixmap, (GCForeground|GCBackground), &gcv);
811 * Fill in the background, set the foreground, copy the bitmap to the
812 * pixmap, and free the gc.
815 XFillRectangle (DISPLAY, pixmap, gc, 0, 0,
816 bitmapc->width, bitmapc->height);
817 XSetForeground (DISPLAY, gc, fg);
818 XCopyPlane (DISPLAY, bitmapc->bitmap, pixmap, gc, 0, 0,
819 bitmapc->width, bitmapc->height, 0, 0, 1L);
820 XFreeGC (DISPLAY, gc);
823 * If have sufficient memory, save the pixmap info in the pixmapCache.
826 if ((pixmapc = (PixmapCache *) XtMalloc(sizeof(PixmapCache))) != NULL)
828 pixmapc->pixmapType = LABEL_PIXMAP;
829 pixmapc->foreground = fg;
830 pixmapc->background = bg;
831 pixmapc->pixmap = pixmap;
832 pixmapc->next = bitmapc->pixmapCache;
833 bitmapc->pixmapCache = pixmapc;
839 } /* END OF FUNCTION MakeCachedLabelPixmap */
843 /*************************************<->*************************************
846 * GetBitmapIndex (pSD, name)
851 * Retrieve bitmap from cache.
856 * pSD = pointer to screen data
857 * name = bitmap file name or NULL pointer
868 * Return = bitmap cache index or -1
875 *************************************<->***********************************/
877 #define BITMAP_CACHE_INC 5
880 int GetBitmapIndex (WmScreenData *pSD, char *name, Boolean bReportError)
882 int GetBitmapIndex (WmScreenData *pSD, char *name)
886 BitmapCache *bitmapc;
891 * Search a nonempty bitmap cache for a pathname match.
893 path = BitmapPathName (name);
894 for (n = 0, bitmapc = pSD->bitmapCache;
895 n < pSD->bitmapCacheCount;
898 if ((!path && !bitmapc->path) ||
899 (path && bitmapc->path &&
900 !strcmp (path, bitmapc->path)))
907 * The bitmap path name was not found in bitmapCache.
908 * Find the next BitmapCache entry, creating or enlarging bitmapCache if
911 if (pSD->bitmapCacheSize == 0)
914 pSD->bitmapCacheSize = BITMAP_CACHE_INC;
916 (BitmapCache *) XtMalloc (BITMAP_CACHE_INC * sizeof (BitmapCache));
918 else if (pSD->bitmapCacheCount == pSD->bitmapCacheSize)
921 pSD->bitmapCacheSize += BITMAP_CACHE_INC;
922 pSD->bitmapCache = (BitmapCache *)
923 XtRealloc ((char*)pSD->bitmapCache,
924 pSD->bitmapCacheSize * sizeof (BitmapCache));
927 if (pSD->bitmapCache == NULL)
929 MWarning (((char *)GETMESSAGE(38, 5, "Insufficient memory for bitmap %s\n")), name);
930 pSD->bitmapCacheSize = 0;
931 pSD->bitmapCacheCount = 0;
935 bitmapc = &(pSD->bitmapCache[pSD->bitmapCacheCount]);
938 * Fill the entry with the bitmap info.
939 * A NULL path indicates the builtin icon bitmap.
940 * Indicate that no pixmapCache exists yet.
945 if ((bitmapc->path = (String)
946 XtMalloc ((unsigned int)(strlen (path) + 1))) == NULL)
948 MWarning (((char *)GETMESSAGE(38, 6, "Insufficient memory for bitmap %s\n")), name);
951 strcpy (bitmapc->path, path);
953 if (XReadBitmapFile (DISPLAY, pSD->rootWindow, path,
954 &bitmapc->width, &bitmapc->height,
955 &bitmapc->bitmap, &x, &y)
961 MWarning (((char *)GETMESSAGE(38, 7, "Unable to read bitmap file %s\n")), path);
962 XtFree ((char *)bitmapc->path);
966 if (bitmapc->width == 0 || bitmapc->height == 0)
971 MWarning (((char *)GETMESSAGE(38, 8, "Invalid bitmap file %s\n")), path);
972 XtFree ((char *)bitmapc->path);
977 /* builtin icon bitmap */
979 bitmapc->path = NULL;
980 bitmapc->bitmap = pSD->builtinIconPixmap;
981 bitmapc->width = iImage_width;
982 bitmapc->height = iImage_height;
985 bitmapc->pixmapCache = NULL;
987 return (pSD->bitmapCacheCount++);
989 } /* END OF FUNCTION GetBitmapIndex */
993 /*************************************<->*************************************
995 * BitmapPathName (string)
1000 * Constructs a bitmap file pathname from the bitmap file name and the
1001 * bitmapDirectory resource value.
1006 * string = bitmap file name or NULL
1007 * wmGD.bitmapDirectory = bitmapDirectory resource value
1008 * HOME = environment variable for home directory
1015 * Return = string containing the bitmap file pathname or NULL.
1020 * If the bitmap file does not exist, searches using XBMLANGPATH.
1021 * Returns NULL path name for a NULL file name.
1023 *************************************<->***********************************/
1025 char *BitmapPathName (string)
1029 static char fileName[MAXWMPATH+1];
1031 SubstitutionRec subs[1];
1032 #ifndef MOTIF_ONE_DOT_ONE
1033 char *homeDir = XmeGetHomeDirName();
1036 if (!string || !*string)
1042 * Interpret "~/.." as relative to the user's home directory.
1043 * Interpret "/.." as an absolute pathname.
1044 * If the bitmapDirectory resource is nonNULL, interpret path as relative
1046 * Else, or if bitmapDirectory has no such file, use a XBMLANGPATH lookup.
1049 if ((string[0] == '~') && (string[1] == '/'))
1054 #ifdef MOTIF_ONE_DOT_ONE
1055 GetHomeDirName(fileName);
1057 strcpy (fileName, homeDir);
1059 strncat (fileName, &(string[1]), MAXWMPATH - strlen (fileName));
1063 if (string[0] == '/')
1068 if (wmGD.bitmapDirectory && *wmGD.bitmapDirectory)
1070 * Relative to nonNULL bitmapDirectory (which may have relative to HOME)
1073 if ((wmGD.bitmapDirectory[0] == '~') &&
1074 (wmGD.bitmapDirectory[1] == '/'))
1076 #ifdef MOTIF_ONE_DOT_ONE
1077 GetHomeDirName(fileName);
1079 strcpy (fileName, homeDir);
1081 strncat (fileName, &wmGD.bitmapDirectory[1],
1082 MAXWMPATH - strlen (fileName));
1084 strcpy (fileName, wmGD.bitmapDirectory);
1086 strncat (fileName, "/", MAXWMPATH - strlen (fileName));
1087 strncat (fileName, string, MAXWMPATH - strlen (fileName));
1089 /* Test file for existence. */
1091 subs[0].substitution = "";
1092 if ((retname = XtFindFile(fileName, subs, 0,
1093 (XtFilePredicate) NULL)) != NULL) {
1099 /* Fall back on a path search */
1101 #ifdef MOTIF_ONE_DOT_ONE
1108 search_path = _XmOSInitPath(string, MATCH_PATH, &user_path);
1109 subs[0].match = user_path ? MATCH_XBM : MATCH_CHAR;
1110 subs[0].substitution = string;
1111 retname = XtResolvePathname(DISPLAY, "bitmaps", NULL, NULL,
1112 search_path, subs, XtNumber(subs),
1113 (XtFilePredicate)NULL);
1114 XtFree(search_path);
1119 strncpy(fileName, retname, MAXWMPATH);
1125 } /* END OF FUNCTION BitmapPathName */
1128 /**************************** eof ***************************/