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