1 /*************************************<+>*************************************
2  *****************************************************************************
3  **
4  **   File:        Button.c
5  **
6  **   Project:     X Widgets
7  **
8  **   Description: Code/Definitions for Button widget meta class.
9  **
10  ****************************************************************************
11  **
12  **   Copyright (c) 1988 by Hewlett-Packard Company
13  **   Copyright (c) 1988 by the Massachusetts Institute of Technology
14  **
15  **   Permission to use, copy, modify, and distribute this software
16  **   and its documentation for any purpose and without fee is hereby
17  **   granted, provided that the above copyright notice appear in all
18  **   copies and that both that copyright notice and this permission
19  **   notice appear in supporting documentation, and that the names of
20  **   Hewlett-Packard or  M.I.T.  not be used in advertising or publicity
21  **   pertaining to distribution of the software without specific, written
22  **   prior permission.
23  **
24  *****************************************************************************
25  *************************************<+>************************************/
26 
27 
28 /*
29  * Include files & Static Routine Definitions
30  */
31 
32 #include <stdio.h>
33 #include <string.h>
34 #include <ctype.h>
35 #include <X11/StringDefs.h>
36 #include <X11/IntrinsicP.h>
37 #include <X11/Intrinsic.h>
38 #include <X11/Xatom.h>
39 #include <Xw/Xw.h>
40 #include <Xw/XwP.h>
41 
42 static Boolean SetValues();
43 static void ButtonDestroy();
44 
45 
46 /*************************************<->*************************************
47  *
48  *
49  *   Description:  resource list for class: Button
50  *   -----------
51  *
52  *   Provides default resource settings for instances of this class.
53  *   To get full set of default settings, examine resouce list of super
54  *   classes of this class.
55  *
56  *************************************<->***********************************/
57 
58 static XtResource resources[] =
59 {
60 
61    {
62      XtNfont, XtCFont, XtRFontStruct, sizeof(XFontStruct *),
63      XtOffset (XwButtonWidget, button.font), XtRString, "Fixed"
64    },
65 
66    {
67      XtNlabel, XtCLabel, XtRString, sizeof (caddr_t),
68      XtOffset (XwButtonWidget, button.label), XtRString, NULL
69    },
70 
71    {
72      XtNlabelLocation, XtCLabelLocation, XtRLabelLocation, sizeof(int),
73      XtOffset (XwButtonWidget, button.label_location), XtRString, "right"
74    },
75 
76    {
77      XtNvSpace, XtCVSpace, XtRDimension, sizeof(Dimension),
78      XtOffset (XwButtonWidget, button.internal_height), XtRString, "2"
79    },
80 
81    {
82      XtNhSpace, XtCHSpace, XtRDimension, sizeof(Dimension),
83      XtOffset (XwButtonWidget, button.internal_width), XtRString, "2"
84    },
85 
86    {
87      XtNset, XtCSet, XtRBoolean, sizeof (Boolean),
88      XtOffset (XwButtonWidget, button.set), XtRString, "False"
89    },
90 
91    {
92       XtNsensitiveTile, XtCSensitiveTile, XtRTileType, sizeof (int),
93       XtOffset(XwButtonWidget, button.sensitive_tile),
94       XtRString, "foreground"
95    },
96 
97    {
98       XtNborderWidth, XtCBorderWidth, XtRDimension, sizeof(Dimension),
99       XtOffset(XwButtonWidget,core.border_width), XtRString, "0"
100    },
101 };
102 
103 
104 
105 
106 /*************************************<->*************************************
107  *
108  *
109  *   Description:  global class record for instances of class: Button
110  *   -----------
111  *
112  *   Defines default field settings for this class record.  Note that
113  *   while Button needs a special type converter, it doesn't need to
114  *   register that converter since Primitive takes care of registering
115  *   all of the converters for the X Widgets library and Button is a
116  *   subclass of Primitive.
117  *
118  *************************************<->***********************************/
119 
120 XwButtonClassRec XwbuttonClassRec =
121 {
122    {
123       (WidgetClass) &XwprimitiveClassRec,    /* superclass   */
124       "XwButton",                       /* class_name	     */
125       sizeof(XwButtonRec),              /* widget_size	     */
126       NULL,                             /* class_initialize  */
127       NULL,                             /* class part initialize */
128       FALSE,                            /* class_inited      */
129       _XwInitializeButton,              /* initialize	     */
130       NULL,                             /* initialize hook   */
131       NULL,                             /* realize	     */
132       NULL,                             /* actions           */
133       0,                                /* num_actions	     */
134       resources,                        /* resources	     */
135       XtNumber(resources),              /* num_resources     */
136       NULLQUARK,                        /* xrm_class	     */
137       TRUE,                             /* compress_motion   */
138       TRUE,                             /* compress_exposure */
139       TRUE,                             /* compress_enterleave */
140       FALSE,                            /* visible_interest  */
141       ButtonDestroy,                    /* destroy           */
142       NULL,                             /* resize            */
143       NULL,                             /* expose            */
144       SetValues,                        /* set_values	     */
145       NULL,                             /* set_values_hook   */
146       XtInheritSetValuesAlmost,         /* set_values_almost */
147       NULL,                             /* get_values_hook   */
148       NULL,                             /* accept_focus	     */
149       XtVersion,                        /* toolkit version   */
150       NULL,                             /* PRIVATE callback  */
151       NULL,                             /* tm_table          */
152       NULL,                             /* query_geometry    */
153     /* display_accelerator	*/	XtInheritDisplayAccelerator,
154     /* extension		*/	NULL
155    },
156 
157  /* Inherit procedures for handling traversal and selection */
158    {
159 	(XtWidgetProc) XtInheritBorderHighlight,
160 	(XtWidgetProc) XtInheritBorderUnhighlight,
161 	(XwEventProc)  XtInheritSelectProc,
162 	(XwEventProc)  XtInheritReleaseProc,
163 	(XwEventProc)  XtInheritToggleProc,
164    },
165 
166    {
167        0,         /* Button class part - unused */
168    }
169 };
170 
171 WidgetClass XwbuttonWidgetClass = (WidgetClass) &XwbuttonClassRec;
172 
173 
174 
175 /*************************************<->*************************************
176  *
177  *  ButtonDestroy (bw)
178  *
179  *   Description:
180  *   -----------
181  *     Free up the space taken by the button's label and free up the
182  *     button's graphic contexts.
183  *
184  *
185  *   Inputs:
186  *   ------
187  *     bw = button (or subclass of button) to be destroyed.
188  *
189  *************************************<->***********************************/
ButtonDestroy(bw)190 static void ButtonDestroy (bw)
191   XwButtonWidget bw;
192 {
193    if (bw->button.label)
194       XtFree (bw->button.label);
195    XtDestroyGC (bw->button.normal_GC);
196    XtDestroyGC (bw->button.inverse_GC);
197 }
198 
199 /*************************************<->*************************************
200  *
201  *  SetValues(current, request, new, last)
202  *
203  *   Description:
204  *   -----------
205  *     This is the set values procedure for the button class.
206  *
207  *
208  *   Inputs:
209  *   ------
210  *    current = original widget;
211  *    request = copy of current (?);
212  *    new = copy of request which reflects changes made to it by
213  *          set values procedures of its superclasses;
214  *    last = TRUE if this is the last set values procedure to be called.
215  *
216  *   Outputs:
217  *   -------
218  *
219  *   Procedures Called
220  *   -----------------
221  *
222  *************************************<->***********************************/
223 
SetValues(current,request,new)224 static Boolean SetValues(current, request, new)
225     Widget current, request, new;
226 {
227     XwButtonWidget curcbox = (XwButtonWidget) current;
228     XwButtonWidget newcbox = (XwButtonWidget) new;
229     Boolean  flag = FALSE;    /* our return value */
230     int  GCflag = 0;
231 
232 #define NewNormal 1
233 #define NewInverse 2
234 
235 
236    /************************************************************
237     * If the button setting has been changed then set flag so that
238     * button will be redisplayed.  NOTE THAT IF THE APPLICATION
239     * WANTS THE CALLBACKS ASSOCIATED WITH THE BUTTON TO BE INVOKED
240     * IT WILL HAVE TO DIRECTLY CALL XTCALLCALLBACKS.
241     ************************************************************/
242     if (curcbox->button.set != newcbox->button.set)    flag = TRUE;
243 
244 
245    /************************************************************
246     * If the font has been changed then we need to
247     * recompute the text width and height. We'll also have
248     * to change other things, see below...
249     ************************************************************/
250     if (curcbox->button.font != newcbox->button.font)
251        {
252  	     _XwSetTextWidthAndHeight(newcbox);
253 	     flag = TRUE;
254        }
255 
256 
257    /**************************************************************
258     * If a new label has been provided then we'll need to copy it
259     * into our data space.
260     * Free up any space previously allocated for the label name.
261     * NOTE: We allow them to specify a NULL label.
262     ***************************************************************/
263     if (curcbox->button.label != newcbox->button.label)
264      {
265 	/* Set label length, height and width */
266 	_XwSetTextWidthAndHeight(newcbox);
267 
268 	if (newcbox->button.label)
269 	   newcbox->button.label = strcpy(
270 	        XtMalloc((unsigned) newcbox->button.label_len + 1),
271 		newcbox->button.label);
272 
273 	if (curcbox->button.label)
274 	   XtFree ((char *) curcbox->button.label);
275 	flag = TRUE;
276       }
277 
278 
279 
280     /**********************************************************************
281      * If the label location flag has changed set the redisplay flag TRUE
282      * and check that it has a valid setting.  If its invalid, then issue
283      * a warning.
284      ********************************************************************/
285     if (curcbox->button.label_location != newcbox->button.label_location)
286        {
287 	  flag = TRUE;
288 	  if ((newcbox->button.label_location != XwLEFT) &&
289 	      (newcbox->button.label_location != XwRIGHT) &&
290 	      (newcbox->button.label_location != XwCENTER))
291 	     {
292 		XtWarning("SetValues: Invalid Label Location Setting.");
293 		newcbox->button.label_location =
294 		   curcbox->button.label_location;
295 	     }
296        }
297 
298    /*********************************************************************
299     * If the sensitive tile has changed, validate it. Then, if the
300     * foreground or background or font or sensitive tile has changed
301     * then recompute/get a new (In)sensitive GC.
302     ********************************************************************/
303     if (newcbox->button.sensitive_tile != XwFOREGROUND)
304       {
305        newcbox->button.sensitive_tile = curcbox->button.sensitive_tile;
306        XtWarning("SetValues: Invalid sensitive tile setting.");
307        }
308 
309     if (curcbox->primitive.foreground != newcbox->primitive.foreground ||
310 	curcbox->core.background_pixel != newcbox->core.background_pixel)
311       {
312         /* GET ALL NEW GC's */
313         GCflag = NewNormal | NewInverse;
314       }
315 
316     if (curcbox->button.font->fid != newcbox->button.font->fid)
317       {
318           /* GET NEW GC's FOR  normal & inverse */
319           GCflag = NewNormal | NewInverse;
320       }
321 
322     if ((curcbox->button.sensitive_tile != newcbox->button.sensitive_tile) &&
323            (! newcbox->core.sensitive || ! newcbox->core.ancestor_sensitive))
324 	 {
325           /* GET NEW normal GC */
326           GCflag |= NewNormal;
327 	 }
328 
329     if ((newcbox->core.sensitive != curcbox->core.sensitive) &&
330         ((newcbox->core.sensitive && newcbox->core.ancestor_sensitive) ||
331          (!newcbox->core.sensitive && curcbox->core.ancestor_sensitive)))
332 	 {
333           /* GET NEW normal GC */
334           GCflag |= NewNormal;
335 	 }
336     else if (newcbox->core.sensitive &&
337         (curcbox->core.ancestor_sensitive != newcbox->core.ancestor_sensitive))
338 	 {
339           /* GET NEW normal GC */
340           GCflag |= NewNormal;
341 	 }
342 
343 
344 
345     if (GCflag & NewNormal)
346       {
347 	XtDestroyGC(curcbox->button.normal_GC);
348 	_XwGetNormalGC(newcbox);
349         flag = TRUE;
350       }
351     if (GCflag & NewInverse)
352       {
353 	XtDestroyGC(curcbox->button.inverse_GC);
354         _XwGetInverseGC(newcbox);
355 	flag = TRUE;
356         }
357 
358 
359  /********************************************************************
360   * NOTE THAT SUBCLASSES OF BUTTON WILL HAVE TO CHECK FOR CHANGES IN
361   * internal_width, internal_height AND DETERMINE WHAT SHOULD BE DONE.
362   * WE'RE JUST BEING GOOD CITIZENS HERE AND FLAGING THAT IT WILL HAVE
363   * TO BE REDISPLAYED BECAUSE OF THE CHANGE.
364   *********************************************************************/
365     if ((curcbox->button.internal_width
366 	  != newcbox->button.internal_width) ||
367 	(curcbox->button.internal_height
368 	  != newcbox->button.internal_height))  flag = TRUE;
369 
370 
371     return( flag );
372 }
373 
374 
375 
376 /*************************************<->*************************************
377  *
378  *  void _XwSetTextWidthAndHeight (aButton)
379  *
380  *   Description:
381  *   -----------
382  *   Calculate width and height of displayed text in pixels.
383  *   Sets the following fields in the button portion of a button
384  *   instance record:
385  *
386  *         label_len
387  *         label_height
388  *         label_width
389  *
390  *   Inputs:
391  *   ------
392  *     aButton = XwButtonWidget
393  *
394  *   Procedures Called
395  *   -----------------
396  *   XwStrlen()  [a macro: #define XwStrlen(s)	((s) ? strlen(s) : 0) ]
397  *   XTextWidth()
398  *************************************<->***********************************/
399 
_XwSetTextWidthAndHeight(aButton)400 void _XwSetTextWidthAndHeight(aButton)
401     XwButtonWidget aButton;
402 {
403     register XFontStruct	*fs = aButton->button.font;
404 
405     aButton->button.label_height =
406        fs->max_bounds.ascent + fs->max_bounds.descent;
407 
408     if (aButton->button.label)
409     {
410        aButton->button.label_len = XwStrlen(aButton->button.label);
411 
412        aButton->button.label_width = XTextWidth(
413 			                      fs, aButton->button.label,
414 				              (int) aButton->button.label_len);
415     }
416     else
417     {
418        aButton->button.label_len = 0;
419        aButton->button.label_width = 0;
420     }
421 }
422 
423 /*************************************<->*************************************
424  *
425  *  void _XwGetNormalGC(aButton)
426  *          XwButtonWidget  aButton;
427  *
428  *   Description:
429  *   -----------
430  *      Uses the widget specific foreground to generate the "normal"
431  *      graphic context.  Note that this is a XToolkit sharable GC.
432  *      Creates the needed GC and sets ptr. in instance record.
433  *
434  *   Inputs:
435  *   ------
436  *     aButton = widget instance.
437  *
438  *   Outputs:
439  *   -------
440  *
441  *   Procedures Called
442  *   -----------------
443  *   XtGetGC
444  *************************************<->***********************************/
445 
_XwGetNormalGC(aButton)446 void _XwGetNormalGC(aButton)
447     XwButtonWidget aButton;
448 {
449     XGCValues	values;
450 
451     values.foreground	= aButton->primitive.foreground;
452     values.background   = aButton->core.background_pixel;
453     values.font		= aButton->button.font->fid;
454 
455     values.line_width   = 1;
456     aButton->button.normal_GC = XtGetGC((Widget)aButton,
457      	                                  (unsigned) GCForeground |
458 					  (unsigned) GCBackground |
459 					             GCLineWidth  |
460 					   GCFont,
461        	                                    &values);
462 }
463 
464 /*************************************<->*************************************
465  *
466  *  void _XwGetInverseGC(aButton)
467  *          XwButtonWidget  aButton;
468  *
469  *   Description:
470  *   -----------
471  *
472  *   Inputs:
473  *   ------
474  *     aButton = widget instance.
475  *
476  *   Outputs:
477  *   -------
478  *
479  *   Procedures Called
480  *   -----------------
481  *   XwGetGC
482  *************************************<->***********************************/
483 
_XwGetInverseGC(aButton)484 void _XwGetInverseGC(aButton)
485     XwButtonWidget aButton;
486 {
487     XGCValues	values;
488     values.foreground	= aButton->core.background_pixel;
489     values.background   = aButton->primitive.foreground;
490     values.font		= aButton->button.font->fid;
491     values.line_width   = 1;
492 
493     aButton->button.inverse_GC = XtGetGC((Widget)aButton,
494      	       (unsigned) GCForeground | (unsigned) GCBackground |
495 	       GCLineWidth  | GCFont, &values);
496 }
497 
498 /*************************************<->*************************************
499  *
500  *  _XwInitializeButton (request, new)
501  *
502  *   Description:
503  *   -----------
504  *     This is the button instance initialize procedure.  Make sure
505  *     that the button has a label, compute its height and width fields;
506  *     set the appropriate graphic contexts.
507  *
508  *   Inputs:
509  *   ------
510  *     request  = original instance record;
511  *
512  *     new      = instance record with modifications induced by
513  *                other initialize routines, changes are made to this
514  *                record;
515  *
516  *     args     = argument list specified in XtCreateWidget;
517  *
518  *     num_args = argument count;
519  *
520  *   Outputs:
521  *   -------
522  *
523  *   Procedures Called
524  *   -----------------
525  *
526  *************************************<->***********************************/
527 
_XwInitializeButton(request,new)528 void _XwInitializeButton (request, new)
529 Widget request, new;
530 
531 {
532     XwButtonWidget aButton = (XwButtonWidget) new;
533 
534    /*
535     * NOTE: we don't allow a NULL string for our button label.
536     * If we do find a NULL at initialize time then we will use the
537     * button name.  The rationale for this is that this allows someone
538     * to change the button label in the .Xdefaults file, whereas if
539     * the application programmer hardwired the name into an arg list
540     * it would be impossible to change.  However, if you really want
541     * a NULL string, do a SetValues and change the label to NULL.
542     *
543     * We need to malloc space for this string and copy it to our
544     * space.  The toolkit simply copies the pointer to the string.
545     */
546     if (aButton->button.label == NULL) aButton->button.label =
547                                                     aButton->core.name;
548 
549     aButton->button.label = strcpy( XtMalloc((unsigned)
550 				     (XwStrlen(aButton->button.label)+1)),
551 		 		                    aButton->button.label);
552 
553 
554     /*
555      * make sure that sensitive_tile is valid
556      */
557     if (aButton->button.sensitive_tile != XwFOREGROUND)
558       {
559          aButton->button.sensitive_tile = XwFOREGROUND;
560          XtWarning("Initialize: Invalid sensitive tile setting.");
561        }
562 
563 
564     _XwGetInverseGC(aButton);
565     _XwGetNormalGC(aButton);
566 
567     _XwSetTextWidthAndHeight(aButton);
568 
569     aButton->primitive.display_sensitive = FALSE;
570     aButton->primitive.highlighted = FALSE;
571 
572 
573 } /* _XwInitializeButton */
574 
575 
576 /*************************************<->*************************************
577  *
578  *  _XwRealize
579  *
580  *   Description:
581  *   -----------
582  *   This is a generalize routine used by both subclasses of Primitive
583  *   and Manager.  It sets bit gravity to NW for managers and to Forget
584  *   for others, but for Buttons is sets it according to the setting of
585  *   label location.
586  *
587  *  Inputs
588  *   ------
589  *     w  =  widget to be realized.
590  *
591  *     valueMask = contains event mask for this window/widget.
592  *
593  *     attributes = window attributes for this window/widget.
594  *
595  *   Outputs:
596  *   -------
597  *
598  *   Procedures Called
599  *   -----------------
600  *   XCreateWindow()
601  *************************************<->***********************************/
602 
_XwRealize(w,p_valueMask,attributes)603 void _XwRealize(w, p_valueMask, attributes)
604     register Widget w;
605     Mask *p_valueMask;
606     XSetWindowAttributes *attributes;
607 {
608    Mask valueMask = *p_valueMask;
609     valueMask |= CWBitGravity;
610 
611     if (XtIsSubclass(w, XwprimitiveWidgetClass)) {
612 	register XwPrimitiveWidget pw = (XwPrimitiveWidget) w;
613 	if (pw->primitive.cursor != None) valueMask |= CWCursor;
614 	attributes->cursor = pw->primitive.cursor;
615     }
616 
617     if (XtIsSubclass(w, XwmanagerWidgetClass))
618       attributes->bit_gravity = NorthWestGravity;
619     else
620       if (w->core.widget_class != XwbuttonWidgetClass)
621          attributes->bit_gravity = ForgetGravity;
622       else
623         switch (((XwButtonWidget)w)->button.label_location)
624 	  {
625 	  case XwRIGHT:
626                attributes->bit_gravity = EastGravity; break;
627           case XwLEFT:
628                attributes->bit_gravity = WestGravity; break;
629           case XwCENTER:
630                attributes->bit_gravity = CenterGravity; break;
631           }
632 
633    XtCreateWindow(w, InputOutput, (Visual *)CopyFromParent,
634 	valueMask, attributes);
635 
636    _XwRegisterName(w);  /* hang widget name as property on window */
637 
638 } /* _XwRealize */
639 
640 
641 /*************************************<->*************************************
642  *
643  *  _XwResizeButton(w)
644  *
645  *   Description:
646  *   -----------
647  *     A resize event has been generated. Recompute location of button
648  *     elements.
649  *
650  *     USED BY CHECKBOX AND PUSHBUTTON CLASSES.
651  *
652  *   Inputs:
653  *   ------
654  *     w  = widget to be resized.
655  *
656  *   Outputs:
657  *   -------
658  *
659  *   Procedures Called
660  *   -----------------
661  *
662  *************************************<->***********************************/
663 
664 
_XwResizeButton(w)665 void _XwResizeButton(w)
666     Widget w;
667 {
668     register XwButtonWidget aButton = (XwButtonWidget) w;
669     int direction = aButton->button.label_location;
670 
671        switch (direction)
672 	 {
673           case XwCENTER:
674             aButton->button.label_x = ((int)aButton->core.width + 1 -
675 				  (int)aButton->button.label_width) / 2;
676             break;
677 
678             case XwRIGHT:
679              aButton->button.label_x = (int)aButton->core.width -
680 	                         (int)aButton->button.internal_width -
681                                   aButton->primitive.highlight_thickness -
682 	 		         (int)aButton->button.label_width;
683              break;
684 
685            default:
686             aButton->button.label_x = aButton->button.internal_width +
687                                  aButton->primitive.highlight_thickness;
688           }
689 
690     aButton->button.label_y =
691        (((int)aButton->core.height - (int)aButton->button.label_height) >> 1)
692  	 + aButton->button.font->max_bounds.ascent;
693 }
694 
695 
696 
697 /*************************************<->*************************************
698  *
699  *  ProcedureName (parameters)
700  *
701  *   Description:
702  *   -----------
703  *    This procedure is used to store the name of the widget as a
704  *    property on the widget's window.  The property name is the
705  *    string "XW_NAME". Note that we do not malloc space for the
706  *    widget's name, we merely use the pointer to this string which
707  *    is already in core.name.  This shouldn't be a problem since
708  *    the name will remain as long as the widget exists.
709  *
710  *    We only want to do this one time, thus the hokey method of
711  *    initializing a static boolean which prevents us from registering
712  *    this atom more than once on the server.
713  *
714  *    If possible, we should put this together with other functions done
715  *    once.  Also, WILL THIS BE A PROBLEM WHEN THE TOOLKIT ALLOWS MORE
716  *    THAN ONE DISPLAY TO BE OPENED?????
717  *
718  *   Inputs:
719  *   ------
720  *     w = widget being created.
721  *
722  *   Outputs:
723  *   -------
724  *
725  *   Procedures Called
726  *   -----------------
727  *
728  *************************************<->***********************************/
729 
730 static Atom widget_name;
731 static Boolean first=True;
732 
_XwRegisterName(w)733 void _XwRegisterName(w)
734  Widget w;
735 {
736   if (first)
737    {
738       widget_name = XInternAtom (XtDisplay(w), "XW_NAME", False);
739       first = False;
740    }
741    XChangeProperty (XtDisplay(w), XtWindow(w), widget_name, XA_STRING, 8,
742 		     PropModeReplace, w->core.name,
743 		       XwStrlen(w->core.name)+1);
744 }
745 
746 
747 /*************************************<->*************************************
748  *  Boolean
749  *  _XwRecomputeSize(current, new)
750  *
751  *   Description:
752  *   -----------
753  *     Used during SetValues for PButton and Toggle.
754  *     If the font has changed OR the label has changed OR
755  *     the internal spacing has changed OR the highlight
756  *     thickness has changed AND the recompute flag is TRUE
757  *     (in the new widget) return TRUE, else return FALSE.
758  *
759  *
760  *   Inputs:
761  *   ------
762  *    current = current version of widget
763  *    new = new version of widget
764  *
765  *   Outputs:
766  *   -------
767  *     TRUE if resize is needed and okay, FALSE otherwise.
768  *
769  *************************************<->***********************************/
_XwRecomputeSize(current,new)770  Boolean _XwRecomputeSize(current, new)
771   XwButtonWidget current, new;
772 {
773   if (((new->button.font != current->button.font) ||
774      (new->button.label != current->button.label) ||
775      (new->primitive.highlight_thickness !=
776          current->primitive.highlight_thickness) ||
777      (new->button.internal_height != current->button.internal_height) ||
778      (new->button.internal_width != current->button.internal_width)) &&
779      (new->primitive.recompute_size == TRUE))
780          return(TRUE);
781   else
782          return(FALSE);
783 }
784 
785 
786 
787