/* * @OPENGROUP_COPYRIGHT@ * COPYRIGHT NOTICE * Copyright (c) 1989, 1990, 1991, 1992 Open Software Foundation, Inc. * Copyright (c) 1996, 1997, 1998, 1999, 2000 The Open Group * ALL RIGHTS RESERVED (MOTIF). See the file named COPYRIGHT.MOTIF for * the full copyright text. * * This software is subject to an open license. It may only be * used on, with or for operating systems which are themselves open * source systems. You must contact The Open Group for a license * allowing distribution and sublicensing of this software on, with, * or for operating systems which are not Open Source programs. * * See http://www.opengroup.org/openmotif/license for full * details of the license agreement. Any use, reproduction, or * distribution of the program constitutes recipient's acceptance of * this agreement. * * EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS * PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY * WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY * OR FITNESS FOR A PARTICULAR PURPOSE * * EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT * NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE * EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. */ /* * Motif Release 1.2 */ #ifdef REV_INFO #ifndef lint static char rcsid[] = "$XConsortium: WmGraphics.c /main/4 1995/11/01 11:38:53 rswiston $" #endif #endif /* * (c) Copyright 1987, 1988, 1989, 1990 HEWLETT-PACKARD COMPANY */ /* * Included Files: */ #include "WmGlobal.h" #include #include #include #include #include #include #include #define RLIST_EXTENSION_SIZE 10 #ifndef MIN #define MAX(x,y) ((x)>(y)?(x):(y)) #endif /* * include extern functions */ #include "WmGraphics.h" #include "WmError.h" /* * Global Variables: */ /* * Macros: */ /* test if > 0 and return 1 if true, 0 if false. */ #define GE1(x) ((x)>0?1:0) /*************************************<->************************************* * * Procedure: BevelRectangle (prTop, prBot, x, y, * width, height, top_wid, right_wid, bot_wid, left_wid) * * Description: * ----------- * Generate data for top- and bottom-shadow bevels on a box. * * Inputs: * ------ * prTop - ptr to top shadow RList * prBot - ptr to bottom shadow RList * x,y - position of rectangle to bevel * width - (outside) width of rectangle * height - (outside) height of rectangle * top_wid - width of beveling on top side of rectangle * right_wid - width of beveling on right side of rectangle * bot_wid - width of beveling on bottom side of rectangle * left_wid - width of beveling on left side of rectangle * * Outputs: * ------- * prTop - top shadows for this rectangle added to list * prBot - bottom shadows for this rectangle added to list * * * Comments: * -------- * *************************************<->***********************************/ void BevelRectangle (RList *prTop, RList *prBot, int x, int y, unsigned int width, unsigned int height, unsigned int top_wid, unsigned int right_wid, unsigned int bot_wid, unsigned int left_wid) { XRectangle *prect; /* pointer to "current" rectangle */ register int count; /* counter used for beveling operation */ int join1, join2; /* used to compute "good" bevel joints */ int x1, y1, len; /* used to compute bevel parameters */ int *piTop, *piBot; /* build the rectangles to implement the beveling on each side */ /* top side */ if (((prTop->used + (top_wid + left_wid)) > prTop->allocated) && (!ExtendRList (prTop, MAX (top_wid+left_wid, RLIST_EXTENSION_SIZE)))) { return; /* not enough memory */ } piTop = &(prTop->used); prect = &(prTop->prect[*piTop]); join1 = left_wid; join2 = right_wid; x1 = x; y1 = y; len = width; for (count=top_wid; count>0; count--, prect++, (*piTop)++) { prect->x = x1; prect->y = y1; prect->width = len; prect->height = 1; x1 += GE1(--join1); y1 += 1; len -= GE1(join1) + GE1(--join2); } /* left side */ join1 = top_wid; join2 = bot_wid; x1 = x; y1 = y+GE1(join1); len = height-GE1(join1); for (count=left_wid; count >0; count--, prect++, (*piTop)++) { prect->x = x1; prect->y = y1; prect->width = 1; prect->height = len; x1 += 1; y1 += GE1(--join1); len -= GE1(join1) + GE1(--join2); } /* bottom side */ if (((prBot->used + (bot_wid + right_wid)) > prBot->allocated) && (!ExtendRList(prBot, MAX (bot_wid+right_wid, RLIST_EXTENSION_SIZE)))) { return; } piBot = &(prBot->used); prect = &(prBot->prect[*piBot]); join1 = left_wid; join2 = right_wid; x1 = x+GE1(join1); y1 = y+height-1; len = width-GE1(join1); /* fudge fat bottom shadow to overwrite corner of skinny left shadow */ if (GE1(join1) && (bot_wid > left_wid)) { len++; x1--; join1++; } for (count=bot_wid; count >0; count--, prect++, (*piBot)++) { prect->x = x1; prect->y = y1; prect->width = len; prect->height = 1; x1 += GE1(--join1); y1 -= 1; len -= GE1(join1) + GE1(--join2); } /* right side */ join1 = top_wid; join2 = bot_wid; x1 = x+width-1; y1 = y+GE1(join1); len = height - GE1(join1) - GE1(join2); /* fudge fat right shadow to overwrite corner of skinny top shadow */ if (GE1(join1) && (right_wid > top_wid)) { len++; y1--; join1++; } for (count=right_wid; count >0; count--, prect++, (*piBot)++) { prect->x = x1; prect->y = y1; prect->width = 1; prect->height = len; x1 -= 1; y1 += GE1(--join1); len -= GE1(join1) + GE1(--join2); } } /* END OF FUNCTION BevelRectangle */ /*************************************<->************************************* * * Procedure: BevelDepressedRectangle (prTop, prBot, x, y, * width, height, top_wid, right_wid, bot_wid, left_wid * in_wid) * * Description: * ----------- * Generate data for top- and bottom-shadow bevels on a rectangle with * the center part depressed. * * Inputs: * ------ * prTop - ptr to top shadow RList * prBot - ptr to bottom shadow RList * x,y - position of rectangle to bevel * width - (outside) width of rectangle * height - (outside) height of rectangle * top_wid - width of beveling on top side of rectangle * right_wid - width of beveling on right side of rectangle * bot_wid - width of beveling on bottom side of rectangle * left_wid - width of beveling on left side of rectangle * in_wid - width of depressed beveling inside of rectangle * * Outputs: * ------- * prTop - top shadows for this rectangle added to list * prBot - bottom shadows for this rectangle added to list * * * Comments: * -------- * *************************************<->***********************************/ void BevelDepressedRectangle (RList *prTop, RList *prBot, int x, int y, unsigned int width, unsigned int height, unsigned int top_wid, unsigned int right_wid, unsigned int bot_wid, unsigned int left_wid, unsigned int in_wid) { XRectangle *prect; /* pointer to "current" rectangle */ register int count; /* counter used for beveling operation */ int join1, join2; /* used to compute "good" bevel joints */ int x1, y1, len; /* used to compute bevel parameters */ int *piTop, *piBot; /* * Build the rectangles to implement the beveling on each side * First, guarantee that there is enough memory. */ if (((prTop->used + (top_wid + left_wid)) > prTop->allocated) && (!ExtendRList (prTop, MAX (top_wid+left_wid, RLIST_EXTENSION_SIZE)))) { return; /* not enough memory */ } if (((prBot->used + (bot_wid + right_wid)) > prBot->allocated) && (!ExtendRList(prBot, MAX (bot_wid+right_wid, RLIST_EXTENSION_SIZE)))) { return; /* not enought memory */ } /* top side (normal beveling) */ piTop = &(prTop->used); prect = &(prTop->prect[*piTop]); join1 = left_wid; join2 = right_wid; x1 = x; y1 = y; len = width; for (count=top_wid - in_wid; count>0; count--, prect++, (*piTop)++) { prect->x = x1; prect->y = y1; prect->width = len; prect->height = 1; x1 += GE1(--join1); y1 += 1; len -= GE1(join1) + GE1(--join2); } /* top side (inverted beveling) */ piBot = &(prBot->used); prect = &(prBot->prect[*piBot]); for (count=in_wid; count>0; count--, prect++, (*piBot)++) { prect->x = x1; prect->y = y1; prect->width = len; prect->height = 1; x1 += GE1(--join1); y1 += 1; len -= GE1(join1) + GE1(--join2); } /* left side (normal beveling) */ piTop = &(prTop->used); prect = &(prTop->prect[*piTop]); join1 = top_wid; join2 = bot_wid; x1 = x; y1 = y+GE1(join1); len = height-GE1(join1); for (count=left_wid-in_wid; count >0; count--, prect++, (*piTop)++) { prect->x = x1; prect->y = y1; prect->width = 1; prect->height = len; x1 += 1; y1 += GE1(--join1); len -= GE1(join1) + GE1(--join2); } /* left side (inverted beveling) */ piBot = &(prBot->used); prect = &(prBot->prect[*piBot]); for (count=in_wid; count >0; count--, prect++, (*piBot)++) { prect->x = x1; prect->y = y1; prect->width = 1; prect->height = len; x1 += 1; y1 += GE1(--join1); len -= GE1(join1) + GE1(--join2); } /* bottom side (normal beveling) */ piBot = &(prBot->used); prect = &(prBot->prect[*piBot]); join1 = left_wid; join2 = right_wid; x1 = x+GE1(join1); y1 = y+height-1; len = width-GE1(join1); /* fudge fat bottom shadow to overwrite corner of skinny left shadow */ if (GE1(join1) && (bot_wid > left_wid)) { len++; x1--; join1++; } for (count=bot_wid-in_wid; count >0; count--, prect++, (*piBot)++) { prect->x = x1; prect->y = y1; prect->width = len; prect->height = 1; x1 += GE1(--join1); y1 -= 1; len -= GE1(join1) + GE1(--join2); } /* bottom side (inverted beveling) */ piTop = &(prTop->used); prect = &(prTop->prect[*piTop]); for (count=in_wid; count >0; count--, prect++, (*piTop)++) { prect->x = x1; prect->y = y1; prect->width = len; prect->height = 1; x1 += GE1(--join1); y1 -= 1; len -= GE1(join1) + GE1(--join2); } /* right side (normal beveling) */ piBot = &(prBot->used); prect = &(prBot->prect[*piBot]); join1 = top_wid; join2 = bot_wid; x1 = x+width-1; y1 = y+GE1(join1); len = height - GE1(join1) - GE1(join2); /* fudge fat right shadow to overwrite corner of skinny top shadow */ if (GE1(join1) && (right_wid > top_wid)) { len++; y1--; join1++; } for (count=right_wid-in_wid; count >0; count--, prect++, (*piBot)++) { prect->x = x1; prect->y = y1; prect->width = 1; prect->height = len; x1 -= 1; y1 += GE1(--join1); len -= GE1(join1) + GE1(--join2); } /* right side (inverted beveling) */ piTop = &(prTop->used); prect = &(prTop->prect[*piTop]); for (count=in_wid; count >0; count--, prect++, (*piTop)++) { prect->x = x1; prect->y = y1; prect->width = 1; prect->height = len; x1 -= 1; y1 += GE1(--join1); len -= GE1(join1) + GE1(--join2); } } /* END OF FUNCTION BevelDepressedRectangle */ /*************************************<->************************************* * * Procedure: StretcherCorner (prTop, prBot, x, y, cnum, * swidth, cwidth, cheight); * * Description: * ----------- * Generate data to draw a corner of the stretcher border. * * Inputs: * ------ * prTop - ptr to top shadow RList * prBot - ptr to bottom shadow RList * x,y - position of rectangle enclosing the cornern * cnum - corner number; which corner to draw * ASSUMES only NW, NE, SE, SW for mwm () * swidth - width (thickness) of border (includes bevels) * cwidth - corner width from corner to end of horizontal run * cheight - corner height from corner to end of vertical run * * Outputs: * ------- * prTop - array filled in for top shadows * prBot - array filledin for bottom shadows * * Comments: * -------- * o Uses only 1 pixel bevels. Beveling is hard coded. * o XFillRectangles assumed as an optimization to take * advantage of the block mover hardware. * *************************************<->***********************************/ void StretcherCorner (RList *prTop, RList *prBot, int x, int y, int cnum, unsigned int swidth, unsigned int cwidth, unsigned int cheight) { XRectangle *prect; /* pointer to "current" rectangle */ int *piTop, *piBot; switch (cnum) { case STRETCH_NORTH_WEST: if (((prTop->used + 4) > prTop->allocated) && (!ExtendRList (prTop, (unsigned int) RLIST_EXTENSION_SIZE))) { return; } piTop = &(prTop->used); prect = &(prTop->prect[*piTop]); prect->x = x; /* top (row 1) */ prect->y = y; prect->width = cwidth; prect->height = 1; prect++; (*piTop)++; prect->x = x+1; /* top (row 2) */ prect->y = y+1; prect->width = cwidth-2; prect->height = 1; prect++; (*piTop)++; prect->x = x; /* left (col 1) */ prect->y = y+1; prect->width = 1; prect->height = cheight-1; prect++; (*piTop)++; prect->x = x+1; /* left (col 2) */ prect->y = y+2; prect->width = 1; prect->height = cheight-3; (*piTop)++; if (((prBot->used + 4) > prBot->allocated) && (!ExtendRList (prBot, (unsigned int) RLIST_EXTENSION_SIZE))) { return; } piBot = &(prBot->used); prect = &(prBot->prect[*piBot]); /* bottom shadow parts */ prect->x = x+1; /* bottom end */ prect->y = y+cheight-1; prect->width = swidth-1; prect->height = 1; prect++; (*piBot)++; if (wmGD.frameStyle == WmRECESSED) { prect->x = x+swidth-1; /* right inside */ prect->y = y+swidth-1; prect->width = 1; prect->height = cheight-swidth; prect++; (*piBot)++; prect->x = x+swidth; /* bottom inside */ prect->y = y+swidth-1; prect->width = cwidth-swidth; prect->height = 1; prect++; (*piBot)++; } prect->x = x+cwidth-1; /* right end */ prect->y = y+1; prect->width = 1; prect->height = swidth-1-((wmGD.frameStyle == WmSLAB)? 0 : 1); (*piBot)++; break; case STRETCH_NORTH_EAST: if (((prTop->used + 4) > prTop->allocated) && (!ExtendRList (prTop, (unsigned int) RLIST_EXTENSION_SIZE))) { return; } piTop = &(prTop->used); prect = &(prTop->prect[*piTop]); prect->x = x; /* top (row 1) */ prect->y = y; prect->width = cwidth; prect->height = 1; prect++; (*piTop)++; prect->x = x+1; /* top (row 2) */ prect->y = y+1; prect->width = cwidth-2; prect->height = 1; prect++; (*piTop)++; prect->x = x; /* left end */ prect->y = y+1; prect->width = 1; prect->height = swidth-1; prect++; (*piTop)++; if (wmGD.frameStyle == WmRECESSED) { prect->x = x+cwidth-swidth; /* left inside (col 1) */ prect->y = y+swidth; prect->width = 1; prect->height = cheight-swidth; (*piTop)++; } if (((prBot->used + 4) > prBot->allocated) && (!ExtendRList (prBot, (unsigned int) RLIST_EXTENSION_SIZE))) { return; } piBot = &(prBot->used); prect = &(prBot->prect[*piBot]); /* bottom shadow parts */ /* bottom end */ prect->x = x+cwidth-swidth+((wmGD.frameStyle == WmSLAB)? 0 : 1); prect->y = y+cheight-1; prect->width = swidth-((wmGD.frameStyle == WmSLAB)? 0 : 1); prect->height = 1; prect++; (*piBot)++; prect->x = x+cwidth-1; /* right (col 2) */ prect->y = y+1; prect->width = 1; prect->height = cheight-2; prect++; (*piBot)++; prect->x = x+cwidth-2; /* right (col 1) */ prect->y = y+2; prect->width = 1; prect->height = cheight-3; prect++; (*piBot)++; if (wmGD.frameStyle == WmRECESSED) { prect->x = x+1; /* bottom inside (row 2) */ prect->y = y+swidth-1; prect->width = cwidth-swidth; prect->height = 1; (*piBot)++; } break; case STRETCH_SOUTH_EAST: if (((prTop->used + 4) > prTop->allocated) && (!ExtendRList (prTop, (unsigned int) RLIST_EXTENSION_SIZE))) { return; } piTop = &(prTop->used); prect = &(prTop->prect[*piTop]); if (wmGD.frameStyle == WmRECESSED) { prect->x = x; /* top inside */ prect->y = y+cheight-swidth; prect->width = cwidth-swidth+1; prect->height = 1; prect++; (*piTop)++; prect->x = x+cwidth-swidth; /* left inside */ prect->y = y; prect->width = 1; prect->height = cheight-swidth; prect++; (*piTop)++; } /* top end */ prect->x = x+cwidth-swidth+ ((wmGD.frameStyle == WmSLAB)? 0 : 1); prect->y = y; prect->width = swidth-2+((wmGD.frameStyle == WmSLAB)? 1 : 0);; prect->height = 1; prect++; (*piTop)++; prect->x = x; /* left end */ prect->y = y+cheight-swidth+ ((wmGD.frameStyle == WmSLAB)? 0 : 1); prect->width = 1; prect->height = swidth-2+((wmGD.frameStyle == WmSLAB)? 1 : 0); (*piTop)++; if (((prBot->used + 4) > prBot->allocated) && (!ExtendRList (prBot, (unsigned int) RLIST_EXTENSION_SIZE))) { return; } piBot = &(prBot->used); prect = &(prBot->prect[*piBot]); /* bottom shadow parts */ prect->x = x+1; /* bottom - row 1 */ prect->y = y+cheight-2; prect->width = cwidth-1; prect->height = 1; prect++; (*piBot)++; prect->x = x; /* bottom - row 2 */ prect->y = y+cheight-1; prect->width = cwidth; prect->height = 1; prect++; (*piBot)++; prect->x = x+cwidth-2; /* right - column 1 */ prect->y = y+1; prect->width = 1; prect->height = cheight-3; prect++; (*piBot)++; prect->x = x+cwidth-1; /* right - column 2 */ prect->y = y; prect->width = 1; prect->height = cheight-2; (*piBot)++; break; case STRETCH_SOUTH_WEST: if (((prTop->used + 4) > prTop->allocated) && (!ExtendRList (prTop, (unsigned int) RLIST_EXTENSION_SIZE))) { return; } piTop = &(prTop->used); prect = &(prTop->prect[*piTop]); prect->x = x; /* top end */ prect->y = y; prect->width = swidth; prect->height = 1; prect++; (*piTop)++; prect->x = x; /* left (col 1) */ prect->y = y+1; prect->width = 1; prect->height = cheight-1; prect++; (*piTop)++; prect->x = x+1; /* left (col 2) */ prect->y = y+1; prect->width = 1; prect->height = cheight-2; prect++; (*piTop)++; if (wmGD.frameStyle == WmRECESSED) { prect->x = x+swidth; /* top inside (row 2) */ prect->y = y+cheight-swidth; prect->width = cwidth-swidth; prect->height = 1; (*piTop)++; } if (((prBot->used + 4) > prBot->allocated) && (!ExtendRList (prBot, (unsigned int) RLIST_EXTENSION_SIZE))) { return; } piBot = &(prBot->used); prect = &(prBot->prect[*piBot]); /* bottom shadow parts */ if (wmGD.frameStyle == WmRECESSED) { prect->x = x+swidth-1; /* right inside (col 2) */ prect->y = y+1; prect->width = 1; prect->height = cheight-swidth; prect++; (*piBot)++; } prect->x = x+cwidth-1; /* right end */ prect->y = y+cheight-swidth+ ((wmGD.frameStyle == WmSLAB)? 0 : 1); prect->width = 1; prect->height = swidth-((wmGD.frameStyle == WmSLAB)? 0 : 1); prect++; (*piBot)++; prect->x = x+2; /* bottom (row 1) */ prect->y = y+cheight-2; prect->width = cwidth-3; prect->height = 1; prect++; (*piBot)++; prect->x = x+1; /* bottom (row 2) */ prect->y = y+cheight-1; prect->width = cwidth-2; prect->height = 1; (*piBot)++; break; } } /* END OF FUNCTION StretcherCorner */ /*************************************<->************************************* * * DrawStringInBox (dpy, win, gc, pbox, str) * * * Description: * ----------- * Draws a null-terminated string inside the specified box (rectangle) * * * Inputs: * ------ * dpy - ptr to Display * win - an X Window * gc - graphics context to use * pfs - pointer to XFontStruct for the font in "gc" * pbox - ptr to XRectangle that encloses text * str - String to write * * Outputs: * ------- * none * * Comments: * -------- * o Assumes 8-bit text for now. * o Algorithm: * get length of String * if String is short than box width then * draw string centered in box * otherwise * draw string left justified and clipped to box * o The clip_x_origin, clip_y_origin, and clip_mask are reset to None * upon exit. * o Due to bugs and / or misunderstanding, I gave up on trying to * extract the XFontStruct from the GC. I just made it a separate * parameter. * *************************************<->***********************************/ void DrawStringInBox (Display *dpy, Window win, GC gc, XFontStruct *pfs, XRectangle *pbox, String str) { XGCValues gcv; int textWidth; int xCenter; XRectangle clipBox; /* compute text position */ textWidth = XTextWidth(pfs, str, strlen(str)); if (textWidth < (int) pbox->width) { /* center text if there's room */ xCenter = (int) pbox->x + ((int) pbox->width - textWidth) / 2 ; WmDrawString(dpy, win, gc, xCenter, (pbox->y + pfs->ascent), str, strlen(str)); } else { /* left justify & clip text */ clipBox.x = 0; /* set up clip rectangle */ clipBox.y = 0; clipBox.width = pbox->width; clipBox.height = pbox->height; XSetClipRectangles (dpy, gc, pbox->x, pbox->y, /* put into gc */ &clipBox, 1, Unsorted); WmDrawString(dpy, win, gc, pbox->x, (pbox->y + pfs->ascent), str, strlen(str)); gcv.clip_x_origin = 0; /* erase clip_mask from gc */ gcv.clip_y_origin = 0; gcv.clip_mask = None; XChangeGC (dpy, gc, GCClipXOrigin | GCClipYOrigin | GCClipMask, &gcv); } } /* END OF FUNCTION DrawStringInBox */ /*************************************<->************************************* * * ExtendRList (prl, amt) * * * Description: * ----------- * Extends the size of the RList * * * Inputs: * ------ * prl - ptr to Display * amt - how much to extend it by * * Outputs: * ------- * Returns True if succeeded, false otherwise. * * Comments: * -------- * *************************************<->***********************************/ Boolean ExtendRList (RList *prl, unsigned int amt) { unsigned int total, count; XRectangle *pNewRect; Boolean rval; total = prl->allocated + amt; if ( (pNewRect = (XRectangle *) XtMalloc (total * sizeof(XRectangle))) == NULL) { Warning (((char *)GETMESSAGE(28, 1, "Insufficient memory for graphics data"))); rval = False; } else { prl->allocated = total; rval = True; if (prl->used != 0) { /* copy from old structure */ count = prl->used * sizeof(XRectangle); (void) memcpy ((void *)pNewRect, (void *)prl->prect, count); if (prl->prect != NULL) XtFree ((char *)prl->prect); prl->prect = pNewRect; } } return (rval); } /* END OF FUNCTION ExtendRList */ /*************************************<->************************************* * * AllocateRList (amt) * * * Description: * ----------- * Allocates an RList of size "amt" * * * Inputs: * ------ * amt - number of XRectangles to allocate in list * * Outputs: * ------- * Returns ptr to new RList structure if success, returns NULL ptr otherwise * * Comments: * -------- * *************************************<->***********************************/ RList *AllocateRList (amt) unsigned int amt; { RList *prl; if ((prl = (RList *) XtMalloc (sizeof (RList))) != NULL) { if ( (prl->prect = (XRectangle *) XtMalloc (amt * sizeof(XRectangle))) == NULL) { XtFree ((char *)prl); prl = NULL; } else { prl->allocated = amt; prl->used = 0; } } return (prl); } /* END OF FUNCTION AllocateRList */ /*************************************<->************************************* * * FreeRList (prl) * * * Description: * ----------- * Frees an RList * * * Inputs: * ------ * prl - ptr to RList to free * * Outputs: * ------- * * Comments: * -------- * *************************************<->***********************************/ void FreeRList (RList *prl) { if (prl) { if (prl->prect) XtFree ((char *)prl->prect); XtFree ((char *)prl); } }/* END OF FUNCTION FreeRList */ /*************************************<->************************************* * * WmDrawString * * * Description: * ----------- * Draws a string * * * Inputs: * ------ * (same parameters used by XDrawString and XDrawImageString) * * Outputs: * ------- * * Comments: * -------- * o If wmGD.cleanText is True, then the text is drawn using * XDrawImageString. This provides some clean space around the text * if the background area is stippled -- especially useful on * B/W displays. * *************************************<->***********************************/ void WmDrawString (Display *dpy, Drawable d, GC gc, int x, int y, char *string, unsigned int length) { if (ACTIVE_PSD->cleanText) { XDrawImageString(dpy, d, gc, x, y, string, length); } else { XDrawString(dpy, d, gc, x, y, string, length); } }/* END OF FUNCTION WmDrawString */ /*************************************<->************************************* * * WmXmDrawString * * * Description: * ----------- * Draws a string * * * Inputs: * ------ * (subset of parameters used by XmStringDraw and XmStringDrawImage) * * Outputs: * ------- * * Comments: * -------- * o If wmGD.cleanText is True, then the text is drawn using * XmStringDrawImage. This provides some clean space around the text * if the background area is stippled -- especially useful on * B/W displays. * *************************************<->***********************************/ #ifdef WSM void WmDrawXmString (Display *dpy, Window w, XmFontList xmfontlist, XmString xmstring, GC gc, Position x, Position y, Dimension width, XRectangle *pbox, Boolean bCenter) #else /* WSM */ void WmDrawXmString (Display *dpy, Window w, XmFontList xmfontlist, XmString xmstring, GC gc, Position x, Position y, Dimension width, XRectangle *pbox) #endif /* WSM */ { Dimension textWidth; #ifdef WSM int alignment; #else /* WSM */ int alignment = XmALIGNMENT_BEGINNING; #endif /* WSM */ textWidth = XmStringWidth(xmfontlist, xmstring); #ifdef WSM alignment = bCenter ? XmALIGNMENT_CENTER : XmALIGNMENT_BEGINNING; if (textWidth >= pbox->width) /* can't center text if no room */ { /* left justify & clip text */ alignment = XmALIGNMENT_BEGINNING; } #else /* WSM */ if (textWidth < pbox->width) { /* center text if there's room */ alignment = XmALIGNMENT_CENTER; } else { /* left justify & clip text */ alignment = XmALIGNMENT_BEGINNING; } #endif /* WSM */ if (ACTIVE_PSD->cleanText) { XmStringDrawImage(dpy, w, xmfontlist, xmstring, gc, x, y, width, alignment, XmSTRING_DIRECTION_L_TO_R, pbox); } else { XmStringDraw (dpy, w, xmfontlist, xmstring, gc, x, y, width, alignment, XmSTRING_DIRECTION_L_TO_R, pbox); } } /* END OF FUNCTION WmDrawXmString */ #ifdef WSM /*************************************<->************************************* * * WmInstallBitmapIntoXmCache (pchName, bitmap, width, height) * * * Description: * ----------- * Installs all or part of a pixmap into the Xm cache. This pixmap * may be retrieved later by a call to XmGetPixmap. * * Inputs: * ------ * pchName = pointer to name of bitmap * bitmap = depth-1 pixmap * width = width of portion to install * height = height of portion to install * * Outputs: * ------- * none * * Comments: * -------- * This always installs the Northwest corner of the passed in bitmap. * If the width and height match the size of the bitmap, then the * whole thing is installed in the cache. * *************************************<->***********************************/ void WmInstallBitmapIntoXmCache (unsigned char *pchName, Pixmap bitmap, unsigned int width, unsigned int height) { XImage *pImage; pImage = XGetImage (DISPLAY, bitmap, 0, 0, width, height, 1L, XYBitmap); XmInstallImage (pImage, (char *)pchName); } /* END OF FUNCTION WmInstallBitmapIntoXmCache */ /*************************************<->************************************* * * WmInstallBitmapDataIntoXmCache (pSD, pchName, pData) * * * Description: * ----------- * Installs built-in bitmap data into the Xm Pixmap cache. The image * may be retrieved later by a call to XmGetPixmap. * * Inputs: * ------ * pSD = pointer to screen data * pchName = pointer to name of bitmap * pData = pointer to the bitmap data * * Outputs: * ------- * none * * Comments: * -------- * This is principally for putting built-in pixmap data into the Xm * cache to allow for uniform access to pixmap creation. * * ***WARNING*** * Do NOT call XmDestroyPixmap on images cached via this routine unless * pData passed in points to malloc'ed memory. XmDestroyPixmap could * try to free this data. * *************************************<->***********************************/ void WmInstallBitmapDataIntoXmCache (WmScreenData *pSD, unsigned char *pchName, char *pData, unsigned int width, unsigned int height) { XImage *pImage; if (pImage = (XImage *) XtMalloc (sizeof (XImage))) { pImage->width = width; pImage->height = height; pImage->xoffset = 0; pImage->data = pData; pImage->format = XYBitmap; pImage->byte_order = MSBFirst; pImage->bitmap_pad = 8; pImage->bitmap_bit_order = LSBFirst; pImage->bitmap_unit = 8; pImage->depth = 1; pImage->bytes_per_line = (width/8) + ((width%8) != 0 ? 1 : 0); pImage->obdata = NULL; XmInstallImage(pImage, (char *)pchName); } } /* END OF FUNCTION WmInstallBitmapDataIntoXmCache */ #endif /* WSM */