1 /**
2  *
3  * $Header: /cvsroot/lesstif/lesstif/lib/Xm-2.1/MainW.c,v 1.1 2004/08/28 19:22:44 dannybackx Exp $
4  *
5  * Copyright (C) 1995 Free Software Foundation, Inc.
6  * Copyright � 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 LessTif Development Team
7  *
8  * This file is part of the GNU LessTif Library.
9  *
10  * This library is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU Library General Public
12  * License as published by the Free Software Foundation; either
13  * version 2 of the License, or (at your option) any later version.
14  *
15  * This library is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18  * Library General Public License for more details.
19  *
20  * You should have received a copy of the GNU Library General Public
21  * License along with this library; if not, write to the Free
22  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23  *
24  **/
25 
26 static const char rcsid[] = "$Id: MainW.c,v 1.1 2004/08/28 19:22:44 dannybackx Exp $";
27 
28 #include <LTconfig.h>
29 
30 #include <stdio.h>
31 #include <string.h>
32 
33 #include <XmI/XmI.h>
34 #include <Xm/XmP.h>
35 #include <Xm/ScrollBarP.h>
36 #include <Xm/BaseClassP.h>
37 #include <Xm/ScrolledWP.h>
38 #include <Xm/RowColumnP.h>
39 #include <Xm/CommandP.h>
40 #include <Xm/MainWP.h>
41 #include <Xm/SeparatoG.h>
42 #include <Xm/SeparatoGP.h>
43 
44 #include <XmI/DebugUtil.h>
45 
46 #define	VALID(w)	(w != NULL && XtIsManaged(w))
47 
48 /* Forward Declarations */
49 
50 #if 0
51 static void class_initialize();
52 #endif
53 
54 static void class_part_initialize(WidgetClass w_class);
55 static void initialize(Widget request, Widget new_w,
56 		       ArgList args, Cardinal *num_args);
57 static void resize(Widget w);
58 
59 #if 0
60 static void realize(Widget w, Mask *value_mask,
61 		    XSetWindowAttributes *attributes);
62 #endif
63 
64 static XtGeometryResult query_geometry(Widget w,
65 				       XtWidgetGeometry *proposed,
66 				       XtWidgetGeometry *answer);
67 static Boolean set_values(Widget current, Widget request, Widget new_w,
68 			  ArgList args, Cardinal *num_args);
69 static XtGeometryResult geometry_manager(Widget w,
70 					 XtWidgetGeometry *request,
71 					 XtWidgetGeometry *reply);
72 static void change_managed(Widget w);
73 static void insert_child(Widget w);
74 static void delete_child(Widget w);
75 static void _XmMainWindowPreferredSize(Widget w, Widget child,
76 				       XtWidgetGeometry *cg, XmMWValues * vals);
77 static XtGeometryResult _XmMainWindowGeomRequest(Widget w, XmMWValues * vals);
78 static void _XmMainWindowLayout(Widget w, Widget child,
79 				XtWidgetGeometry *cg, XmMWValues * vals);
80 static void _XmMainWindowConfigureChildren(Widget w, Widget child,
81 					   XtWidgetGeometry *cg,
82 					   XmMWValues * vals);
83 
84 void _XmConfigureScrollBars(Widget w, Widget child,
85 			    XtWidgetGeometry *childgeom, XmSWValues * vals);
86 
87 void _XmRepositionScrolledWindow(Widget w,
88 				 XtPointer client,
89 				 XtPointer call);
90 
91 void _XmFixupScrollBars(Widget w, Dimension ww, Dimension wh);
92 
93 static void ReparentChild(Widget w, Widget child);
94 
95 /*
96  * Resources for the MainWindow class
97  */
98 #define Offset(field) XtOffsetOf(XmMainWindowRec, mwindow.field)
99 static XtResource resources[] =
100 {
101     {
102 	XmNcommandWindow, XmCCommandWindow, XmRWidget,
103 	sizeof(Widget), Offset(CommandWindow),
104 	XmRImmediate, NULL
105     },
106     {
107   XmNcommandWindowLocation, XmCCommandWindowLocation, XmRCommandWindowLocation,
108 	sizeof(unsigned char), Offset(CommandLoc),
109 	XmRImmediate, (XtPointer)XmCOMMAND_ABOVE_WORKSPACE
110     },
111     {
112 	XmNmenuBar, XmCMenuBar, XmRWidget,
113 	sizeof(Widget), Offset(MenuBar),
114 	XmRImmediate, NULL
115     },
116     {
117 	XmNmessageWindow, XmCMessageWindow, XmRWidget,
118 	sizeof(Widget), Offset(Message),
119 	XmRImmediate, NULL
120     },
121     {
122     XmNmainWindowMarginWidth, XmCMainWindowMarginWidth, XmRHorizontalDimension,
123 	sizeof(Dimension), Offset(margin_width),
124 	XmRImmediate, (XtPointer)0
125     },
126     {
127     XmNmainWindowMarginHeight, XmCMainWindowMarginHeight, XmRVerticalDimension,
128 	sizeof(Dimension), Offset(margin_height),
129 	XmRImmediate, (XtPointer)0
130     },
131     {
132 	XmNshowSeparator, XmCShowSeparator, XmRBoolean,
133 	sizeof(Boolean), Offset(ShowSep),
134 	XtRImmediate, (XtPointer)False
135     }
136 };
137 
138 static XmSyntheticResource syn_resources[] =
139 {
140     {
141 	XmNmainWindowMarginWidth,
142 	sizeof(Dimension), Offset(margin_width),
143 	_XmFromHorizontalPixels, _XmToHorizontalPixels
144     },
145     {
146 	XmNmainWindowMarginHeight,
147 	sizeof(Dimension), Offset(margin_height),
148 	_XmFromVerticalPixels, _XmToVerticalPixels
149     }
150 };
151 
152 /* Add Actions and Translations -- FIX ME */
153 #if 0
154 static XmBaseClassExtRec _XmMainWindowCoreClassExtRec = {
155     /* next_extension            */ NULL,
156     /* record_type               */ NULLQUARK,
157     /* version                   */ XmBaseClassExtVersion,
158     /* size                      */ sizeof(XmBaseClassExtRec),
159     /* initialize_prehook        */ NULL,
160     /* set_values_prehook        */ NULL,
161     /* initialize_posthook       */ NULL,
162     /* set_values_posthook       */ NULL,
163     /* secondary_object_class    */ NULL,
164     /* secondary_object_create   */ NULL,
165     /* get_secondary_resources   */ NULL,
166     /* fast_subclass             */ { 0 },
167     /* get_values_prehook        */ NULL,
168     /* get_values_posthook       */ NULL,
169     /* class_part_init_prehook   */ NULL,
170     /* class_part_init_posthook  */ NULL,
171     /* ext_resources             */ NULL,
172     /* compiled_ext_resources    */ NULL,
173     /* num_ext_resources         */ 0,
174     /* use_sub_resources         */ False,
175     /* widget_navigable          */ XmInheritWidgetNavigable,
176     /* focus_change              */ XmInheritFocusChange,
177     /* wrapper_data              */ NULL
178 };
179 
180 static XmManagerClassExtRec _XmMainWMClassExtRec = {
181     /* next_extension            */ NULL,
182     /* record_type               */ NULLQUARK,
183     /* version                   */ XmManagerClassExtVersion,
184     /* record_size               */ sizeof(XmManagerClassExtRec),
185     /* traversal_children        */ NULL /* FIX ME */
186 };
187 #endif
188 
189 XmMainWindowClassRec xmMainWindowClassRec = {
190     /* Core class part */
191     {
192 	/* superclass            */ (WidgetClass) &xmScrolledWindowClassRec,
193         /* class_name            */ "XmMainWindow",
194 	/* widget_size           */ sizeof(XmMainWindowRec),
195 	/* class_initialize      */ NULL /*class_initialize*/,
196 	/* class_part_initialize */ class_part_initialize,
197 	/* class_inited          */ False,
198 	/* initialize            */ initialize,
199 	/* initialize_hook       */ NULL,
200 	/* realize               */ XtInheritRealize /*realize*/,
201 	/* actions               */ NULL,
202 	/* num_actions           */ 0,
203 	/* resources             */ resources,
204 	/* num_resources         */ XtNumber(resources),
205 	/* xrm_class             */ NULLQUARK,
206 	/* compress_motion       */ True,
207 	/* compress_exposure     */ XtExposeCompressSeries,
208 	/* compress_enterleave   */ True,
209 	/* visible_interest      */ False,
210 	/* destroy               */ NULL,
211 	/* resize                */ resize,
212 	/* expose                */ XtInheritExpose,
213 	/* set_values            */ set_values,
214 	/* set_values_hook       */ NULL,
215 	/* set_values_almost     */ XtInheritSetValuesAlmost,
216 	/* get_values_hook       */ NULL,
217 	/* accept_focus          */ NULL,
218 	/* version               */ XtVersion,
219 	/* callback offsets      */ NULL,
220 	/* tm_table              */ XtInheritTranslations /*NULL*/,
221 	/* query_geometry        */ query_geometry,
222 	/* display_accelerator   */ NULL,
223 	/* extension             */ (XtPointer)NULL /*&_XmMainWindowCoreClassExtRec*/
224     },
225     /* Composite class part */
226     {
227 	/* geometry manager */ geometry_manager,
228         /* change_managed   */ change_managed,
229         /* insert_child     */ insert_child,
230         /* delete_child     */ delete_child,
231         /* extension        */ NULL,
232     },
233     /* Constraint class part */
234     {
235 	/* subresources      */ NULL,
236         /* subresource_count */ 0,
237         /* constraint_size   */ 0,
238         /* initialize        */ NULL,
239         /* destroy           */ NULL,
240         /* set_values        */ NULL,
241         /* extension         */ NULL,
242     },
243     /* XmManager class part */
244     {
245 	/* translations                 */ XtInheritTranslations,
246 	/* syn_resources                */ syn_resources,
247 	/* num_syn_resources            */ XtNumber(syn_resources),
248 	/* syn_constraint_resources     */ NULL,
249 	/* num_syn_constraint_resources */ 0,
250 	/* parent_process               */ XmInheritParentProcess,
251 	/* extension                    */ (XtPointer)NULL /*&_XmMainWMClassExtRec*/
252     },
253     /* XmScrolledWindow part */
254     {
255 	/* extension */ NULL,
256     },
257     /* XmMainWindow part */
258     {
259 	/* extension */ NULL,
260     },
261 };
262 
263 
264 WidgetClass xmMainWindowWidgetClass = (WidgetClass)&xmMainWindowClassRec;
265 
266 #if 0
267 static void
268 class_initialize()
269 {
270     _XmMainWindowCoreClassExtRec.record_type = XmQmotif;
271 }
272 #endif
273 
274 static void
class_part_initialize(WidgetClass widget_class)275 class_part_initialize(WidgetClass widget_class)
276 {
277     _XmFastSubclassInit(widget_class, XmMAIN_WINDOW_BIT);
278 }
279 
280 static void
initialize(Widget request,Widget new_w,ArgList args,Cardinal * num_args)281 initialize(Widget request, Widget new_w,
282 	   ArgList args, Cardinal *num_args)
283 {
284     /* Revert setting from XmScrolledWindow's initialize */
285     /* T. Straumann:
286      *        do this only if an initial window size
287      *        was specified. The default (100x100 for
288      *        XmAUTOMATIC should be set for the
289      *        working window, not the whole mainWindow.
290      *        Furthermore, there is a weird difference
291      *        between >tif's ScrolledW and MainW regarding the
292      *        default size of 100x100.
293      *        The 100x100 is the _overall_ default size of
294      *        their ScrolledW. Their MainW however chooses
295      *        a default size of the entire clip window as
296      *
297      *            (100 + spacing + highlightThickness + VsbW)
298      *          x
299      *            (100 + spacing + highlightThickness + HsbH)
300      *
301      *        I.e. if scrollbars are not needed and/or the
302      *        highlightThickness is > 0, the effective space
303      *        left for the clip window is actually bigger
304      *        than 100x100.
305      *
306      *        NOTE:  highlightThickness means the highlight
307      *               Thickness of VSB/HSB. >tif's ScrolledW
308      *               (and also MainW) will do VERY weird
309      *               layout if
310      *
311      *               VSB.highlightThickness != HSB.highlightThickness
312      *
313      *               I refuse spending any effort to re-implement
314      *               this behavior. IT SUCKS.
315      */
316     if (XtWidth(request) == 0)
317     {
318 	XtWidth(new_w) = 0;
319 	if (SW_ScrollPolicy(new_w) == XmAUTOMATIC)
320 	{
321 	    SW_GivenWidth(new_w) = 100 + SW_Spacing(new_w)
322 #ifdef I_WANT_THEIR_SUCKING_EXTRA_SEP
323 		+ Prim_HighlightThickness(SW_VSB(new_w))
324 #endif
325 		+ XtWidth(SW_VSB(new_w));
326 	}
327 	else
328 	{
329 	    /* T. Straumann: FIXME (don't know what they do in this case) */
330 	}
331     }
332     if (XtHeight(request) == 0)
333     {
334 	XtHeight(new_w) = 0;
335 	if (SW_ScrollPolicy(new_w) == XmAUTOMATIC)
336 	{
337 	    SW_GivenHeight(new_w) = 100 + SW_Spacing(new_w)
338 #ifdef I_WANT_THEIR_SUCKING_EXTRA_SEP
339 		+ Prim_HighlightThickness(SW_HSB(new_w))
340 #endif
341 		+ XtHeight(SW_HSB(new_w));
342 	}
343 	else
344 	{
345 	    /* T. Straumann: FIXME (don't know what they do in this case) */
346 	}
347     }
348 
349     /* Override setting of XmScrolledWindow's Margin[Width|Height] resources */
350     SW_MarginWidth(new_w) = MW_MarginWidth(new_w);
351     SW_MarginHeight(new_w) = MW_MarginHeight(new_w);
352 
353     MW_Sep1(new_w) = (XmSeparatorGadget)XmCreateSeparatorGadget(new_w,
354 								"Separator1",
355 								args,
356 								*num_args);
357     MW_Sep2(new_w) = (XmSeparatorGadget)XmCreateSeparatorGadget(new_w,
358 								"Separator2",
359 								args,
360 								*num_args);
361     MW_Sep3(new_w) = (XmSeparatorGadget)XmCreateSeparatorGadget(new_w,
362 								"Separator3",
363 								args,
364 								*num_args);
365     if (MW_ShowSep(new_w))
366     {
367 	if (VALID(MW_MenuBar(new_w)))
368 	{
369 	    XtManageChild((Widget)MW_Sep1(new_w));
370 	}
371 	if (VALID(MW_CommandWindow(new_w)))
372 	{
373 	    XtManageChild((Widget)MW_Sep2(new_w));
374 	}
375 	if (VALID(MW_MessageWindow(new_w)))
376 	{
377 	    XtManageChild((Widget)MW_Sep3(new_w));
378 	}
379     }
380 }
381 
382 static Boolean
set_values(Widget old,Widget request,Widget new_w,ArgList args,Cardinal * num_args)383 set_values(Widget old, Widget request, Widget new_w,
384 	   ArgList args, Cardinal *num_args)
385 {
386     Boolean refresh = False;
387     Boolean relayout = False;
388 #define NE(x)	(x(old) != x(new_w))
389 
390     DEBUGOUT(_LtDebug(__FILE__, new_w,
391 		      "%s:set_values(%d) - %i args\n"
392 		      "\t    old X %5i Y %5i W %5i H %5i\n"
393 		      "\trequest X %5i Y %5i W %5i H %5i\n"
394 		      "\t  new_w X %5i Y %5i W %5i H %5i\n",
395 		      __FILE__, __LINE__,
396 		      *num_args,
397 		      XtX(old), XtY(old),
398 		      XtWidth(old), XtHeight(old),
399 		      XtX(request), XtY(request),
400 		      XtWidth(request), XtHeight(request),
401 		      XtX(new_w), XtY(new_w),
402 		      XtWidth(new_w), XtHeight(new_w)));
403     DEBUGOUT(_LtDebugPrintArgList(__FILE__, new_w, args, *num_args, False));
404 
405     if (NE(MW_CommandLoc))
406     {
407 	refresh = True;
408 	/* T. Straumann: mainw/test10 failed; we need a relayout to propagate the change */
409 	relayout = True;
410     }
411 
412     if (NE(SW_WorkWindow))
413     {
414 	DEBUGOUT(_LtDebug(__FILE__, new_w,
415 			  "SetValues: Changed the work window !\n"));
416 
417 	if (SW_ClipWindow(new_w))
418 	{
419 	    if (SW_WorkWindow(old))
420 	    {
421 		ReparentChild(new_w, SW_WorkWindow(old));
422 	    }
423 	    ReparentChild((Widget)SW_ClipWindow(new_w), SW_WorkWindow(new_w));
424 	}
425 
426 	if (MW_CommandWindow(new_w) == SW_WorkWindow(new_w))
427 	{
428 	    MW_CommandWindow(new_w) = NULL;
429 	}
430 	if (MW_MessageWindow(new_w) == SW_WorkWindow(new_w))
431 	{
432 	    MW_MessageWindow(new_w) = NULL;
433 	}
434 	if (MW_MenuBar(new_w) == SW_WorkWindow(new_w))
435 	{
436 	    MW_MenuBar(new_w) = NULL;
437 	}
438 
439 	refresh = True;
440     }
441 
442     if (NE(MW_CommandWindow))
443     {
444 	DEBUGOUT(_LtDebug(__FILE__, new_w,
445 			  "SetValues: Changed the command window !\n"));
446 
447 	if (SW_VisualPolicy(new_w) == XmCONSTANT &&
448 	    MW_CommandWindow(new_w) &&
449 	    XtParent(MW_CommandWindow(new_w)) == (Widget)SW_ClipWindow(new_w))
450 	{
451 	    ReparentChild(new_w, MW_CommandWindow(new_w));
452 	}
453 
454 	if (SW_WorkWindow(new_w) == MW_CommandWindow(new_w))
455 	{
456 	    SW_WorkWindow(new_w) = NULL;
457 	}
458 	if (MW_MessageWindow(new_w) == MW_CommandWindow(new_w))
459 	{
460 	    MW_MessageWindow(new_w) = NULL;
461 	}
462 	if (MW_MenuBar(new_w) == MW_CommandWindow(new_w))
463 	{
464 	    MW_MenuBar(new_w) = NULL;
465 	}
466 
467 	refresh = True;
468     }
469 
470     if (NE(MW_MessageWindow))
471     {
472 	DEBUGOUT(_LtDebug(__FILE__, new_w,
473 			  "SetValues: Changed the message window !\n"));
474 
475 	if (SW_VisualPolicy(new_w) == XmCONSTANT &&
476 	    MW_MessageWindow(new_w) &&
477 	    XtParent(MW_MessageWindow(new_w)) == (Widget)SW_ClipWindow(new_w))
478 	{
479 	    ReparentChild(new_w, MW_MessageWindow(new_w));
480 	}
481 
482 	if (MW_CommandWindow(new_w) == MW_MessageWindow(new_w))
483 	{
484 	    MW_CommandWindow(new_w) = NULL;
485 	}
486 	if (SW_WorkWindow(new_w) == MW_MessageWindow(new_w))
487 	{
488 	    SW_WorkWindow(new_w) = NULL;
489 	}
490 	if (MW_MenuBar(new_w) == MW_MessageWindow(new_w))
491 	{
492 	    MW_MenuBar(new_w) = NULL;
493 	}
494 
495 	refresh = True;
496     }
497 
498     if (NE(MW_MenuBar))
499     {
500 	DEBUGOUT(_LtDebug(__FILE__, new_w,
501 			  "SetValues: Changed the menu bar !\n"));
502 
503 	if (SW_VisualPolicy(new_w) == XmCONSTANT &&
504 	    XtParent(MW_MenuBar(new_w)) == (Widget)SW_ClipWindow(new_w))
505 	{
506 	    ReparentChild(new_w, MW_MenuBar(new_w));
507 	}
508 
509 	if (MW_CommandWindow(new_w) == MW_MenuBar(new_w))
510 	{
511 	    MW_CommandWindow(new_w) = NULL;
512 	}
513 	if (SW_WorkWindow(new_w) == MW_MenuBar(new_w))
514 	{
515 	    SW_WorkWindow(new_w) = NULL;
516 	}
517 	if (MW_MessageWindow(new_w) == MW_MenuBar(new_w))
518 	{
519 	    MW_MessageWindow(new_w) = NULL;
520 	}
521 
522 	refresh = True;
523     }
524 
525     if (MW_ShowSep(new_w))
526     {
527 	if (VALID(MW_MenuBar(new_w)))
528 	{
529 	    XtManageChild((Widget)MW_Sep1(new_w));
530 	}
531 	else
532 	{
533 	    XtUnmanageChild((Widget)MW_Sep1(new_w));
534 	}
535 	if (VALID(MW_CommandWindow(new_w)))
536 	{
537 	    XtManageChild((Widget)MW_Sep2(new_w));
538 	}
539 	else
540 	{
541 	    XtUnmanageChild((Widget)MW_Sep2(new_w));
542 	}
543 	if (VALID(MW_MessageWindow(new_w)))
544 	{
545 	    XtManageChild((Widget)MW_Sep3(new_w));
546 	}
547 	else
548 	{
549 	    XtUnmanageChild((Widget)MW_Sep3(new_w));
550 	}
551     }
552     else if (NE(MW_ShowSep))
553     {
554 	XtUnmanageChild((Widget)MW_Sep1(new_w));
555 	XtUnmanageChild((Widget)MW_Sep2(new_w));
556 	XtUnmanageChild((Widget)MW_Sep3(new_w));
557 	refresh = True;
558     }
559 
560     if (NE(MW_MarginHeight))
561     {
562 	SW_MarginHeight(new_w) = MW_MarginHeight(new_w);
563 	refresh = True;
564     }
565 
566     if (NE(MW_MarginWidth))
567     {
568 	SW_MarginWidth(new_w) = MW_MarginWidth(new_w);
569 	refresh = True;
570     }
571 
572     if (XtIsRealized(new_w) && refresh)
573     {
574 	XmMWValues vals;
575 
576 	_XmMainWindowPreferredSize(new_w, NULL, NULL, &vals);
577 	XtWidth(new_w) = vals.MwW;
578 	XtHeight(new_w) = vals.MwH;
579 	if (relayout)
580 	{
581 	    _XmMainWindowLayout(new_w, NULL, NULL, &vals);
582 	    _XmMainWindowConfigureChildren(new_w, NULL, NULL, &vals);
583 	}
584     }
585 
586     return refresh;
587 }
588 
589 static void
resize(Widget w)590 resize(Widget w)
591 {
592     XmMWValues vals;
593 
594     DEBUGOUT(_LtDebug(__FILE__, w, "%s:resize(%d) (%dx%d)\n",
595 		      __FILE__, __LINE__,
596 		      XtWidth(w), XtHeight(w)));
597 
598     SW_FromResize(w) = True;
599 
600     _XmMainWindowPreferredSize(w, NULL, NULL, &vals);
601 
602     vals.MwW = XtWidth(w);
603     vals.MwH = XtHeight(w);
604 
605     _XmMainWindowLayout(w, NULL, NULL, &vals);
606 
607     _XmMainWindowConfigureChildren(w, NULL, NULL, &vals);
608 
609     SW_FromResize(w) = False;
610 }
611 
612 #if 0
613 static void
614 realize(Widget w, Mask *value_mask, XSetWindowAttributes *attributes)
615 {
616 /* Motif inherits this method */
617 /* and we could also, if ScrolledW gets rid of the geo stuff in realize */
618 
619     /*
620        XmMWValues vals;
621      */
622 
623     DEBUGOUT(_LtDebug(__FILE__, w, "Realize ...\n"));
624 
625 #define superclass (&xmManagerClassRec)
626     (*superclass->core_class.realize) (w, value_mask, attributes);
627 #undef superclass
628 
629 #if 0
630     /* mainw/test13 */
631     if (XtWidth(w) != 0 && XtWidth(w) != 1)
632     {
633 	SW_GivenWidth(w) = XtWidth(w);
634     }
635     if (XtHeight(w) != 0 && XtHeight(w) != 1)
636     {
637 	SW_GivenHeight(w) = XtHeight(w);
638     }
639 
640     _XmMainWindowPreferredSize(w, NULL, NULL, &vals);
641 
642     _XmMainWindowGeomRequest(w, &vals);
643 
644     /* ordinarily, we'd look at the return code and reset w/h based on
645      * it.  But our routine does that for us. */
646 
647     _XmMainWindowLayout(w, NULL, NULL, &vals);
648 
649     _XmMainWindowConfigureChildren(w, NULL, NULL, &vals);
650 
651     DEBUGOUT(_LtDebug(__FILE__, w, "Realize => size %d %d\n",
652 		      XtWidth(w), XtHeight(w)));
653 #endif
654 }
655 #endif
656 
657 static XtGeometryResult
query_geometry(Widget w,XtWidgetGeometry * intended,XtWidgetGeometry * preferred)658 query_geometry(Widget w,
659 	       XtWidgetGeometry *intended,
660 	       XtWidgetGeometry *preferred)
661 {
662 #if 0
663     XtWidgetGeometry wants;
664     XmMWValues vals;
665 
666     wants = *intended;
667 
668     _XmMainWindowPreferredSize(w, w, NULL, &vals);
669 
670     if (preferred)
671     {
672 	preferred->width = vals.MwW;
673 	preferred->height = vals.MwH;
674     }
675 
676     if (((wants.request_mode & CWWidth) &&
677 	 wants.width == preferred->width) &&
678 	((wants.request_mode & CWHeight) &&
679 	 wants.height == preferred->height))
680     {
681 	return XtGeometryNo;
682     }
683 
684     if ((wants.request_mode & CWWidth) &&
685 	wants.width != preferred->width)
686     {
687 	return XtGeometryAlmost;	/* Something's different */
688     }
689     if ((wants.request_mode & CWHeight) &&
690 	wants.height != preferred->height)
691     {
692 	return XtGeometryAlmost;	/* Something's different */
693     }
694 
695     return XtGeometryYes;
696 #else
697     XtWidgetGeometry wants;
698     XmMWValues vals;
699 
700     /* see if they propose a width */
701     if (intended->request_mode & CWWidth)
702     {
703 	/* yes, propagate it to _XmMainWindowPreferredSize() */
704 	wants.request_mode = CWWidth;
705 	wants.width = intended->width;
706 	_XmMainWindowPreferredSize(w, w, &wants, &vals);
707     }
708     else
709     {
710 	_XmMainWindowPreferredSize(w, w, NULL, &vals);
711     }
712 
713     wants = *intended;
714 
715     if (preferred)
716     {
717 	preferred->width = vals.MwW;
718 	preferred->height = vals.MwH;
719     }
720 
721     return _XmGMReplyToQueryGeometry(w, &wants, preferred);
722 #endif
723 }
724 
725 static void
CreateManagedList(Widget w,Widget ** managed,int * num_managed,int * num_allocated)726 CreateManagedList(Widget w, Widget **managed, int *num_managed,
727 		  int *num_allocated)
728 {
729     if (XtIsComposite(w) && MGR_NumChildren(w) > 0)
730     {
731 	Cardinal i;
732 	for (i = 0; i < MGR_NumChildren(w); i++)
733 	{
734 	    CreateManagedList(MGR_Children(w)[i], managed, num_managed,
735 			      num_allocated);
736 	}
737     }
738     if (XtIsManaged(w))
739     {
740 	if (*num_managed == *num_allocated)
741 	{
742 	    /* Allocate more space */
743 	    *num_allocated += (*num_allocated / 2) + 2;
744 	    *managed =
745 		(WidgetList)XtRealloc((char *)*managed,
746 				      (unsigned)(*num_allocated *
747 						 sizeof(Widget)));
748 	}
749 	*managed[*num_managed++] = w;
750     }
751 }
752 
753 static void
ReparentChild(Widget w,Widget child)754 ReparentChild(Widget w, Widget child)
755 {
756 
757     Widget old_parent = XtParent(child), *managed;
758     Cardinal i, j;
759     int num_managed, num_allocated;
760     Boolean is_realized;
761 
762     if (old_parent == w)
763     {
764 	return;
765     }
766     /* first make a list of children who needs to be managed again */
767     num_managed = 0;
768     num_allocated = 2;
769     managed = (Widget *)XtMalloc(num_allocated * sizeof(Widget));
770     CreateManagedList(child, &managed, &num_managed, &num_allocated);
771     for (i = 0; i < MGR_NumChildren(old_parent); i++)
772     {
773 	if (MGR_Children(old_parent)[i] == child)
774 	{
775 	    break;
776 	}
777     }
778     if (MGR_NumChildren(w) == MGR_NumSlots(w))
779     {
780 	/* Allocate more space */
781 	MGR_NumSlots(w) += (MGR_NumSlots(w) / 2) + 2;
782 	MGR_Children(w) =
783 	    (WidgetList)XtRealloc((char *)MGR_Children(w),
784 				  (unsigned)(MGR_NumSlots(w) *
785 					     sizeof(Widget)));
786     }
787     if ((is_realized = XtIsRealized(child)))
788     {
789 	XtUnrealizeWidget(child);
790     }
791     MGR_Children(w)[MGR_NumChildren(w)++] = child;
792     XtParent(child) = w;
793     if (is_realized)
794     {
795 	XtRealizeWidget(child);
796     }
797     for (j = 0; j < (int)num_managed; j++)
798     {
799 	XtManageChild(managed[j]);
800     }
801     XtFree((char *)managed);
802 
803     for (j = i + 1; j < MGR_NumChildren(old_parent); j++)
804     {
805 	MGR_Children(old_parent)[j - 1] = MGR_Children(old_parent)[j];
806     }
807     MGR_NumChildren(old_parent)--;
808 }
809 
810 
811 
812 
813 static void
change_managed(Widget w)814 change_managed(Widget w)
815 {
816     XmMWValues vals;
817 
818     DEBUGOUT(_LtDebug(__FILE__, w, "ChangeManaged\n"));
819     /*
820      * It is possible that some of the MainWindows children is made children
821      * of ClipWindow by the ScrolledWindow. Steal them back.
822      */
823     if (SW_VisualPolicy(w) == XmCONSTANT &&
824 	MGR_NumChildren(SW_ClipWindow(w)) > 1)
825     {
826 	XmDrawingAreaWidget cw = SW_ClipWindow(w);
827 	Widget mw_children[3];
828 	Cardinal i, num_mw_children = 0;
829 
830 	for (i = 0; i < MGR_NumChildren(cw); i++)
831 	{
832 	    if (MGR_Children(cw)[i] == MW_CommandWindow(w) ||
833 		MGR_Children(cw)[i] == MW_MenuBar(w) ||
834 		MGR_Children(cw)[i] == MW_MessageWindow(w))
835 	    {
836 		mw_children[num_mw_children++] = MGR_Children(cw)[i];
837 	    }
838 	}
839 	for (i = 0; i < num_mw_children; i++)
840 	{
841 	    ReparentChild(w, mw_children[i]);
842 	}
843     }
844     if (SW_HSB(w) && XtIsManaged(SW_HSB(w)))
845     {
846 	SW_HasHSB(w) = True;
847     }
848     else
849     {
850 	SW_HasHSB(w) = False;
851     }
852 
853     if (SW_VSB(w) && XtIsManaged(SW_VSB(w)))
854     {
855 	SW_HasVSB(w) = True;
856     }
857     else
858     {
859 	SW_HasVSB(w) = False;
860     }
861 
862     if (MW_ShowSep(w))
863     {
864 	if (VALID(MW_MenuBar(w)))
865 	{
866 	    XtManageChild((Widget)MW_Sep1(w));
867 	}
868 	else
869 	{
870 	    XtUnmanageChild((Widget)MW_Sep1(w));
871 	}
872 	if (VALID(MW_CommandWindow(w)))
873 	{
874 	    XtManageChild((Widget)MW_Sep2(w));
875 	}
876 	else
877 	{
878 	    XtUnmanageChild((Widget)MW_Sep2(w));
879 	}
880 	if (VALID(MW_MessageWindow(w)))
881 	{
882 	    XtManageChild((Widget)MW_Sep3(w));
883 	}
884 	else
885 	{
886 	    XtUnmanageChild((Widget)MW_Sep3(w));
887 	}
888     }
889     _XmMainWindowPreferredSize(w, NULL, NULL, &vals);
890 
891 #if 0				/* T. Straumann: what's that for ? */
892     if (!XtIsRealized(w))
893     {
894 	/* mainw/test11 */
895 	if (SW_GivenWidth(w) == 0)
896 	{
897 	    vals.MwW = SW_GivenWidth(w);
898 	}
899 	if (SW_GivenHeight(w) == 0)
900 	{
901 	    vals.MwH = SW_GivenHeight(w);
902 	}
903     }
904 #endif
905 
906     _XmMainWindowGeomRequest(w, &vals);
907 
908     /* ordinarily, we'd look at the return code and reset w/h based on
909      * it.  But our routine does that for us. */
910 
911     _XmMainWindowLayout(w, NULL, NULL, &vals);
912 
913     _XmMainWindowConfigureChildren(w, NULL, NULL, &vals);
914 }
915 
916 
917 /*
918  * This is the new implementation of MainWindow Layout.
919  * Danny 16/1/1997
920  *
921  * Parameters :
922  *      w is the MainWindow
923  *      ParentResize - True if we are allowed to try to change our own size
924  *      child - the 'instigator' (the child causing this request, its
925  *              geometry should not be changed)
926  *      TestMode - True if we're not allowed to change anything
927  *      cg - the childs geometry
928  *      mwg - return the mainwindow geometry
929  *
930  * Stuff to layout is :
931  *      - MenuBar (MW_MenuBar)
932  *      - Command Area (MW_CommandWindow)
933  *      - Work Area (SW_WorkWindow)             note SW_
934  *      - Message Area (MW_MessageWindow)
935  * If MW_CommandLoc == XmCOMMAND_ABOVE_WORKSPACE then the order as given above.
936  * Otherwise reverse order of Command Area and Work Area.
937  *
938  * If MW_ShowSep then separators (three) must be shown.
939  */
940 
941 static void
_XmMainWindowPreferredSize(Widget w,Widget child,XtWidgetGeometry * cg,XmMWValues * vals)942 _XmMainWindowPreferredSize(Widget w, Widget child, XtWidgetGeometry *cg,
943 			   XmMWValues * vals)
944 {
945     /* Dimension variables typed as int to allow for negative values. */
946     Dimension curh, savedh;
947     Boolean childNotHappy;
948 
949     int curw;
950     int maxw = -1;
951 
952     Widget chld[3], sep[3];
953 
954     struct wxh
955     {
956 	Dimension w, h;
957 	char *name;
958     }
959     chldwh[3], sepwh[3];
960 
961     int i, nchld, nsep = 0;
962 
963     memset(vals, 0, sizeof(XmMWValues));
964 
965     /* ignore the instigator if resizing */
966     if (SW_FromResize(w))
967     {
968 	maxw = XtWidth(w) - 2 * SW_MarginWidth(w);
969     }
970     else
971     {
972 	if (cg && child)
973 	{
974 	    /* T. Straumann: hmmm... we must take care. If the instigator
975 	     *                             is the work window in variable mode, we
976 	     *               have to ask scrolledW first. However, to do its
977 	     *               computation correctly, scrolledW needs to know
978 	     *               its XtWidth and XtHeight respectively. Unfortunately,
979 	     *               the height left for the scrolled area
980 	     *               depends on all the other items (menu bar etc.) which
981 	     *               we don't know yet.
982 	     *               Therefore, we just take their actual height.
983 	     */
984 	    if (child == SW_WorkWindow(w) && SW_VisualPolicy(child) == XmVARIABLE)
985 	    {
986 		/* T. Straumann: first, compute the height left. This calculation is
987 		 *                             based on the actual height.
988 		 */
989 		Dimension swh;
990 		savedh = swh = XtHeight(w);
991 
992 		if (VALID(MW_MenuBar(w)))
993 		{
994 		    swh -= XtHeight(MW_MenuBar(w));
995 		}
996 		if (VALID(MW_CommandWindow(w)))
997 		{
998 		    swh -= XtHeight(MW_CommandWindow(w));
999 		}
1000 		if (VALID(MW_MessageWindow(w)))
1001 		{
1002 		    swh -= XtHeight(MW_MessageWindow(w));
1003 		}
1004 		if (MW_ShowSep(w))
1005 		{
1006 		    swh -= XtHeight(MW_Sep1(w)) + XtHeight(MW_Sep2(w)) + XtHeight(MW_Sep3(w));
1007 		}
1008 		/* Now, we do some hacking. The scrolled window routine should believe
1009 		 * this is all it has got.
1010 		 */
1011 		XtHeight(w) = swh > 0 ? swh : 0;
1012 
1013 		/*
1014 		 * T. Straumann:  let the scrolledW do its job
1015 		 * NOTE: this is _ugly_, should be a method, but alas, we must not
1016 		 *               add to ScrolledWP.h
1017 		 * Hey, what about an class extension record?
1018 		 */
1019 		_XmScrolledWPreferredSize(w, child, cg, (XmSWValues *) vals);
1020 		/* restore the height */
1021 		XtHeight(w) = savedh;
1022 
1023 		maxw = vals->MwW - 2 * SW_MarginWidth(w);
1024 	    }
1025 	    else
1026 	    {			/* it's not a child already handled by ScrolledW */
1027 
1028 		/* T. Straumann: allow changes of border width of work window,
1029 		 *               and other children
1030 		 */
1031 		if (child == MW_CommandWindow(w)
1032 		    || child == MW_MessageWindow(w) || child == MW_MenuBar(w))
1033 		{
1034 		    cg->request_mode &= (CWWidth | CWHeight | XtCWQueryOnly | CWBorderWidth);
1035 		}
1036 		else
1037 		{
1038 		    cg->request_mode &= (CWWidth | CWHeight | XtCWQueryOnly);
1039 		}
1040 		/* T. Straumann: if an instigator asks for a new width, we try to calculate the
1041 		 *                             preferred size based on this value.
1042 		 *                               -1 (default) meaning that no width is asked for.
1043 		 */
1044 		if (cg->request_mode & CWWidth)
1045 		{
1046 		    maxw = cg->width;
1047 		    maxw += 2 * (cg->request_mode & CWBorderWidth ?
1048 				 cg->border_width : XtBorderWidth(child));
1049 		}
1050 	    }
1051 	}
1052     }				/* if FromResize */
1053 
1054     /*
1055      * As in all the complicated layout functions, this is the algorithm :
1056      * - keep everything in local variables for implementing TestMode
1057      * - first figure out how much space we need
1058      * - if we're allowed, request geometry change
1059      * - layout children (in local variables !) based on geometry
1060      *      which may be different from the geometry requested above
1061      * - if not in TestMode, apply all changes
1062      *      Otherwise, return some values in parameters.
1063      */
1064 
1065     /* Talk */
1066     DEBUGOUT(_LtDebug2(__FILE__, w, child, "_XmMainWindowPreferredSize request %s\n",
1067 		       _LtDebugWidgetGeometry2String(cg)));
1068 
1069     /* T. Straumann: do querying the kids using a loop (I'm lazy) */
1070 
1071     nchld = 0;
1072     chld[nchld] = VALID(MW_MenuBar(w)) ? MW_MenuBar(w) : 0;
1073     chldwh[nchld].name = "menu bar";
1074     chldwh[nchld].w = chldwh[nchld].h = 0;
1075     nchld++;
1076     chld[nchld] = VALID(MW_CommandWindow(w)) ? MW_CommandWindow(w) : 0;
1077     chldwh[nchld].name = "command window";
1078     chldwh[nchld].w = chldwh[nchld].h = 0;
1079     nchld++;
1080     chld[nchld] = VALID(MW_MessageWindow(w)) ? MW_MessageWindow(w) : 0;
1081     chldwh[nchld].name = "message window";
1082     chldwh[nchld].w = chldwh[nchld].h = 0;
1083     nchld++;
1084 
1085     if (MW_ShowSep(w))
1086     {
1087 	nsep = 0;
1088 	sep[nsep] = VALID(MW_Sep1(w)) ? (Widget)MW_Sep1(w) : 0;
1089 	sepwh[nsep].w = sepwh[nsep].h = 0;
1090 	sepwh[nsep].name = "Sep1";
1091 	nsep++;
1092 	sep[nsep] = VALID(MW_Sep2(w)) ? (Widget)MW_Sep2(w) : 0;
1093 	sepwh[nsep].w = sepwh[nsep].h = 0;
1094 	sepwh[nsep].name = "Sep2";
1095 	nsep++;
1096 	sep[nsep] = VALID(MW_Sep3(w)) ? (Widget)MW_Sep3(w) : 0;
1097 	sepwh[nsep].w = sepwh[nsep].h = 0;
1098 	sepwh[nsep].name = "Sep3";
1099 	nsep++;
1100     }
1101 
1102 
1103     /* T. Straumann:
1104 
1105      * find out how big we wanna be:
1106      *
1107      * repeat asking all children for their size given a proposed
1108      * width until the proposed width seems acceptable for all children.
1109      *
1110      * The proposed width is initially set to
1111      *
1112      *  - the width proposed by the instigator if any.
1113      *  - the current width of mainw (minus margin & friends) if we are
1114      *    resizing.
1115      *
1116      * (These are orthogonal; SW_FromResize implies cg==NULL)
1117      *
1118      * If any child is not happy with the proposed width, the proposed
1119      * width (`curw') is increased to the maximal width of all children
1120      * and the query process restarted.
1121      *
1122      * Note that we have to repeat this until things get stable. Consider
1123      * e.g. the following scenario:
1124      *
1125      * child A accepts the proposed width but arranges for a bigger
1126      * height (e.g. wraps a line).
1127      * child B rejects -> width is increased.
1128      * child A does not need the bigger height anymore.
1129      *
1130      * If we wouldn't restart the query, the recorded height of A
1131      * would be wrong.
1132      */
1133     do
1134     {
1135 
1136 	/* calculate the size based on a proposed width of the last maxw */
1137 	curw = maxw;
1138 
1139 	maxw = 0;
1140 	childNotHappy = False;
1141 
1142 	/*
1143 	 * Find out how big we need to be.
1144 	 *      Only count SW_MarginWidth etc. at the end.
1145 	 *      Don't need to care about child order yet.
1146 	 */
1147 	curh = 0;
1148 
1149 	for (i = 0; i < nchld; i++)
1150 	{
1151 	    if (chld[i])
1152 	    {
1153 		Dimension bw = XtBorderWidth(chld[i]);
1154 		XtWidgetGeometry rcg, rcg_r;
1155 
1156 		DEBUGOUT(_LtDebug2(__FILE__, w, chld[i],
1157 		       "_XmMainWindowPreferredSize: %s current wid %d ht %d\n",
1158 			 chldwh[i].name, XtWidth(chld[i]), XtHeight(chld[i])));
1159 
1160 		rcg.request_mode = (curw >= 0) ? CWWidth : 0;
1161 		rcg.width = (Dimension)curw;
1162 
1163 		if (SW_FromResize(w))
1164 		{
1165 		    /* T. Straumann: account for border */
1166 		    rcg.width -= 2 * bw;
1167 		}
1168 
1169 		XtQueryGeometry(chld[i], &rcg, &rcg_r);
1170 
1171 #define	Wants(xx)	(cg && ((cg->request_mode) & xx))
1172 
1173 		/*
1174 		 * If we are resizing, the proposed width is mandatory and we
1175 		 * don't have to loop.
1176 		 */
1177 		if (!SW_FromResize(w) && Wants(CWWidth) && rcg.width != rcg_r.width)
1178 		{
1179 		    childNotHappy = True;
1180 		}
1181 		chldwh[i].w = rcg_r.width;
1182 		chldwh[i].h = rcg_r.height;
1183 
1184 		if (child && chld[i] == child)
1185 		{
1186 		    if (Wants(CWWidth) && chldwh[i].w != cg->width)
1187 		    {
1188 			chldwh[i].w = cg->width;
1189 			childNotHappy = True;
1190 			DEBUGOUT(_LtDebug0(__FILE__, w, "\tbut it wants width %d\n",
1191 					   cg->width));
1192 		    }
1193 		    if (Wants(CWHeight) && chldwh[i].h != cg->height)
1194 		    {
1195 			chldwh[i].h = cg->height;
1196 			childNotHappy = True;
1197 			DEBUGOUT(_LtDebug0(__FILE__, w, "\tbut it wants height %d\n",
1198 					   cg->height));
1199 		    }
1200 		    /* T. Straumann: allow changes of border width */
1201 		    if (Wants(CWBorderWidth) && bw != cg->border_width)
1202 		    {
1203 			childNotHappy = True;
1204 			bw = cg->border_width;
1205 			/* FIXME: need to store the border width somewhere? */
1206 		    }
1207 		}
1208 		chldwh[i].w += 2 * bw;
1209 		chldwh[i].h += 2 * bw;
1210 
1211 		DEBUGOUT(_LtDebug2(__FILE__, w, chld[i],
1212 				   "%s w %d h %d\n",
1213 				   chldwh[i].name, chldwh[i].w, chldwh[i].h));
1214 
1215 		curh += chldwh[i].h;
1216 		if (maxw < chldwh[i].w)
1217 		{
1218 		    maxw = chldwh[i].w;
1219 		}
1220 	    }
1221 	}			/* for menubar command_window message_window */
1222 
1223 	/* T. Straumann: moved separator stuff here, so we know the
1224 	 *                     remaining space.
1225 	 */
1226 
1227 	if (MW_ShowSep(w))
1228 	{
1229 	    for (i = 0; i < nsep; i++)
1230 	    {
1231 		if (sep[i])
1232 		{
1233 		    sepwh[i].w = XtWidth(sep[i]);
1234 		    sepwh[i].h = XtHeight(sep[i]);
1235 
1236 		    if (sep[i] == child)
1237 		    {
1238 			if (Wants(CWWidth))
1239 			{
1240 			    sepwh[i].w = cg->width;
1241 			}
1242 			if (Wants(CWHeight))
1243 			{
1244 			    sepwh[i].h = cg->height;
1245 			}
1246 		    }
1247 
1248 		    curh += sepwh[i].h;
1249 		}
1250 	    }
1251 
1252 	}
1253 
1254 	/* T. Straumann: ok - now it's time to let ScrolledW do the rest.
1255 	   *               first, we have to hack the size of the widget.
1256 	   * NOTE: this is _ugly_, should be a method, but alas, we must not
1257 	   *             add to ScrolledWP.h
1258 	   * Hey, what about an class extension record?
1259 	 */
1260 	savedh = XtHeight(w);
1261 	XtHeight(w) = savedh > curh ? savedh - curh : 0;
1262 	_XmScrolledWPreferredSize(w, child, cg, (XmSWValues *) vals);
1263 	XtHeight(w) = savedh;
1264 
1265 	/* move the SwW to www etc. */
1266 	vals->www = vals->MwW - 2 * SW_MarginWidth(w);
1267 	vals->wwh = vals->MwH - 2 * SW_MarginHeight(w);
1268 
1269 	/* T. Straumann: removed the code that was pasted from ScrolledW;
1270 	   *               instead, we call _XmScrolledWPreferredSize()
1271 	 */
1272 
1273 	curh += vals->wwh;
1274 	if (maxw < vals->www)
1275 	{
1276 	    maxw = vals->www;
1277 	}
1278 
1279     }
1280     while (childNotHappy && maxw != curw);
1281     /*
1282      * T. Straumann
1283      * repeat the child query process based on a new proposed width.
1284      * Consider the following:
1285      * Children are queried proposing a new width (proposed by instigator).
1286      * Child arranges for a height based on new width.
1287      * Another child (the widest one) sets the width of MainW.
1288      * First child doesn't need up the height it requested when the layout
1289      * is done eventually (because the actual width is bigger than the one
1290      * proposed at the time of the query).
1291      */
1292     curw = maxw;
1293 
1294     /* Now count them in */
1295     if (curw > 0)
1296     {
1297 	curw += 2 * SW_MarginWidth(w);
1298     }
1299     if (curh > 0)
1300     {
1301 	curh += 2 * SW_MarginHeight(w);
1302     }
1303 
1304     /* fill in the values */
1305     i = 0;
1306     vals->mbw = chldwh[i].w;
1307     vals->mbh = chldwh[i].h;
1308     i++;
1309     vals->cww = chldwh[i].w;
1310     vals->cwh = chldwh[i].h;
1311     i++;
1312     vals->mww = chldwh[i].w;
1313     vals->mwh = chldwh[i].h;
1314     i++;
1315 
1316     i = 0;
1317     vals->s1w = sepwh[i].w;
1318     vals->s1h = sepwh[i].h;
1319     i++;
1320     vals->s2w = sepwh[i].w;
1321     vals->s2h = sepwh[i].h;
1322     i++;
1323     vals->s3w = sepwh[i].w;
1324     vals->s3h = sepwh[i].h;
1325     i++;
1326 
1327     vals->MwW = (Dimension)curw;
1328     vals->MwH = curh;
1329 }
1330 #undef	Wants
1331 
1332 static XtGeometryResult
_XmMainWindowGeomRequest(Widget w,XmMWValues * vals)1333 _XmMainWindowGeomRequest(Widget w, XmMWValues * vals)
1334 {
1335     XtGeometryResult res;
1336     XtWidgetGeometry geo;
1337 
1338     /*
1339      * MLM: This breaks xmgr.  Don't do this!
1340      * Well, ok, don't use 100x100
1341      * also check out mainw/test12
1342      */
1343 #if 0
1344 #if 0
1345     if (SW_GivenWidth(w) != 0)
1346     {
1347 	vals->MwW = SW_GivenWidth(w);
1348     }
1349 
1350     if (SW_GivenHeight(w) != 0)
1351     {
1352 	vals->MwH = SW_GivenHeight(w);
1353     }
1354 #else
1355     if (!XtIsRealized(w))
1356     {
1357 	if (SW_GivenWidth(w) != 0)
1358 	{
1359 	    vals->MwW = SW_GivenWidth(w);
1360 	}
1361 	if (SW_GivenHeight(w) != 0)
1362 	{
1363 	    vals->MwH = SW_GivenHeight(w);
1364 	}
1365     }
1366 #endif
1367 #endif
1368 
1369     geo.width = vals->MwW;
1370     geo.height = vals->MwH;
1371     geo.request_mode = CWWidth | CWHeight;
1372 
1373     DEBUGOUT(_LtDebug(__FILE__, w,
1374 		      "_XmMainWindowGeomRequests: request geo %s: "
1375 		      "am %d %d given: %d %d\n",
1376 		      _LtDebugWidgetGeometry2String(&geo),
1377 		      XtWidth(w), XtHeight(w),
1378 		      SW_GivenWidth(w), SW_GivenHeight(w)));
1379 
1380     if ((res = _XmMakeGeometryRequest(w, &geo)) == XtGeometryYes)
1381     {
1382 	vals->MwW = geo.width;
1383 	vals->MwH = geo.height;
1384     }
1385     else
1386     {
1387 	vals->MwW = XtWidth(w);
1388 	vals->MwH = XtHeight(w);
1389 
1390 	DEBUGOUT(_LtDebug(__FILE__, w,
1391 			  "_XmMainWindowGeomRequests CONF got %s\n",
1392 			  _LtDebugWidgetGeometry2String(&geo)));
1393     }
1394 
1395     return res;
1396 }
1397 
1398 static void
_XmMainWindowLayout(Widget w,Widget child,XtWidgetGeometry * cg,XmMWValues * vals)1399 _XmMainWindowLayout(Widget w, Widget child, XtWidgetGeometry *cg,
1400 		    XmMWValues * vals)
1401 {
1402     Position curx, cury;
1403     int savedh;
1404 
1405     /*
1406      * Now actually lay out the children.
1407      * Assume that resizing the widget larger than requested grows
1408      * the work area, and similarly with resizes smaller than requested.
1409      */
1410     /* T. Straumann: shadow only around the working area */
1411     curx = SW_MarginWidth(w);
1412     cury = SW_MarginHeight(w);
1413 
1414     if (VALID(MW_MenuBar(w)))
1415     {
1416 	vals->mbx = curx;
1417 	vals->mby = cury;
1418 	vals->mbw = vals->MwW - 2 * SW_MarginWidth(w);
1419 
1420 	cury += vals->mbh;
1421     }
1422 
1423     if (MW_ShowSep(w) && VALID(MW_Sep1(w)))
1424     {
1425 	vals->s1x = curx;
1426 	vals->s1y = cury;
1427 	vals->s1w = vals->MwW - 2 * SW_MarginWidth(w);
1428 
1429 	cury += vals->s1h;
1430     }
1431 
1432     if (MW_CommandLoc(w) == XmCOMMAND_ABOVE_WORKSPACE)
1433     {
1434 	DEBUGOUT(_LtDebug(__FILE__, w,
1435 			  "_XmMainWindowLayout COMMAND_ABOVE_WORKSPACE\n"));
1436 	if (VALID(MW_CommandWindow(w)))
1437 	{
1438 	    vals->cwx = curx;
1439 	    vals->cwy = cury;
1440 	    vals->cww = vals->MwW - 2 * SW_MarginWidth(w);
1441 
1442 	    cury += vals->cwh;
1443 	}
1444 	if (MW_ShowSep(w) && VALID(MW_Sep2(w)))
1445 	{
1446 	    vals->s2x = curx;
1447 	    vals->s2y = cury;
1448 	    vals->s2w = vals->MwW - 2 * SW_MarginWidth(w);
1449 
1450 	    cury += vals->s2h;
1451 	}
1452 
1453 	vals->wwy = cury;
1454 
1455 	/*
1456 	 * Now work from below (in opposite direction) to get to the size
1457 	 * of WorkWindow.
1458 	 */
1459 	cury = vals->MwH - SW_MarginHeight(w);
1460 	if (VALID(MW_MessageWindow(w)))
1461 	{
1462 	    vals->mwx = curx;
1463 	    vals->mwy = cury - vals->mwh;
1464 	    vals->mww = vals->MwW - 2 * SW_MarginWidth(w);
1465 
1466 	    cury = vals->mwy;
1467 	}
1468 	if (MW_ShowSep(w) && VALID(MW_Sep3(w)))
1469 	{
1470 	    vals->s3x = curx;
1471 	    vals->s3y = cury - vals->s3h;
1472 	    vals->s3w = vals->MwW - 2 * SW_MarginWidth(w);
1473 
1474 	    cury = vals->s3y;
1475 	}
1476 
1477 	if (VALID(SW_WorkWindow(w)))
1478 	{
1479 	    vals->wwx = curx;
1480 	    /* Statement to set WWY is moved up to where CURY is still useful */
1481 	    vals->www = vals->MwW - 2 * SW_MarginWidth(w);
1482 	    vals->wwh = cury - vals->wwy;
1483 	}
1484     }
1485     else
1486     {				/* XmCOMMAND_BELOW_WORKSPACE */
1487 	DEBUGOUT(_LtDebug(__FILE__, w,
1488 			  "_XmMainWindowLayout COMMAND_BELOW_WORKSPACE\n"));
1489 	/*
1490 	 * Start working from the bottom immediately, eventually getting
1491 	 * to the WorkWindow which will have to swallow all size changes.
1492 	 */
1493 	vals->wwy = cury;	/* For later on */
1494 	cury = vals->MwH - SW_MarginHeight(w);
1495 
1496 	if (VALID(MW_MessageWindow(w)))
1497 	{
1498 	    cury -= vals->mwh;
1499 
1500 	    vals->mwx = curx;
1501 	    vals->mwy = cury;
1502 	    vals->mww = vals->MwW - 2 * SW_MarginWidth(w);
1503 	}
1504 	if (MW_ShowSep(w) && VALID(MW_Sep3(w)))
1505 	{
1506 	    cury -= vals->s3h;
1507 
1508 	    vals->s3x = curx;
1509 	    vals->s3y = cury;
1510 	    vals->s3w = vals->MwW - 2 * SW_MarginWidth(w);
1511 	}
1512 	if (VALID(MW_CommandWindow(w)))
1513 	{
1514 	    cury -= vals->cwh;
1515 
1516 	    vals->cwx = curx;
1517 	    vals->cwy = cury;
1518 	    vals->cww = vals->MwW - 2 * SW_MarginWidth(w);
1519 	}
1520 	if (MW_ShowSep(w) && VALID(MW_Sep2(w)))
1521 	{
1522 	    cury -= vals->s2h;
1523 
1524 	    vals->s2x = curx;
1525 	    vals->s2y = cury;
1526 	    vals->s2w = vals->MwW - 2 * SW_MarginWidth(w);
1527 	}
1528 
1529 	if (VALID(SW_WorkWindow(w)))
1530 	{
1531 	    vals->wwx = curx;
1532 	    /* See above. wwy = cury; */
1533 	    vals->www = vals->MwW - 2 * SW_MarginWidth(w);
1534 	    vals->wwh = cury - vals->wwy;
1535 	}
1536     }
1537 
1538     savedh = vals->MwH;
1539     vals->MwH = vals->wwy + vals->wwh + SW_MarginHeight(w);
1540     vals->SwY = vals->wwy - SW_MarginHeight(w);
1541     /* T. Straumann: let the ScrolledW do its part of the job
1542      * NOTE: this is _ugly_, should be a method, but alas, we must not
1543      *               add to ScrolledWP.h
1544      * Hey, what about an class extension record?
1545      */
1546     _XmScrolledWLayout(w, child, cg, (XmSWValues *) vals);
1547     vals->MwH = savedh;
1548 
1549     if (child)
1550     {
1551 	if (child == MW_MenuBar(w))
1552 	{
1553 	    cg->x = vals->mbx;
1554 	    cg->y = vals->mby;
1555 	    cg->width = vals->mbw < 0 ? XtWidth(child) : vals->mbw;
1556 	    cg->height = vals->mbh < 0 ? XtHeight(child) : vals->mbh;
1557 	    cg->request_mode = CWWidth | CWHeight | CWX | CWY;
1558 	}
1559 	else if (child == MW_CommandWindow(w))
1560 	{
1561 	    cg->x = vals->cwx;
1562 	    cg->y = vals->cwy;
1563 	    cg->width = vals->cww < 0 ? XtWidth(child) : vals->cww;
1564 	    cg->height = vals->cwh < 0 ? XtHeight(child) : vals->cwh;
1565 	    cg->request_mode = CWWidth | CWHeight | CWX | CWY;
1566 	}
1567 	else if (child == MW_MessageWindow(w))
1568 	{
1569 	    cg->x = vals->mwx;
1570 	    cg->y = vals->mwy;
1571 	    cg->width = vals->mww < 0 ? XtWidth(child) : vals->mww;
1572 	    cg->height = vals->mwh < 0 ? XtHeight(child) : vals->mwh;
1573 	    cg->request_mode = CWWidth | CWHeight | CWX | CWY;
1574 	}
1575 	else if (child == (Widget)MW_Sep1(w))
1576 	{
1577 	    cg->x = vals->s1x;
1578 	    cg->y = vals->s1y;
1579 	    cg->width = vals->s1w < 0 ? XtWidth(child) : vals->s1w;
1580 	    cg->height = vals->s1h < 0 ? XtHeight(child) : vals->s1h;
1581 	    cg->request_mode = CWWidth | CWHeight | CWX | CWY;
1582 	}
1583 	else if (child == (Widget)MW_Sep2(w))
1584 	{
1585 	    cg->x = vals->s2x;
1586 	    cg->y = vals->s2y;
1587 	    cg->width = vals->s2w < 0 ? XtWidth(child) : vals->s2w;
1588 	    cg->height = vals->s2h < 0 ? XtHeight(child) : vals->s2h;
1589 	    cg->request_mode = CWWidth | CWHeight | CWX | CWY;
1590 	}
1591 	else if (child == (Widget)MW_Sep3(w))
1592 	{
1593 	    cg->x = vals->s3x;
1594 	    cg->y = vals->s3y;
1595 	    cg->width = vals->s3w < 0 ? XtWidth(child) : vals->s3w;
1596 	    cg->height = vals->s3h < 0 ? XtHeight(child) : vals->s3h;
1597 	    cg->request_mode = CWWidth | CWHeight | CWX | CWY;
1598 	}
1599 
1600 	DEBUGOUT(_LtDebug2(__FILE__, w, child, "feedback => %s\n",
1601 			   _LtDebugWidgetGeometry2String(cg)));
1602     }
1603 }
1604 
1605 
1606 /* Configure the children, or return their geometry if they're the instigator */
1607 /* T. Straumann: there is no field for borderWidth in vals;
1608  *               however, we can get away with using the value
1609  *               from cg. The only case when the bw is changed seems
1610  *               be a geometry request by a child (e.g. as a consequence
1611  *               of a XtSetValues()). In this case however, we have the
1612  *               new value at hand, namely in cg.
1613  *
1614  *               I also added the child and cg parameters - I don't like
1615  *               macros with this kind of side effects.
1616  */
1617 #define	CONF(wid, xx, yy, ww, hh, child, cg)				\
1618     {								\
1619 	DEBUGOUT(_LtDebug2(__FILE__, w, wid,                    \
1620                            "CONF: x %d y %d w %d h %d\n",   \
1621 			   xx, yy, ww, hh));	\
1622 	if (child && wid == child)		\
1623 	{								\
1624 	    XtX(wid) = (cg->request_mode & CWX ? cg->x : xx);	\
1625 	    XtY(wid) = (cg->request_mode & CWY ? cg->y : yy);	\
1626 		if ( cg->request_mode & CWBorderWidth )				\
1627 		{\
1628 			XtBorderWidth(wid) = cg->border_width;			\
1629 		}\
1630 	    XtWidth(wid) = (cg->request_mode & CWWidth ? cg->width : ww) - 2 * XtBorderWidth(wid);\
1631 	    XtHeight(wid) = (cg->request_mode & CWHeight ? cg->height : hh) - 2 * XtBorderWidth(wid);\
1632 	}								\
1633 	else							\
1634 	{								\
1635 	    _XmConfigureObject(	wid,	\
1636 							xx, yy,	\
1637 							ww - 2 * XtBorderWidth(wid), hh - 2 * XtBorderWidth(wid),\
1638 							XtBorderWidth(wid));			\
1639 	}								\
1640     }
1641 
1642 static void
_XmMainWindowConfigureChildren(Widget w,Widget child,XtWidgetGeometry * cg,XmMWValues * vals)1643 _XmMainWindowConfigureChildren(Widget w, Widget child,
1644 			       XtWidgetGeometry *cg, XmMWValues * vals)
1645 {
1646     if (VALID(MW_MenuBar(w)))
1647     {
1648 	CONF(MW_MenuBar(w), vals->mbx, vals->mby, vals->mbw, vals->mbh, child, cg);
1649     }
1650     if (MW_ShowSep(w) && VALID(MW_Sep1(w)))
1651     {
1652 	CONF((Widget)MW_Sep1(w), vals->s1x, vals->s1y, vals->s1w, vals->s1h, child, cg);
1653     }
1654     if (VALID(MW_CommandWindow(w)))
1655     {
1656 	CONF(MW_CommandWindow(w), vals->cwx, vals->cwy, vals->cww, vals->cwh, child, cg);
1657     }
1658     if (MW_ShowSep(w) && VALID(MW_Sep2(w)))
1659     {
1660 	CONF((Widget)MW_Sep2(w), vals->s2x, vals->s2y, vals->s2w, vals->s2h, child, cg);
1661     }
1662     if (VALID(MW_MessageWindow(w)))
1663     {
1664 	CONF(MW_MessageWindow(w), vals->mwx, vals->mwy, vals->mww, vals->mwh, child, cg);
1665     }
1666     if (MW_ShowSep(w) && VALID(MW_Sep3(w)))
1667     {
1668 	CONF((Widget)MW_Sep3(w), vals->s3x, vals->s3y, vals->s3w, vals->s3h, child, cg);
1669     }
1670 
1671     /* T. Straumann: let the ScrolledW do its part of the job
1672      * NOTE: this is _ugly_, should be a method, but alas, we must not
1673      *               add to ScrolledWP.h
1674      * Hey, what about an class extension record?
1675      */
1676     _XmScrolledWConfigureChildren(w, child, cg, (XmSWValues *) vals);
1677 }
1678 
1679 static XtGeometryResult
geometry_manager(Widget w,XtWidgetGeometry * desired,XtWidgetGeometry * allowed)1680 geometry_manager(Widget w,
1681 		 XtWidgetGeometry *desired,
1682 		 XtWidgetGeometry *allowed)
1683 {
1684     XmMWValues vals;
1685     Widget mw = XtParent(w);
1686     XtWidgetGeometry wants;
1687     XtGeometryResult rval;
1688 
1689     DEBUGOUT(_LtDebug2(__FILE__, XtParent(w), w,
1690 		       "geometry_manager request %s\n",
1691 		       _LtDebugWidgetGeometry2String(desired)));
1692 
1693 #define Wants(flag)     (wants.request_mode & flag)
1694 
1695     wants = *desired;
1696 
1697     if (Wants(XtCWQueryOnly))
1698     {
1699 	DEBUGOUT(_LtDebug(__FILE__, w,
1700 			  "Geometry Mgr Query Only Unimplemented\n"));
1701 	return XtGeometryYes;
1702     }
1703     if (Wants(CWX) || Wants(CWY))
1704 	return XtGeometryNo;
1705 
1706     /*
1707      * Special case: Work Window trying to resize itself in XmAUTOMATIC
1708      * (T. Straumann: copied this from ScrolledW.c; consult comments there)
1709      */
1710     if (SW_ScrollPolicy(mw) == XmAUTOMATIC && w == (Widget)SW_ClipWindow(mw))
1711     {
1712 	DEBUGOUT(_LtDebug2(__FILE__, mw, w,
1713 			   "BEGIN AUTOMATIC FAKE\n\n"));
1714 
1715 	DEBUGOUT(_LtDebug2(__FILE__, mw, w,
1716 			   "geometry_manager: resize WorkWindow: %d %d\n",
1717 			   wants.width, wants.height));
1718 	/* bypass the clipwindow; the _real_ instigator is the work window */
1719 	_XmMainWindowPreferredSize(mw, SW_WorkWindow(mw), &wants, &vals);
1720 	_XmMainWindowLayout(mw, SW_WorkWindow(mw), &wants, &vals);
1721 	_XmMainWindowConfigureChildren(mw, SW_WorkWindow(mw), &wants, &vals);
1722 	DEBUGOUT(_LtDebug2(__FILE__, mw, w, "END AUTOMATIC FAKE\n"));
1723 	/* consult ScrolledW.c about this return value */
1724 	return XtGeometryNo;
1725     }
1726 
1727     /*
1728      * We control the XY of all children.  Width/Height is all I care about
1729      */
1730     _XmMainWindowPreferredSize(mw, w, &wants, &vals);
1731 
1732     /*
1733      * T. Straumann: we have to do the layout before asking the parent
1734      *                               for more space. Otherwise, we may end up with a resized
1735      *               MainW but possibly we'll still reject the child's
1736      *               request after calculating the layout (--> new window, old
1737      *               configuration :-( ).
1738      */
1739     _XmMainWindowLayout(mw, w, &wants, &vals);
1740 
1741     /* T. Straumann: express this a little nicer */
1742     rval = ((Wants(CWWidth) && (wants.width != desired->width))
1743 	    || (Wants(CWHeight) && (wants.height != desired->height))
1744     || (Wants(CWBorderWidth) && (wants.border_width != desired->border_width)))
1745     /*
1746      * Try this : if we have a difference, just report "Almost"
1747      */
1748 #undef DO_RETURN_ALMOST
1749     /* till 26 may 1999; re-enabled the `almost' return value.
1750      * This fixed `thot' and I couldn't observe anything strange
1751      * happening with grace 5.0.2
1752      * amai 20010228: well, situation is that #undefining it
1753      * makes emacs 20.x to start up at least instead of an
1754      * (almost, finished by crash probably) endless loop.
1755      * Grace 5.1.x (CVS) seems to be still happy, I played with the
1756      * Zoom function - no problem showed up. I haven't checked
1757      * Thot so far.
1758      */
1759 #ifdef DO_RETURN_ALMOST
1760     /* rws 20 Nov 1998
1761        This is causing tons of second request refused messages in xmgrace
1762        if you click on the Zoom button and then move the cursor around
1763        the work space
1764      */
1765 	? XtGeometryAlmost : XtGeometryYes;
1766 #else
1767 	? XtGeometryNo : XtGeometryYes;
1768 #endif
1769 
1770     if (XtGeometryYes == rval)
1771     {
1772 	/* FIX ME: Pay attention to return code? */
1773 	if (_XmMainWindowGeomRequest(mw, &vals) == XtGeometryYes)
1774 	{
1775 	    /* ok, apply the new layout */
1776 	}
1777 	else
1778 	{
1779 	    /* sigh... they didn't allow the size change. The new layout is actually
1780 	     * a resize...
1781 	     */
1782 	    SW_FromResize(mw) = True;
1783 	    _XmMainWindowPreferredSize(mw, w, &wants, &vals);
1784 	    vals.MwW = XtWidth(mw);
1785 	    vals.MwH = XtHeight(mw);
1786 	    _XmMainWindowLayout(mw, w, &wants, &vals);
1787 	    SW_FromResize(mw) = False;
1788 	    rval = ((Wants(CWWidth) && (wants.width != desired->width))
1789 		    || (Wants(CWHeight) && (wants.height != desired->height))
1790 		    || (Wants(CWBorderWidth) && (wants.border_width != desired->border_width)))
1791 #ifdef DO_RETURN_ALMOST
1792 		? XtGeometryAlmost : XtGeometryYes;
1793 #else
1794 		? XtGeometryNo : XtGeometryYes;
1795 #endif
1796 	}
1797     }
1798 
1799     /* T. Straumann: we are also able to manage the border width */
1800     wants.request_mode = desired->request_mode & (CWWidth | CWHeight | CWBorderWidth);
1801 
1802     *allowed = wants;
1803 
1804 
1805     if (rval == XtGeometryYes)
1806     {
1807 	_XmMainWindowConfigureChildren(mw, w, &wants, &vals);
1808     }
1809     else if (rval == XtGeometryAlmost)
1810     {
1811 	DEBUGOUT(_LtDebug2(__FILE__, mw, w,
1812 		       "geometry_manager : child wants %s gets %s => Almost\n",
1813 			   _LtDebugWidgetGeometry2String(&wants),
1814 			   _LtDebugWidgetGeometry2String(desired)));
1815     }
1816 
1817     /* Strip off unwanted bits */
1818 
1819     allowed->request_mode &= wants.request_mode;
1820     if (allowed->request_mode & CWX && desired->x == allowed->x)
1821     {
1822     	allowed->request_mode &= ~CWX;
1823     }
1824     if (allowed->request_mode & CWY && desired->y == allowed->y)
1825     {
1826     	allowed->request_mode &= ~CWY;
1827     }
1828     if (allowed->request_mode & CWWidth && desired->width == allowed->width)
1829     {
1830     	allowed->request_mode &= ~CWWidth;
1831     }
1832     if (allowed->request_mode & CWHeight && desired->height == allowed->height)
1833     {
1834     	allowed->request_mode &= ~CWHeight;
1835     }
1836     return rval;
1837 #undef	Wants
1838 }
1839 
1840 Widget
XmCreateMainWindow(Widget parent,char * name,Arg * argList,Cardinal argcount)1841 XmCreateMainWindow(Widget parent,
1842 		   char *name,
1843 		   Arg *argList,
1844 		   Cardinal argcount)
1845 {
1846     return XtCreateWidget(name,
1847 			  xmMainWindowWidgetClass,
1848 			  parent,
1849 			  argList, argcount);
1850 
1851 }
1852 
1853 Widget
XmMainWindowSep1(Widget widget)1854 XmMainWindowSep1(Widget widget)
1855 {
1856     return (Widget)MW_Sep1(widget);
1857 }
1858 
1859 Widget
XmMainWindowSep2(Widget widget)1860 XmMainWindowSep2(Widget widget)
1861 {
1862     return (Widget)MW_Sep2(widget);
1863 }
1864 
1865 Widget
XmMainWindowSep3(Widget widget)1866 XmMainWindowSep3(Widget widget)
1867 {
1868     return (Widget)MW_Sep3(widget);
1869 }
1870 
1871 void
XmMainWindowSetAreas(Widget widget,Widget menu_bar,Widget command_window,Widget horizontal_scrollbar,Widget vertical_scrollbar,Widget work_region)1872 XmMainWindowSetAreas(Widget widget,
1873 		     Widget menu_bar,
1874 		     Widget command_window,
1875 		     Widget horizontal_scrollbar,
1876 		     Widget vertical_scrollbar,
1877 		     Widget work_region)
1878 {
1879     Pixel trough;
1880     Arg args[5];
1881     int n = 0;
1882 
1883     DEBUGOUT(_LtDebug(__FILE__, widget, "XmMainWindowSetAreas ["));
1884 
1885 #define	P(cw, t)						\
1886     if (cw)							\
1887 	{ DEBUGOUT(_LtDebug0(__FILE__, widget, t, XtName(cw))); }\
1888     else							\
1889 	{ DEBUGOUT(_LtDebug0(__FILE__, widget, t, ": NULL")); }
1890 
1891     P(menu_bar, " MenuBar %s");
1892     P(command_window, " CommandWindow %s");
1893     P(horizontal_scrollbar, " Hor.Scrollbar %s");
1894     P(vertical_scrollbar, " Vert.Scrollbar %s");
1895     P(work_region, " WorkRegion %s");
1896     DEBUGOUT(_LtDebug0(__FILE__, widget, "]\n"));
1897 
1898 #if 1
1899     if (menu_bar)
1900     {
1901     	XtSetArg(args[n], XmNmenuBar, menu_bar); n++;
1902     }
1903     if (command_window)
1904     {
1905     	XtSetArg(args[n], XmNcommandWindow, command_window); n++;
1906     }
1907     if (work_region)
1908     {
1909     	XtSetArg(args[n], XmNworkWindow, work_region); n++;
1910     }
1911     if (horizontal_scrollbar)
1912     {
1913     	XtSetArg(args[n], XmNhorizontalScrollBar, horizontal_scrollbar); n++;
1914     }
1915     if (vertical_scrollbar)
1916     {
1917     	XtSetArg(args[n], XmNverticalScrollBar, vertical_scrollbar); n++;
1918     }
1919 
1920     XtSetValues(widget, args, n);
1921 #else
1922     /* rws 11 Sep 1999
1923        This is _way_ too simplistic. Take a look at set_values. We need to
1924        take into account the re-parenting of the work window!!!!!
1925      */
1926     if (menu_bar)
1927     {
1928 	MW_MenuBar(widget) = menu_bar;
1929 
1930 	if (menu_bar == MW_MessageWindow(widget))
1931 	{
1932 	    MW_MessageWindow(widget) = NULL;
1933 	}
1934     }
1935     if (command_window)
1936     {
1937 	MW_CommandWindow(widget) = command_window;
1938 	if (command_window == MW_MessageWindow(widget))
1939 	{
1940 	    MW_MessageWindow(widget) = NULL;
1941 	}
1942     }
1943     if (work_region)
1944     {
1945 	SW_WorkWindow(widget) = work_region;
1946 	if (work_region == MW_MessageWindow(widget))
1947 	{
1948 	    MW_MessageWindow(widget) = NULL;
1949 	}
1950     }
1951     if (horizontal_scrollbar)
1952     {
1953 	SW_HSB(widget) = (XmScrollBarWidget)horizontal_scrollbar;
1954 	if (horizontal_scrollbar == MW_MessageWindow(widget))
1955 	{
1956 	    MW_MessageWindow(widget) = NULL;
1957 	}
1958     }
1959     if (vertical_scrollbar)
1960     {
1961 	SW_VSB(widget) = (XmScrollBarWidget)vertical_scrollbar;
1962 	if (vertical_scrollbar == MW_MessageWindow(widget))
1963 	{
1964 	    MW_MessageWindow(widget) = NULL;
1965 	}
1966     }
1967 #endif
1968 
1969     if (horizontal_scrollbar || vertical_scrollbar)
1970     {
1971 	XmGetColors(XtScreen(widget), CoreColormap(widget),
1972 		    XtBackground(widget), NULL, NULL, NULL, &trough);
1973     }
1974 
1975     if (horizontal_scrollbar)
1976     {
1977 	XtVaSetValues(horizontal_scrollbar,
1978 		      XmNforeground, MGR_Foreground(widget),
1979 		      XmNbackground, XtBackground(widget),
1980 		      XmNtroughColor, trough,
1981 		      XmNtopShadowColor, MGR_TopShadowColor(widget),
1982 		      XmNtopShadowPixmap, MGR_TopShadowPixmap(widget),
1983 		      XmNbottomShadowColor, MGR_BottomShadowColor(widget),
1984 		      XmNbottomShadowPixmap, MGR_BottomShadowPixmap(widget),
1985 		      NULL);
1986     }
1987     if (vertical_scrollbar)
1988     {
1989 	XtVaSetValues(vertical_scrollbar,
1990 		      XmNforeground, MGR_Foreground(widget),
1991 		      XmNbackground, XtBackground(widget),
1992 		      XmNtroughColor, trough,
1993 		      XmNtopShadowColor, MGR_TopShadowColor(widget),
1994 		      XmNtopShadowPixmap, MGR_TopShadowPixmap(widget),
1995 		      XmNbottomShadowColor, MGR_BottomShadowColor(widget),
1996 		      XmNbottomShadowPixmap, MGR_BottomShadowPixmap(widget),
1997 		      NULL);
1998     }
1999 
2000 #if 0
2001     if (XtIsRealized(widget))
2002     {
2003 	XmMWValues vals;
2004 
2005 	_XmMainWindowPreferredSize(widget, NULL, NULL, &vals);
2006 
2007 	_XmMainWindowGeomRequest(widget, &vals);
2008 
2009 	_XmMainWindowLayout(widget, NULL, NULL, &vals);
2010 
2011 	_XmMainWindowConfigureChildren(widget, NULL, NULL, &vals);
2012     }
2013 #else
2014 #endif
2015 }
2016 
2017 static void
insert_child(Widget w)2018 insert_child(Widget w)
2019 {
2020     Widget p = XtParent(w);
2021 
2022     if ((XmIsRowColumn(w) && RC_Type(w) == XmMENU_BAR) ||
2023 	XmIsSeparator(w) || XmIsSeparatorGadget(w))
2024     {
2025 #define	superclass	(&xmManagerClassRec)
2026 	(*superclass->composite_class.insert_child) (w);
2027 #undef	superclass
2028 
2029 	if (XmIsRowColumn(w) && RC_Type(w) == XmMENU_BAR)
2030 	{
2031 	    DEBUGOUT(_LtDebug2(__FILE__, p, w,
2032 			       "insert_child : this is the menu bar\n"));
2033 	    MW_MenuBar(p) = w;
2034 	}
2035 	else if (XmIsSeparator(w) || XmIsSeparatorGadget(w))
2036 	{
2037 	    DEBUGOUT(_LtDebug2(__FILE__, p, w,
2038 			       "insert_child : this is a separator\n"));
2039 	}
2040 	else if (MW_MessageWindow(p) == NULL &&
2041 		 w != MW_CommandWindow(p) &&
2042 		 w != MW_MenuBar(p) &&
2043 		 w != SW_WorkWindow(p) &&
2044 		 w != (Widget)SW_ClipWindow(p) &&
2045 		 w != (Widget)SW_HSB(p) &&
2046 		 w != (Widget)SW_VSB(p))
2047 	{
2048 	    DEBUGOUT(_LtDebug2(__FILE__, p, w,
2049 			       "insert_child : this is the message window\n"));
2050 	    MW_MessageWindow(p) = w;
2051 	}
2052     }
2053     else
2054     {
2055 	/*
2056 	 * Now we have a scrollbar or a workwindow - let scrolledwindow
2057 	 * handle this
2058 	 */
2059 #define	superclass	(&xmScrolledWindowClassRec)
2060 	(*superclass->composite_class.insert_child) (w);
2061 #undef	superclass
2062 
2063 	if (MW_MessageWindow(p) == NULL &&
2064 	    w != MW_CommandWindow(p) &&
2065 	    w != MW_MenuBar(p) &&
2066 	    w != SW_WorkWindow(p) &&
2067 	    w != (Widget)SW_ClipWindow(p) &&
2068 	    w != (Widget)SW_HSB(p) &&
2069 	    w != (Widget)SW_VSB(p))
2070 	{
2071 	    DEBUGOUT(_LtDebug2(__FILE__, p, w,
2072 			       "insert_child : this is the message window\n"));
2073 	    MW_MessageWindow(p) = w;
2074 	}
2075     }
2076 }
2077 
2078 static void
delete_child(Widget w)2079 delete_child(Widget w)
2080 {
2081 	Widget	mw = XtParent(w);
2082 
2083 	DEBUGOUT(_LtDebug2(__FILE__, mw, w, "DeleteChild\n"));
2084 
2085 #define	superclass	(&xmScrolledWindowClassRec)
2086 	(*superclass->composite_class.delete_child) (w);
2087 #undef	superclass
2088 
2089 	if (w == MW_MenuBar(mw))
2090 		MW_MenuBar(mw) = NULL;
2091 	else if (w == MW_CommandWindow(mw))
2092 		MW_CommandWindow(mw) = NULL;
2093 	else if (w == MW_MessageWindow(mw))
2094 		MW_MessageWindow(mw) = NULL;
2095 	else if (w == SW_WorkWindow(mw))
2096 		SW_WorkWindow(mw) = NULL;
2097 	else if (w == (Widget)SW_ClipWindow(mw))
2098 		SW_ClipWindow(mw) = NULL;
2099 	else if (w == (Widget)SW_HSB(mw))
2100 		SW_HSB(mw) = NULL;
2101 	else if (w == (Widget)SW_VSB(mw))
2102 		SW_VSB(mw) = NULL;
2103 }
2104