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