1 /* $XConsortium: Command.c,v 1.79 94/04/17 20:11:58 kaleb Exp $ */
2 
3 /* MODIFIED FOR N*XTSTEP LOOK	 				*/
4 /* Modifications Copyright (c) 1996 by Alfredo Kojima		*/
5 /***********************************************************
6 
7 Copyright (c) 1987, 1988, 1994  X Consortium
8 
9 Permission is hereby granted, free of charge, to any person obtaining a copy
10 of this software and associated documentation files (the "Software"), to deal
11 in the Software without restriction, including without limitation the rights
12 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 copies of the Software, and to permit persons to whom the Software is
14 furnished to do so, subject to the following conditions:
15 
16 The above copyright notice and this permission notice shall be included in
17 all copies or substantial portions of the Software.
18 
19 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
22 X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
23 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 
26 Except as contained in this notice, the name of the X Consortium shall not be
27 used in advertising or otherwise to promote the sale, use or other dealings
28 in this Software without prior written authorization from the X Consortium.
29 
30 
31 Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts.
32 
33                         All Rights Reserved
34 
35 Permission to use, copy, modify, and distribute this software and its
36 documentation for any purpose and without fee is hereby granted,
37 provided that the above copyright notice appear in all copies and that
38 both that copyright notice and this permission notice appear in
39 supporting documentation, and that the name of Digital not be
40 used in advertising or publicity pertaining to distribution of the
41 software without specific, written prior permission.
42 
43 DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
44 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
45 DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
46 ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
47 WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
48 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
49 SOFTWARE.
50 
51 ******************************************************************/
52 
53 /*
54  * Command.c - Command button widget
55  */
56 
57 #include <stdio.h>
58 #include <X11/IntrinsicP.h>
59 #include <X11/StringDefs.h>
60 #include <X11/Xmu/Misc.h>
61 #include "XawInit.h"
62 #include "CommandP.h"
63 #include "ToggleP.h"
64 #include "TraversalP.h"
65 #include <X11/Xmu/Converters.h>
66 #include <X11/extensions/shape.h>
67 #ifdef XPM_TILE
68 #include "Misc.h"
69 #endif
70 #define DEFAULT_HIGHLIGHT_THICKNESS 1
71 #define DEFAULT_SHAPE_HIGHLIGHT 32767
72 
73 /****************************************************************
74  *
75  * Full class record constant
76  *
77  ****************************************************************/
78 
79 /* Private Data */
80 
81 static char defaultTranslations[] =
82 #if 0	/* from neXtaw */
83     "<EnterWindow>:     highlight()             \n\
84      <LeaveWindow>:     reset()                 \n\
85      <Btn1Down>:        set()                   \n\
86      <Btn1Up>:          notify() unset()        ";
87 #else	/* from XawM */
88 "    <EnterWindow>:     FocusEnterWindow()      \n\
89      <FocusIn>:         highlight()             \n\
90      <LeaveWindow>:     FocusLeaveWindow()      \n\
91      <FocusOut>:        reset()                 \n\
92      <Btn1Down>:        set()                   \n\
93      <Btn1Up>:          notify() unset()        \n\
94      Shift<Key>Tab:     FocusPrevious()         \n\
95      <Key>Tab:          FocusNext()             \n\
96      <Key>Home:         FocusHome()             \n\
97      <Key>End:          FocusEnd()              \n\
98      <Key>Up:           FocusPreviousGroup()    \n\
99      <Key>Down:         FocusNextGroup()        \n\
100      <Key>KP_Home:      FocusHome()             \n\
101      <Key>KP_End:       FocusEnd()              \n\
102      <Key>KP_Up:        FocusPreviousGroup()    \n\
103      <Key>KP_Down:      FocusNextGroup()        \n\
104      <KeyDown>space:    set()                   \n\
105      <KeyUp>space:      notify() unset()        ";
106 #endif
107 
108 #define offset(field) XtOffsetOf(CommandRec, field)
109 static XtResource resources[] = {
110    {XtNcallback, XtCCallback, XtRCallback, sizeof(XtPointer),
111       offset(command.callbacks), XtRCallback, (XtPointer)NULL},
112    {XtNhighlightThickness, XtCThickness, XtRDimension, sizeof(Dimension),
113       offset(command.highlight_thickness), XtRImmediate,
114       (XtPointer) DEFAULT_SHAPE_HIGHLIGHT},
115    {XtNshapeStyle, XtCShapeStyle, XtRShapeStyle, sizeof(int),
116       offset(command.shape_style), XtRImmediate, (XtPointer)XawShapeRectangle},
117    {XtNcornerRoundPercent, XtCCornerRoundPercent,
118 	XtRDimension, sizeof(Dimension),
119 	offset(command.corner_round), XtRImmediate, (XtPointer) 25},
120    {XtNshadowWidth, XtCShadowWidth, XtRDimension, sizeof(Dimension),
121       offset(threeD.shadow_width), XtRImmediate, (XtPointer) 2},
122    {XtNborderWidth, XtCBorderWidth, XtRDimension, sizeof(Dimension),
123       XtOffsetOf(RectObjRec,rectangle.border_width), XtRImmediate,
124       (XtPointer)0}
125 };
126 #undef offset
127 
128 static Boolean SetValues();
129 static void Initialize(), Redisplay(), Set(), Reset(), Notify(), Unset();
130 static void Highlight(), Unhighlight(), Destroy();
131 static void PaintCommandWidget(Widget, XEvent *, Region, Boolean);
132 static void ClassInitialize();
133 static Boolean ShapeButton(CommandWidget cbw, Boolean checkRectangular);
134 static void Realize(), Resize();
135 
136 static XtActionsRec actionsList[] = {
137   {"set",		Set},
138   {"notify",		Notify},
139   {"highlight",		Highlight},
140   {"reset",		Reset},
141   {"unset",		Unset},
142   {"unhighlight",	Unhighlight},
143 };
144 
145 #define SuperClass ((LabelWidgetClass)&labelClassRec)
146 
147 CommandClassRec commandClassRec = {
148   {
149     (WidgetClass) SuperClass,		/* superclass		  */
150     "Command",				/* class_name		  */
151     sizeof(CommandRec),			/* size			  */
152     ClassInitialize,			/* class_initialize	  */
153     NULL,				/* class_part_initialize  */
154     FALSE,				/* class_inited		  */
155     Initialize,				/* initialize		  */
156     NULL,				/* initialize_hook	  */
157     Realize,				/* realize		  */
158     actionsList,			/* actions		  */
159     XtNumber(actionsList),		/* num_actions		  */
160     resources,				/* resources		  */
161     XtNumber(resources),		/* resource_count	  */
162     NULLQUARK,				/* xrm_class		  */
163     FALSE,				/* compress_motion	  */
164     TRUE,				/* compress_exposure	  */
165     TRUE,				/* compress_enterleave    */
166     FALSE,				/* visible_interest	  */
167     Destroy,				/* destroy		  */
168     Resize,				/* resize		  */
169     Redisplay,				/* expose		  */
170     SetValues,				/* set_values		  */
171     NULL,				/* set_values_hook	  */
172     XtInheritSetValuesAlmost,		/* set_values_almost	  */
173     NULL,				/* get_values_hook	  */
174     XawAcceptFocus,			/* accept_focus		  */
175     XtVersion,				/* version		  */
176     NULL,				/* callback_private	  */
177     defaultTranslations,		/* tm_table		  */
178     XtInheritQueryGeometry,		/* query_geometry	  */
179     XtInheritDisplayAccelerator,	/* display_accelerator	  */
180     NULL				/* extension		  */
181   },  /* CoreClass fields initialization */
182   {
183     XtInheritChangeSensitive		/* change_sensitive	*/
184   },  /* SimpleClass fields initialization */
185   {
186     XtInheritXaw3dShadowDraw           /* shadowdraw           */
187   },  /* ThreeD Class fields initialization */
188   {
189     0,                                     /* field not used    */
190   },  /* LabelClass fields initialization */
191   {
192     0,                                     /* field not used    */
193   },  /* CommandClass fields initialization */
194 };
195 
196   /* for public consumption */
197 WidgetClass commandWidgetClass = (WidgetClass) &commandClassRec;
198 
199 /****************************************************************
200  *
201  * Private Procedures
202  *
203  ****************************************************************/
204 
205 static GC
Get_GC(CommandWidget cbw,Pixel fg,Pixel bg)206 Get_GC(CommandWidget cbw, Pixel fg, Pixel bg)
207 {
208   XGCValues	values;
209   static char pattern[] = {1};
210   GC gc;
211 
212 
213   values.foreground   = fg;
214   values.background	= bg;
215   values.font		= cbw->label.font->fid;
216   values.cap_style = CapProjecting;
217   values.line_style = LineOnOffDash;
218 
219   if (cbw->command.highlight_thickness > 1 )
220     values.line_width   = cbw->command.highlight_thickness;
221   else
222     values.line_width   = 0;
223 
224   if ( cbw->simple.international == True )
225       gc = XtAllocateGC((Widget)cbw, 0,
226 		 (GCForeground|GCBackground|GCLineWidth|GCCapStyle|GCLineStyle),
227 		 &values, GCFont, 0 );
228   else
229       gc = XtGetGC((Widget)cbw,
230 		 (GCForeground|GCBackground|GCFont|GCLineWidth|GCCapStyle|GCLineStyle),
231 		 &values);
232 
233   XSetDashes(XtDisplay(cbw), gc, 0, pattern, 1);
234   return gc;
235 }
236 
237 
238 /* ARGSUSED */
239 static void
Initialize(Widget request,Widget new,ArgList args,Cardinal * num_args)240 Initialize(Widget request, Widget new, ArgList args, Cardinal *num_args)
241 {
242   CommandWidget cbw = (CommandWidget) new;
243   int shape_event_base, shape_error_base;
244 
245   if (cbw->command.shape_style != XawShapeRectangle
246       && !XShapeQueryExtension(XtDisplay(new), &shape_event_base,
247 			       &shape_error_base))
248       cbw->command.shape_style = XawShapeRectangle;
249   if (cbw->command.highlight_thickness == DEFAULT_SHAPE_HIGHLIGHT) {
250       if (cbw->command.shape_style != XawShapeRectangle)
251 	  cbw->command.highlight_thickness = 0;
252       else
253 	  cbw->command.highlight_thickness = DEFAULT_HIGHLIGHT_THICKNESS;
254   }
255   if (cbw->command.shape_style != XawShapeRectangle) {
256     cbw->threeD.shadow_width = 0;
257     cbw->core.border_width = 1;
258   }
259   cbw->command.was_set = False;
260 
261   cbw->command.normal_GC = Get_GC(cbw, cbw->label.foreground,
262 				  cbw->core.background_pixel);
263   cbw->command.inverse_GC = Get_GC(cbw, cbw->core.background_pixel,
264 				   cbw->label.foreground);
265   XtReleaseGC(new, cbw->label.normal_GC);
266   cbw->label.normal_GC = cbw->command.normal_GC;
267 
268   cbw->command.set = FALSE;
269   cbw->command.highlighted = HighlightNone;
270 }
271 
272 static Region
HighlightRegion(CommandWidget cbw)273 HighlightRegion(CommandWidget cbw)
274 {
275   static Region outerRegion = NULL, innerRegion, emptyRegion;
276   Dimension s = cbw->threeD.shadow_width;
277   XRectangle rect;
278 
279   if (cbw->command.highlight_thickness == 0 ||
280       cbw->command.highlight_thickness >
281       (Dimension) ((Dimension) Min(cbw->core.width, cbw->core.height)/2))
282     return(NULL);
283 
284   if (outerRegion == NULL) {
285     /* save time by allocating scratch regions only once. */
286     outerRegion = XCreateRegion();
287     innerRegion = XCreateRegion();
288     emptyRegion = XCreateRegion();
289   }
290 
291   rect.x = rect.y = s;
292   rect.width = cbw->core.width - 2 * s;
293   rect.height = cbw->core.height - 2 * s;
294   XUnionRectWithRegion( &rect, emptyRegion, outerRegion );
295   rect.x = rect.y += cbw->command.highlight_thickness;
296   rect.width -= cbw->command.highlight_thickness * 2;
297   rect.height -= cbw->command.highlight_thickness * 2;
298   XUnionRectWithRegion( &rect, emptyRegion, innerRegion );
299   XSubtractRegion( outerRegion, innerRegion, outerRegion );
300   return outerRegion;
301 }
302 
303 /***************************
304 *
305 *  Action Procedures
306 *
307 ***************************/
308 
309 /* ARGSUSED */
310 static void
Set(Widget w,XEvent * event,String * params,Cardinal * num_params)311 Set(Widget w,XEvent *event,String *params,Cardinal *num_params)
312 {
313   CommandWidget cbw = (CommandWidget)w;
314 
315   if (cbw->command.set)
316     return;
317 
318   cbw->command.set= TRUE;
319   if (XtIsRealized(w))
320     PaintCommandWidget(w, event, (Region) NULL, TRUE);
321 }
322 
323 /* ARGSUSED */
324 static void
Unset(Widget w,XEvent * event,String * params,Cardinal * num_params)325 Unset(Widget w,XEvent *event,String *params,Cardinal *num_params)
326 {
327   CommandWidget cbw = (CommandWidget)w;
328 
329   if (!cbw->command.set)
330     return;
331 
332   cbw->command.set = FALSE;
333   if (XtIsRealized(w)) {
334     XClearWindow(XtDisplay(w), XtWindow(w));
335     PaintCommandWidget(w, event, (Region) NULL, TRUE);
336   }
337 }
338 
339 /* ARGSUSED */
340 static void
Reset(Widget w,XEvent * event,String * params,Cardinal * num_params)341 Reset(Widget w,XEvent *event,String *params,Cardinal *num_params)
342 {
343   CommandWidget cbw = (CommandWidget)w;
344 
345   if (cbw->command.set) {
346     cbw->command.highlighted = HighlightNone;
347     Unset(w, event, params, num_params);
348   } else
349     Unhighlight(w, event, params, num_params);
350 }
351 
352 /* ARGSUSED */
353 static void
Highlight(Widget w,XEvent * event,String * params,Cardinal * num_params)354 Highlight(Widget w,XEvent *event,String *params,Cardinal *num_params)
355 {
356   CommandWidget cbw = (CommandWidget)w;
357 
358   if ( *num_params == (Cardinal) 0)
359     cbw->command.highlighted = HighlightWhenUnset;
360   else {
361     if ( *num_params != (Cardinal) 1)
362       XtWarning("Too many parameters passed to highlight action table.");
363     switch (params[0][0]) {
364     case 'A':
365     case 'a':
366       cbw->command.highlighted = HighlightAlways;
367       break;
368     default:
369       cbw->command.highlighted = HighlightWhenUnset;
370       break;
371     }
372   }
373   if (XtIsRealized(w))
374     PaintCommandWidget(w, event, HighlightRegion(cbw), TRUE);
375 }
376 
377 /* ARGSUSED */
378 static void
Unhighlight(Widget w,XEvent * event,String * params,Cardinal * num_params)379 Unhighlight(Widget w,XEvent *event,String *params,Cardinal *num_params)
380 {
381   CommandWidget cbw = (CommandWidget)w;
382 
383   cbw->command.highlighted = HighlightNone;
384   if (XtIsRealized(w))
385     PaintCommandWidget(w, event, HighlightRegion(cbw), TRUE);
386 }
387 
388 /* ARGSUSED */
389 static void
Notify(Widget w,XEvent * event,String * params,Cardinal * num_params)390 Notify(Widget w,XEvent *event,String *params,Cardinal *num_params)
391 {
392   CommandWidget cbw = (CommandWidget)w;
393 
394   /* check to be sure state is still Set so that user can cancel
395      the action (e.g. by moving outside the window, in the default
396      bindings.
397   */
398   if (cbw->command.set)
399     XtCallCallbackList(w, cbw->command.callbacks, (XtPointer) NULL);
400 }
401 
402 /*
403  * Repaint the widget window
404  */
405 
406 /************************
407 *
408 *  REDISPLAY (DRAW)
409 *
410 ************************/
411 
412 /* ARGSUSED */
413 static void
Redisplay(Widget w,XEvent * event,Region region)414 Redisplay(Widget w, XEvent *event, Region region)
415 {
416   PaintCommandWidget(w, event, region, FALSE);
417 }
418 
419 /*	Function Name: PaintCommandWidget
420  *	Description: Paints the command widget.
421  *	Arguments: w - the command widget.
422  *                 region - region to paint (passed to the superclass).
423  *                 change - did it change either set or highlight state?
424  *	Returns: none
425  */
426 
427 static void
PaintCommandWidget(Widget w,XEvent * event,Region region,Boolean change)428 PaintCommandWidget(Widget w, XEvent *event, Region region, Boolean change)
429 {
430   CommandWidget cbw = (CommandWidget) w;
431   CommandWidgetClass cwclass = (CommandWidgetClass) XtClass (w);
432   Boolean very_thick;
433   GC norm_gc, rev_gc;
434   Dimension	s = cbw->threeD.shadow_width;
435   Pixmap old_pixmap;
436 
437   very_thick = cbw->command.highlight_thickness >
438                (Dimension)((Dimension) Min(cbw->core.width, cbw->core.height)/2);
439 
440 /*
441   if (cbw->command.set) {
442     cbw->label.normal_GC = cbw->command.inverse_GC;
443     XFillRectangle(XtDisplay(w), XtWindow(w), cbw->command.normal_GC,
444 		   s, s, cbw->core.width - 2 * s, cbw->core.height - 2 * s);
445     region = NULL;	*/	/* Force label to repaint text. */
446 /*  }
447   else
448     cbw->label.normal_GC = cbw->command.normal_GC;
449 */
450     XClearArea(XtDisplay(w), XtWindow(w), s, s, cbw->core.width - 2 * s,
451 	       cbw->core.height - 2 * s, False);
452     region=NULL;
453 
454     /* this ugly hack shifts the text one pixel if we are set */
455     /* but we don't want that for Toggle in radio or check style! */
456     old_pixmap = cbw->label.pixmap;
457     if (XtIsSubclass(w, toggleWidgetClass) &&
458 		((ToggleWidget)w)->toggle.toggle_style != XtToggleSimple) {
459 	cbw->label.pixmap = 1;	/* brr... */
460     }
461     if (cbw->label.pixmap == None ) {
462 	if (cbw->command.set) {
463 	    if (!cbw->command.was_set) {
464 		cbw->label.label_x+=1/*s*/;
465 		cbw->label.label_y+=1/*s*/;
466 		cbw->command.was_set=True;
467 	    }
468 	} else if (cbw->command.was_set) {
469 	    cbw->label.label_x-=1/*s*/;
470 	    cbw->label.label_y-=1/*s*/;
471 	    cbw->command.was_set=False;
472 	}
473     }
474     cbw->label.pixmap = old_pixmap;
475 
476   /* now draw the Label text and the 3d shadow */
477   if (cbw->command.highlight_thickness <= 0) {
478     (*SuperClass->core_class.expose) (w, event, region);
479     (*cwclass->threeD_class.shadowdraw) (w, event, region, !cbw->command.set);
480     return;
481   }
482 
483 /*
484  * If we are set then use the same colors as if we are not highlighted.
485  */
486 
487   if (cbw->command.set == (cbw->command.highlighted == HighlightNone)) {
488     norm_gc = cbw->command.inverse_GC;
489     rev_gc = cbw->command.normal_GC;
490   } else {
491     norm_gc = cbw->command.normal_GC;
492     rev_gc = cbw->command.inverse_GC;
493   }
494 
495   if ( !( (!change && (cbw->command.highlighted == HighlightNone)) ||
496 	  ((cbw->command.highlighted == HighlightWhenUnset) &&
497 	   (cbw->command.set))) ) {
498     if (very_thick) {
499       cbw->label.normal_GC = norm_gc; /* Give the label the right GC. */
500       XFillRectangle(XtDisplay(w),XtWindow(w), rev_gc,
501 		     s, s, cbw->core.width - 2 * s, cbw->core.height - 2 * s);
502     }
503     else {
504       /* wide lines are centered on the path, so indent it */
505 #if 0	/* Temporarily out */
506       int offset = cbw->command.highlight_thickness/2;
507       if (cbw->command.highlight_thickness>0)
508 	  XDrawRectangle(XtDisplay(w),XtWindow(w), rev_gc, s + offset, s + offset,
509 		     cbw->core.width - cbw->command.highlight_thickness - 2 * s,
510 		     cbw->core.height - cbw->command.highlight_thickness - 2 * s);
511 #endif
512     }
513   }
514 
515   /* Draw a dotted rectangle if we are highlighted */
516   if (cbw->command.highlighted != HighlightNone &&
517       cbw->command.highlight_thickness>0) {
518     int offset = cbw->command.highlight_thickness/2;
519     XDrawRectangle(XtDisplay(w), XtWindow(w), cbw->command.normal_GC,
520 		 s+offset+1, s+offset+1,
521 		 cbw->core.width - cbw->command.highlight_thickness - 2*s-2,
522 		 cbw->core.height - cbw->command.highlight_thickness - 2*s-2);
523   }
524 
525   (*SuperClass->core_class.expose) (w, event, region);
526   (*cwclass->threeD_class.shadowdraw) (w, event, region, !cbw->command.set);
527 }
528 
529 static void
Destroy(Widget w)530 Destroy(Widget w)
531 {
532   CommandWidget cbw = (CommandWidget) w;
533 
534   /* so Label can release it */
535   if (cbw->label.normal_GC == cbw->command.normal_GC)
536     XtReleaseGC( w, cbw->command.inverse_GC );
537   else
538     XtReleaseGC( w, cbw->command.normal_GC );
539 }
540 
541 /*
542  * Set specified arguments into widget
543  */
544 
545 /* ARGSUSED */
546 static Boolean
SetValues(Widget current,Widget request,Widget new,ArgList args,Cardinal * num_args)547 SetValues (Widget current, Widget request, Widget new,
548 	ArgList args, Cardinal *num_args)
549 {
550   CommandWidget oldcbw = (CommandWidget) current;
551   CommandWidget cbw = (CommandWidget) new;
552   Boolean redisplay = False;
553 
554   if ( oldcbw->core.sensitive != cbw->core.sensitive && !cbw->core.sensitive) {
555     /* about to become insensitive */
556     cbw->command.set = FALSE;
557     cbw->command.highlighted = HighlightNone;
558     redisplay = TRUE;
559   }
560 
561   if ( (oldcbw->label.foreground != cbw->label.foreground)           ||
562        (oldcbw->core.background_pixel != cbw->core.background_pixel) ||
563        (oldcbw->command.highlight_thickness !=
564                                    cbw->command.highlight_thickness) ||
565        (oldcbw->label.font != cbw->label.font) )
566   {
567     if (oldcbw->label.normal_GC == oldcbw->command.normal_GC)
568 	/* Label has release one of these */
569       XtReleaseGC(new, cbw->command.inverse_GC);
570     else
571       XtReleaseGC(new, cbw->command.normal_GC);
572 
573     cbw->command.normal_GC = Get_GC(cbw, cbw->label.foreground,
574 				    cbw->core.background_pixel);
575     cbw->command.inverse_GC = Get_GC(cbw, cbw->core.background_pixel,
576 				     cbw->label.foreground);
577     XtReleaseGC(new, cbw->label.normal_GC);
578     cbw->label.normal_GC = (cbw->command.set
579 			    ? cbw->command.inverse_GC
580 			    : cbw->command.normal_GC);
581 
582     redisplay = True;
583   }
584 
585   if ( XtIsRealized(new)
586        && oldcbw->command.shape_style != cbw->command.shape_style
587        && !ShapeButton(cbw, TRUE))
588   {
589       cbw->command.shape_style = oldcbw->command.shape_style;
590   }
591 
592   return (redisplay);
593 }
594 
ClassInitialize(void)595 static void ClassInitialize(void)
596 {
597     XawInitializeWidgetSet();
598     XtSetTypeConverter( XtRString, XtRShapeStyle, XmuCvtStringToShapeStyle,
599 		        (XtConvertArgList)NULL, 0, XtCacheNone, (XtDestructor)NULL );
600 }
601 
602 
603 static Boolean
ShapeButton(CommandWidget cbw,Boolean checkRectangular)604 ShapeButton(CommandWidget cbw, Boolean checkRectangular)
605 {
606     Dimension corner_size = 0;
607 
608     if ( (cbw->command.shape_style == XawShapeRoundedRectangle) ) {
609 	corner_size = (cbw->core.width < cbw->core.height) ? cbw->core.width
610 	                                                   : cbw->core.height;
611 	corner_size = (int) (corner_size * cbw->command.corner_round) / 100;
612     }
613 
614     if (checkRectangular || cbw->command.shape_style != XawShapeRectangle) {
615 	if (!XmuReshapeWidget((Widget) cbw, cbw->command.shape_style,
616 			      corner_size, corner_size)) {
617 	    cbw->command.shape_style = XawShapeRectangle;
618 	    return(False);
619 	}
620     }
621     return(TRUE);
622 }
623 
Realize(Widget w,Mask * valueMask,XSetWindowAttributes * attributes)624 static void Realize(Widget w, Mask *valueMask, XSetWindowAttributes *attributes)
625 {
626     (*commandWidgetClass->core_class.superclass->core_class.realize)
627 	(w, valueMask, attributes);
628     ShapeButton( (CommandWidget) w, FALSE);
629 }
630 
Resize(Widget w)631 static void Resize(Widget w)
632 {
633     if (XtIsRealized(w))
634 	ShapeButton( (CommandWidget) w, FALSE);
635 
636     (*commandWidgetClass->core_class.superclass->core_class.resize)(w);
637 }
638