SmeBSB.c revision 421c997b
1/*
2Copyright 1989, 1994, 1998  The Open Group
3
4Permission to use, copy, modify, distribute, and sell this software and its
5documentation for any purpose is hereby granted without fee, provided that
6the above copyright notice appear in all copies and that both that
7copyright notice and this permission notice appear in supporting
8documentation.
9
10The above copyright notice and this permission notice shall be included in
11all copies or substantial portions of the Software.
12
13THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
16OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
17AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
18CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19
20Except as contained in this notice, the name of The Open Group shall not be
21used in advertising or otherwise to promote the sale, use or other dealings
22in this Software without prior written authorization from The Open Group.
23 */
24
25/*
26 * SmeBSB.c - Source code file for BSB Menu Entry object.
27 *
28 * Date:    September 26, 1989
29 *
30 * By:      Chris D. Peterson
31 *          MIT X Consortium
32 *          kit@expo.lcs.mit.edu
33 */
34
35#ifdef HAVE_CONFIG_H
36#include <config.h>
37#endif
38#include <stdio.h>
39#include <X11/IntrinsicP.h>
40#include <X11/StringDefs.h>
41#include <X11/Xos.h>
42#include <X11/Xmu/Drawing.h>
43#include <X11/Xaw/Cardinals.h>
44#include <X11/Xaw/SimpleMenu.h>
45#include <X11/Xaw/SmeBSBP.h>
46#include <X11/Xaw/XawInit.h>
47#include "Private.h"
48
49#define ONE_HUNDRED 100
50
51/*
52 * Class Methods
53 */
54static void FlipColors(Widget);
55static void XawSmeBSBClassInitialize(void);
56static void XawSmeBSBInitialize(Widget, Widget, ArgList, Cardinal*);
57static void XawSmeBSBDestroy(Widget);
58static XtGeometryResult XawSmeBSBQueryGeometry(Widget, XtWidgetGeometry*,
59					       XtWidgetGeometry*);
60static void XawSmeBSBRedisplay(Widget, XEvent*, Region);
61static Boolean XawSmeBSBSetValues(Widget, Widget, Widget,
62				  ArgList, Cardinal*);
63
64/*
65 * Prototypes
66 */
67static void CreateGCs(Widget);
68static void GetBitmapInfo(Widget, Bool);
69static void GetDefaultSize(Widget, Dimension*, Dimension*);
70static void DestroyGCs(Widget);
71static void DrawBitmaps(Widget, GC);
72
73/*
74 * Initialization
75 */
76#define offset(field) XtOffsetOf(SmeBSBRec, sme_bsb.field)
77static XtResource resources[] = {
78  {
79    XtNlabel,
80    XtCLabel,
81    XtRString,
82    sizeof(String),
83    offset(label),
84    XtRString,
85    NULL
86  },
87  {
88    XtNvertSpace,
89    XtCVertSpace,
90    XtRInt,
91    sizeof(int),
92    offset(vert_space),
93    XtRImmediate,
94    (XtPointer)25
95  },
96  {
97    XtNleftBitmap,
98    XtCLeftBitmap,
99    XtRBitmap,
100    sizeof(Pixmap),
101    offset(left_bitmap),
102    XtRImmediate,
103    (XtPointer)None
104  },
105  {
106    XtNjustify,
107    XtCJustify,
108    XtRJustify,
109    sizeof(XtJustify),
110    offset(justify),
111    XtRImmediate,
112    (XtPointer)XtJustifyLeft
113  },
114  {
115    XtNrightBitmap,
116    XtCRightBitmap,
117    XtRBitmap,
118    sizeof(Pixmap),
119    offset(right_bitmap),
120    XtRImmediate,
121    (XtPointer)None
122  },
123  {
124    XtNleftMargin,
125    XtCHorizontalMargins,
126    XtRDimension,
127    sizeof(Dimension),
128    offset(left_margin),
129    XtRImmediate,
130    (XtPointer)4
131  },
132  {
133    XtNrightMargin,
134    XtCHorizontalMargins,
135    XtRDimension,
136    sizeof(Dimension),
137    offset(right_margin),
138    XtRImmediate,
139    (XtPointer)4
140  },
141  {
142    XtNforeground,
143    XtCForeground,
144    XtRPixel,
145    sizeof(Pixel),
146    offset(foreground),
147    XtRString,
148    XtDefaultForeground
149  },
150  {
151    XtNfont,
152    XtCFont,
153    XtRFontStruct,
154    sizeof(XFontStruct*),
155    offset(font),
156    XtRString,
157    XtDefaultFont
158  },
159  {
160    XtNfontSet,
161    XtCFontSet,
162    XtRFontSet,
163    sizeof(XFontSet),
164    offset(fontset),
165    XtRString,
166    XtDefaultFontSet
167  },
168#ifndef OLDXAW
169  {
170    XtNmenuName,
171    XtCMenuName,
172    XtRString,
173    sizeof(String),
174    offset(menu_name),
175    XtRImmediate,
176    (XtPointer)NULL
177  },
178#endif
179};
180#undef offset
181
182#define superclass (&smeClassRec)
183SmeBSBClassRec smeBSBClassRec = {
184  /* rectangle */
185  {
186    (WidgetClass)superclass,		/* superclass */
187    "SmeBSB",				/* class_name */
188    sizeof(SmeBSBRec),			/* size */
189    XawSmeBSBClassInitialize,		/* class_init */
190    NULL,				/* class_part_initialize */
191    False,				/* class_inited */
192    XawSmeBSBInitialize,		/* initialize */
193    NULL,				/* initialize_hook */
194    NULL,				/* realize */
195    NULL,				/* actions */
196    0,					/* num_actions */
197    resources,				/* resources */
198    XtNumber(resources),		/* num_resources */
199    NULLQUARK,				/* xrm_class */
200    False,				/* compress_motion */
201    False,				/* compress_exposure */
202    False,				/* compress_enterleave */
203    False,				/* visible_interest */
204    XawSmeBSBDestroy,			/* destroy */
205    NULL,				/* resize */
206    XawSmeBSBRedisplay,			/* expose */
207    XawSmeBSBSetValues,			/* set_values */
208    NULL,				/* set_values_hook */
209    XtInheritSetValuesAlmost,		/* set_values_almost */
210    NULL,				/* get_values_hook */
211    NULL,				/* accept_focus */
212    XtVersion,				/* intrinsics version */
213    NULL,				/* callback offsets */
214    NULL,				/* tm_table */
215    XawSmeBSBQueryGeometry,		/* query_geometry */
216    NULL,				/* display_accelerator */
217    NULL,				/* extension */
218  },
219  /* sme */
220  {
221    FlipColors,				/* highlight */
222    FlipColors,				/* unhighlight */
223    XtInheritNotify,			/* notify */
224    NULL,				/* extension */
225  },
226  /* sme_bsb */
227  {
228    NULL,				/* extension */
229  },
230};
231WidgetClass smeBSBObjectClass = (WidgetClass)&smeBSBClassRec;
232
233/*
234 * Function:
235 *	XawSmeBSBClassInitialize
236 *
237 * Description:
238 *	Initializes the SmeBSBObject.
239 */
240static void
241XawSmeBSBClassInitialize(void)
242{
243    XawInitializeWidgetSet();
244    XtAddConverter(XtRString, XtRJustify, XmuCvtStringToJustify, NULL, 0);
245    XtSetTypeConverter(XtRJustify, XtRString, XmuCvtJustifyToString,
246		       NULL, 0, XtCacheNone, NULL);
247}
248
249/*
250 * Function:
251 *	XawSmeBSBInitialize
252 *
253 * Parameters:
254 *	request	- widget requested by the argument list
255 *	cnew	- new widget with both resource and non resource values
256 *
257 * Description:
258 *	Initializes the simple menu widget entry.
259 */
260/*ARGSUSED*/
261static void
262XawSmeBSBInitialize(Widget request, Widget cnew,
263		    ArgList args, Cardinal *num_args)
264{
265    SmeBSBObject entry = (SmeBSBObject)cnew;
266
267    if (!entry->sme_bsb.font) XtError("Aborting: no font found\n");
268
269    if (entry->sme_bsb.label == NULL)
270	entry->sme_bsb.label = XtName(cnew);
271    else
272	entry->sme_bsb.label = XtNewString(entry->sme_bsb.label);
273
274    GetDefaultSize(cnew, &entry->rectangle.width, &entry->rectangle.height);
275    CreateGCs(cnew);
276
277    entry->sme_bsb.left_bitmap_width = entry->sme_bsb.left_bitmap_height = 0;
278    entry->sme_bsb.right_bitmap_width = entry->sme_bsb.right_bitmap_height = 0;
279
280    GetBitmapInfo(cnew, True);	/* Left Bitmap Info */
281    GetBitmapInfo(cnew, False);	/* Right Bitmap Info */
282}
283
284/*
285 * Function:
286 *	XawSmeBSBDestroy
287 *
288 * Parameters:
289 *	w - simple menu widget entry
290 */
291static void
292XawSmeBSBDestroy(Widget w)
293{
294    SmeBSBObject entry = (SmeBSBObject)w;
295
296    DestroyGCs(w);
297    if (entry->sme_bsb.label != XtName(w))
298	XtFree(entry->sme_bsb.label);
299}
300
301/*
302 * Function:
303 *	XawSmeBSBRedisplay
304 *
305 * Parameters:
306 *	w      - simple menu widget entry
307 *	event  - X event that caused this redisplay
308 *	region - region the needs to be repainted
309 *
310 * Description:
311 *	Redisplays the contents of the widget.
312 */
313/* ARGSUSED */
314static void
315XawSmeBSBRedisplay(Widget w, XEvent *event, Region region)
316{
317    GC gc;
318    SmeBSBObject entry = (SmeBSBObject)w;
319    int	font_ascent, font_descent, y_loc;
320    int	fontset_ascent, fontset_descent;
321    XFontSetExtents *ext = XExtentsOfFontSet(entry->sme_bsb.fontset);
322
323    font_ascent = font_descent = fontset_ascent = fontset_descent = 0;
324    entry->sme_bsb.set_values_area_cleared = False;
325
326    if (entry->sme.international == True) {
327	fontset_ascent = XawAbs(ext->max_ink_extent.y);
328	fontset_descent = ext->max_ink_extent.height - fontset_ascent;
329    }
330    else {
331	font_ascent = entry->sme_bsb.font->max_bounds.ascent;
332	font_descent = entry->sme_bsb.font->max_bounds.descent;
333    }
334    y_loc = XtY(entry);
335
336    if (XtIsSensitive(w) && XtIsSensitive(XtParent(w))) {
337	if (w == XawSimpleMenuGetActiveEntry(XtParent(w))) {
338	    XFillRectangle(XtDisplayOfObject(w), XtWindowOfObject(w),
339			   entry->sme_bsb.norm_gc, XtX(w), y_loc,
340			   XtWidth(entry), XtHeight(entry));
341	    gc = entry->sme_bsb.rev_gc;
342	}
343	else
344	    gc = entry->sme_bsb.norm_gc;
345    }
346    else
347	gc = entry->sme_bsb.norm_gray_gc;
348
349    if (entry->sme_bsb.label != NULL) {
350	int x_loc = entry->sme_bsb.left_margin;
351	int len = strlen(entry->sme_bsb.label);
352	char *label = entry->sme_bsb.label;
353	 int width, t_width;
354
355	switch(entry->sme_bsb.justify) {
356	    case XtJustifyCenter:
357		if (entry->sme.international == True) {
358		    t_width = XmbTextEscapement(entry->sme_bsb.fontset,label,
359						len);
360		    width = XtWidth(entry) - (entry->sme_bsb.left_margin +
361					      entry->sme_bsb.right_margin);
362		}
363		else {
364		    t_width = XTextWidth(entry->sme_bsb.font, label, len);
365		    width = XtWidth(entry) - (entry->sme_bsb.left_margin +
366					      entry->sme_bsb.right_margin);
367		}
368		x_loc += (width - t_width) >> 1;
369		break;
370	    case XtJustifyRight:
371		if (entry->sme.international == True) {
372		    t_width = XmbTextEscapement(entry->sme_bsb.fontset,label,
373						len);
374		    x_loc = XtWidth(entry) - (entry->sme_bsb.right_margin +
375					      t_width);
376		}
377		else {
378		    t_width = XTextWidth(entry->sme_bsb.font, label, len);
379		    x_loc = XtWidth(entry) - (entry->sme_bsb.right_margin +
380					      t_width);
381		}
382		break;
383	    case XtJustifyLeft:
384		/*FALLTHROUGH*/
385	    default:
386		break;
387	}
388
389	/* this will center the text in the gadget top-to-bottom */
390	if (entry->sme.international == True) {
391	    y_loc += ((XtHeight(entry) -
392		      (fontset_ascent + fontset_descent)) >> 1) +
393		       fontset_ascent;
394
395	    XmbDrawString(XtDisplayOfObject(w), XtWindowOfObject(w),
396		          entry->sme_bsb.fontset, gc,
397			  XtX(w) + x_loc, y_loc, label, len);
398	}
399	else {
400	    y_loc += ((XtHeight(entry) -
401		      (font_ascent + font_descent)) >> 1) + font_ascent;
402
403	    XDrawString(XtDisplayOfObject(w), XtWindowOfObject(w), gc,
404			XtX(w) + x_loc, y_loc, label, len);
405	}
406    }
407
408    DrawBitmaps(w, gc);
409}
410
411
412/*
413 * Function:
414 *	XawSmeBSBSetValues
415 *
416 * Parameters:
417 *	current	- current state of the widget
418 *	request	- what was requested
419 *	cnew	- what the widget will become
420 *
421 * Description:
422 *	Relayout the menu when one of the resources is changed.
423 */
424
425/*ARGSUSED*/
426static Boolean
427XawSmeBSBSetValues(Widget current, Widget request, Widget cnew,
428		   ArgList args, Cardinal *num_args)
429{
430    SmeBSBObject entry = (SmeBSBObject)cnew;
431    SmeBSBObject old_entry = (SmeBSBObject)current;
432    Boolean ret_val = False;
433
434    if (old_entry->sme_bsb.label != entry->sme_bsb.label) {
435	if (old_entry->sme_bsb.label != XtName(cnew))
436	    XtFree((char *)old_entry->sme_bsb.label);
437
438	if (entry->sme_bsb.label != XtName(cnew))
439	    entry->sme_bsb.label = XtNewString(entry->sme_bsb.label);
440
441	ret_val = True;
442    }
443
444    if (entry->rectangle.sensitive != old_entry->rectangle.sensitive)
445	ret_val = True;
446
447    if (entry->sme_bsb.left_bitmap != old_entry->sme_bsb.left_bitmap) {
448	GetBitmapInfo(cnew, True);
449	ret_val = True;
450    }
451
452    if (entry->sme_bsb.right_bitmap != old_entry->sme_bsb.right_bitmap) {
453	GetBitmapInfo(cnew, False);
454	ret_val = True;
455    }
456
457    if ((old_entry->sme_bsb.font != entry->sme_bsb.font
458	 && old_entry->sme.international == False)
459	|| old_entry->sme_bsb.foreground != entry->sme_bsb.foreground)  {
460	DestroyGCs(current);
461	CreateGCs(cnew);
462	ret_val = True;
463    }
464
465    if (old_entry->sme_bsb.fontset != entry->sme_bsb.fontset &&
466	old_entry->sme.international == True)
467	/* DONT changes the GCs, because the fontset is not in them */
468	ret_val = True;
469
470    if (ret_val) {
471	Dimension width, height;
472
473	GetDefaultSize(cnew, &width, &height);
474	entry->sme_bsb.set_values_area_cleared = True;
475	XtMakeResizeRequest(cnew, width, height, NULL, NULL);
476    }
477
478    return (ret_val);
479}
480
481/*
482 * Function:
483 *	XawSmeBSBQueryGeometry
484 *
485 * Parameters:
486 *	w	   - menu entry object
487 *	itended	   - intended and return geometry info
488 *	return_val - ""
489 *
490 * Returns:
491 *	Geometry Result
492 *
493 * Description:
494 *	  Returns the preferred geometry for this widget.
495 *	  See the Intrinsics manual for details on what this function is for.
496 */
497static XtGeometryResult
498XawSmeBSBQueryGeometry(Widget w, XtWidgetGeometry *intended,
499		       XtWidgetGeometry *return_val)
500{
501    SmeBSBObject entry = (SmeBSBObject)w;
502    Dimension width, height;
503    XtGeometryResult ret_val = XtGeometryYes;
504    XtGeometryMask mode = intended->request_mode;
505
506    GetDefaultSize(w, &width, &height);
507
508    if (((mode & CWWidth) && intended->width != width) || !(mode & CWWidth)) {
509	return_val->request_mode |= CWWidth;
510	return_val->width = width;
511	ret_val = XtGeometryAlmost;
512    }
513
514    if (((mode & CWHeight) && intended->height != height) || !(mode & CWHeight)) {
515	return_val->request_mode |= CWHeight;
516	return_val->height = height;
517	ret_val = XtGeometryAlmost;
518    }
519
520    if (ret_val == XtGeometryAlmost) {
521	mode = return_val->request_mode;
522	if (((mode & CWWidth) && width == XtWidth(entry)) &&
523	    ((mode & CWHeight) && height == XtHeight(entry)))
524	    return (XtGeometryNo);
525    }
526
527    return (ret_val);
528}
529
530/*
531 * Function:
532 *	FlipColors
533 *
534 * Parameters:
535 *	w - bsb menu entry widget
536 *
537 * Description:
538 *	Invert the colors of the current entry.
539 */
540static void
541FlipColors(Widget w)
542{
543    SmeBSBObject entry = (SmeBSBObject)w;
544
545    if (entry->sme_bsb.set_values_area_cleared)
546	return;
547
548    XFillRectangle(XtDisplayOfObject(w), XtWindowOfObject(w),
549		   entry->sme_bsb.invert_gc,
550		   XtX(w), XtY(entry), XtWidth(entry), XtHeight(entry));
551}
552
553/*
554 * Function:
555 *	GetDefaultSize
556 *
557 * Parameters:
558 *	w      - menu entry widget.
559 *	width  - default width (return)
560 *	height - default height (return)
561 *
562 * Description:
563 *	Calculates the Default (preferred) size of this menu entry.
564 */
565static void
566GetDefaultSize(Widget w, Dimension *width, Dimension *height)
567{
568    SmeBSBObject entry = (SmeBSBObject)w;
569
570    if (entry->sme.international == True) {
571	XFontSetExtents *ext = XExtentsOfFontSet(entry->sme_bsb.fontset);
572
573	if (entry->sme_bsb.label == NULL)
574	    *width = 0;
575	else
576	    *width = XmbTextEscapement(entry->sme_bsb.fontset,
577				       entry->sme_bsb.label,
578				       strlen(entry->sme_bsb.label));
579	*width += entry->sme_bsb.left_margin + entry->sme_bsb.right_margin;
580	*height = ext->max_ink_extent.height;
581	*height = ((int)*height * (ONE_HUNDRED +
582				   entry->sme_bsb.vert_space)) / ONE_HUNDRED;
583    }
584    else {
585	if (entry->sme_bsb.label == NULL)
586	    *width = 0;
587	else
588	    *width = XTextWidth(entry->sme_bsb.font, entry->sme_bsb.label,
589			    strlen(entry->sme_bsb.label));
590
591	*width += entry->sme_bsb.left_margin + entry->sme_bsb.right_margin;
592
593	*height = entry->sme_bsb.font->max_bounds.ascent +
594		  entry->sme_bsb.font->max_bounds.descent;
595
596	*height = ((int)*height * (ONE_HUNDRED +
597				   entry->sme_bsb.vert_space)) / ONE_HUNDRED;
598    }
599}
600
601/*
602 * Function:
603 *	DrawBitmaps
604 *
605 * Parameters:
606 *	w  - simple menu widget entry
607 *	gc - graphics context to use for drawing
608 *
609 * Description:
610 *	Draws left and right bitmaps.
611 */
612static void
613DrawBitmaps(Widget w, GC gc)
614{
615    int x_loc, y_loc;
616    SmeBSBObject entry = (SmeBSBObject)w;
617
618    if (entry->sme_bsb.left_bitmap == None &&
619	entry->sme_bsb.right_bitmap == None)
620    return;
621
622    /*
623     * Draw Left Bitmap
624     */
625    if (entry->sme_bsb.left_bitmap != None) {
626	x_loc = ((entry->sme_bsb.left_margin -
627		  entry->sme_bsb.left_bitmap_width) >> 1) + XtX(w);
628
629	y_loc = XtY(entry) + ((XtHeight(entry) -
630			       entry->sme_bsb.left_bitmap_height) >> 1);
631
632	XCopyPlane(XtDisplayOfObject(w), entry->sme_bsb.left_bitmap,
633		   XtWindowOfObject(w), gc, 0, 0,
634		   entry->sme_bsb.left_bitmap_width,
635		   entry->sme_bsb.left_bitmap_height, x_loc, y_loc, 1);
636    }
637
638    /*
639     * Draw Right Bitmap
640     */
641    if (entry->sme_bsb.right_bitmap != None) {
642	x_loc = XtWidth(entry) - ((entry->sme_bsb.right_margin +
643				  entry->sme_bsb.right_bitmap_width) >> 1) +
644				  XtX(w);
645	y_loc = XtY(entry) + ((XtHeight(entry) -
646			      entry->sme_bsb.right_bitmap_height) >> 1);
647
648	XCopyPlane(XtDisplayOfObject(w), entry->sme_bsb.right_bitmap,
649		   XtWindowOfObject(w), gc, 0, 0,
650		   entry->sme_bsb.right_bitmap_width,
651	 	   entry->sme_bsb.right_bitmap_height, x_loc, y_loc, 1);
652    }
653}
654
655/*
656 * Function:
657 *	GetBitmapInfo
658 *
659 * Parameters:
660 *	w	- bsb menu entry object
661 *	is_left - True: if we are testing left bitmap
662 *		  False: if we are testing the right bitmap
663 *
664 * Description:
665 *	Gets the bitmap information from either of the bitmaps.
666 */
667static void
668GetBitmapInfo(Widget w, Bool is_left)
669{
670    SmeBSBObject entry = (SmeBSBObject)w;
671    unsigned int depth, bw;
672    Window root;
673    int x, y;
674    unsigned int width, height;
675
676    if (is_left) {
677	if (entry->sme_bsb.left_bitmap != None &&
678	    XGetGeometry(XtDisplayOfObject(w),
679			 entry->sme_bsb.left_bitmap, &root,
680			 &x, &y, &width, &height, &bw, &depth))	{
681	    entry->sme_bsb.left_bitmap_width = width;
682	    entry->sme_bsb.left_bitmap_height = height;
683	}
684    }
685    else if (entry->sme_bsb.right_bitmap != None &&
686	     XGetGeometry(XtDisplayOfObject(w),
687			  entry->sme_bsb.right_bitmap, &root,
688			  &x, &y, &width, &height, &bw, &depth)) {
689	entry->sme_bsb.right_bitmap_width = width;
690	entry->sme_bsb.right_bitmap_height = height;
691    }
692}
693
694/*
695 * Function:
696 *	CreateGCs
697 *
698 * Parameters:
699 *	w - simple menu widget entry
700 *
701 * Description:
702 *	Creates all gc's for the simple menu widget.
703 */
704static void
705CreateGCs(Widget w)
706{
707    SmeBSBObject entry = (SmeBSBObject)w;
708    XGCValues values;
709    XtGCMask mask, mask_i18n;
710
711    values.foreground = XtParent(w)->core.background_pixel;
712    values.background = entry->sme_bsb.foreground;
713    values.font = entry->sme_bsb.font->fid;
714    values.graphics_exposures = False;
715    mask      = GCForeground | GCBackground | GCGraphicsExposures | GCFont;
716    mask_i18n = GCForeground | GCBackground | GCGraphicsExposures;
717    if (entry->sme.international == True)
718	entry->sme_bsb.rev_gc = XtAllocateGC(w, 0, mask_i18n, &values, GCFont, 0);
719    else
720	entry->sme_bsb.rev_gc = XtGetGC(w, mask, &values);
721
722    values.foreground = entry->sme_bsb.foreground;
723    values.background = XtParent(w)->core.background_pixel;
724    if (entry->sme.international == True)
725	entry->sme_bsb.norm_gc = XtAllocateGC(w, 0, mask_i18n, &values, GCFont, 0);
726    else
727	entry->sme_bsb.norm_gc = XtGetGC(w, mask, &values);
728
729    values.fill_style = FillTiled;
730    values.tile   = XmuCreateStippledPixmap(XtScreenOfObject(w),
731					    entry->sme_bsb.foreground,
732					    XtParent(w)->core.background_pixel,
733					    XtParent(w)->core.depth);
734    values.graphics_exposures = False;
735    mask |= GCTile | GCFillStyle;
736    mask_i18n |= GCTile | GCFillStyle;
737    if (entry->sme.international == True)
738	entry->sme_bsb.norm_gray_gc = XtAllocateGC(w, 0, mask_i18n, &values,
739						   GCFont, 0);
740    else
741	entry->sme_bsb.norm_gray_gc = XtGetGC(w, mask, &values);
742
743    values.foreground ^= values.background;
744    values.background = 0;
745    values.function = GXxor;
746    mask = GCForeground | GCBackground | GCGraphicsExposures | GCFunction;
747    entry->sme_bsb.invert_gc = XtGetGC(w, mask, &values);
748}
749
750/*
751 * Function:
752 *	DestroyGCs
753 *
754 * Parameters:
755 *	w - simple menu widget entry
756 *
757 * Description:
758 *	Removes all gc's for the simple menu widget.
759 */
760static void
761DestroyGCs(Widget w)
762{
763    SmeBSBObject entry = (SmeBSBObject)w;
764
765    XtReleaseGC(w, entry->sme_bsb.norm_gc);
766    XtReleaseGC(w, entry->sme_bsb.norm_gray_gc);
767    XtReleaseGC(w, entry->sme_bsb.rev_gc);
768    XtReleaseGC(w, entry->sme_bsb.invert_gc);
769}
770