1054 lines
26 KiB
C
1054 lines
26 KiB
C
/*
|
|
* CDE - Common Desktop Environment
|
|
*
|
|
* Copyright (c) 1993-2012, The Open Group. All rights reserved.
|
|
*
|
|
* These libraries and programs are free software; you can
|
|
* redistribute them and/or modify them under the terms of the GNU
|
|
* Lesser General Public License as published by the Free Software
|
|
* Foundation; either version 2 of the License, or (at your option)
|
|
* any later version.
|
|
*
|
|
* These libraries and programs are distributed in the hope that
|
|
* they will be useful, but WITHOUT ANY WARRANTY; without even the
|
|
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
|
* PURPOSE. See the GNU Lesser General Public License for more
|
|
* details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with these libraries and programs; if not, write
|
|
* to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
|
|
* Floor, Boston, MA 02110-1301 USA
|
|
*/
|
|
/*
|
|
* (c) Copyright 1989, 1990, 1991, 1992, 1993 OPEN SOFTWARE FOUNDATION, INC.
|
|
* ALL RIGHTS RESERVED
|
|
*/
|
|
/*
|
|
* Motif Release 1.2.3
|
|
*/
|
|
/*
|
|
* (c) Copyright 1987, 1988, 1989, 1990 HEWLETT-PACKARD COMPANY */
|
|
|
|
/*
|
|
* Included Files:
|
|
*/
|
|
|
|
#include "WmGlobal.h"
|
|
|
|
#define MWM_NEED_IIMAGE
|
|
#include "WmIBitmap.h"
|
|
|
|
#include <Xm/XmosP.h>
|
|
/* Copied from XmosI.h */
|
|
extern String _XmOSInitPath(
|
|
String file_name,
|
|
String env_pathname,
|
|
Boolean *user_path) ;
|
|
#include <Xm/IconFile.h>
|
|
#include <Dt/GetDispRes.h>
|
|
|
|
#define MATCH_XBM 'B' /* .xbm character: see XmGetPixmap */
|
|
#define MATCH_PATH "XBMLANGPATH"
|
|
|
|
/*
|
|
* include extern functions
|
|
*/
|
|
|
|
#include "WmImage.h"
|
|
#include "WmGraphics.h"
|
|
#include "WmResource.h"
|
|
#include "WmResParse.h"
|
|
#include "WmMenu.h"
|
|
#include "WmError.h"
|
|
|
|
/******************************<->*************************************
|
|
*
|
|
* MakeClientIconPixmap (pCD, iconBitmap, iconMask)
|
|
*
|
|
*
|
|
* Description:
|
|
* -----------
|
|
* This function takes a client supplied icon image pixmap and mask
|
|
* bitmap and makes it into a colored pixmap suitable for use as an
|
|
* icon image.
|
|
*
|
|
*
|
|
* Inputs:
|
|
* ------
|
|
* pCD = pointer to client data (icon colors and tiles)
|
|
*
|
|
* iconBitmap = icon bitmap
|
|
* iconMask = mask bitmap
|
|
*
|
|
*
|
|
* Outputs:
|
|
* -------
|
|
* RETURN = icon pixmap (NULL if error)
|
|
*
|
|
******************************<->***********************************/
|
|
|
|
Pixmap MakeClientIconPixmap (
|
|
ClientData *pCD,
|
|
Pixmap iconBitmap,
|
|
Pixmap iconMask)
|
|
{
|
|
Window root;
|
|
int x;
|
|
int y;
|
|
unsigned int bitmapWidth;
|
|
unsigned int bitmapHeight;
|
|
unsigned int border;
|
|
unsigned int depth;
|
|
|
|
|
|
/*
|
|
* Check out the attributes of the bitmap to insure that it is usable.
|
|
*/
|
|
|
|
if (!XGetGeometry (DISPLAY, iconBitmap, &root, &x, &y,
|
|
&bitmapWidth, &bitmapHeight, &border, &depth))
|
|
{
|
|
Warning (((char *)GETMESSAGE(38, 1, "Invalid icon bitmap")));
|
|
return ((Pixmap)NULL);
|
|
}
|
|
|
|
if (ROOT_FOR_CLIENT(pCD) != root)
|
|
{
|
|
/*
|
|
* The bitmap was not made with usable parameters.
|
|
*/
|
|
Warning (((char *)GETMESSAGE(38, 9, "Icon bitmap cannot be used on this screen")));
|
|
return ((Pixmap)NULL);
|
|
}
|
|
|
|
#ifdef DISALLOW_DEEP_ICONS
|
|
if (depth != 1)
|
|
{
|
|
Warning (((char *)GETMESSAGE(38, 10, "Color icon pixmap not supported")));
|
|
return ((Pixmap)NULL);
|
|
}
|
|
#endif
|
|
|
|
/*
|
|
* Color the bitmap, center it in a pixmap ....
|
|
*/
|
|
|
|
return (MakeIconPixmap (pCD, iconBitmap, (Pixmap)iconMask,
|
|
bitmapWidth, bitmapHeight, depth));
|
|
|
|
|
|
} /* END OF FUNCTION MakeClientIconPixmap */
|
|
|
|
|
|
|
|
/*************************************<->*************************************
|
|
*
|
|
* MakeNamedIconPixmap (pCD, iconName)
|
|
*
|
|
*
|
|
* Description:
|
|
* -----------
|
|
* This function makes an icon pixmap for a particular client given the
|
|
* name of a bitmap file.
|
|
*
|
|
*
|
|
* Inputs:
|
|
* ------
|
|
* pCD = (nonNULL) pointer to client data
|
|
* iconName = pointer to the icon name (bitmap file path name or NULL)
|
|
*
|
|
*
|
|
* Outputs:
|
|
* -------
|
|
* RETURN = icon pixmap or NULL
|
|
*
|
|
*************************************<->***********************************/
|
|
|
|
Pixmap MakeNamedIconPixmap (ClientData *pCD, String iconName)
|
|
{
|
|
int bitmapIndex;
|
|
Pixmap pixmap, pixmap_r, mask;
|
|
Window root;
|
|
int x, y;
|
|
unsigned int width, height, border_width, depth;
|
|
String sIconFileName;
|
|
int iconSizeDesired;
|
|
|
|
/*
|
|
* Get the bitmap cache entry (will read data from file if necessary).
|
|
* If unable to find the iconName file return NULL.
|
|
*/
|
|
|
|
if ((bitmapIndex = GetBitmapIndex (PSD_FOR_CLIENT(pCD), iconName,
|
|
False)) < 0)
|
|
{
|
|
if ((PSD_FOR_CLIENT(pCD)->displayResolutionType == LOW_RES_DISPLAY) ||
|
|
(PSD_FOR_CLIENT(pCD)->displayResolutionType == VGA_RES_DISPLAY))
|
|
{
|
|
iconSizeDesired = XmMEDIUM_ICON_SIZE;
|
|
}
|
|
else
|
|
{
|
|
iconSizeDesired = XmLARGE_ICON_SIZE;
|
|
}
|
|
|
|
pixmap = XmUNSPECIFIED_PIXMAP;
|
|
|
|
sIconFileName = XmGetIconFileName(
|
|
XtScreen(PSD_FOR_CLIENT(pCD)->screenTopLevelW1),
|
|
NULL,
|
|
iconName,
|
|
NULL,
|
|
iconSizeDesired);
|
|
|
|
if (sIconFileName != NULL)
|
|
{
|
|
pixmap = XmGetPixmap (
|
|
XtScreen (PSD_FOR_CLIENT(pCD)->screenTopLevelW1),
|
|
sIconFileName,
|
|
pCD->iconImageForeground,
|
|
pCD->iconImageBackground);
|
|
}
|
|
|
|
if (pixmap == XmUNSPECIFIED_PIXMAP)
|
|
{
|
|
pixmap = XmGetPixmap (
|
|
XtScreen (PSD_FOR_CLIENT(pCD)->screenTopLevelW1),
|
|
iconName,
|
|
pCD->iconImageForeground,
|
|
pCD->iconImageBackground);
|
|
}
|
|
|
|
if (pixmap == XmUNSPECIFIED_PIXMAP)
|
|
{
|
|
MWarning (((char *)GETMESSAGE(38, 7, "Unable to read bitmap file %s\n")), iconName);
|
|
}
|
|
else
|
|
{
|
|
mask = XmeGetMask (XtScreen(PSD_FOR_CLIENT(pCD)->screenTopLevelW1),
|
|
(sIconFileName == NULL) ? iconName : sIconFileName);
|
|
if (mask == XmUNSPECIFIED_PIXMAP)
|
|
{
|
|
mask = (Pixmap) NULL;
|
|
}
|
|
|
|
if (sIconFileName != NULL)
|
|
XtFree(sIconFileName);
|
|
|
|
/*
|
|
* We need to synchronize DISPLAY1 here because the pixmap and mask
|
|
* were created on that display connection, and we must ensure that
|
|
* the server has processed those requests before we attempt to use
|
|
* the pixmap and mask on DISPLAY. We thus assume that the
|
|
* subsequent XGetGeometry() call is successful.
|
|
*/
|
|
XSync(DISPLAY1, False);
|
|
|
|
(void) XGetGeometry (DISPLAY, pixmap, &root, &x, &y, &width,
|
|
&height, &border_width, &depth);
|
|
|
|
pixmap_r = MakeIconPixmap (pCD, pixmap, mask,
|
|
width, height, depth);
|
|
|
|
XmDestroyPixmap (XtScreen (PSD_FOR_CLIENT(pCD)->screenTopLevelW1),
|
|
pixmap);
|
|
if (mask)
|
|
XmDestroyPixmap (
|
|
XtScreen (PSD_FOR_CLIENT(pCD)->screenTopLevelW1), mask);
|
|
|
|
return (pixmap_r);
|
|
}
|
|
|
|
if (sIconFileName != NULL)
|
|
XtFree (sIconFileName);
|
|
return ((Pixmap)NULL);
|
|
}
|
|
|
|
/*
|
|
* Color the bitmap, center it in a pixmap ....
|
|
*/
|
|
|
|
return (MakeCachedIconPixmap (pCD, bitmapIndex, (Pixmap)NULL));
|
|
|
|
} /* END OF FUNCTION MakeNamedIconPixmap */
|
|
|
|
|
|
|
|
|
|
/*************************************<->*************************************
|
|
*
|
|
* Pixmap
|
|
* MakeCachedIconPixmap (pCD, bitmapIndex, mask)
|
|
*
|
|
*
|
|
* Description:
|
|
* -----------
|
|
* Convert the cached bitmap and mask into an icon pixmap.
|
|
*
|
|
*
|
|
* Inputs:
|
|
* ------
|
|
* pCD - (nonNULL) pointer to client data (icon colors and tiles)
|
|
* bitmapIndex - bitmap cache index of image to be converted
|
|
* mask - bitmap mask, 1 for bits of "bitmap" to be kept
|
|
*
|
|
*
|
|
* Outputs:
|
|
* -------
|
|
* RETURN - icon pixmap or NULL
|
|
*
|
|
*
|
|
* Comments:
|
|
* --------
|
|
* o "mask" is not used.
|
|
*
|
|
*************************************<->***********************************/
|
|
Pixmap MakeCachedIconPixmap (ClientData *pCD, int bitmapIndex, Pixmap mask)
|
|
{
|
|
BitmapCache *bitmapc;
|
|
PixmapCache *pixmapc;
|
|
Pixmap pixmap = (Pixmap)NULL;
|
|
WmScreenData *pSD = PSD_FOR_CLIENT(pCD);
|
|
|
|
if (bitmapIndex < 0)
|
|
{
|
|
return ((Pixmap)NULL);
|
|
}
|
|
bitmapc = &(pSD->bitmapCache[bitmapIndex]);
|
|
|
|
/*
|
|
* Search for an icon pixmap matching the client icon colors.
|
|
*/
|
|
|
|
pixmapc = bitmapc->pixmapCache;
|
|
while (pixmapc)
|
|
{
|
|
if ((pixmapc->pixmapType == ICON_PIXMAP) &&
|
|
(pixmapc->foreground == pCD->iconImageForeground) &&
|
|
(pixmapc->background == pCD->iconImageBackground))
|
|
{
|
|
pixmap = pixmapc->pixmap;
|
|
break;
|
|
}
|
|
pixmapc = pixmapc->next;
|
|
}
|
|
|
|
/*
|
|
* If a matching pixmap was not found in the pixmap cache for this bitmap
|
|
* then create the icon pixmap with the appropriate colors.
|
|
* If have sufficient memory, save the pixmap info in the pixmapCache.
|
|
*/
|
|
|
|
if (!pixmap &&
|
|
(pixmap = MakeIconPixmap (pCD, bitmapc->bitmap, mask,
|
|
bitmapc->width, bitmapc->height, 1)) &&
|
|
(pixmapc = (PixmapCache *) XtMalloc (sizeof (PixmapCache))))
|
|
{
|
|
|
|
pixmapc->pixmapType = ICON_PIXMAP;
|
|
pixmapc->foreground = pCD->iconImageForeground;
|
|
pixmapc->background = pCD->iconImageBackground;
|
|
pixmapc->pixmap = pixmap;
|
|
pixmapc->next = bitmapc->pixmapCache;
|
|
bitmapc->pixmapCache = pixmapc;
|
|
}
|
|
|
|
return (pixmap);
|
|
|
|
} /* END OF FUNCTION MakeCachedIconPixmap */
|
|
|
|
|
|
|
|
/*************************************<->*************************************
|
|
*
|
|
* MakeIconPixmap (pCD, bitmap, mask, width, height, depth)
|
|
*
|
|
*
|
|
* Description:
|
|
* -----------
|
|
* Convert the bitmap and mask into an icon pixmap.
|
|
*
|
|
*
|
|
* Inputs:
|
|
* ------
|
|
* pCD - pointer to client data (icon colors and tiles)
|
|
* pWS - pointer to workspace data
|
|
* bitmap - bitmap image to be converted
|
|
* mask - bitmap mask, 1 for bits of "bitmap" to be kept
|
|
* width - pixel width of bitmap
|
|
* height - pixel height of bitmap
|
|
* depth - depth of bitmap (pixmap, really)
|
|
*
|
|
*
|
|
* Outputs:
|
|
* -------
|
|
* RETURN - icon pixmap or NULL
|
|
*
|
|
*
|
|
* Comments:
|
|
* --------
|
|
* o "mask" is not used.
|
|
*
|
|
*************************************<->***********************************/
|
|
Pixmap MakeIconPixmap (ClientData *pCD, Pixmap bitmap, Pixmap mask, unsigned int width, unsigned int height, unsigned int depth)
|
|
{
|
|
Pixmap iconPixmap;
|
|
GC imageGC, topGC, botGC;
|
|
XGCValues gcv;
|
|
unsigned long gc_mask;
|
|
XmPixelSet *pPS = NULL;
|
|
unsigned int imageWidth;
|
|
unsigned int imageHeight;
|
|
int dest_x, dest_y;
|
|
#ifndef NO_CLIP_CENTER
|
|
int src_x, src_y;
|
|
#endif /* NO_CLIP_CENTER */
|
|
Pixel fg;
|
|
Pixel bg;
|
|
static RList *top_rects = NULL;
|
|
static RList *bot_rects = NULL;
|
|
WmScreenData *pSD;
|
|
|
|
if ((top_rects == NULL) &&
|
|
(top_rects = AllocateRList
|
|
((unsigned)2 * ICON_INTERNAL_SHADOW_WIDTH)) == NULL)
|
|
{
|
|
/* Out of memory! */
|
|
Warning (((char *)GETMESSAGE(38, 3, "Insufficient memory to bevel icon image")));
|
|
return ((Pixmap)NULL);
|
|
}
|
|
|
|
if ((bot_rects == NULL) &&
|
|
(bot_rects = AllocateRList
|
|
((unsigned)2 * ICON_INTERNAL_SHADOW_WIDTH)) == NULL)
|
|
{
|
|
/* Out of memory! */
|
|
Warning (((char *)GETMESSAGE(38, 4, "Insufficient memory to bevel icon image")));
|
|
return ((Pixmap)NULL);
|
|
}
|
|
|
|
if (pCD)
|
|
{
|
|
pSD = pCD->pSD;
|
|
}
|
|
else
|
|
{
|
|
pSD = wmGD.pActiveSD;
|
|
}
|
|
|
|
/* don't make icon pixmap if bitmap is too small */
|
|
|
|
if ((width < pSD->iconImageMinimum.width) ||
|
|
(height < pSD->iconImageMinimum.height))
|
|
{
|
|
/* bitmap is too small */
|
|
return ((Pixmap)NULL);
|
|
}
|
|
#ifndef NO_CLIP_CENTER
|
|
|
|
/* copy the center of the icon if too big */
|
|
if (width > pSD->iconImageMaximum.width)
|
|
{
|
|
src_x = (width - pSD->iconImageMaximum.width)/2;
|
|
}
|
|
else
|
|
{
|
|
src_x = 0;
|
|
}
|
|
if (height > pSD->iconImageMaximum.height)
|
|
{
|
|
src_y = (height - pSD->iconImageMaximum.height)/2;
|
|
}
|
|
else
|
|
{
|
|
src_y = 0;
|
|
}
|
|
#endif /* NO_CLIP_CENTER */
|
|
|
|
/*
|
|
* SLAB frameStyle adds a single pixel of background color around
|
|
* the image to set it off from the beveling.
|
|
*/
|
|
imageWidth = pSD->iconImageMaximum.width +
|
|
2 * ICON_INTERNAL_SHADOW_WIDTH +
|
|
((wmGD.frameStyle == WmSLAB) ? 2 : 0);
|
|
imageHeight = pSD->iconImageMaximum.height +
|
|
2 * ICON_INTERNAL_SHADOW_WIDTH +
|
|
((wmGD.frameStyle == WmSLAB) ? 2 : 0);
|
|
|
|
/* create a pixmap (to be returned) */
|
|
|
|
iconPixmap = XCreatePixmap (DISPLAY, pSD->rootWindow,
|
|
imageWidth, imageHeight,
|
|
DefaultDepth(DISPLAY, pSD->screen));
|
|
|
|
/*
|
|
* If a client is not specified use icon component colors, otherwise
|
|
* use the client-specific icon colors.
|
|
*/
|
|
|
|
if (pCD)
|
|
{
|
|
bg = pCD->iconImageBackground;
|
|
fg = pCD->iconImageForeground;
|
|
}
|
|
else
|
|
{
|
|
bg = pSD->iconAppearance.background;
|
|
fg = pSD->iconAppearance.foreground;
|
|
}
|
|
|
|
/* create a GC to use */
|
|
gc_mask = GCForeground | GCBackground | GCGraphicsExposures;
|
|
if (mask)
|
|
{
|
|
if (pSD->pPrimaryPixelSet != NULL)
|
|
{
|
|
pPS = pSD->pPrimaryPixelSet;
|
|
gcv.background = pPS->bg;
|
|
/* set fg to bg color to clear it first */
|
|
gcv.foreground = pPS->bg;
|
|
}
|
|
else
|
|
{
|
|
gcv.background = ICON_APPEARANCE(pCD).background;
|
|
/* set fg to bg color to clear it first */
|
|
gcv.foreground = ICON_APPEARANCE(pCD).background;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
gcv.foreground = bg; /* clear it first! */
|
|
gcv.background = bg;
|
|
}
|
|
gcv.graphics_exposures = False;
|
|
|
|
imageGC = XCreateGC (DISPLAY, iconPixmap, gc_mask, &gcv);
|
|
|
|
/*
|
|
* Format the image.
|
|
*/
|
|
|
|
/* fill in background */
|
|
|
|
XFillRectangle(DISPLAY, iconPixmap, imageGC, 0, 0,
|
|
imageWidth, imageHeight);
|
|
|
|
/* center the image */
|
|
|
|
if (width > pSD->iconImageMaximum.width)
|
|
{
|
|
width = pSD->iconImageMaximum.width;
|
|
}
|
|
if (height > pSD->iconImageMaximum.height)
|
|
{
|
|
height = pSD->iconImageMaximum.height;
|
|
}
|
|
/* center the image */
|
|
|
|
dest_x = (imageWidth - width) / 2;
|
|
dest_y = (imageHeight - height) / 2;
|
|
|
|
if (mask)
|
|
{
|
|
if (pPS != NULL)
|
|
{
|
|
gcv.foreground = pPS->fg;
|
|
}
|
|
else
|
|
{
|
|
gcv.foreground = ICON_APPEARANCE(pCD).foreground;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
gcv.foreground = fg;
|
|
}
|
|
gc_mask = GCForeground;
|
|
if (mask)
|
|
{
|
|
gcv.clip_mask = mask;
|
|
#ifndef NO_CLIP_CENTER
|
|
gcv.clip_x_origin = dest_x - src_x;
|
|
gcv.clip_y_origin = dest_y - src_y;
|
|
#else /* NO_CLIP_CENTER */
|
|
gcv.clip_x_origin = dest_x;
|
|
gcv.clip_y_origin = dest_y;
|
|
#endif /* NO_CLIP_CENTER */
|
|
gc_mask |= GCClipXOrigin | GCClipYOrigin | GCClipMask;
|
|
}
|
|
|
|
XChangeGC (DISPLAY, imageGC, gc_mask, &gcv);
|
|
|
|
/* copy the bitmap to the pixmap */
|
|
#ifndef DISALLOW_DEEP_ICONS
|
|
if ((depth > 1) &&
|
|
(depth == DefaultDepth(DISPLAY, pSD->screen)))
|
|
{
|
|
#ifndef NO_CLIP_CENTER
|
|
XCopyArea (DISPLAY, bitmap, iconPixmap, imageGC, src_x, src_y,
|
|
width, height, dest_x, dest_y);
|
|
#else /* NO_CLIP_CENTER */
|
|
XCopyArea (DISPLAY, bitmap, iconPixmap, imageGC, 0, 0,
|
|
width, height, dest_x, dest_y);
|
|
#endif /* NO_CLIP_CENTER */
|
|
}
|
|
else
|
|
#endif /* DISALLOW_DEEP_ICONS */
|
|
#ifndef NO_CLIP_CENTER
|
|
XCopyPlane (DISPLAY, bitmap, iconPixmap, imageGC, src_x, src_y, width,
|
|
height, dest_x, dest_y, 1L);
|
|
#else /* NO_CLIP_CENTER */
|
|
XCopyPlane (DISPLAY, bitmap, iconPixmap, imageGC, 0, 0, width, height,
|
|
dest_x, dest_y, 1L);
|
|
#endif /* NO_CLIP_CENTER */
|
|
|
|
/* free resources */
|
|
XFreeGC (DISPLAY, imageGC);
|
|
|
|
if (pCD)
|
|
{
|
|
/*
|
|
* Shadowing
|
|
*/
|
|
|
|
if (mask && (pPS != NULL))
|
|
{
|
|
topGC = GetHighlightGC (pSD, pPS->ts, pPS->bg,
|
|
pCD->iconImageTopShadowPixmap);
|
|
|
|
botGC = GetHighlightGC (pSD, pPS->bs, pPS->bg,
|
|
pCD->iconImageBottomShadowPixmap);
|
|
}
|
|
else
|
|
{
|
|
topGC = GetHighlightGC (pSD, pCD->iconImageTopShadowColor,
|
|
pCD->iconImageBackground,
|
|
pCD->iconImageTopShadowPixmap);
|
|
|
|
botGC = GetHighlightGC (pSD, pCD->iconImageBottomShadowColor,
|
|
pCD->iconImageBackground,
|
|
pCD->iconImageBottomShadowPixmap);
|
|
}
|
|
|
|
/*
|
|
* CR5208 - Better fix than from OSF!
|
|
* Zero out the rectangle count in our
|
|
* static structures so that BevelRectangle
|
|
* won't extend the RList causing a memory leak.
|
|
* Old fix allocated and freed rectangle structure
|
|
* each time through.
|
|
*/
|
|
top_rects->used = 0; /* reset count */
|
|
bot_rects->used = 0;
|
|
|
|
BevelRectangle (top_rects,
|
|
bot_rects,
|
|
0, 0,
|
|
imageWidth, imageHeight,
|
|
ICON_INTERNAL_SHADOW_WIDTH,
|
|
ICON_INTERNAL_SHADOW_WIDTH,
|
|
ICON_INTERNAL_SHADOW_WIDTH,
|
|
ICON_INTERNAL_SHADOW_WIDTH);
|
|
|
|
XFillRectangles (DISPLAY, iconPixmap, topGC, top_rects->prect,
|
|
top_rects->used);
|
|
XFillRectangles (DISPLAY, iconPixmap, botGC, bot_rects->prect,
|
|
bot_rects->used);
|
|
}
|
|
return (iconPixmap);
|
|
|
|
} /* END OF FUNCTION MakeIconPixmap */
|
|
|
|
|
|
|
|
/*************************************<->*************************************
|
|
*
|
|
* Pixmap
|
|
* MakeCachedLabelPixmap (pSD, menuW, bitmapIndex)
|
|
*
|
|
*
|
|
* Description:
|
|
* -----------
|
|
* Creates and returns a label pixmap.
|
|
*
|
|
*
|
|
* Inputs:
|
|
* ------
|
|
* pSD = pointer to screen data
|
|
* menuW = menu widget (for foreground and background colors)
|
|
* bitmapIndex = bitmap cache index
|
|
*
|
|
*
|
|
* Outputs:
|
|
* -------
|
|
* Return = label pixmap or NULL.
|
|
*
|
|
*
|
|
* Comments:
|
|
* --------
|
|
* Assumes bitmapIndex is valid.
|
|
*
|
|
*************************************<->***********************************/
|
|
|
|
Pixmap MakeCachedLabelPixmap (WmScreenData *pSD, Widget menuW, int bitmapIndex)
|
|
{
|
|
BitmapCache *bitmapc;
|
|
PixmapCache *pixmapc;
|
|
int i;
|
|
Arg args[5];
|
|
Pixel fg, bg;
|
|
Pixmap pixmap = (Pixmap)NULL;
|
|
GC gc;
|
|
XGCValues gcv;
|
|
|
|
if (bitmapIndex < 0)
|
|
{
|
|
return ((Pixmap)NULL);
|
|
}
|
|
bitmapc = &(pSD->bitmapCache[bitmapIndex]);
|
|
|
|
/*
|
|
* Get the foreground and background colors from the menu widget.
|
|
* Search for a label pixmap matching those colors.
|
|
*/
|
|
|
|
i = 0;
|
|
XtSetArg (args[i], XtNforeground, &fg); i++;
|
|
XtSetArg (args[i], XtNbackground, &bg); i++;
|
|
XtGetValues (menuW, (ArgList)args, i);
|
|
|
|
pixmapc = bitmapc->pixmapCache;
|
|
while (pixmapc)
|
|
{
|
|
if ((pixmapc->pixmapType == LABEL_PIXMAP) &&
|
|
(pixmapc->foreground == fg) &&
|
|
(pixmapc->background == bg))
|
|
{
|
|
pixmap = pixmapc->pixmap;
|
|
break;
|
|
}
|
|
pixmapc = pixmapc->next;
|
|
}
|
|
|
|
if (!pixmap)
|
|
/*
|
|
* A matching pixmap was not found in the pixmap cache for this bitmap.
|
|
* Create and save the label pixmap with appropriate colors.
|
|
*/
|
|
{
|
|
/*
|
|
* Create a pixmap of the appropriate size, root, and depth.
|
|
* Only BadAlloc error possible; BadDrawable and BadValue are avoided.
|
|
*/
|
|
|
|
pixmap = XCreatePixmap (DISPLAY, pSD->rootWindow,
|
|
bitmapc->width, bitmapc->height,
|
|
DefaultDepth (DISPLAY, pSD->screen));
|
|
|
|
/*
|
|
* Create a GC and copy the bitmap to the pixmap.
|
|
* Only BadAlloc and BadDrawable errors are possible; others are avoided
|
|
*/
|
|
|
|
gcv.foreground = bg;
|
|
gcv.background = bg;
|
|
gcv.graphics_exposures = False;
|
|
gc = XCreateGC(DISPLAY, pixmap, (GCForeground|GCBackground), &gcv);
|
|
|
|
/*
|
|
* Fill in the background, set the foreground, copy the bitmap to the
|
|
* pixmap, and free the gc.
|
|
*/
|
|
|
|
XFillRectangle (DISPLAY, pixmap, gc, 0, 0,
|
|
bitmapc->width, bitmapc->height);
|
|
XSetForeground (DISPLAY, gc, fg);
|
|
XCopyPlane (DISPLAY, bitmapc->bitmap, pixmap, gc, 0, 0,
|
|
bitmapc->width, bitmapc->height, 0, 0, 1L);
|
|
XFreeGC (DISPLAY, gc);
|
|
|
|
/*
|
|
* If have sufficient memory, save the pixmap info in the pixmapCache.
|
|
*/
|
|
|
|
if ((pixmapc = (PixmapCache *) XtMalloc(sizeof(PixmapCache))) != NULL)
|
|
{
|
|
pixmapc->pixmapType = LABEL_PIXMAP;
|
|
pixmapc->foreground = fg;
|
|
pixmapc->background = bg;
|
|
pixmapc->pixmap = pixmap;
|
|
pixmapc->next = bitmapc->pixmapCache;
|
|
bitmapc->pixmapCache = pixmapc;
|
|
}
|
|
}
|
|
|
|
return (pixmap);
|
|
|
|
} /* END OF FUNCTION MakeCachedLabelPixmap */
|
|
|
|
|
|
|
|
/*************************************<->*************************************
|
|
*
|
|
* int
|
|
* GetBitmapIndex (pSD, name)
|
|
*
|
|
*
|
|
* Description:
|
|
* -----------
|
|
* Retrieve bitmap from cache.
|
|
*
|
|
*
|
|
* Inputs:
|
|
* ------
|
|
* pSD = pointer to screen data
|
|
* name = bitmap file name or NULL pointer
|
|
* bitmapCache[]
|
|
* bitmapCacheSize
|
|
* bitmapCacheCount
|
|
*
|
|
*
|
|
* Outputs:
|
|
* -------
|
|
* bitmapCache[]
|
|
* bitmapCacheSize
|
|
* bitmapCacheCount
|
|
* Return = bitmap cache index or -1
|
|
*
|
|
*
|
|
* Comments:
|
|
* --------
|
|
* None
|
|
*
|
|
*************************************<->***********************************/
|
|
|
|
#define BITMAP_CACHE_INC 5
|
|
|
|
int GetBitmapIndex (WmScreenData *pSD, char *name, Boolean bReportError)
|
|
{
|
|
char *path;
|
|
BitmapCache *bitmapc;
|
|
unsigned int n;
|
|
int x, y;
|
|
|
|
/*
|
|
* Search a nonempty bitmap cache for a pathname match.
|
|
*/
|
|
path = BitmapPathName (name);
|
|
for (n = 0, bitmapc = pSD->bitmapCache;
|
|
n < pSD->bitmapCacheCount;
|
|
n++, bitmapc++)
|
|
{
|
|
if ((!path && !bitmapc->path) ||
|
|
(path && bitmapc->path &&
|
|
!strcmp (path, bitmapc->path)))
|
|
{
|
|
return (n);
|
|
}
|
|
}
|
|
|
|
/*
|
|
* The bitmap path name was not found in bitmapCache.
|
|
* Find the next BitmapCache entry, creating or enlarging bitmapCache if
|
|
* necessary.
|
|
*/
|
|
if (pSD->bitmapCacheSize == 0)
|
|
/* create */
|
|
{
|
|
pSD->bitmapCacheSize = BITMAP_CACHE_INC;
|
|
pSD->bitmapCache =
|
|
(BitmapCache *) XtMalloc (BITMAP_CACHE_INC * sizeof (BitmapCache));
|
|
}
|
|
else if (pSD->bitmapCacheCount == pSD->bitmapCacheSize)
|
|
/* enlarge */
|
|
{
|
|
pSD->bitmapCacheSize += BITMAP_CACHE_INC;
|
|
pSD->bitmapCache = (BitmapCache *)
|
|
XtRealloc ((char*)pSD->bitmapCache,
|
|
pSD->bitmapCacheSize * sizeof (BitmapCache));
|
|
}
|
|
|
|
if (pSD->bitmapCache == NULL)
|
|
{
|
|
MWarning (((char *)GETMESSAGE(38, 5, "Insufficient memory for bitmap %s\n")), name);
|
|
pSD->bitmapCacheSize = 0;
|
|
pSD->bitmapCacheCount = 0;
|
|
return (-1);
|
|
}
|
|
|
|
bitmapc = &(pSD->bitmapCache[pSD->bitmapCacheCount]);
|
|
|
|
/*
|
|
* Fill the entry with the bitmap info.
|
|
* A NULL path indicates the builtin icon bitmap.
|
|
* Indicate that no pixmapCache exists yet.
|
|
*/
|
|
|
|
if (path)
|
|
{
|
|
if ((bitmapc->path = (String)
|
|
XtMalloc ((unsigned int)(strlen (path) + 1))) == NULL)
|
|
{
|
|
MWarning (((char *)GETMESSAGE(38, 6, "Insufficient memory for bitmap %s\n")), name);
|
|
return (-1);
|
|
}
|
|
strcpy (bitmapc->path, path);
|
|
|
|
if (XReadBitmapFile (DISPLAY, pSD->rootWindow, path,
|
|
&bitmapc->width, &bitmapc->height,
|
|
&bitmapc->bitmap, &x, &y)
|
|
!= BitmapSuccess)
|
|
{
|
|
if (bReportError)
|
|
MWarning (((char *)GETMESSAGE(38, 7, "Unable to read bitmap file %s\n")), path);
|
|
XtFree ((char *)bitmapc->path);
|
|
return (-1);
|
|
}
|
|
|
|
if (bitmapc->width == 0 || bitmapc->height == 0)
|
|
{
|
|
if (bReportError)
|
|
MWarning (((char *)GETMESSAGE(38, 8, "Invalid bitmap file %s\n")), path);
|
|
XtFree ((char *)bitmapc->path);
|
|
return (-1);
|
|
}
|
|
}
|
|
else
|
|
/* builtin icon bitmap */
|
|
{
|
|
bitmapc->path = NULL;
|
|
bitmapc->bitmap = pSD->builtinIconPixmap;
|
|
bitmapc->width = iImage_width;
|
|
bitmapc->height = iImage_height;
|
|
}
|
|
|
|
bitmapc->pixmapCache = NULL;
|
|
|
|
return (pSD->bitmapCacheCount++);
|
|
|
|
} /* END OF FUNCTION GetBitmapIndex */
|
|
|
|
|
|
|
|
/*************************************<->*************************************
|
|
*
|
|
* BitmapPathName (string)
|
|
*
|
|
*
|
|
* Description:
|
|
* -----------
|
|
* Constructs a bitmap file pathname from the bitmap file name and the
|
|
* bitmapDirectory resource value.
|
|
*
|
|
*
|
|
* Inputs:
|
|
* ------
|
|
* string = bitmap file name or NULL
|
|
* wmGD.bitmapDirectory = bitmapDirectory resource value
|
|
* HOME = environment variable for home directory
|
|
* XBMLANGPATH
|
|
* XAPPLRESDIR
|
|
*
|
|
*
|
|
* Outputs:
|
|
* -------
|
|
* Return = string containing the bitmap file pathname or NULL.
|
|
*
|
|
*
|
|
* Comments:
|
|
* --------
|
|
* If the bitmap file does not exist, searches using XBMLANGPATH.
|
|
* Returns NULL path name for a NULL file name.
|
|
*
|
|
*************************************<->***********************************/
|
|
|
|
char *BitmapPathName (char *string)
|
|
{
|
|
static char fileName[MAXWMPATH+1];
|
|
char *retname;
|
|
SubstitutionRec subs[1];
|
|
char *homeDir = XmeGetHomeDirName();
|
|
|
|
if (!string || !*string)
|
|
{
|
|
return (NULL);
|
|
}
|
|
|
|
/*
|
|
* Interpret "~/.." as relative to the user's home directory.
|
|
* Interpret "/.." as an absolute pathname.
|
|
* If the bitmapDirectory resource is nonNULL, interpret path as relative
|
|
* to it.
|
|
* Else, or if bitmapDirectory has no such file, use a XBMLANGPATH lookup.
|
|
*/
|
|
|
|
if ((string[0] == '~') && (string[1] == '/'))
|
|
/*
|
|
* Handle "~/.."
|
|
*/
|
|
{
|
|
strcpy (fileName, homeDir);
|
|
strncat (fileName, &(string[1]), MAXWMPATH - strlen (fileName));
|
|
return (fileName);
|
|
}
|
|
|
|
if (string[0] == '/')
|
|
{
|
|
return(string);
|
|
}
|
|
|
|
if (wmGD.bitmapDirectory && *wmGD.bitmapDirectory)
|
|
/*
|
|
* Relative to nonNULL bitmapDirectory (which may have relative to HOME)
|
|
*/
|
|
{
|
|
if ((wmGD.bitmapDirectory[0] == '~') &&
|
|
(wmGD.bitmapDirectory[1] == '/'))
|
|
{
|
|
strcpy (fileName, homeDir);
|
|
strncat (fileName, &wmGD.bitmapDirectory[1],
|
|
MAXWMPATH - strlen (fileName));
|
|
} else {
|
|
snprintf(fileName, sizeof(fileName), "%s", wmGD.bitmapDirectory);
|
|
}
|
|
strncat (fileName, "/", MAXWMPATH - strlen (fileName));
|
|
strncat (fileName, string, MAXWMPATH - strlen (fileName));
|
|
|
|
/* Test file for existence. */
|
|
|
|
subs[0].substitution = "";
|
|
if ((retname = XtFindFile(fileName, subs, 0,
|
|
(XtFilePredicate) NULL)) != NULL) {
|
|
XtFree(retname);
|
|
return (fileName);
|
|
}
|
|
}
|
|
|
|
/* Fall back on a path search */
|
|
|
|
{
|
|
char *search_path;
|
|
Boolean user_path;
|
|
|
|
search_path = _XmOSInitPath(string, MATCH_PATH, &user_path);
|
|
subs[0].match = user_path ? MATCH_XBM : MATCH_CHAR;
|
|
subs[0].substitution = string;
|
|
retname = XtResolvePathname(DISPLAY, "bitmaps", NULL, NULL,
|
|
search_path, subs, XtNumber(subs),
|
|
(XtFilePredicate)NULL);
|
|
XtFree(search_path);
|
|
|
|
if (!retname)
|
|
return (string);
|
|
|
|
strncpy(fileName, retname, MAXWMPATH);
|
|
XtFree(retname);
|
|
return (fileName);
|
|
}
|
|
|
|
} /* END OF FUNCTION BitmapPathName */
|
|
|
|
/**************************** eof ***************************/
|