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