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