1 /*
2 **
3 ** Frame.c -- File composition widget
4 **
5 ** Copyright (C) 2004 Jose E. Marchesi
6 **
7 ** This program is free software; you can redistribute it and/or modify
8 ** it under the terms of the GNU General Public License as published by
9 ** the Free Software Foundation; either version 3 of the License, or
10 ** (at your option) any later version.
11 **
12 ** This program is distributed in the hope that it will be useful,
13 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
14 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 ** GNU General Public License for more details.
16 **
17 ** You should have received a copy of the GNU General Public License
18 ** along with GNU gv; see the file COPYING.  If not, write to
19 ** the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 ** Boston, MA 02111-1307, USA.
21 **
22 ** Author:   Jose E. Marchesi (jemarch@gnu.org)
23 **           GNU Project
24 **
25 */
26 #include "ac_config.h"
27 
28 #include <stdio.h>
29 
30 #include "paths.h"
31 #include INC_X11(IntrinsicP.h)
32 #include INC_X11(StringDefs.h)
33 #include INC_XMU(Converters.h)
34 #include INC_XMU(CharSet.h)
35 #include INC_XAW(XawInit.h)
36 #include "FrameP.h"
37 
38 /*
39 #define MESSAGES
40 #define MESSAGES1
41 */
42 #include "message.h"
43 
44 /****************************************************************
45  *
46  * Frame Resources
47  *
48  ****************************************************************/
49 #define offset(name) XtOffsetOf(FrameRec, frame.name)
50 static XtResource resources[] = {
51     {XtNhSpace, XtCHSpace, XtRDimension, sizeof(Dimension),
52         offset(h_space_nat), XtRImmediate, (XtPointer)4 },
53     {XtNvSpace, XtCVSpace, XtRDimension, sizeof(Dimension),
54         offset(v_space_nat), XtRImmediate, (XtPointer)4 },
55     {XtNframeType, XtCFrameType, XtRFrameType, sizeof(XawFrameType),
56         offset(frame_type), XtRImmediate, (XtPointer) XawCHISELED },
57     {XtNshadowWidth, XtCShadowWidth, XtRDimension, sizeof(Dimension),
58 	offset(shadow_width_nat), XtRImmediate, (XtPointer) 2},
59     {XtNtopShadowPixel, XtCTopShadowPixel, XtRPixel, sizeof(Pixel),
60 	offset(top_shadow_pixel), XtRString, XtDefaultForeground},
61     {XtNbottomShadowPixel, XtCBottomShadowPixel, XtRPixel, sizeof(Pixel),
62 	offset(bot_shadow_pixel), XtRString, XtDefaultForeground},
63     {XtNresize, XtCBoolean, XtRBoolean, sizeof(Boolean),
64 	offset(resize), XtRImmediate, (XtPointer) True},
65 };
66 #undef offset
67 
68 #define FW_FRAME       fw->frame
69 #define FW_CORE        fw->core
70 #define FW_COMPOSITE   fw->composite
71 
72 #define FW_HSPACE      FW_FRAME.h_space
73 #define FW_VSPACE      FW_FRAME.v_space
74 #define FW_SHADOW      FW_FRAME.shadow_width
75 #define FW_RESIZE      FW_FRAME.resize
76 
77 #define FW_NAT_HSPACE  FW_FRAME.h_space_nat
78 #define FW_NAT_VSPACE  FW_FRAME.v_space_nat
79 #define FW_NAT_SHADOW  FW_FRAME.shadow_width_nat
80 #define FW_CHILD_NAT_WIDTH FW_FRAME.child_width_nat
81 #define FW_CHILD_NAT_HEIGHT FW_FRAME.child_height_nat
82 #define FW_CHILD_NAT_BORDER FW_FRAME.child_border_nat
83 
84 #define FW_CHILD_P     FW_COMPOSITE.children
85 #define FW_CHILD       (*(FW_CHILD_P))
86 
87 /***************************************************************************
88  *
89  * Frame  class record
90  *
91  ***************************************************************************/
92 
93 static void ClassInitialize(void);
94 static void Resize(Widget);
95 static void Redisplay(Widget,XEvent *,Region);
96 static void Initialize(Widget,Widget,ArgList,Cardinal*);
97 static void InsertChild(Widget);
98 static void ChangeManaged(Widget);
99 static XtGeometryResult GeometryManager(Widget,XtWidgetGeometry*,XtWidgetGeometry*);
100 static XtGeometryResult QueryGeometry(Widget,XtWidgetGeometry*,XtWidgetGeometry*);
101 static XtGeometryResult LayoutFrame(FrameWidget);
102 static void Destroy(Widget);
103 static void GetDesiredSizeOfChild(Widget);
104 static void GetNaturalSize(FrameWidget,Dimension*,Dimension*);
105 
106 #define SuperClass ((CompositeWidgetClass)&compositeClassRec)
107 
108 FrameClassRec frameClassRec = {
109   {
110     /* superclass	  */	(WidgetClass)SuperClass,
111     /* class_name	  */	"Frame",
112     /* size		  */	sizeof(FrameRec),
113     /* class_initialize	  */	ClassInitialize,
114     /* class_part_init    */	NULL,
115     /* class inited	  */	FALSE,
116     /* initialize	  */	Initialize,
117     /* initialize_hook	  */	NULL,
118     /* realize		  */	XtInheritRealize,
119     /* actions		  */	NULL,
120     /* num_actions	  */	0,
121     /* resources	  */	resources,
122     /* resource_count	  */	XtNumber(resources),
123     /* xrm_class	  */	NULLQUARK,
124     /* compress_motion	  */	FALSE,
125     /* compress_exposure  */	XtExposeCompressMultiple,
126     /* compress_enterleave*/	FALSE,
127     /* visible_interest	  */	FALSE,
128     /* destroy		  */	Destroy,
129     /* resize		  */	Resize,
130     /* expose		  */	Redisplay,
131     /* set_values	  */	NULL,
132     /* set_values_hook	  */	NULL,
133     /* set_values_almost  */	XtInheritSetValuesAlmost,
134     /* get_values_hook	  */	NULL,
135     /* accept_focus	  */	NULL,
136     /* intrinsics version */	XtVersion,
137     /* callback offsets	  */	NULL,
138     /* tm_table		  */	NULL,
139     /* query_geometry	  */	QueryGeometry,
140     /* display_accelerator*/	XtInheritDisplayAccelerator,
141     /* extension	  */	NULL
142   },
143   { /* composite_class fields */
144     /* geometry_manager	  */	GeometryManager,
145     /* change_managed	  */	ChangeManaged,
146     /* insert_child	  */	InsertChild,
147     /* delete_child	  */	XtInheritDeleteChild,
148     /* extension	  */	NULL
149   },
150   { /* frame_class fields */
151     /* dummy              */    NULL
152   }
153 };
154 
155 WidgetClass frameWidgetClass =	(WidgetClass) (&frameClassRec);
156 
157 /****************************************************************
158  * Private Routines
159  ****************************************************************/
160 
161 /*---------------------------------------------------*/
162 /* FrameConvertStringToFrameType */
163 /*---------------------------------------------------*/
164 
165 #define done(type, value)  {			\
166    if (to->addr != NULL) {			\
167       if (to->size < sizeof(type)) {		\
168 	 to->size = sizeof(type);		\
169 	 return False;				\
170       }						\
171       *(type*)(to->addr) = (value);		\
172    } else {					\
173       static type static_val;			\
174       static_val = (value);			\
175       to->addr = (XtPointer)&static_val;	\
176    }						\
177    to->size = sizeof(type);			\
178    ENDMESSAGE1(FrameConvertStringToFrameType)	\
179    return True;					\
180 }
181 
182 Boolean
FrameConvertStringToFrameType(Display * display,XrmValue * args _GL_UNUSED,Cardinal * num_args _GL_UNUSED,XrmValuePtr from,XrmValuePtr to,XtPointer * converter_data _GL_UNUSED)183 FrameConvertStringToFrameType(Display *display, XrmValue *args _GL_UNUSED, Cardinal *num_args _GL_UNUSED, XrmValuePtr from, XrmValuePtr to, XtPointer *converter_data _GL_UNUSED)
184 {
185    String s = (String) from->addr;
186 
187    BEGINMESSAGE1(FrameConvertStringToFrameType)
188    if (XmuCompareISOLatin1(s, "raised")   == 0) done(XawFrameType, XawRAISED);
189    if (XmuCompareISOLatin1(s, "sunken")   == 0) done(XawFrameType, XawSUNKEN);
190    if (XmuCompareISOLatin1(s, "chiseled") == 0) done(XawFrameType, XawCHISELED);
191    if (XmuCompareISOLatin1(s, "ledged")   == 0) done(XawFrameType, XawLEDGED);
192    if (XmuCompareISOLatin1(s, "massiveRaised") == 0) done(XawFrameType,XawFrameMassiveRaised);
193    XtDisplayStringConversionWarning(display, s, XtRFrameType);
194    done(XawFrameType, XawRAISED);
195 }
196 
197 /*---------------------------------------------------*/
198 /* ClassInitialize */
199 /*---------------------------------------------------*/
200 
201 static void
ClassInitialize(void)202 ClassInitialize(void)
203 {
204    BEGINMESSAGE(ClassInitialize)
205    XawInitializeWidgetSet();
206    XtSetTypeConverter(XtRString, XtRFrameType, FrameConvertStringToFrameType,
207 		     (XtConvertArgList)NULL, 0, XtCacheNone, NULL);
208    ENDMESSAGE(ClassInitialize)
209 }
210 
211 /*---------------------------------------------------*/
212 /* Initialize */
213 /*---------------------------------------------------*/
214 
215 static GC
shadow_getGC(Widget w,Pixel pixel)216 shadow_getGC (Widget w, Pixel pixel)
217 {
218    Screen    *scn = XtScreen (w);
219    XtGCMask  valuemask;
220    XGCValues myXGCV;
221    GC        gc;
222 
223    BEGINMESSAGE(shadow_getGC)
224    if (DefaultDepthOfScreen(scn) > 1) {
225       valuemask = GCForeground;
226       myXGCV.foreground = pixel;
227       gc = XtGetGC(w, valuemask, &myXGCV);
228    }
229    else gc = (GC) NULL;
230    ENDMESSAGE(shadow_getGC)
231    return gc;
232 }
233 
234 static void
Initialize(Widget request _GL_UNUSED,Widget new,ArgList args _GL_UNUSED,Cardinal * num_args _GL_UNUSED)235 Initialize(Widget request _GL_UNUSED, Widget new, ArgList args _GL_UNUSED, Cardinal *num_args _GL_UNUSED)
236 {
237    FrameWidget fw = (FrameWidget) new;
238 
239    BEGINMESSAGE(Initialize)
240    FW_FRAME.top_shadow_GC = shadow_getGC(new,FW_FRAME.top_shadow_pixel);
241    FW_FRAME.bot_shadow_GC = shadow_getGC(new,FW_FRAME.bot_shadow_pixel);
242    if (!FW_FRAME.top_shadow_GC || !FW_FRAME.bot_shadow_GC) {
243       INFMESSAGE(disallowing shadows)
244       FW_FRAME.shadow_width_nat = 0;
245    }
246 
247    if (FW_CORE.width == 0)  FW_CORE.width  = 1;
248    if (FW_CORE.height == 0) FW_CORE.height = 1;
249    FW_SHADOW = FW_HSPACE = FW_VSPACE = 0;
250    FW_CHILD_NAT_WIDTH = FW_CHILD_NAT_HEIGHT = FW_CHILD_NAT_BORDER = 0;
251 
252    ENDMESSAGE(Initialize)
253 }
254 
255 /*---------------------------------------------------*/
256 /* Destroy */
257 /*---------------------------------------------------*/
258 
259 static void
Destroy(Widget w)260 Destroy (Widget w)
261 {
262    FrameWidget fw = (FrameWidget) w;
263 
264    BEGINMESSAGE(Destroy)
265    XtReleaseGC(w,FW_FRAME.top_shadow_GC);
266    XtReleaseGC(w,FW_FRAME.bot_shadow_GC);
267    ENDMESSAGE(Destroy)
268 }
269 
270 /*---------------------------------------------------*/
271 /* Resize */
272 /*---------------------------------------------------*/
273 
274 #define MIN_CHILD 4
275 
276 static void
Resize(Widget w)277 Resize(Widget w)
278 {
279    int x,y,cw,ch,hs,vs,bw,sw;
280    FrameWidget fw = (FrameWidget) w;
281 
282    BEGINMESSAGE(Resize)
283 
284    hs  = (int)(FW_NAT_HSPACE);
285    vs  = (int)(FW_NAT_VSPACE);
286    sw  = (int)(FW_NAT_SHADOW);
287    bw  = (int)(FW_CHILD_NAT_BORDER);
288 
289    ch  = (int)(FW_CORE.height) - 2*vs -2*sw;
290    cw  = (int)(FW_CORE.width)  - 2*hs -2*sw;
291 
292    if ((ch<MIN_CHILD || cw<MIN_CHILD) && (hs>0||vs>0||sw>0)) {
293       INFMESSAGE(adjusting size of decorations)
294       while (ch<MIN_CHILD && vs>0) { ch +=2; --vs; }
295       while (cw<MIN_CHILD && hs>0) { cw +=2; --hs; }
296       while ((cw<MIN_CHILD || ch<MIN_CHILD) && sw>0) { ch+=2; cw +=2; --sw; }
297    }
298 
299    if (cw <= 0 || ch <= 0) {
300       INFMESSAGE(child too small; will place it off screen)
301       cw = ch = 1;
302       sw = hs = vs = 0;
303       x = -1 - 2*bw;
304       y = -1 - 2*bw;
305    } else {
306       x = hs+sw-bw;
307       y = vs+sw-bw;
308    }
309    IIMESSAGE(hs,vs)
310    IIMESSAGE(cw,ch)
311    IIMESSAGE(bw,sw)
312 
313    FW_HSPACE= (Dimension) hs;
314    FW_VSPACE= (Dimension) vs;
315    FW_SHADOW= (Dimension) sw;
316 
317    XtConfigureWidget(FW_CHILD,x,y,((Dimension)cw),((Dimension)ch),((Dimension)bw));
318 
319    ENDMESSAGE(Resize)
320 }
321 
322 /*---------------------------------------------------*/
323 /* Redisplay */
324 /*---------------------------------------------------*/
325 
326 #define topPolygon(i,xx,yy)		\
327   top_polygon[i].x = (short) (xx);	\
328   top_polygon[i].y = (short) (yy)
329 
330 #define bottomPolygon(i,xx,yy)		\
331   bottom_polygon[i].x = (short) (xx);	\
332   bottom_polygon[i].y = (short) (yy)
333 
334 void
FrameDrawFrame(Widget gw,int x,int y,int w,int h,XawFrameType frame_type,int fw,GC lightgc,GC darkgc)335 FrameDrawFrame (Widget gw, int x, int y, int w, int h, XawFrameType frame_type, int fw, GC lightgc, GC darkgc)
336 {
337    XPoint top_polygon[6];
338    XPoint bottom_polygon[6];
339 
340    BEGINMESSAGE1(FrameDrawFrame)
341 
342    if (lightgc == (GC)NULL ){
343       XtWarning("FrameDrawFrame: lightgc is NULL.");
344       ENDMESSAGE1(FrameDrawFrame)
345       return;
346    }
347    if (darkgc == (GC)NULL ){
348       XtWarning("FrameDrawFrame: darkgc is NULL.");
349       ENDMESSAGE1(FrameDrawFrame)
350       return;
351    }
352    if (!XtIsRealized(gw)) {
353       XtWarning("FrameDrawFrame: widget is not realized.");
354       ENDMESSAGE1(FrameDrawFrame)
355       return;
356    }
357 
358    if (frame_type == XawRAISED || frame_type == XawSUNKEN ) {
359       topPolygon (0,x    ,y    ); bottomPolygon (0,x+w  ,y+h    );
360       topPolygon (1,x+w  ,y    ); bottomPolygon (1,x    ,y+h    );
361       topPolygon (2,x+w-fw,y+fw); bottomPolygon (2,x+fw  ,y+h-fw);
362       topPolygon (3,x+fw,y+fw  ); bottomPolygon (3,x+w-fw,y+h-fw);
363       topPolygon (4,x+fw,y+h-fw); bottomPolygon (4,x+w-fw,y+fw  );
364       topPolygon (5,x    ,y+h  ); bottomPolygon (5,x+w  ,y      );
365       if (frame_type == XawSUNKEN) {
366          XFillPolygon(XtDisplayOfObject(gw), XtWindowOfObject(gw), darkgc,
367 		      top_polygon, 6, Nonconvex, CoordModeOrigin);
368          XFillPolygon(XtDisplayOfObject(gw), XtWindowOfObject(gw), lightgc,
369 	    	      bottom_polygon, 6, Nonconvex, CoordModeOrigin);
370       } else {
371 	 XFillPolygon(XtDisplayOfObject(gw), XtWindowOfObject(gw), lightgc,
372 		      top_polygon, 6, Nonconvex, CoordModeOrigin);
373 	 XFillPolygon(XtDisplayOfObject(gw), XtWindowOfObject(gw), darkgc,
374 		      bottom_polygon, 6, Nonconvex, CoordModeOrigin);
375       }
376    }
377    else if (frame_type == XawFrameMassiveRaised) {
378      if (fw>=3) {
379         int it,mt,ot;
380         ot = 1;
381         it = 1;
382         mt = fw-ot-it;
383         FrameDrawFrame(gw, x, y, w, h, XawRAISED, ot, lightgc, darkgc);
384         FrameDrawFrame(gw,x+mt+ot,y+mt+ot,w-2*mt-2*ot,h-2*mt-2*ot,
385 		       XawSUNKEN, it, lightgc, darkgc);
386      }
387    }
388    else if ( frame_type == XawLEDGED ) {
389      int it,ot;
390      it = ot = fw/2;
391      if (fw&1) it += 1;
392      FrameDrawFrame(gw, x, y, w, h, XawRAISED, ot, lightgc, darkgc);
393      FrameDrawFrame(gw,x+ot, y+ot,w-2*ot, h-2*ot,
394 		  XawSUNKEN, it, lightgc, darkgc);
395    }
396    else if ( frame_type == XawCHISELED ) {
397      int it,ot;
398      it = ot = fw/2;
399      if (fw&1) it += 1;
400      FrameDrawFrame(gw, x, y, w, h, XawSUNKEN, ot, lightgc, darkgc);
401      FrameDrawFrame(gw,x+ot,y+ot,w-2*ot, h-2*ot,
402 		    XawRAISED, it, lightgc, darkgc);
403    }
404 
405    ENDMESSAGE1(FrameDrawFrame)
406 
407 }
408 #undef topPolygon
409 #undef bottomPolygon
410 
411 static void
Redisplay(Widget w,XEvent * event _GL_UNUSED,Region region _GL_UNUSED)412 Redisplay(Widget w, XEvent *event _GL_UNUSED, Region region _GL_UNUSED)
413 {
414    FrameWidget fw = (FrameWidget) w;
415    int wh,ww,sw,bw;
416 
417    BEGINMESSAGE1(Redisplay)
418 
419    bw = (int)FW_CORE.border_width;
420    ww = (int)FW_CORE.width;
421    wh = (int)FW_CORE.height;
422    sw = (int)FW_SHADOW;
423    if (sw == 0 || 2*sw>ww || 2*sw>wh) {
424       INFMESSAGE(not enough space to display anything) ENDMESSAGE1(Redisplay)
425       return;
426    }
427    FrameDrawFrame(w,0,0,ww,wh,FW_FRAME.frame_type,sw,
428 		  FW_FRAME.top_shadow_GC,
429 		  FW_FRAME.bot_shadow_GC);
430    ENDMESSAGE1(Redisplay)
431 }
432 
433 /*---------------------------------------------------*/
434 /* GetDesiredSizeOfChild */
435 /*---------------------------------------------------*/
436 
437 static void
GetDesiredSizeOfChild(Widget child)438 GetDesiredSizeOfChild(Widget child)
439 {
440    FrameWidget fw;
441 
442    BEGINMESSAGE(GetDesiredSizeOfChild)
443    fw = (FrameWidget) XtParent(child);
444    if (XtIsManaged(child)) {
445       XtWidgetGeometry desired;
446       INFSMESSAGE(is managed,XtName(child))
447       XtQueryGeometry (child, (XtWidgetGeometry *)NULL, &desired);
448       FW_CHILD_NAT_BORDER = desired.border_width;
449       FW_CHILD_NAT_WIDTH  = desired.width;
450       FW_CHILD_NAT_HEIGHT = desired.height;
451    } else {
452       INFSMESSAGE(not managed,XtName(child))
453       FW_CHILD_NAT_BORDER = 0;
454       FW_CHILD_NAT_WIDTH  = 0;
455       FW_CHILD_NAT_HEIGHT = 0;
456    }
457    IIMESSAGE(FW_CHILD_NAT_WIDTH,FW_CHILD_NAT_HEIGHT)
458    IMESSAGE(FW_CHILD_NAT_BORDER)
459    ENDMESSAGE(GetDesiredSizeOfChild)
460 }
461 
462 /*---------------------------------------------------*/
463 /* InsertChild */
464 /*---------------------------------------------------*/
465 
466 static void
InsertChild(Widget child)467 InsertChild(Widget child)
468 {
469    BEGINMESSAGE(InsertChild)
470    (*SuperClass->composite_class.insert_child) (child);
471    GetDesiredSizeOfChild(child);
472    ENDMESSAGE(InsertChild)
473 }
474 
475 /*---------------------------------------------------*/
476 /* GetNaturalSize */
477 /*---------------------------------------------------*/
478 
479 static void
GetNaturalSize(FrameWidget fw,Dimension * wP,Dimension * hP)480 GetNaturalSize(FrameWidget fw, Dimension *wP, Dimension *hP)
481 {
482    BEGINMESSAGE(GetNaturalSize)
483    *wP = FW_CHILD_NAT_WIDTH  + 2*FW_NAT_SHADOW +2*FW_NAT_HSPACE;
484    *hP = FW_CHILD_NAT_HEIGHT + 2*FW_NAT_SHADOW +2*FW_NAT_VSPACE;
485    ENDMESSAGE(GetNaturalSize)
486 }
487 
488 /*---------------------------------------------------*/
489 /* ChangeManaged */
490 /*---------------------------------------------------*/
491 
492 static void
ChangeManaged(Widget w)493 ChangeManaged(Widget w)
494 {
495    FrameWidget fw = (FrameWidget) w;
496 
497    BEGINMESSAGE(ChangeManaged)
498    GetDesiredSizeOfChild(FW_CHILD);
499    LayoutFrame(fw);
500    ENDMESSAGE(ChangeManaged)
501 }
502 
503 /*---------------------------------------------------*/
504 /* GeometryManager */
505 /*---------------------------------------------------*/
506 
507 #define IS_REQUEST(fff) (request->request_mode & fff)
508 
509 static XtGeometryResult
GeometryManager(Widget child,XtWidgetGeometry * request,XtWidgetGeometry * geometry_return _GL_UNUSED)510 GeometryManager(Widget child, XtWidgetGeometry *request, XtWidgetGeometry *geometry_return _GL_UNUSED)
511 {
512    FrameWidget fw;
513    XtGeometryResult answer;
514    int changed;
515 
516    BEGINMESSAGE(GeometryManager)
517 
518    INFSMESSAGE(received request from child, XtName(child))
519 
520    if (!(request->request_mode & (CWWidth | CWHeight | CWBorderWidth))) {
521       INFMESSAGE(request not of interest) ENDMESSAGE(GeometryManager)
522       return XtGeometryYes;
523    }
524    if (request->request_mode & XtCWQueryOnly) {
525       /* query requests are not properly implemented ... ###jp### */
526       INFMESSAGE(request is query only and will be denied) ENDMESSAGE(GeometryManager)
527       return XtGeometryNo;
528    }
529    INFIIMESSAGE(current size of child:,child->core.width,child->core.height)
530 
531    fw = (FrameWidget) XtParent(child);
532    changed = 0;
533    if (IS_REQUEST(CWBorderWidth)) {
534       IIMESSAGE(request->border_width,child->core.border_width)
535       FW_CHILD_NAT_BORDER = request->border_width;
536       if (FW_CHILD_NAT_BORDER != child->core.border_width) changed = 1;
537    }
538    if (IS_REQUEST(CWWidth)) {
539       IIMESSAGE(request->width,child->core.width)
540       FW_CHILD_NAT_WIDTH = request->width;
541       if (FW_CHILD_NAT_WIDTH != child->core.width) changed = 1;
542    }
543    if (IS_REQUEST(CWHeight)) {
544       IIMESSAGE(request->height,child->core.height)
545       FW_CHILD_NAT_HEIGHT = request->height;
546       if (FW_CHILD_NAT_HEIGHT != child->core.height) changed = 1;
547    }
548 
549    if (changed) {
550       answer = LayoutFrame(fw);
551       INFIIMESSAGE(new size of child:,child->core.width,child->core.height)
552       INFIMESSAGE(new border width of child:,child->core.border_width)
553       ENDMESSAGE(GeometryManager)
554       return answer;
555    } else {
556       ENDMESSAGE(GeometryManager)
557       return XtGeometryYes;
558    }
559 }
560 
561 /*---------------------------------------------------*/
562 /* QueryGeometry */
563 /*---------------------------------------------------*/
564 
565 static XtGeometryResult
QueryGeometry(Widget w,XtWidgetGeometry * request,XtWidgetGeometry * preferred_return)566 QueryGeometry(Widget w, XtWidgetGeometry *request, XtWidgetGeometry *preferred_return)
567 {
568    FrameWidget fw = (FrameWidget)w;
569    Dimension nw,nh;
570 
571    BEGINMESSAGE(QueryGeometry)
572    if (fw->composite.children && fw->composite.children[0])
573      GetDesiredSizeOfChild(fw->composite.children[0]);
574    GetNaturalSize(fw,&nw,&nh);
575    preferred_return->request_mode = (CWWidth|CWHeight);
576    preferred_return->width  = nw;
577    preferred_return->height = nh;
578    if (    !(request->request_mode & CWWidth)
579         || !(request->request_mode & CWHeight)
580         || ((request->request_mode & CWWidth)  && nw != request->width)
581         || ((request->request_mode & CWHeight) && nh != request->height)
582       ) {
583       INFMESSAGE(XtGeometryAlmost) ENDMESSAGE(QueryGeometry)
584       return XtGeometryAlmost;
585    }
586    if ((nw == w->core.width) && (nh == w->core.height)) {
587       INFMESSAGE(XtGeometryNo) ENDMESSAGE(QueryGeometry)
588       return XtGeometryNo;
589    }
590 
591    INFMESSAGE(XtGeometryYes) ENDMESSAGE(QueryGeometry)
592    return XtGeometryYes;
593 }
594 
595 /*---------------------------------------------------*/
596 /* LayoutFrame */
597 /*---------------------------------------------------*/
598 
599 static XtGeometryResult
LayoutFrame(FrameWidget fw)600 LayoutFrame(FrameWidget fw)
601 {
602    XtWidgetGeometry request;
603    XtGeometryResult answer;
604 
605    BEGINMESSAGE(LayoutFrame)
606 
607    GetNaturalSize(fw,&request.width,&request.height);
608 
609    if (FW_RESIZE && (request.width != fw->core.width || request.height != fw->core.height)) {
610       request.request_mode = (CWWidth | CWHeight);
611       INFMESSAGE(will request new geometry from parent)
612       answer = XtMakeGeometryRequest((Widget) fw, &request, &request);
613       switch (answer) {
614          case XtGeometryYes:
615             INFMESSAGE(XtGeometryYes)
616             INFMESSAGE(parent reconfigured window)
617             break;
618          case XtGeometryAlmost:
619             INFIIMESSAGE(XtGeometryAlmost:,request.width,request.height)
620             INFMESSAGE(requesting approval of these values)
621             answer = XtMakeGeometryRequest((Widget) fw, &request, &request);
622             if (answer!=XtGeometryYes) {
623                INFIIMESSAGE(parent proposes,request.width,request.height)
624                fprintf(stderr,"FrameWidget: Warning, parent didn't accept the size he proposed.");
625                INFMESSAGE(giving up)
626                answer = XtGeometryNo;
627             } else {
628                INFMESSAGE(XtGeometryYes)
629                INFMESSAGE(parent reconfigured window)
630             }
631             break;
632          case XtGeometryNo:
633             INFMESSAGE(XtGeometryNo)
634             answer = XtGeometryNo;
635             break;
636          case XtGeometryDone:
637             INFMESSAGE(XtGeometryDone)
638 	      /* never reached */
639             break;
640       }
641       if (answer == XtGeometryYes) {
642          Resize((Widget)fw);
643          answer = XtGeometryDone;
644       }
645    } else {
646      INFMESSAGE(XtGeometryDone)
647      Resize((Widget)fw);
648      answer = XtGeometryDone;
649    }
650 
651    ENDMESSAGE(LayoutFrame)
652    return answer;
653 }
654