SmeBSB.c revision 5ec34c4c
17a84e134Smrg/*
27a84e134SmrgCopyright 1989, 1994, 1998  The Open Group
37a84e134Smrg
47a84e134SmrgPermission to use, copy, modify, distribute, and sell this software and its
57a84e134Smrgdocumentation for any purpose is hereby granted without fee, provided that
67a84e134Smrgthe above copyright notice appear in all copies and that both that
77a84e134Smrgcopyright notice and this permission notice appear in supporting
87a84e134Smrgdocumentation.
97a84e134Smrg
107a84e134SmrgThe above copyright notice and this permission notice shall be included in
117a84e134Smrgall copies or substantial portions of the Software.
127a84e134Smrg
137a84e134SmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
147a84e134SmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
157a84e134SmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
167a84e134SmrgOPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
177a84e134SmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
187a84e134SmrgCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
197a84e134Smrg
207a84e134SmrgExcept as contained in this notice, the name of The Open Group shall not be
217a84e134Smrgused in advertising or otherwise to promote the sale, use or other dealings
227a84e134Smrgin this Software without prior written authorization from The Open Group.
237a84e134Smrg */
247a84e134Smrg
257a84e134Smrg/*
267a84e134Smrg * SmeBSB.c - Source code file for BSB Menu Entry object.
277a84e134Smrg *
287a84e134Smrg * Date:    September 26, 1989
297a84e134Smrg *
307a84e134Smrg * By:      Chris D. Peterson
31421c997bSmrg *          MIT X Consortium
327a84e134Smrg *          kit@expo.lcs.mit.edu
337a84e134Smrg */
347a84e134Smrg
357a84e134Smrg#ifdef HAVE_CONFIG_H
367a84e134Smrg#include <config.h>
377a84e134Smrg#endif
387a84e134Smrg#include <stdio.h>
397a84e134Smrg#include <X11/IntrinsicP.h>
407a84e134Smrg#include <X11/StringDefs.h>
417a84e134Smrg#include <X11/Xos.h>
427a84e134Smrg#include <X11/Xmu/Drawing.h>
437a84e134Smrg#include <X11/Xaw/Cardinals.h>
447a84e134Smrg#include <X11/Xaw/SimpleMenu.h>
457a84e134Smrg#include <X11/Xaw/SmeBSBP.h>
467a84e134Smrg#include <X11/Xaw/XawInit.h>
477a84e134Smrg#include "Private.h"
487a84e134Smrg
497a84e134Smrg#define ONE_HUNDRED 100
507a84e134Smrg
517a84e134Smrg/*
527a84e134Smrg * Class Methods
537a84e134Smrg */
547a84e134Smrgstatic void FlipColors(Widget);
557a84e134Smrgstatic void XawSmeBSBClassInitialize(void);
567a84e134Smrgstatic void XawSmeBSBInitialize(Widget, Widget, ArgList, Cardinal*);
577a84e134Smrgstatic void XawSmeBSBDestroy(Widget);
587a84e134Smrgstatic XtGeometryResult XawSmeBSBQueryGeometry(Widget, XtWidgetGeometry*,
597a84e134Smrg					       XtWidgetGeometry*);
607a84e134Smrgstatic void XawSmeBSBRedisplay(Widget, XEvent*, Region);
617a84e134Smrgstatic Boolean XawSmeBSBSetValues(Widget, Widget, Widget,
627a84e134Smrg				  ArgList, Cardinal*);
637a84e134Smrg
64421c997bSmrg/*
657a84e134Smrg * Prototypes
667a84e134Smrg */
677a84e134Smrgstatic void CreateGCs(Widget);
687a84e134Smrgstatic void GetBitmapInfo(Widget, Bool);
697a84e134Smrgstatic void GetDefaultSize(Widget, Dimension*, Dimension*);
707a84e134Smrgstatic void DestroyGCs(Widget);
717a84e134Smrgstatic void DrawBitmaps(Widget, GC);
727a84e134Smrg
737a84e134Smrg/*
747a84e134Smrg * Initialization
757a84e134Smrg */
767a84e134Smrg#define offset(field) XtOffsetOf(SmeBSBRec, sme_bsb.field)
777a84e134Smrgstatic XtResource resources[] = {
787a84e134Smrg  {
797a84e134Smrg    XtNlabel,
807a84e134Smrg    XtCLabel,
817a84e134Smrg    XtRString,
827a84e134Smrg    sizeof(String),
837a84e134Smrg    offset(label),
847a84e134Smrg    XtRString,
857a84e134Smrg    NULL
867a84e134Smrg  },
877a84e134Smrg  {
887a84e134Smrg    XtNvertSpace,
897a84e134Smrg    XtCVertSpace,
907a84e134Smrg    XtRInt,
917a84e134Smrg    sizeof(int),
927a84e134Smrg    offset(vert_space),
937a84e134Smrg    XtRImmediate,
947a84e134Smrg    (XtPointer)25
957a84e134Smrg  },
967a84e134Smrg  {
977a84e134Smrg    XtNleftBitmap,
987a84e134Smrg    XtCLeftBitmap,
997a84e134Smrg    XtRBitmap,
1007a84e134Smrg    sizeof(Pixmap),
1017a84e134Smrg    offset(left_bitmap),
1027a84e134Smrg    XtRImmediate,
1037a84e134Smrg    (XtPointer)None
1047a84e134Smrg  },
1057a84e134Smrg  {
1067a84e134Smrg    XtNjustify,
1077a84e134Smrg    XtCJustify,
1087a84e134Smrg    XtRJustify,
1097a84e134Smrg    sizeof(XtJustify),
1107a84e134Smrg    offset(justify),
1117a84e134Smrg    XtRImmediate,
1127a84e134Smrg    (XtPointer)XtJustifyLeft
1137a84e134Smrg  },
1147a84e134Smrg  {
1157a84e134Smrg    XtNrightBitmap,
1167a84e134Smrg    XtCRightBitmap,
1177a84e134Smrg    XtRBitmap,
1187a84e134Smrg    sizeof(Pixmap),
1197a84e134Smrg    offset(right_bitmap),
1207a84e134Smrg    XtRImmediate,
1217a84e134Smrg    (XtPointer)None
1227a84e134Smrg  },
1237a84e134Smrg  {
1247a84e134Smrg    XtNleftMargin,
1257a84e134Smrg    XtCHorizontalMargins,
1267a84e134Smrg    XtRDimension,
1277a84e134Smrg    sizeof(Dimension),
1287a84e134Smrg    offset(left_margin),
1297a84e134Smrg    XtRImmediate,
1307a84e134Smrg    (XtPointer)4
1317a84e134Smrg  },
1327a84e134Smrg  {
1337a84e134Smrg    XtNrightMargin,
1347a84e134Smrg    XtCHorizontalMargins,
1357a84e134Smrg    XtRDimension,
1367a84e134Smrg    sizeof(Dimension),
1377a84e134Smrg    offset(right_margin),
1387a84e134Smrg    XtRImmediate,
1397a84e134Smrg    (XtPointer)4
1407a84e134Smrg  },
1417a84e134Smrg  {
1427a84e134Smrg    XtNforeground,
1437a84e134Smrg    XtCForeground,
1447a84e134Smrg    XtRPixel,
1457a84e134Smrg    sizeof(Pixel),
1467a84e134Smrg    offset(foreground),
1477a84e134Smrg    XtRString,
1485ec34c4cSmrg    (XtPointer)XtDefaultForeground
1497a84e134Smrg  },
1507a84e134Smrg  {
1517a84e134Smrg    XtNfont,
1527a84e134Smrg    XtCFont,
1537a84e134Smrg    XtRFontStruct,
1547a84e134Smrg    sizeof(XFontStruct*),
1557a84e134Smrg    offset(font),
1567a84e134Smrg    XtRString,
1575ec34c4cSmrg    (XtPointer)XtDefaultFont
1587a84e134Smrg  },
1597a84e134Smrg  {
1607a84e134Smrg    XtNfontSet,
1617a84e134Smrg    XtCFontSet,
1627a84e134Smrg    XtRFontSet,
1637a84e134Smrg    sizeof(XFontSet),
1647a84e134Smrg    offset(fontset),
1657a84e134Smrg    XtRString,
1665ec34c4cSmrg    (XtPointer)XtDefaultFontSet
1677a84e134Smrg  },
1687a84e134Smrg#ifndef OLDXAW
1697a84e134Smrg  {
1707a84e134Smrg    XtNmenuName,
1717a84e134Smrg    XtCMenuName,
1727a84e134Smrg    XtRString,
1737a84e134Smrg    sizeof(String),
1747a84e134Smrg    offset(menu_name),
1757a84e134Smrg    XtRImmediate,
1767a84e134Smrg    (XtPointer)NULL
1777a84e134Smrg  },
1787a84e134Smrg#endif
1797a84e134Smrg};
1807a84e134Smrg#undef offset
181421c997bSmrg
1827a84e134Smrg#define superclass (&smeClassRec)
1837a84e134SmrgSmeBSBClassRec smeBSBClassRec = {
1847a84e134Smrg  /* rectangle */
1857a84e134Smrg  {
1867a84e134Smrg    (WidgetClass)superclass,		/* superclass */
1877a84e134Smrg    "SmeBSB",				/* class_name */
1887a84e134Smrg    sizeof(SmeBSBRec),			/* size */
1897a84e134Smrg    XawSmeBSBClassInitialize,		/* class_init */
1907a84e134Smrg    NULL,				/* class_part_initialize */
1917a84e134Smrg    False,				/* class_inited */
1927a84e134Smrg    XawSmeBSBInitialize,		/* initialize */
1937a84e134Smrg    NULL,				/* initialize_hook */
1947a84e134Smrg    NULL,				/* realize */
1957a84e134Smrg    NULL,				/* actions */
1967a84e134Smrg    0,					/* num_actions */
1977a84e134Smrg    resources,				/* resources */
1987a84e134Smrg    XtNumber(resources),		/* num_resources */
1997a84e134Smrg    NULLQUARK,				/* xrm_class */
2007a84e134Smrg    False,				/* compress_motion */
2017a84e134Smrg    False,				/* compress_exposure */
2027a84e134Smrg    False,				/* compress_enterleave */
2037a84e134Smrg    False,				/* visible_interest */
2047a84e134Smrg    XawSmeBSBDestroy,			/* destroy */
2057a84e134Smrg    NULL,				/* resize */
2067a84e134Smrg    XawSmeBSBRedisplay,			/* expose */
2077a84e134Smrg    XawSmeBSBSetValues,			/* set_values */
2087a84e134Smrg    NULL,				/* set_values_hook */
2097a84e134Smrg    XtInheritSetValuesAlmost,		/* set_values_almost */
2107a84e134Smrg    NULL,				/* get_values_hook */
2117a84e134Smrg    NULL,				/* accept_focus */
2127a84e134Smrg    XtVersion,				/* intrinsics version */
2137a84e134Smrg    NULL,				/* callback offsets */
2147a84e134Smrg    NULL,				/* tm_table */
2157a84e134Smrg    XawSmeBSBQueryGeometry,		/* query_geometry */
2167a84e134Smrg    NULL,				/* display_accelerator */
217421c997bSmrg    NULL,				/* extension */
2187a84e134Smrg  },
2197a84e134Smrg  /* sme */
2207a84e134Smrg  {
2217a84e134Smrg    FlipColors,				/* highlight */
2227a84e134Smrg    FlipColors,				/* unhighlight */
2237a84e134Smrg    XtInheritNotify,			/* notify */
2247a84e134Smrg    NULL,				/* extension */
2257a84e134Smrg  },
2267a84e134Smrg  /* sme_bsb */
2277a84e134Smrg  {
2287a84e134Smrg    NULL,				/* extension */
2297a84e134Smrg  },
2307a84e134Smrg};
2317a84e134SmrgWidgetClass smeBSBObjectClass = (WidgetClass)&smeBSBClassRec;
2327a84e134Smrg
2337a84e134Smrg/*
2347a84e134Smrg * Function:
2357a84e134Smrg *	XawSmeBSBClassInitialize
2367a84e134Smrg *
2377a84e134Smrg * Description:
2387a84e134Smrg *	Initializes the SmeBSBObject.
2397a84e134Smrg */
240421c997bSmrgstatic void
2417a84e134SmrgXawSmeBSBClassInitialize(void)
2427a84e134Smrg{
2437a84e134Smrg    XawInitializeWidgetSet();
2447a84e134Smrg    XtAddConverter(XtRString, XtRJustify, XmuCvtStringToJustify, NULL, 0);
2457a84e134Smrg    XtSetTypeConverter(XtRJustify, XtRString, XmuCvtJustifyToString,
2467a84e134Smrg		       NULL, 0, XtCacheNone, NULL);
2477a84e134Smrg}
2487a84e134Smrg
2497a84e134Smrg/*
2507a84e134Smrg * Function:
2517a84e134Smrg *	XawSmeBSBInitialize
2527a84e134Smrg *
2537a84e134Smrg * Parameters:
2547a84e134Smrg *	request	- widget requested by the argument list
2557a84e134Smrg *	cnew	- new widget with both resource and non resource values
2567a84e134Smrg *
2577a84e134Smrg * Description:
2587a84e134Smrg *	Initializes the simple menu widget entry.
2597a84e134Smrg */
2607a84e134Smrg/*ARGSUSED*/
2617a84e134Smrgstatic void
2625ec34c4cSmrgXawSmeBSBInitialize(Widget request _X_UNUSED, Widget cnew,
2635ec34c4cSmrg		    ArgList args _X_UNUSED, Cardinal *num_args _X_UNUSED)
2647a84e134Smrg{
2657a84e134Smrg    SmeBSBObject entry = (SmeBSBObject)cnew;
2667a84e134Smrg
2677a84e134Smrg    if (!entry->sme_bsb.font) XtError("Aborting: no font found\n");
2687a84e134Smrg
269421c997bSmrg    if (entry->sme_bsb.label == NULL)
2707a84e134Smrg	entry->sme_bsb.label = XtName(cnew);
2717a84e134Smrg    else
2727a84e134Smrg	entry->sme_bsb.label = XtNewString(entry->sme_bsb.label);
2737a84e134Smrg
2747a84e134Smrg    GetDefaultSize(cnew, &entry->rectangle.width, &entry->rectangle.height);
2757a84e134Smrg    CreateGCs(cnew);
2767a84e134Smrg
2777a84e134Smrg    entry->sme_bsb.left_bitmap_width = entry->sme_bsb.left_bitmap_height = 0;
2787a84e134Smrg    entry->sme_bsb.right_bitmap_width = entry->sme_bsb.right_bitmap_height = 0;
2797a84e134Smrg
2807a84e134Smrg    GetBitmapInfo(cnew, True);	/* Left Bitmap Info */
2817a84e134Smrg    GetBitmapInfo(cnew, False);	/* Right Bitmap Info */
2827a84e134Smrg}
2837a84e134Smrg
2847a84e134Smrg/*
2857a84e134Smrg * Function:
2867a84e134Smrg *	XawSmeBSBDestroy
2877a84e134Smrg *
2887a84e134Smrg * Parameters:
2897a84e134Smrg *	w - simple menu widget entry
2907a84e134Smrg */
2917a84e134Smrgstatic void
2927a84e134SmrgXawSmeBSBDestroy(Widget w)
2937a84e134Smrg{
2947a84e134Smrg    SmeBSBObject entry = (SmeBSBObject)w;
2957a84e134Smrg
2967a84e134Smrg    DestroyGCs(w);
2977a84e134Smrg    if (entry->sme_bsb.label != XtName(w))
2985ec34c4cSmrg	XtFree((char *)entry->sme_bsb.label);
2997a84e134Smrg}
3007a84e134Smrg
3017a84e134Smrg/*
3027a84e134Smrg * Function:
3037a84e134Smrg *	XawSmeBSBRedisplay
3047a84e134Smrg *
3057a84e134Smrg * Parameters:
3067a84e134Smrg *	w      - simple menu widget entry
3077a84e134Smrg *	event  - X event that caused this redisplay
3087a84e134Smrg *	region - region the needs to be repainted
3097a84e134Smrg *
3107a84e134Smrg * Description:
3117a84e134Smrg *	Redisplays the contents of the widget.
3127a84e134Smrg */
3137a84e134Smrg/* ARGSUSED */
3147a84e134Smrgstatic void
3155ec34c4cSmrgXawSmeBSBRedisplay(Widget w, XEvent *event _X_UNUSED, Region region _X_UNUSED)
3167a84e134Smrg{
3177a84e134Smrg    GC gc;
3187a84e134Smrg    SmeBSBObject entry = (SmeBSBObject)w;
3197a84e134Smrg    int	font_ascent, font_descent, y_loc;
3207a84e134Smrg    int	fontset_ascent, fontset_descent;
3217a84e134Smrg    XFontSetExtents *ext = XExtentsOfFontSet(entry->sme_bsb.fontset);
3227a84e134Smrg
3237a84e134Smrg    font_ascent = font_descent = fontset_ascent = fontset_descent = 0;
3247a84e134Smrg    entry->sme_bsb.set_values_area_cleared = False;
3257a84e134Smrg
3267a84e134Smrg    if (entry->sme.international == True) {
3277a84e134Smrg	fontset_ascent = XawAbs(ext->max_ink_extent.y);
3287a84e134Smrg	fontset_descent = ext->max_ink_extent.height - fontset_ascent;
3297a84e134Smrg    }
3307a84e134Smrg    else {
3317a84e134Smrg	font_ascent = entry->sme_bsb.font->max_bounds.ascent;
3327a84e134Smrg	font_descent = entry->sme_bsb.font->max_bounds.descent;
3337a84e134Smrg    }
3347a84e134Smrg    y_loc = XtY(entry);
3357a84e134Smrg
3367a84e134Smrg    if (XtIsSensitive(w) && XtIsSensitive(XtParent(w))) {
3377a84e134Smrg	if (w == XawSimpleMenuGetActiveEntry(XtParent(w))) {
338421c997bSmrg	    XFillRectangle(XtDisplayOfObject(w), XtWindowOfObject(w),
3397a84e134Smrg			   entry->sme_bsb.norm_gc, XtX(w), y_loc,
3407a84e134Smrg			   XtWidth(entry), XtHeight(entry));
3417a84e134Smrg	    gc = entry->sme_bsb.rev_gc;
3427a84e134Smrg	}
3437a84e134Smrg	else
3447a84e134Smrg	    gc = entry->sme_bsb.norm_gc;
3457a84e134Smrg    }
3467a84e134Smrg    else
3477a84e134Smrg	gc = entry->sme_bsb.norm_gray_gc;
348421c997bSmrg
3497a84e134Smrg    if (entry->sme_bsb.label != NULL) {
3507a84e134Smrg	int x_loc = entry->sme_bsb.left_margin;
3515ec34c4cSmrg	int len = (int)strlen(entry->sme_bsb.label);
3525ec34c4cSmrg	_Xconst char *label = entry->sme_bsb.label;
3537a84e134Smrg	 int width, t_width;
3547a84e134Smrg
3557a84e134Smrg	switch(entry->sme_bsb.justify) {
3567a84e134Smrg	    case XtJustifyCenter:
3577a84e134Smrg		if (entry->sme.international == True) {
3587a84e134Smrg		    t_width = XmbTextEscapement(entry->sme_bsb.fontset,label,
3597a84e134Smrg						len);
3607a84e134Smrg		    width = XtWidth(entry) - (entry->sme_bsb.left_margin +
3617a84e134Smrg					      entry->sme_bsb.right_margin);
3627a84e134Smrg		}
3637a84e134Smrg		else {
3647a84e134Smrg		    t_width = XTextWidth(entry->sme_bsb.font, label, len);
3657a84e134Smrg		    width = XtWidth(entry) - (entry->sme_bsb.left_margin +
3667a84e134Smrg					      entry->sme_bsb.right_margin);
3677a84e134Smrg		}
3687a84e134Smrg		x_loc += (width - t_width) >> 1;
3697a84e134Smrg		break;
3707a84e134Smrg	    case XtJustifyRight:
3717a84e134Smrg		if (entry->sme.international == True) {
3727a84e134Smrg		    t_width = XmbTextEscapement(entry->sme_bsb.fontset,label,
3737a84e134Smrg						len);
3747a84e134Smrg		    x_loc = XtWidth(entry) - (entry->sme_bsb.right_margin +
3757a84e134Smrg					      t_width);
3767a84e134Smrg		}
3777a84e134Smrg		else {
3787a84e134Smrg		    t_width = XTextWidth(entry->sme_bsb.font, label, len);
3797a84e134Smrg		    x_loc = XtWidth(entry) - (entry->sme_bsb.right_margin +
3807a84e134Smrg					      t_width);
3817a84e134Smrg		}
3827a84e134Smrg		break;
3837a84e134Smrg	    case XtJustifyLeft:
3847a84e134Smrg		/*FALLTHROUGH*/
3857a84e134Smrg	    default:
3867a84e134Smrg		break;
3877a84e134Smrg	}
3887a84e134Smrg
3897a84e134Smrg	/* this will center the text in the gadget top-to-bottom */
3907a84e134Smrg	if (entry->sme.international == True) {
3917a84e134Smrg	    y_loc += ((XtHeight(entry) -
3927a84e134Smrg		      (fontset_ascent + fontset_descent)) >> 1) +
3937a84e134Smrg		       fontset_ascent;
3947a84e134Smrg
3957a84e134Smrg	    XmbDrawString(XtDisplayOfObject(w), XtWindowOfObject(w),
3967a84e134Smrg		          entry->sme_bsb.fontset, gc,
3977a84e134Smrg			  XtX(w) + x_loc, y_loc, label, len);
3987a84e134Smrg	}
3997a84e134Smrg	else {
4007a84e134Smrg	    y_loc += ((XtHeight(entry) -
4017a84e134Smrg		      (font_ascent + font_descent)) >> 1) + font_ascent;
402421c997bSmrg
4037a84e134Smrg	    XDrawString(XtDisplayOfObject(w), XtWindowOfObject(w), gc,
4047a84e134Smrg			XtX(w) + x_loc, y_loc, label, len);
4057a84e134Smrg	}
4067a84e134Smrg    }
4077a84e134Smrg
4087a84e134Smrg    DrawBitmaps(w, gc);
4097a84e134Smrg}
4107a84e134Smrg
4117a84e134Smrg
4127a84e134Smrg/*
4137a84e134Smrg * Function:
4147a84e134Smrg *	XawSmeBSBSetValues
4157a84e134Smrg *
4167a84e134Smrg * Parameters:
4177a84e134Smrg *	current	- current state of the widget
4187a84e134Smrg *	request	- what was requested
4197a84e134Smrg *	cnew	- what the widget will become
4207a84e134Smrg *
4217a84e134Smrg * Description:
4227a84e134Smrg *	Relayout the menu when one of the resources is changed.
4237a84e134Smrg */
4247a84e134Smrg
4257a84e134Smrg/*ARGSUSED*/
4267a84e134Smrgstatic Boolean
4275ec34c4cSmrgXawSmeBSBSetValues(Widget current, Widget request _X_UNUSED, Widget cnew,
4285ec34c4cSmrg		   ArgList args _X_UNUSED, Cardinal *num_args _X_UNUSED)
4297a84e134Smrg{
4307a84e134Smrg    SmeBSBObject entry = (SmeBSBObject)cnew;
4317a84e134Smrg    SmeBSBObject old_entry = (SmeBSBObject)current;
4327a84e134Smrg    Boolean ret_val = False;
4337a84e134Smrg
4347a84e134Smrg    if (old_entry->sme_bsb.label != entry->sme_bsb.label) {
4357a84e134Smrg	if (old_entry->sme_bsb.label != XtName(cnew))
4367a84e134Smrg	    XtFree((char *)old_entry->sme_bsb.label);
4377a84e134Smrg
4387a84e134Smrg	if (entry->sme_bsb.label != XtName(cnew))
4397a84e134Smrg	    entry->sme_bsb.label = XtNewString(entry->sme_bsb.label);
4407a84e134Smrg
4417a84e134Smrg	ret_val = True;
4427a84e134Smrg    }
4437a84e134Smrg
4447a84e134Smrg    if (entry->rectangle.sensitive != old_entry->rectangle.sensitive)
4457a84e134Smrg	ret_val = True;
4467a84e134Smrg
4477a84e134Smrg    if (entry->sme_bsb.left_bitmap != old_entry->sme_bsb.left_bitmap) {
4487a84e134Smrg	GetBitmapInfo(cnew, True);
4497a84e134Smrg	ret_val = True;
4507a84e134Smrg    }
4517a84e134Smrg
4527a84e134Smrg    if (entry->sme_bsb.right_bitmap != old_entry->sme_bsb.right_bitmap) {
4537a84e134Smrg	GetBitmapInfo(cnew, False);
4547a84e134Smrg	ret_val = True;
4557a84e134Smrg    }
4567a84e134Smrg
4577a84e134Smrg    if ((old_entry->sme_bsb.font != entry->sme_bsb.font
4587a84e134Smrg	 && old_entry->sme.international == False)
4597a84e134Smrg	|| old_entry->sme_bsb.foreground != entry->sme_bsb.foreground)  {
4607a84e134Smrg	DestroyGCs(current);
4617a84e134Smrg	CreateGCs(cnew);
4627a84e134Smrg	ret_val = True;
4637a84e134Smrg    }
4647a84e134Smrg
4657a84e134Smrg    if (old_entry->sme_bsb.fontset != entry->sme_bsb.fontset &&
4667a84e134Smrg	old_entry->sme.international == True)
4677a84e134Smrg	/* DONT changes the GCs, because the fontset is not in them */
4687a84e134Smrg	ret_val = True;
4697a84e134Smrg
4707a84e134Smrg    if (ret_val) {
4717a84e134Smrg	Dimension width, height;
4727a84e134Smrg
4737a84e134Smrg	GetDefaultSize(cnew, &width, &height);
4747a84e134Smrg	entry->sme_bsb.set_values_area_cleared = True;
4757a84e134Smrg	XtMakeResizeRequest(cnew, width, height, NULL, NULL);
4767a84e134Smrg    }
4777a84e134Smrg
4787a84e134Smrg    return (ret_val);
4797a84e134Smrg}
4807a84e134Smrg
4817a84e134Smrg/*
4827a84e134Smrg * Function:
4837a84e134Smrg *	XawSmeBSBQueryGeometry
4847a84e134Smrg *
4857a84e134Smrg * Parameters:
4867a84e134Smrg *	w	   - menu entry object
4877a84e134Smrg *	itended	   - intended and return geometry info
4887a84e134Smrg *	return_val - ""
489421c997bSmrg *
4907a84e134Smrg * Returns:
4917a84e134Smrg *	Geometry Result
4927a84e134Smrg *
4937a84e134Smrg * Description:
4947a84e134Smrg *	  Returns the preferred geometry for this widget.
4957a84e134Smrg *	  See the Intrinsics manual for details on what this function is for.
4967a84e134Smrg */
4977a84e134Smrgstatic XtGeometryResult
4987a84e134SmrgXawSmeBSBQueryGeometry(Widget w, XtWidgetGeometry *intended,
4997a84e134Smrg		       XtWidgetGeometry *return_val)
5007a84e134Smrg{
5017a84e134Smrg    SmeBSBObject entry = (SmeBSBObject)w;
5027a84e134Smrg    Dimension width, height;
5037a84e134Smrg    XtGeometryResult ret_val = XtGeometryYes;
5047a84e134Smrg    XtGeometryMask mode = intended->request_mode;
5057a84e134Smrg
5067a84e134Smrg    GetDefaultSize(w, &width, &height);
5077a84e134Smrg
5087a84e134Smrg    if (((mode & CWWidth) && intended->width != width) || !(mode & CWWidth)) {
5097a84e134Smrg	return_val->request_mode |= CWWidth;
5107a84e134Smrg	return_val->width = width;
5117a84e134Smrg	ret_val = XtGeometryAlmost;
5127a84e134Smrg    }
5137a84e134Smrg
5147a84e134Smrg    if (((mode & CWHeight) && intended->height != height) || !(mode & CWHeight)) {
5157a84e134Smrg	return_val->request_mode |= CWHeight;
5167a84e134Smrg	return_val->height = height;
5177a84e134Smrg	ret_val = XtGeometryAlmost;
5187a84e134Smrg    }
5197a84e134Smrg
5207a84e134Smrg    if (ret_val == XtGeometryAlmost) {
5217a84e134Smrg	mode = return_val->request_mode;
5227a84e134Smrg	if (((mode & CWWidth) && width == XtWidth(entry)) &&
5237a84e134Smrg	    ((mode & CWHeight) && height == XtHeight(entry)))
5247a84e134Smrg	    return (XtGeometryNo);
5257a84e134Smrg    }
5267a84e134Smrg
5277a84e134Smrg    return (ret_val);
5287a84e134Smrg}
529421c997bSmrg
5307a84e134Smrg/*
5317a84e134Smrg * Function:
5327a84e134Smrg *	FlipColors
5337a84e134Smrg *
5347a84e134Smrg * Parameters:
5357a84e134Smrg *	w - bsb menu entry widget
5367a84e134Smrg *
5377a84e134Smrg * Description:
5387a84e134Smrg *	Invert the colors of the current entry.
5397a84e134Smrg */
540421c997bSmrgstatic void
5417a84e134SmrgFlipColors(Widget w)
5427a84e134Smrg{
5437a84e134Smrg    SmeBSBObject entry = (SmeBSBObject)w;
5447a84e134Smrg
5457a84e134Smrg    if (entry->sme_bsb.set_values_area_cleared)
5467a84e134Smrg	return;
5477a84e134Smrg
5487a84e134Smrg    XFillRectangle(XtDisplayOfObject(w), XtWindowOfObject(w),
549421c997bSmrg		   entry->sme_bsb.invert_gc,
5507a84e134Smrg		   XtX(w), XtY(entry), XtWidth(entry), XtHeight(entry));
5517a84e134Smrg}
5527a84e134Smrg
5537a84e134Smrg/*
5547a84e134Smrg * Function:
5557a84e134Smrg *	GetDefaultSize
5567a84e134Smrg *
5577a84e134Smrg * Parameters:
5587a84e134Smrg *	w      - menu entry widget.
5597a84e134Smrg *	width  - default width (return)
5607a84e134Smrg *	height - default height (return)
5617a84e134Smrg *
5627a84e134Smrg * Description:
5637a84e134Smrg *	Calculates the Default (preferred) size of this menu entry.
5647a84e134Smrg */
5657a84e134Smrgstatic void
5667a84e134SmrgGetDefaultSize(Widget w, Dimension *width, Dimension *height)
5677a84e134Smrg{
5687a84e134Smrg    SmeBSBObject entry = (SmeBSBObject)w;
5697a84e134Smrg
5707a84e134Smrg    if (entry->sme.international == True) {
5717a84e134Smrg	XFontSetExtents *ext = XExtentsOfFontSet(entry->sme_bsb.fontset);
5727a84e134Smrg
573421c997bSmrg	if (entry->sme_bsb.label == NULL)
5747a84e134Smrg	    *width = 0;
5757a84e134Smrg	else
5765ec34c4cSmrg	    *width = (Dimension)XmbTextEscapement(entry->sme_bsb.fontset,
5777a84e134Smrg				       entry->sme_bsb.label,
5785ec34c4cSmrg				       (int)strlen(entry->sme_bsb.label));
5795ec34c4cSmrg	*width = (Dimension)(*width + (entry->sme_bsb.left_margin + entry->sme_bsb.right_margin));
5807a84e134Smrg	*height = ext->max_ink_extent.height;
5815ec34c4cSmrg	*height = (Dimension)(((int)*height * (ONE_HUNDRED +
5825ec34c4cSmrg				   entry->sme_bsb.vert_space)) / ONE_HUNDRED);
5837a84e134Smrg    }
5847a84e134Smrg    else {
585421c997bSmrg	if (entry->sme_bsb.label == NULL)
5867a84e134Smrg	    *width = 0;
5877a84e134Smrg	else
5885ec34c4cSmrg	    *width = (Dimension)XTextWidth(entry->sme_bsb.font, entry->sme_bsb.label,
5895ec34c4cSmrg			    (int)strlen(entry->sme_bsb.label));
5907a84e134Smrg
5915ec34c4cSmrg	*width = (Dimension)(*width + (entry->sme_bsb.left_margin + entry->sme_bsb.right_margin));
592421c997bSmrg
5935ec34c4cSmrg	*height = (Dimension)(entry->sme_bsb.font->max_bounds.ascent +
5945ec34c4cSmrg		  entry->sme_bsb.font->max_bounds.descent);
5957a84e134Smrg
5965ec34c4cSmrg	*height = (Dimension)(((int)*height * (ONE_HUNDRED +
5975ec34c4cSmrg				   entry->sme_bsb.vert_space)) / ONE_HUNDRED);
5987a84e134Smrg    }
5997a84e134Smrg}
6007a84e134Smrg
6017a84e134Smrg/*
6027a84e134Smrg * Function:
6037a84e134Smrg *	DrawBitmaps
6047a84e134Smrg *
6057a84e134Smrg * Parameters:
6067a84e134Smrg *	w  - simple menu widget entry
6077a84e134Smrg *	gc - graphics context to use for drawing
6087a84e134Smrg *
6097a84e134Smrg * Description:
6107a84e134Smrg *	Draws left and right bitmaps.
6117a84e134Smrg */
6127a84e134Smrgstatic void
6137a84e134SmrgDrawBitmaps(Widget w, GC gc)
6147a84e134Smrg{
6157a84e134Smrg    int x_loc, y_loc;
6167a84e134Smrg    SmeBSBObject entry = (SmeBSBObject)w;
617421c997bSmrg
6187a84e134Smrg    if (entry->sme_bsb.left_bitmap == None &&
6197a84e134Smrg	entry->sme_bsb.right_bitmap == None)
6207a84e134Smrg    return;
6217a84e134Smrg
6227a84e134Smrg    /*
6237a84e134Smrg     * Draw Left Bitmap
6247a84e134Smrg     */
6257a84e134Smrg    if (entry->sme_bsb.left_bitmap != None) {
6267a84e134Smrg	x_loc = ((entry->sme_bsb.left_margin -
6277a84e134Smrg		  entry->sme_bsb.left_bitmap_width) >> 1) + XtX(w);
6287a84e134Smrg
6297a84e134Smrg	y_loc = XtY(entry) + ((XtHeight(entry) -
6307a84e134Smrg			       entry->sme_bsb.left_bitmap_height) >> 1);
6317a84e134Smrg
6327a84e134Smrg	XCopyPlane(XtDisplayOfObject(w), entry->sme_bsb.left_bitmap,
633421c997bSmrg		   XtWindowOfObject(w), gc, 0, 0,
6347a84e134Smrg		   entry->sme_bsb.left_bitmap_width,
6357a84e134Smrg		   entry->sme_bsb.left_bitmap_height, x_loc, y_loc, 1);
6367a84e134Smrg    }
6377a84e134Smrg
6387a84e134Smrg    /*
6397a84e134Smrg     * Draw Right Bitmap
6407a84e134Smrg     */
6417a84e134Smrg    if (entry->sme_bsb.right_bitmap != None) {
6427a84e134Smrg	x_loc = XtWidth(entry) - ((entry->sme_bsb.right_margin +
6437a84e134Smrg				  entry->sme_bsb.right_bitmap_width) >> 1) +
6447a84e134Smrg				  XtX(w);
6457a84e134Smrg	y_loc = XtY(entry) + ((XtHeight(entry) -
6467a84e134Smrg			      entry->sme_bsb.right_bitmap_height) >> 1);
6477a84e134Smrg
6487a84e134Smrg	XCopyPlane(XtDisplayOfObject(w), entry->sme_bsb.right_bitmap,
649421c997bSmrg		   XtWindowOfObject(w), gc, 0, 0,
6507a84e134Smrg		   entry->sme_bsb.right_bitmap_width,
6517a84e134Smrg	 	   entry->sme_bsb.right_bitmap_height, x_loc, y_loc, 1);
6527a84e134Smrg    }
6537a84e134Smrg}
6547a84e134Smrg
6557a84e134Smrg/*
6567a84e134Smrg * Function:
6577a84e134Smrg *	GetBitmapInfo
6587a84e134Smrg *
6597a84e134Smrg * Parameters:
6607a84e134Smrg *	w	- bsb menu entry object
6617a84e134Smrg *	is_left - True: if we are testing left bitmap
6627a84e134Smrg *		  False: if we are testing the right bitmap
6637a84e134Smrg *
6647a84e134Smrg * Description:
6657a84e134Smrg *	Gets the bitmap information from either of the bitmaps.
6667a84e134Smrg */
6677a84e134Smrgstatic void
6687a84e134SmrgGetBitmapInfo(Widget w, Bool is_left)
6697a84e134Smrg{
6707a84e134Smrg    SmeBSBObject entry = (SmeBSBObject)w;
6717a84e134Smrg    unsigned int depth, bw;
6727a84e134Smrg    Window root;
6737a84e134Smrg    int x, y;
6747a84e134Smrg    unsigned int width, height;
675421c997bSmrg
6767a84e134Smrg    if (is_left) {
6777a84e134Smrg	if (entry->sme_bsb.left_bitmap != None &&
6787a84e134Smrg	    XGetGeometry(XtDisplayOfObject(w),
679421c997bSmrg			 entry->sme_bsb.left_bitmap, &root,
6807a84e134Smrg			 &x, &y, &width, &height, &bw, &depth))	{
6815ec34c4cSmrg	    entry->sme_bsb.left_bitmap_width = (Dimension)width;
6825ec34c4cSmrg	    entry->sme_bsb.left_bitmap_height = (Dimension)height;
6837a84e134Smrg	}
6847a84e134Smrg    }
6857a84e134Smrg    else if (entry->sme_bsb.right_bitmap != None &&
6867a84e134Smrg	     XGetGeometry(XtDisplayOfObject(w),
6877a84e134Smrg			  entry->sme_bsb.right_bitmap, &root,
6887a84e134Smrg			  &x, &y, &width, &height, &bw, &depth)) {
6895ec34c4cSmrg	entry->sme_bsb.right_bitmap_width = (Dimension)width;
6905ec34c4cSmrg	entry->sme_bsb.right_bitmap_height = (Dimension)height;
6917a84e134Smrg    }
6927a84e134Smrg}
6937a84e134Smrg
6947a84e134Smrg/*
6957a84e134Smrg * Function:
6967a84e134Smrg *	CreateGCs
6977a84e134Smrg *
6987a84e134Smrg * Parameters:
6997a84e134Smrg *	w - simple menu widget entry
7007a84e134Smrg *
7017a84e134Smrg * Description:
7027a84e134Smrg *	Creates all gc's for the simple menu widget.
7037a84e134Smrg */
7047a84e134Smrgstatic void
7057a84e134SmrgCreateGCs(Widget w)
7067a84e134Smrg{
7077a84e134Smrg    SmeBSBObject entry = (SmeBSBObject)w;
7087a84e134Smrg    XGCValues values;
7097a84e134Smrg    XtGCMask mask, mask_i18n;
710421c997bSmrg
7117a84e134Smrg    values.foreground = XtParent(w)->core.background_pixel;
7127a84e134Smrg    values.background = entry->sme_bsb.foreground;
7137a84e134Smrg    values.font = entry->sme_bsb.font->fid;
7147a84e134Smrg    values.graphics_exposures = False;
7157a84e134Smrg    mask      = GCForeground | GCBackground | GCGraphicsExposures | GCFont;
7167a84e134Smrg    mask_i18n = GCForeground | GCBackground | GCGraphicsExposures;
7177a84e134Smrg    if (entry->sme.international == True)
7187a84e134Smrg	entry->sme_bsb.rev_gc = XtAllocateGC(w, 0, mask_i18n, &values, GCFont, 0);
7197a84e134Smrg    else
7207a84e134Smrg	entry->sme_bsb.rev_gc = XtGetGC(w, mask, &values);
721421c997bSmrg
7227a84e134Smrg    values.foreground = entry->sme_bsb.foreground;
7237a84e134Smrg    values.background = XtParent(w)->core.background_pixel;
7247a84e134Smrg    if (entry->sme.international == True)
7257a84e134Smrg	entry->sme_bsb.norm_gc = XtAllocateGC(w, 0, mask_i18n, &values, GCFont, 0);
7267a84e134Smrg    else
7277a84e134Smrg	entry->sme_bsb.norm_gc = XtGetGC(w, mask, &values);
7287a84e134Smrg
7297a84e134Smrg    values.fill_style = FillTiled;
730421c997bSmrg    values.tile   = XmuCreateStippledPixmap(XtScreenOfObject(w),
7317a84e134Smrg					    entry->sme_bsb.foreground,
7327a84e134Smrg					    XtParent(w)->core.background_pixel,
7337a84e134Smrg					    XtParent(w)->core.depth);
7347a84e134Smrg    values.graphics_exposures = False;
7357a84e134Smrg    mask |= GCTile | GCFillStyle;
7367a84e134Smrg    mask_i18n |= GCTile | GCFillStyle;
7377a84e134Smrg    if (entry->sme.international == True)
7387a84e134Smrg	entry->sme_bsb.norm_gray_gc = XtAllocateGC(w, 0, mask_i18n, &values,
7397a84e134Smrg						   GCFont, 0);
7407a84e134Smrg    else
7417a84e134Smrg	entry->sme_bsb.norm_gray_gc = XtGetGC(w, mask, &values);
7427a84e134Smrg
7437a84e134Smrg    values.foreground ^= values.background;
7447a84e134Smrg    values.background = 0;
7457a84e134Smrg    values.function = GXxor;
7467a84e134Smrg    mask = GCForeground | GCBackground | GCGraphicsExposures | GCFunction;
7477a84e134Smrg    entry->sme_bsb.invert_gc = XtGetGC(w, mask, &values);
7487a84e134Smrg}
7497a84e134Smrg
7507a84e134Smrg/*
7517a84e134Smrg * Function:
7527a84e134Smrg *	DestroyGCs
7537a84e134Smrg *
7547a84e134Smrg * Parameters:
7557a84e134Smrg *	w - simple menu widget entry
7567a84e134Smrg *
7577a84e134Smrg * Description:
7587a84e134Smrg *	Removes all gc's for the simple menu widget.
7597a84e134Smrg */
7607a84e134Smrgstatic void
7617a84e134SmrgDestroyGCs(Widget w)
7627a84e134Smrg{
7637a84e134Smrg    SmeBSBObject entry = (SmeBSBObject)w;
7647a84e134Smrg
7657a84e134Smrg    XtReleaseGC(w, entry->sme_bsb.norm_gc);
7667a84e134Smrg    XtReleaseGC(w, entry->sme_bsb.norm_gray_gc);
7677a84e134Smrg    XtReleaseGC(w, entry->sme_bsb.rev_gc);
7687a84e134Smrg    XtReleaseGC(w, entry->sme_bsb.invert_gc);
7697a84e134Smrg}
770