1 /*
2  * Motif
3  *
4  * Copyright (c) 1987-2012, The Open Group. All rights reserved.
5  *
6  * These libraries and programs are free software; you can
7  * redistribute them and/or modify them under the terms of the GNU
8  * Lesser General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * These libraries and programs are distributed in the hope that
13  * they will be useful, but WITHOUT ANY WARRANTY; without even the
14  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  * PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these librararies and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22 */
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26 
27 
28 #ifdef REV_INFO
29 #ifndef lint
30 static char rcsid[] = "$XConsortium: MainW.c /main/20 1996/10/17 15:21:07 cde-osf $"
31 #endif
32 #endif
33 
34 #include "XmI.h"
35 #include <Xm/SeparatoGP.h>  /* just access the position/dimension fields,*/
36 #include <Xm/ScrollBarP.h>  /*   could live without that if needed */
37 #include <Xm/MainWP.h>
38 #include <Xm/VaSimpleP.h>
39 #include <Xm/MenuT.h>
40 #include <Xm/TraitP.h>
41 #include "MessagesI.h"
42 #include "RepTypeI.h"
43 #include "GeoUtilsI.h"
44 
45 #define MWMessage1	_XmMMsgMainW_0000
46 #define MWMessage2	_XmMMsgMainW_0001
47 
48 #define ExistManaged( wid)      (wid && XtIsManaged( wid))
49 
50 #define DEFAULT_SIZE 50
51 
52 /********    Static Function Declarations    ********/
53 
54 static void ClassPartInitialize(
55                         WidgetClass wc) ;
56 static void Initialize(
57                         Widget rw,
58                         Widget nw,
59                         ArgList args,
60                         Cardinal *num_args) ;
61 static void DeleteChild(
62                         Widget w) ;
63 static void InsertChild(
64                         Widget w) ;
65 static void Layout(
66                         XmMainWindowWidget mw) ;
67 static void Resize(
68                         Widget wid) ;
69 static void GetSize(
70                         XmMainWindowWidget mw,
71 	                Dimension *pwidth,
72                         Dimension *pheight) ;
73 static XtGeometryResult GeometryManager(
74                         Widget w,
75                         XtWidgetGeometry *request,
76                         XtWidgetGeometry *reply) ;
77 static void ChangeManaged(
78                         Widget wid) ;
79 static Boolean SetValues(
80                         Widget cw,
81                         Widget rw,
82                         Widget nw,
83                         ArgList args,
84                         Cardinal *num_args) ;
85 static void GetVertRects(
86 			Widget sw,
87 			XRectangle ** vrect,
88 			Cardinal * num_vrect);
89 
90 static void CheckKids(
91 			XmMainWindowWidget mw);
92 
93 /********    End Static Function Declarations    ********/
94 
95 
96 
97 
98 /************************************************************************
99  *									*
100  * Main Window Resources						*
101  *									*
102  ************************************************************************/
103 
104 static XtResource resources[] =
105 {
106     {
107 	XmNcommandWindow, XmCCommandWindow, XmRWidget, sizeof(Widget),
108         XtOffsetOf(XmMainWindowRec, mwindow.CommandWindow),
109 	XmRImmediate, NULL
110     },
111     {
112 	XmNcommandWindowLocation, XmCCommandWindowLocation,
113         XmRCommandWindowLocation, sizeof(unsigned char),
114         XtOffsetOf(XmMainWindowRec, mwindow.CommandLoc),
115 	XmRImmediate, (XtPointer) XmCOMMAND_ABOVE_WORKSPACE
116     },
117     {
118 	XmNmenuBar, XmCMenuBar, XmRWidget, sizeof(Widget),
119         XtOffsetOf(XmMainWindowRec, mwindow.MenuBar),
120 	XmRImmediate, NULL
121     },
122     {
123 	XmNmessageWindow, XmCMessageWindow, XmRWidget, sizeof(Widget),
124         XtOffsetOf(XmMainWindowRec, mwindow.Message),
125 	XmRImmediate, NULL
126     },
127     {
128         XmNmainWindowMarginWidth, XmCMainWindowMarginWidth,
129         XmRHorizontalDimension, sizeof (Dimension),
130         XtOffsetOf(XmMainWindowRec, mwindow.margin_width),
131 	XmRImmediate, (XtPointer) 0
132     },
133     {
134         XmNmainWindowMarginHeight, XmCMainWindowMarginHeight,
135         XmRVerticalDimension, sizeof (Dimension),
136         XtOffsetOf(XmMainWindowRec, mwindow.margin_height),
137 	XmRImmediate, (XtPointer) 0
138     },
139     {
140 	XmNshowSeparator, XmCShowSeparator, XmRBoolean, sizeof(Boolean),
141         XtOffsetOf(XmMainWindowRec, mwindow.ShowSep),
142 	XmRImmediate, (XtPointer) False
143     }
144 };
145 
146 /****************
147  *
148  * Resolution independent resources
149  *
150  ****************/
151 
152 static XmSyntheticResource syn_resources[] =
153 {
154    { XmNmainWindowMarginWidth,
155      sizeof (Dimension),
156      XtOffsetOf(XmMainWindowRec, mwindow.margin_width),
157      XmeFromHorizontalPixels, XmeToHorizontalPixels },
158 
159    { XmNmainWindowMarginHeight,
160      sizeof (Dimension),
161      XtOffsetOf(XmMainWindowRec, mwindow.margin_height),
162      XmeFromVerticalPixels, XmeToVerticalPixels },
163 
164 };
165 
166 /*******************************************/
167 /*  Declaration of class extension records */
168 /*******************************************/
169 
170 static XmScrolledWindowClassExtRec scrolled_windowClassExtRec = {
171     NULL,
172     NULLQUARK,
173     XmScrolledWindowClassExtVersion,
174     sizeof(XmScrolledWindowClassExtRec),
175     NULL,                              /* inherit get_hor_rects */
176     GetVertRects,                      /* overide get_vert_rects */
177 };
178 
179 
180 /****************************************************************
181  *
182  * Full class record constant
183  *
184  ****************************************************************/
185 
186 externaldef(xmmainwindowclassrec) XmMainWindowClassRec xmMainWindowClassRec = {
187   {
188 /* core_class fields      */
189     /* superclass         */    (WidgetClass) &xmScrolledWindowClassRec,
190     /* class_name         */    "XmMainWindow",
191     /* widget_size        */    sizeof(XmMainWindowRec),
192     /* class_initialize   */    NULL,
193     /* class_partinit     */    ClassPartInitialize,
194     /* class_inited       */	False,
195     /* initialize         */    Initialize,
196     /* Init hook	  */    NULL,
197     /* realize            */    XtInheritRealize,
198     /* actions		  */	NULL,
199     /* num_actions	  */	0,
200     /* resources          */    resources,
201     /* num_resources      */    XtNumber(resources),
202     /* xrm_class          */    NULLQUARK,
203     /* compress_motion	  */	True,
204     /* compress_exposure  */	XtExposeCompressSeries,
205     /* compress_enterleave*/	True,
206     /* visible_interest   */    False,
207     /* destroy            */    NULL,
208     /* resize             */    Resize,
209     /* expose             */    XtInheritExpose,
210     /* set_values         */    SetValues,
211     /* set values hook    */    NULL,
212     /* set values almost  */    XtInheritSetValuesAlmost,
213     /* get values hook    */    NULL,
214     /* accept_focus       */    NULL,
215     /* Version            */    XtVersion,
216     /* PRIVATE cb list    */    NULL,
217     /* tm_table		  */    XtInheritTranslations,
218     /* query_geometry     */    NULL,
219     /* display_accelerator*/    NULL,
220     /* extension          */    NULL,
221   },
222   {
223 /* composite_class fields */
224     /* geometry_manager   */    GeometryManager,
225     /* change_managed     */    ChangeManaged,
226     /* insert_child	  */	InsertChild,
227     /* delete_child	  */	DeleteChild,
228     /* Extension          */    NULL,
229   },{
230 /* Constraint class Init */
231     NULL,
232     0,
233     sizeof (XmScrolledWindowConstraintRec),
234     NULL,
235     NULL,
236     NULL,
237     NULL
238 
239   },
240 /* Manager Class */
241    {
242       XtInheritTranslations,    		/* translations        */
243       syn_resources,				/* get resources      	  */
244       XtNumber(syn_resources),			/* num get_resources 	  */
245       NULL,					/* get_cont_resources     */
246       0,					/* num_get_cont_resources */
247       XmInheritParentProcess,                   /* parent_process         */
248       NULL,					/* extension           */
249    },
250 
251  {
252 /* Scrolled Window class */
253     (XtPointer) &scrolled_windowClassExtRec,    /* auto drag extension */
254  },
255  {
256 /* Main Window class - just the extension pointer */
257      /* extension */            (XtPointer) NULL
258  }
259 };
260 
261 externaldef(xmmainwindowwidgetclass) WidgetClass
262              xmMainWindowWidgetClass = (WidgetClass)&xmMainWindowClassRec;
263 
264 
265 
266 
267 /************************************************************************
268  *									*
269  *  ClassPartInitialize - Set up the fast subclassing.			*
270  *									*
271  ************************************************************************/
272 static void
ClassPartInitialize(WidgetClass wc)273 ClassPartInitialize(
274         WidgetClass wc )
275 {
276    _XmFastSubclassInit (wc, XmMAIN_WINDOW_BIT);
277 }
278 
279 
280 /************************************************************************
281  *									*
282  *  Initialize								*
283  *									*
284  ************************************************************************/
285 /* ARGSUSED */
286 static void
Initialize(Widget rw,Widget nw,ArgList args,Cardinal * num_args)287 Initialize(
288         Widget rw,
289         Widget nw,
290         ArgList args,
291         Cardinal *num_args )
292 {
293     XmMainWindowWidget new_w = (XmMainWindowWidget) nw ;
294     int   n;
295     Arg loc_args[20];
296 
297 
298     /* First, undo our superclass defaulting to a real size in
299        AUTOMATIC mode, because MainWindow can build a real size
300        out of its children in AUTOMATIC */
301     if (new_w->swindow.ScrollPolicy == XmAUTOMATIC) {
302 	if ((rw->core.width == 0) && new_w->core.width)
303 	    new_w->core.width = 0 ;
304 	if ((rw->core.height == 0) && new_w->core.height)
305 	    new_w->core.height = 0 ;
306     }
307 
308     if (!XmRepTypeValidValue(XmRID_COMMAND_WINDOW_LOCATION,
309 			    new_w->mwindow.CommandLoc, nw))
310         new_w->mwindow.CommandLoc = XmCOMMAND_ABOVE_WORKSPACE;
311 
312     n = 0;
313     XtSetArg (loc_args[n], XmNorientation, XmHORIZONTAL); n++;
314     XtSetArg (loc_args[n], XmNscrolledWindowChildType, XmSEPARATOR); n++;
315 
316     new_w->mwindow.ManagingSep = True ;
317 
318     new_w->mwindow.Sep1 = (XmSeparatorGadget)
319 	XtCreateManagedWidget("Separator1", xmSeparatorGadgetClass,
320 			      nw, loc_args, n);
321     new_w->mwindow.Sep2 = (XmSeparatorGadget)
322 	XtCreateManagedWidget("Separator2", xmSeparatorGadgetClass,
323 			      nw, loc_args, n);
324     new_w->mwindow.Sep3 = (XmSeparatorGadget)
325 	XtCreateManagedWidget("Separator3", xmSeparatorGadgetClass,
326 			      nw, loc_args, n);
327 
328     new_w->mwindow.ManagingSep = False ;
329 
330     /* override the SW setting here */
331     new_w->swindow.XOffset = new_w->mwindow.margin_width;
332     new_w->swindow.YOffset = new_w->mwindow.margin_height;
333     new_w->swindow.WidthPad = new_w->mwindow.margin_width;
334     new_w->swindow.HeightPad = new_w->mwindow.margin_height;
335 }
336 
337 
338 /************************************************************************
339  *									*
340  *  DeleteChild								*
341  *									*
342  ************************************************************************/
343 /* ARGSUSED */
344 static void
DeleteChild(Widget child)345 DeleteChild(
346         Widget child)
347 {
348     XmMainWindowWidget mw = (XmMainWindowWidget) XtParent(child);
349     CompositeWidgetClass superclass = (CompositeWidgetClass)
350 	                xmMainWindowClassRec.core_class.superclass ;
351     XtWidgetProc      delete_child;
352 
353     /* update our own internals first */
354     if (child == mw->mwindow.CommandWindow)
355         mw->mwindow.CommandWindow = NULL;
356     if (child == mw->mwindow.MenuBar)
357         mw->mwindow.MenuBar = NULL;
358     if (child == mw->mwindow.Message)
359         mw->mwindow.Message = NULL;
360 
361     _XmProcessLock();
362     delete_child = superclass->composite_class.delete_child;
363     _XmProcessUnlock();
364     (*delete_child)(child);
365 }
366 
367 static void
CheckKids(XmMainWindowWidget mw)368 CheckKids(
369         XmMainWindowWidget mw )
370 {
371 
372     /* do a sanity check */
373     if( mw->swindow.WorkWindow != NULL &&
374        mw->swindow.WorkWindow->core.being_destroyed ) {
375 	mw->swindow.WorkWindow = NULL;
376     }
377     if( mw->swindow.hScrollBar != NULL &&
378        mw->swindow.hScrollBar->core.being_destroyed ) {
379 	mw->swindow.hScrollBar = NULL;
380     }
381     if( mw->swindow.vScrollBar != NULL &&
382        mw->swindow.vScrollBar->core.being_destroyed ) {
383 	mw->swindow.vScrollBar = NULL;
384     }
385     if( mw->mwindow.CommandWindow != NULL &&
386        mw->mwindow.CommandWindow->core.being_destroyed ) {
387 	mw->mwindow.CommandWindow = NULL;
388     }
389     if( mw->mwindow.MenuBar != NULL &&
390        mw->mwindow.MenuBar->core.being_destroyed ) {
391 	mw->mwindow.MenuBar = NULL;
392     }
393     if( mw->mwindow.Message != NULL &&
394        mw->mwindow.Message->core.being_destroyed ) {
395 	mw->mwindow.Message = NULL;
396     }
397 }
398 
399 
400 
401 /************************************************************************
402  *									*
403  *  InsertChild								*
404  *									*
405  ************************************************************************/
406 static void
InsertChild(Widget w)407 InsertChild(
408         Widget w )
409 {
410     CompositeWidgetClass superclass = (CompositeWidgetClass)
411 	                xmMainWindowClassRec.core_class.superclass ;
412     XmMainWindowWidget   mw = (XmMainWindowWidget ) w->core.parent;
413     XmScrolledWindowConstraint nc = GetSWConstraint(w);
414     XtWidgetProc insert_child;
415 
416     if (!XtIsRectObj(w)) return;
417 
418 
419     /* Try to guess the nature of the child_type .
420        If we're lucky, fine, otherwise, something bad might happens: the
421        scrolledwindow can take it as a workwindow and possibly reparents
422        it to the clipwindow.
423        In the absence of a set childType constraint resource set,
424        there is not much we can do to avoid the problem */
425     /* Note: auto created Separator were already labelled in Initialize */
426 
427     if (nc->child_type == (unsigned char) RESOURCE_DEFAULT) {
428 	XmMenuSystemTrait menuSTrait;
429 
430 	if ((menuSTrait = (XmMenuSystemTrait)
431 	     XmeTraitGet ((XtPointer) XtClass(w), XmQTmenuSystem)) != NULL) {
432 	    if (menuSTrait->type(w) == XmMENU_BAR &&
433 		!mw->mwindow.MenuBar) {
434 		/* If it's a menubar, and we don't have one yet, use it. */
435 		nc->child_type = XmMENU_BAR ;
436 	    }
437 	}  else
438 
439 	if (XmIsCommandBox(w)) {
440 	    if (!mw->mwindow.CommandWindow)   {
441 		/* If it's a command, and we don't have one, get it */
442 		nc->child_type = XmCOMMAND_WINDOW ;
443 	    }
444 	} else
445 
446 	    /* new in 2.0 */
447 	if (XmIsMessageBox(w)) {
448 	    if (!mw->mwindow.Message)   {
449 		nc->child_type = XmMESSAGE_WINDOW ;
450 	    }
451 	}
452     }
453 
454     if (nc->child_type == XmMENU_BAR) {
455 	mw->mwindow.MenuBar = w;
456     } else
457     if (nc->child_type == XmCOMMAND_WINDOW) {
458 	mw->mwindow.CommandWindow = w;
459     } else
460     if (nc->child_type == XmMESSAGE_WINDOW) {
461 	mw->mwindow.Message = w;
462     }
463 
464     /* call ScrolledWindow InsertChild directly, since it does nothing
465        to the MainWindow known childType */
466     _XmProcessLock();
467     insert_child = superclass->composite_class.insert_child;
468     _XmProcessUnlock();
469     (*insert_child)(w);
470 
471 }
472 
473 
474 /************************************************************************
475  *									*
476  * Layout - Layout the main window.					*
477  *                                                                      *
478  *									*
479  ************************************************************************/
480 static void
Layout(XmMainWindowWidget mw)481 Layout(
482         XmMainWindowWidget mw )
483 {
484     Position mbx,mby, cwx,cwy, swy, mwx, mwy, sepy, sep2y = 0;
485     Dimension mbwidth, mbheight, cwwidth= 0, cwheight;
486     Dimension MyXpad, MyYpad, mwwidth, mwheight;
487     Dimension	bw = 0, sep2h, sep3h;
488     XtWidgetGeometry  desired, preferred;
489     int tmp ; /* used for checking negative Dimension value */
490 
491 
492     CheckKids(mw);
493 
494 /****************
495  *
496  * Query the kids - and we have definite preferences as to their sizes.
497  * The Menubar gets top billing - we tell it it how wide it is going to be ,
498  * and let it have whatever height it wants. The command box gets to stay
499  * it's current height, but has to go to the new width. The scrolled window
500  * gets the leftovers.
501  *
502  ****************/
503     MyXpad = mw->mwindow.margin_width;
504     MyYpad = mw->mwindow.margin_height;
505 
506     mw->swindow.XOffset = MyXpad;
507     mw->swindow.YOffset = MyYpad;
508     mw->swindow.HeightPad = mw->mwindow.margin_height;
509     mw->swindow.WidthPad = mw->mwindow.margin_width;
510 
511     cwx = MyXpad;
512     cwy = swy = MyYpad;
513     mw->mwindow.ManagingSep = True;
514     if (ExistManaged(mw->mwindow.MenuBar))
515     {
516 	bw = mw->mwindow.MenuBar->core.border_width;
517 	mbx = MyXpad;
518 	mby = MyYpad;
519 	tmp = mw->core.width - (2 * (MyXpad + bw));
520 	if (tmp <= 0) mbwidth = 10; else  mbwidth = tmp ;
521 	mbheight = mw->mwindow.MenuBar->core.height;
522 
523 	desired.x = mbx;
524 	desired.y = mby;
525 	desired.border_width = bw;
526         desired.width = mbwidth;
527         desired.height = mbheight;
528         desired.request_mode = (CWWidth);
529         if (XtQueryGeometry(mw->mwindow.MenuBar, &desired, &preferred)
530 	    != XtGeometryYes) {
531    	    bw = preferred.border_width;
532 	    mbheight = preferred.height;
533         }
534         XmeConfigureObject(mw->mwindow.MenuBar, mbx, mby,
535 			   mbwidth, mbheight,bw);
536 
537         if (mw->mwindow.ShowSep)
538         {
539 	    XtManageChild((Widget) mw->mwindow.Sep1);
540             XmeConfigureObject( (Widget) mw->mwindow.Sep1, 0,
541 			       mby + mbheight + (2 * bw),
542 	        	       mw->core.width,
543 			       mw->mwindow.Sep1->rectangle.height, 0);
544             cwy = swy = mw->mwindow.Sep1->rectangle.y +
545 		mw->mwindow.Sep1->rectangle.height ;
546         }
547         else
548         {
549             XtUnmanageChild((Widget) mw->mwindow.Sep1);
550             cwy = swy = mby + mbheight + (2 * bw);
551         }
552     }
553     else
554     {
555 	XtUnmanageChild((Widget) mw->mwindow.Sep1);
556     }
557 
558     if (ExistManaged(mw->mwindow.CommandWindow))
559     {
560         bw = mw->mwindow.CommandWindow->core.border_width;
561 	tmp = mw->core.width - (2 * (MyXpad + bw));
562 	if (tmp <= 0) cwwidth = 10; else cwwidth = tmp ;
563 	cwheight = mw->mwindow.CommandWindow->core.height;
564 
565 	desired.x = cwx;
566 	desired.y = cwy;
567 	desired.border_width = bw;
568         desired.width = cwwidth;
569         desired.height = cwheight;
570         desired.request_mode = (CWWidth);
571         if (XtQueryGeometry(mw->mwindow.CommandWindow, &desired, &preferred)
572             != XtGeometryYes)
573         {
574    	    bw = preferred.border_width;
575 	    cwheight = preferred.height;
576         }
577 
578         if ((cwheight + cwy + (2 * bw)) > (mw->core.height - MyYpad)) {
579 	    tmp = mw->core.height - (2 * bw) - MyYpad - cwy;
580 	    if (tmp <= 0) cwheight = 10 ; else cwheight = tmp;
581 	}
582 
583         if (mw->mwindow.ShowSep)
584             sep2h = mw->mwindow.Sep2->rectangle.height;
585         else
586             sep2h = 0;
587 
588         sep2y = (cwy +  cwheight) + 2 * bw;
589         swy = sep2y + sep2h ;
590 
591         if (mw->mwindow.CommandLoc == XmCOMMAND_BELOW_WORKSPACE)
592         {
593             mby = swy;
594             sep2y = cwy + (mw->core.height - swy - MyYpad);
595             swy = cwy;
596             mw->swindow.HeightPad = sep2h + cwheight
597 		+ mw->mwindow.margin_height;
598             if (mw->mwindow.ShowSep)
599                 cwy = sep2y + mw->mwindow.Sep2->rectangle.height;
600             else
601                 cwy = sep2y;
602         }
603     }
604     else
605     {
606 	XtUnmanageChild((Widget) mw->mwindow.Sep2);
607         sep2h = 0;
608         cwheight = 0;
609     }
610 
611     if (ExistManaged(mw->mwindow.Message))
612     {
613         bw = mw->mwindow.Message->core.border_width;
614 	mwx = MyXpad;
615 	tmp = mw->core.width - (2 * (MyXpad + bw));
616 	if (tmp <= 0) mwwidth = 10 ; else mwwidth = tmp ;
617 	mwheight = mw->mwindow.Message->core.height;
618 
619 	desired.x = mwx;
620 	desired.y = swy;
621 	desired.border_width = bw;
622         desired.width = mwwidth;
623         desired.height = mwheight;
624         desired.request_mode = (CWWidth);
625         if (XtQueryGeometry(mw->mwindow.Message, &desired, &preferred)
626             != XtGeometryYes)
627         {
628    	    bw = preferred.border_width;
629 	    mwheight = preferred.height;
630         }
631         if (mw->mwindow.ShowSep)
632             sep3h = mw->mwindow.Sep3->rectangle.height;
633         else
634             sep3h = 0;
635 
636         sepy = mw->core.height - mwheight - (2 * bw) -
637 	    mw->mwindow.margin_height - sep3h;
638         mwy = sepy + sep3h;
639 
640         if (mw->mwindow.CommandLoc == XmCOMMAND_BELOW_WORKSPACE)
641         {
642             mw->swindow.HeightPad = sep2h + cwheight + sep3h + mwheight
643 		+ mw->mwindow.margin_height;
644             sep2y -= (sep3h + mwheight);
645             cwy -= (sep3h + mwheight);
646         }
647         else
648             mw->swindow.HeightPad = sep3h + mwheight
649 		+ mw->mwindow.margin_height;
650 
651         XmeConfigureObject(mw->mwindow.Message, mwx, mwy,
652 			   mwwidth, mwheight, bw);
653         if (mw->mwindow.ShowSep)
654         {
655 	    XtManageChild((Widget) mw->mwindow.Sep3);
656             XmeConfigureObject( (Widget) mw->mwindow.Sep3,
657 			       0, sepy, mw->core.width,
658                                mw->mwindow.Sep3->rectangle.height, 0);
659         }
660         else
661             XtUnmanageChild((Widget) mw->mwindow.Sep3);
662     }
663     else
664     {
665 	XtUnmanageChild((Widget) mw->mwindow.Sep3);
666     }
667 
668     if (ExistManaged(mw->mwindow.CommandWindow))
669     {
670         XmeConfigureObject( mw->mwindow.CommandWindow,
671 			   cwx, cwy, cwwidth, cwheight, bw);
672         if (mw->mwindow.ShowSep)
673         {
674 	    XtManageChild((Widget) mw->mwindow.Sep2);
675             XmeConfigureObject((Widget) mw->mwindow.Sep2,
676 			       0, sep2y, mw->core.width,
677                                mw->mwindow.Sep2->rectangle.height, 0);
678         }
679         else
680             XtUnmanageChild((Widget) mw->mwindow.Sep2);
681     }
682 
683     mw->swindow.YOffset = swy;
684     mw->mwindow.ManagingSep = False;
685 }
686 
687 /************************************************************************
688  *                                                                      *
689  *  Relayout the main window.				*
690  *									*
691  ************************************************************************/
692 static void
Resize(Widget wid)693 Resize(
694         Widget wid )
695 {
696     CompositeWidgetClass superclass = (CompositeWidgetClass)
697 	                xmMainWindowClassRec.core_class.superclass ;
698     XtWidgetProc resize;
699 
700     Layout((XmMainWindowWidget) wid);
701 
702     /* call our superclass layout now that MainWindow has updated
703        some internal positional fields: offset, pads */
704     _XmProcessLock();
705     resize = superclass->core_class.resize;
706     _XmProcessUnlock();
707     (*resize)(wid);
708 }
709 
710 
711 
712 /************************************************************************
713  *									*
714  * GetSize - compute the size of the Main window to enclose all the	*
715  * visible widgets.							*
716  *									*
717  ************************************************************************/
718 static void
GetSize(XmMainWindowWidget mw,Dimension * pwidth,Dimension * pheight)719 GetSize(
720         XmMainWindowWidget mw,
721         Dimension *pwidth,
722         Dimension *pheight)
723 {
724     Dimension	    newWidth,newHeight;
725     XmScrollBarWidget	hsb = mw->swindow.hScrollBar,
726                         vsb = mw->swindow.vScrollBar;
727     Widget 	    w;
728     Dimension	    hsheight = 0, vmwidth = 0,
729 		    ht = mw->manager.shadow_thickness  * 2,
730 		    hsbht = 0, vsbht = 0;
731     Dimension	    width, MyXpad, MyYpad;
732     XtWidgetGeometry  preferred;
733 
734 
735     MyXpad = mw->mwindow.margin_width * 2;
736     MyYpad = mw->mwindow.margin_height * 2;
737 
738 
739     /* what id to use for the sw frame */
740    if (mw->swindow.ScrollPolicy == XmAPPLICATION_DEFINED)
741         w = mw->swindow.WorkWindow;
742     else
743         w = (Widget)mw->swindow.ClipWindow;
744 
745 
746     /* note: first time through, all relevant values are 0, but we need to
747     ** take account of the preferred size anyway
748     */
749     if (ExistManaged((Widget) vsb) &&
750         ((0 == mw->core.width) || ((Dimension)vsb->core.x < mw->core.width)))  /* needed */
751     {
752        	vsbht = 2 * vsb->primitive.highlight_thickness;
753 	vmwidth = vsb->core.width + mw->swindow.pad +
754 	          (2 * vsb->primitive.highlight_thickness);
755     }
756 
757     if (ExistManaged((Widget) hsb) &&
758         ((0 == mw->core.height) || ((Dimension)hsb->core.y < mw->core.height)))  /* needed */
759     {
760        	hsbht = 2 * hsb->primitive.highlight_thickness;
761 	hsheight = hsb->core.height + mw->swindow.pad +
762 		   (2 * hsb->primitive.highlight_thickness);
763     }
764 
765 /****************
766  *
767  * Use the work window as the basis for our height. If the mode is
768  * constant, and we are not realized, use the areawidth and areaheight
769  * variables instead of the clipwindow width and height, since they are a
770  * match for the workspace until the swindow is realized.
771  *
772  ****************/
773 
774     if (ExistManaged(w))
775     {
776         if ((mw->swindow.ScrollPolicy == XmAUTOMATIC) &&
777 	    !XtIsRealized((Widget)mw))
778 	{
779   	    newWidth = mw->swindow.AreaWidth + (w->core.border_width * 2) +
780 		       hsbht + vmwidth + ht + MyXpad;
781             newHeight = mw->swindow.AreaHeight + (w->core.border_width * 2) +
782 		        vsbht + hsheight + ht + MyYpad;
783         }
784 	else
785 	{
786             XtQueryGeometry(w, NULL, &preferred);
787 	    newWidth = preferred.width + (w->core.border_width * 2) +
788 		       hsbht + vmwidth + ht + MyXpad;
789             newHeight = preferred.height  + (w->core.border_width * 2) +
790 		        vsbht + hsheight + ht + MyYpad;
791 	}
792     }
793     else
794     {
795 	newWidth = MyXpad;
796         newHeight = MyYpad;
797     }
798 
799     /* Take the max width, add the height of the other kids */
800 
801     if (ExistManaged(mw->mwindow.CommandWindow))
802     {
803         XtQueryGeometry(mw->mwindow.CommandWindow, NULL, &preferred);
804         width = preferred.width + MyXpad +
805 	        (2 * mw->mwindow.CommandWindow->core.border_width);
806     	if (newWidth < width) newWidth = width;
807 	newHeight += preferred.height +
808   	            (2 * mw->mwindow.CommandWindow->core.border_width);
809         if (mw->mwindow.Sep2 && mw->mwindow.ShowSep)
810 	    newHeight += mw->mwindow.Sep2->rectangle.height;
811 
812     }
813 
814     if (ExistManaged(mw->mwindow.MenuBar))
815     {
816         XtQueryGeometry(mw->mwindow.MenuBar, NULL, &preferred);
817         width = preferred.width + MyXpad +
818 	        (2 * mw->mwindow.MenuBar->core.border_width);
819     	if (newWidth < width) newWidth = width;
820 	newHeight += preferred.height +
821   	            (2 * mw->mwindow.MenuBar->core.border_width);
822         if (mw->mwindow.Sep1  && mw->mwindow.ShowSep)
823 	    newHeight += mw->mwindow.Sep1->rectangle.height;
824     }
825 
826     if (ExistManaged(mw->mwindow.Message))
827     {
828         XtQueryGeometry(mw->mwindow.Message, NULL, &preferred);
829         width = preferred.width +  MyXpad +
830 	        (2 * mw->mwindow.Message->core.border_width);
831     	if (newWidth < width) newWidth = width;
832 	newHeight += preferred.height +
833   	            (2 * mw->mwindow.Message->core.border_width);
834         if (mw->mwindow.Sep3 && mw->mwindow.ShowSep)
835 	    newHeight += mw->mwindow.Sep3->rectangle.height;
836 
837     }
838 
839     if (!*pwidth) *pwidth = newWidth ;
840     if (!*pheight) *pheight = newHeight ;
841 
842     /* might still be null */
843     if (!*pwidth) *pwidth = DEFAULT_SIZE ;
844     if (!*pheight) *pheight = DEFAULT_SIZE ;
845 
846 }
847 
848 /************************************************************************
849  *									*
850  *  GeometryManager							*
851  *									*
852  ************************************************************************/
853 static XtGeometryResult
GeometryManager(Widget w,XtWidgetGeometry * request,XtWidgetGeometry * reply)854 GeometryManager(
855         Widget w,
856         XtWidgetGeometry *request,
857         XtWidgetGeometry *reply )
858 {
859     CompositeWidgetClass superclass = (CompositeWidgetClass)
860 	                xmMainWindowClassRec.core_class.superclass ;
861     XmMainWindowWidget mw = (XmMainWindowWidget ) w->core.parent;
862     XtGeometryResult res;
863     Dimension	    newWidth,newHeight, OldHeight;
864     Dimension	    bw;
865     XtWidgetGeometry  parent_request ;
866     XtWidgetGeometry  desired, preferred;
867     XtWidgetProc resize;
868 
869 
870     CheckKids(mw);
871 
872 /****************
873  *
874  * If it's not a mainwindow kid, let the scrolled window deal with it.
875  * If it's from the workwindow, and the width changed, resize the menubar
876  * and ask for a new height so my layout routine doesn't clip the workwindow.
877  *
878  ****************/
879     if (w != mw->mwindow.MenuBar &&
880         w != mw->mwindow.Message &&
881         w != mw->mwindow.CommandWindow &&
882         w != (Widget )mw->mwindow.Sep1 &&
883         w != (Widget) mw->mwindow.Sep2 &&
884         w != (Widget) mw->mwindow.Sep3) {
885 
886 	/* this is the only case of geometry manager enveloping that
887 	   I know of in Motif */
888 
889 	XtGeometryHandler geo_mgr;
890 	_XmProcessLock();
891 	geo_mgr = superclass->composite_class.geometry_manager;
892 	_XmProcessUnlock();
893 
894         res = (*geo_mgr)(w, request, reply);
895 
896         if (res == XtGeometryYes) {
897 
898 	    Widget mb = mw->mwindow.MenuBar;
899 
900 	    if ((w == mw->swindow.WorkWindow) &&
901                 (request->request_mode & CWWidth) &&
902                 mb && XtIsManaged(mb)) {
903                 desired.x = mb->core.x;
904 	        desired.y = mb->core.y;
905 	        desired.border_width = mb->core.border_width;
906                 desired.width = mw->core.width -
907                                 (2 * mw->mwindow.margin_width);
908                 desired.height = mb->core.height;
909                 desired.request_mode = (CWWidth);
910                 XtQueryGeometry(mw->mwindow.MenuBar, &desired, &preferred);
911                 if (preferred.height != mb->core.height) {
912                     parent_request.request_mode = CWWidth | CWHeight;
913 		    if (request->request_mode & XtCWQueryOnly)
914 			parent_request.request_mode |= XtCWQueryOnly;
915 		    parent_request.width = mw->core.width ;
916 		    parent_request.height = newHeight = mw->core.height -
917 			(mb->core.height - (2 * mb->core.border_width)) +
918 			    preferred.height + (2 *preferred.border_width);
919                     if (XtMakeGeometryRequest((Widget) mw,
920 					      &parent_request, NULL)
921                         == XtGeometryYes) {
922 			if (!(request->request_mode & XtCWQueryOnly))
923 			    XmeConfigureObject(mw->mwindow.MenuBar,
924 					       mb->core.x, mb->core.y,
925 					       preferred.width, preferred.height,
926 					       preferred.border_width);
927 			else return XtGeometryYes ;
928 		    }
929 		}
930 	    }
931 	    _XmProcessLock();
932 	    resize = XtCoreProc(mw, resize);
933 	    _XmProcessUnlock();
934 	    (*resize)((Widget)mw) ;
935 	}
936 	return(res);
937     }
938 
939     /** Disallow any X or Y changes for MainW children **/
940     if ((request -> request_mode & CWX || request -> request_mode & CWY))
941 	return(XtGeometryNo);
942 
943 
944     if(request->request_mode & CWBorderWidth)
945 	bw = request->border_width;
946     else
947         bw = w->core.border_width;
948 
949     if (request->request_mode & CWWidth)
950 	newWidth = request->width + 2 * (bw + mw->mwindow.margin_width);
951     else
952         newWidth = mw->core.width ;
953 
954     /* grow only in width */
955     if (newWidth <= mw->core.width) newWidth = mw->core.width;
956 
957 /****************
958 *
959  * Margins are already included in the old width & height
960  *
961  ****************/
962      if(request->request_mode & CWHeight)
963          newHeight = mw->core.height -
964 	             (w->core.height - (2 * w->core.border_width)) +
965 	    	     request->height + 2 * bw;
966     else
967          newHeight = mw->core.height;
968 
969     OldHeight = mw->core.height;
970 
971     parent_request.request_mode = CWWidth | CWHeight;
972     if (request->request_mode & XtCWQueryOnly)
973 	parent_request.request_mode |= XtCWQueryOnly;
974     parent_request.width = newWidth ;
975     parent_request.height = newHeight;
976 
977     res = XtMakeGeometryRequest((Widget) mw, &parent_request, NULL) ;
978 
979     if (res == XtGeometryYes) {
980 	if (!(request->request_mode & XtCWQueryOnly)) {
981 	    if(request->request_mode & CWWidth)
982 		w->core.width = request->width;
983 	    if(request->request_mode & CWHeight)
984 		w->core.height = request->height;
985 
986 	    mw->swindow.YOffset = mw->swindow.YOffset +
987 		(newHeight - OldHeight);
988 
989 	    _XmProcessLock();
990 	    resize = XtCoreProc(mw, resize);
991 	    _XmProcessUnlock();
992 	    (*resize) ((Widget)mw) ;
993 	}
994     }
995 
996     return(res);
997 }
998 
999 
1000 
1001 /************************************************************************
1002  *									*
1003  *  ChangeManaged - called whenever there is a change in the managed	*
1004  *		    set.						*
1005  *									*
1006  ************************************************************************/
1007 static void
ChangeManaged(Widget wid)1008 ChangeManaged(
1009         Widget wid )
1010 {
1011     XmMainWindowWidget mw = (XmMainWindowWidget) wid ;
1012     XtWidgetGeometry desired ;
1013     CompositeWidget cw = (CompositeWidget) mw->swindow.ClipWindow;
1014     Widget   w;
1015     register int i;
1016     XtWidgetProc resize;
1017 
1018     if (mw->mwindow.ManagingSep || mw->swindow.FromResize) return;
1019 
1020     CheckKids(mw);
1021 
1022 /****************
1023  *
1024  * This is an ugly bit of work... It's possible for the clip window to get
1025  * "extra" kids that really want to be mainwindow widgets.
1026  *
1027  ****************/
1028     if ((mw->swindow.ScrollPolicy == XmAUTOMATIC) &&
1029         (cw->composite.num_children > 1) &&
1030 	(mw->swindow.WorkWindow != NULL)) {
1031 
1032 	/* loop over the clip window child list and treat the bogus */
1033 	for (i = 0; i < cw->composite.num_children; i++) {
1034 	    XmScrolledWindowConstraint swc ;
1035 	    int j ;
1036 
1037 	    w = cw->composite.children[i];
1038 	    swc = GetSWConstraint(w);
1039 
1040 	    /* only those kind are allowed as clipwindow kids */
1041 	    if ((swc->child_type != XmWORK_AREA) &&
1042 		(swc->child_type != XmSCROLL_HOR) &&
1043 		(swc->child_type != XmSCROLL_VERT) &&
1044 		(swc->child_type != XmNO_SCROLL)) {
1045 
1046 		/* add it to the main window child list. first increase
1047 		   the list if needed- Gee, I wish I remember what made
1048 		   me keep this hacky code around... */
1049 		if (mw->composite.num_children ==
1050 		    mw->composite.num_slots)  {
1051 		    mw->composite.num_slots +=  (mw->composite.num_slots
1052 						 / 2) + 2;
1053 		    mw->composite.children = (WidgetList) XtRealloc(
1054 					(char *) mw->composite.children,
1055 					(unsigned) (mw->composite.num_slots)
1056 						* sizeof(Widget));
1057 		}
1058 		mw->composite.children[mw->composite.num_children++] = w;
1059 		w->core.parent = (Widget) mw;
1060 
1061 		/* remove it from the clipwindow child list by
1062 		   moving all the siblings that comes after it
1063 		   one slot down */
1064 		for (j = i+1; j < cw->composite.num_children; j++) {
1065 		    cw->composite.children[i-1] = cw->composite.children[i] ;
1066 		}
1067 		cw->composite.num_children -- ;
1068 	    }
1069 	}
1070    }
1071 
1072     if (!XtIsRealized(wid))  {
1073 	desired.width = XtWidth(wid) ;   /* might be 0 */
1074 	desired.height = XtHeight(wid) ; /* might be 0 */
1075     } else {
1076 	desired.width = 0 ;
1077 	desired.height = 0 ;
1078     }
1079 
1080     GetSize(mw, &desired.width, &desired.height);
1081     desired.request_mode = (CWWidth | CWHeight);
1082     (void) _XmMakeGeometryRequest(wid, &desired);
1083 
1084     _XmProcessLock();
1085     resize = XtCoreProc(mw, resize);
1086     _XmProcessUnlock();
1087     (*resize) (wid) ;
1088 
1089     XmeNavigChangeManaged(wid);
1090 }
1091 
1092 
1093 /************************************************************************
1094  *									*
1095  *  SetValues								*
1096  *									*
1097  ************************************************************************/
1098 /*ARGSUSED*/
1099 static Boolean
SetValues(Widget cw,Widget rw,Widget nw,ArgList args,Cardinal * num_args)1100 SetValues(
1101         Widget cw,
1102         Widget rw,		/* unused */
1103         Widget nw,
1104         ArgList args,		/* unused */
1105         Cardinal *num_args )	/* unused */
1106 {
1107     XmMainWindowWidget current = (XmMainWindowWidget) cw ;
1108     XmMainWindowWidget new_w = (XmMainWindowWidget) nw ;
1109     Boolean flag = False;
1110 
1111     CheckKids(new_w);
1112 
1113     /* somehow, this used not to create problem in 1.2,
1114        some apps did setvalue of XmNmenubar to itself ?
1115        check that and change back */
1116     if ((new_w->mwindow.MenuBar != current->mwindow.MenuBar) &&
1117         (new_w->mwindow.MenuBar == nw)) {
1118 	new_w->mwindow.MenuBar = current->mwindow.MenuBar;
1119     }
1120 
1121     /* fix for 8990: these warnings must be here for bc... */
1122     if ((new_w->mwindow.MenuBar != current->mwindow.MenuBar) &&
1123         (new_w->mwindow.MenuBar == NULL)) {
1124         XmeWarning( (Widget) new_w, MWMessage1);
1125 	new_w->mwindow.MenuBar = current->mwindow.MenuBar;
1126     }
1127 
1128     if ((new_w->mwindow.CommandWindow != current->mwindow.CommandWindow) &&
1129         (new_w->mwindow.CommandWindow == NULL)) {
1130         XmeWarning( (Widget) new_w, MWMessage2);
1131 	new_w->mwindow.CommandWindow = current->mwindow.CommandWindow;
1132     }
1133 
1134     /* first deal with the layout attributes, and set up a flag */
1135 
1136     /* There is a potential bug here: if the change in margin
1137        concur with a change on some other stuff, like separator
1138        or a new child, and the getSize call return the same size,
1139        no resize call will be generated by Xt.
1140        A way to fix that is to check this no change in size
1141        and to fake a request.. maybe not worth. */
1142 
1143     if ((new_w->mwindow.margin_width != current->mwindow.margin_width) ||
1144 	(new_w->mwindow.margin_height != current->mwindow.margin_height) ||
1145 	(new_w->mwindow.ShowSep != current->mwindow.ShowSep)) {
1146 	flag = True;
1147     }
1148 
1149     if ((new_w->mwindow.CommandLoc != current->mwindow.CommandLoc) &&
1150         (XmRepTypeValidValue(XmRID_COMMAND_WINDOW_LOCATION,
1151 			     new_w->mwindow.CommandLoc, (Widget) new_w))) {
1152         XtWidgetProc resize;
1153 	_XmProcessLock();
1154 	resize = XtCoreProc(nw, resize);
1155 	_XmProcessUnlock();
1156 	(*resize) (nw) ;
1157     }
1158     else
1159         new_w->mwindow.CommandLoc = current->mwindow.CommandLoc;
1160 
1161 
1162     /* At InsertChild time, a lot of bad things might have happened.
1163        The command window, messagewindow and work window, which we have
1164        no real way to identify at that time, might have been mixed up.
1165        (MenuBar and application ScrollBars shouldn't be a problem)
1166        The first unidentifiable kid will take the workwindow slot (and
1167        possibly be reparented), and the followers will be just inserted
1168        in the child list without reparenting (to the clipwindow in
1169        AUTO mode I mean).
1170        After creation time, the application will use XtSetValues to set up
1171        things correctly (except changing the workwindow in AUTO,
1172        which is not allowed).
1173        The requirement, if a childType resource isn't provided,
1174        is that the workwindow be created first, at least in AUTO mode
1175        where the reparenting happens */
1176 
1177 
1178 
1179     if ((new_w->mwindow.MenuBar != current->mwindow.MenuBar) ||
1180         (new_w->mwindow.Message != current->mwindow.Message) ||
1181         (new_w->mwindow.CommandWindow != current->mwindow.CommandWindow ) ||
1182         (new_w->swindow.hScrollBar != current->swindow.hScrollBar) ||
1183 	(new_w->swindow.vScrollBar != current->swindow.vScrollBar) ||
1184 	(new_w->swindow.WorkWindow != current->swindow.WorkWindow ) ||
1185         (flag)) {
1186 	/* set our core geometry to the needed size -
1187 	   no resizePolicy here...
1188 	   Change in child type can happen before realize time, before
1189 	   change managed has been called, and we don't want to set up
1190 	   a size for the main window at this point, since its children
1191 	   size haven't been set up yet */
1192 	if (XtIsRealized((Widget)new_w)) {
1193 	    Dimension width = 0, height = 0 ;
1194 	    GetSize (new_w, &width, &height);
1195 	    new_w->core.width = width ;
1196 	    new_w->core.height = height ;
1197 	}
1198     }
1199 
1200     return (False);
1201 }
1202 
1203 
1204 /************************************************************************
1205  *									*
1206  * GetAutoDragVertRects	class methods					*
1207  *									*
1208  ************************************************************************/
1209 
1210 static void
GetVertRects(Widget sw,XRectangle ** vrect,Cardinal * num_vrect)1211 GetVertRects(
1212 	     Widget sw,
1213 	     XRectangle ** vrect,
1214 	     Cardinal * num_vrect)
1215 {
1216     Widget w ;
1217     XmMainWindowWidget mw = (XmMainWindowWidget) sw ;
1218 
1219     *num_vrect = 2 ;
1220     *vrect = (XRectangle *) XtMalloc(sizeof(XRectangle) * (*num_vrect)) ;
1221 
1222     /* The vertical rectangles are the ones that vertically auto scroll,
1223        they are defined by areas on the top and bottom of the
1224        workarea, e.g. the margins, the spacing, the scrollbars
1225        and the shadows */
1226 
1227     /* Both rects are computed using only the relative work_area or
1228        clipwindow (in AUTO) location within the scrolled window:
1229        this is the area between the widget and its parent frame.
1230 
1231        Then they need to be translated into the scrollbar coord system. */
1232 
1233     /* what id to use for the sw child frame */
1234    if (mw->swindow.ScrollPolicy == XmAPPLICATION_DEFINED) {
1235        w = mw->swindow.WorkWindow;
1236        if (!w) w = sw ; /* fallback */
1237    } else
1238         w = (Widget) mw->swindow.ClipWindow;
1239 
1240 
1241     /* the vertical rectangle are more complex to compute than for
1242        the SW case because we cannot go blindy to the SW boundary,
1243        we have to stop at the next sibling window boundary */
1244 
1245     /* We have to consider all case of existing/managed menubar, command,
1246        or message area, with the command up or down too. */
1247 
1248     if (!ExistManaged(mw->mwindow.MenuBar) &&
1249 	!ExistManaged(mw->mwindow.CommandWindow)) {
1250 	(*vrect)[0].y = 0 ;
1251 	(*vrect)[0].height = w->core.y ;
1252     } else
1253     if (ExistManaged(mw->mwindow.MenuBar) &&
1254 	!ExistManaged(mw->mwindow.CommandWindow)) {
1255 	(*vrect)[0].y = mw->mwindow.MenuBar->core.y +
1256 	    mw->mwindow.MenuBar->core.height ;
1257 	(*vrect)[0].height = w->core.y - mw->mwindow.MenuBar->core.y -
1258 	    mw->mwindow.MenuBar->core.height ;
1259     } else
1260     if (ExistManaged(mw->mwindow.MenuBar) &&
1261 	ExistManaged(mw->mwindow.CommandWindow) &&
1262 	(mw->mwindow.CommandLoc == XmCOMMAND_ABOVE_WORKSPACE)) {
1263 	(*vrect)[0].y = mw->mwindow.CommandWindow->core.y +
1264 	    mw->mwindow.CommandWindow->core.height ;
1265 	(*vrect)[0].height = w->core.y - mw->mwindow.CommandWindow->core.y -
1266 	    mw->mwindow.CommandWindow->core.height ;
1267     }
1268 
1269 
1270     /* The first rectangle is the one that makes the scrollbar goes up */
1271     (*vrect)[0].x = w->core.x - mw->swindow.vScrollBar->core.x ;
1272     /* just translate to the scrollbar coordinate */
1273     (*vrect)[0].y =- mw->swindow.vScrollBar->core.y ;
1274     (*vrect)[0].width = w->core.width ;
1275 
1276     /* The second rectangle is the one that makes the scrollbar goes down */
1277 
1278     (*vrect)[1].x = (*vrect)[0].x ;
1279     (*vrect)[1].y = w->core.y + w->core.height
1280 	- mw->swindow.vScrollBar->core.y ;
1281     (*vrect)[1].width = (*vrect)[0].width ;
1282 
1283     if (!ExistManaged(mw->mwindow.CommandWindow) &&
1284 	!ExistManaged(mw->mwindow.Message)) {
1285 	(*vrect)[1].height = mw->core.height - (*vrect)[1].y ;
1286     } else
1287     if (ExistManaged(mw->mwindow.CommandWindow) &&
1288 	(mw->mwindow.CommandLoc == XmCOMMAND_BELOW_WORKSPACE)) {
1289 	(*vrect)[1].height = mw->mwindow.CommandWindow->core.y -
1290 	    w->core.y - w->core.height;
1291     } else
1292     if (ExistManaged(mw->mwindow.Message)) {
1293 	(*vrect)[1].height = mw->mwindow.Message->core.y -
1294 	    w->core.y - w->core.height;
1295     }
1296 
1297 }
1298 
1299 
1300 /************************************************************************
1301  *									*
1302  * Public API Functions							*
1303  *									*
1304  ************************************************************************/
1305 
1306 /************************************************************************
1307  *									*
1308  * XmMainWindowSetAreas - set a new children set.				*
1309  *	-to be deprecated in favor of XtSetValues			*
1310  *      -doesn't even handle message window                             *
1311  *									*
1312  ************************************************************************/
1313 void
XmMainWindowSetAreas(Widget w,Widget menu,Widget command,Widget hscroll,Widget vscroll,Widget wregion)1314 XmMainWindowSetAreas(
1315         Widget w,
1316         Widget menu,
1317         Widget command,
1318         Widget hscroll,
1319         Widget vscroll,
1320         Widget wregion )
1321 {
1322      Arg args[5] ;
1323      Cardinal    n;
1324 
1325      n = 0;
1326      if (menu) {
1327 	 XtSetArg (args[n], XmNmenuBar, menu); n++;
1328      }
1329      if (command) {
1330 	 XtSetArg (args[n], XmNcommandWindow, command); n++;
1331      }
1332      if (hscroll) {
1333 	 XtSetArg (args[n], XmNhorizontalScrollBar, hscroll); n++;
1334      }
1335      if (vscroll) {
1336 	 XtSetArg (args[n], XmNverticalScrollBar, vscroll); n++;
1337      }
1338      if (wregion) {
1339 	 XtSetArg (args[n], XmNworkWindow, wregion); n++;
1340      }
1341      XtSetValues(w, args, n);
1342 }
1343 
1344 
1345 /************************************************************************
1346  *									*
1347  * XmMainWindowSep1, 2 and 3                                            *
1348  *   - return the id of the top seperator widget.	                *
1349  *   - to be deprecated in favor of using XtNameToWidget               *
1350  *									*
1351  *									*
1352  ************************************************************************/
1353 Widget
XmMainWindowSep1(Widget w)1354 XmMainWindowSep1(
1355         Widget w )
1356 {
1357     XmMainWindowWidget   mw = (XmMainWindowWidget) w;
1358     Widget separator;
1359     _XmWidgetToAppContext(w);
1360 
1361     _XmAppLock(app);
1362     separator =  (Widget) mw->mwindow.Sep1;
1363     _XmAppUnlock(app);
1364 
1365     return separator;
1366 }
1367 
1368 Widget
XmMainWindowSep2(Widget w)1369 XmMainWindowSep2(
1370         Widget w )
1371 {
1372     XmMainWindowWidget   mw = (XmMainWindowWidget) w;
1373     Widget separator;
1374     _XmWidgetToAppContext(w);
1375 
1376     _XmAppLock(app);
1377     separator = (Widget) mw->mwindow.Sep2;
1378     _XmAppUnlock(app);
1379 
1380     return separator;
1381 }
1382 
1383 
1384 Widget
XmMainWindowSep3(Widget w)1385 XmMainWindowSep3(
1386         Widget w )
1387 {
1388     XmMainWindowWidget   mw = (XmMainWindowWidget) w;
1389     Widget separator;
1390     _XmWidgetToAppContext(w);
1391 
1392     _XmAppLock(app);
1393     separator = (Widget) mw->mwindow.Sep3;
1394     _XmAppUnlock(app);
1395 
1396     return separator;
1397 }
1398 
1399 
1400 /************************************************************************
1401  *									*
1402  * XmCreateMainWindow -                                         	*
1403  *									*
1404  ************************************************************************/
1405 Widget
XmCreateMainWindow(Widget parent,char * name,ArgList args,Cardinal argCount)1406 XmCreateMainWindow(
1407         Widget parent,
1408         char *name,
1409         ArgList args,
1410         Cardinal argCount )
1411 {
1412     return (XtCreateWidget(name, xmMainWindowWidgetClass, parent,
1413 			     args, argCount ) );
1414 }
1415 
1416 Widget
XmVaCreateMainWindow(Widget parent,char * name,...)1417 XmVaCreateMainWindow(
1418         Widget parent,
1419         char *name,
1420         ...)
1421 {
1422     register Widget w;
1423     va_list var;
1424     int count;
1425 
1426     Va_start(var,name);
1427     count = XmeCountVaListSimple(var);
1428     va_end(var);
1429 
1430 
1431     Va_start(var, name);
1432     w = XmeVLCreateWidget(name,
1433                          xmMainWindowWidgetClass,
1434                          parent, False,
1435                          var, count);
1436     va_end(var);
1437     return w;
1438 }
1439 
1440 Widget
XmVaCreateManagedMainWindow(Widget parent,char * name,...)1441 XmVaCreateManagedMainWindow(
1442         Widget parent,
1443         char *name,
1444         ...)
1445 {
1446     Widget w = NULL;
1447     va_list var;
1448     int count;
1449 
1450     Va_start(var, name);
1451     count = XmeCountVaListSimple(var);
1452     va_end(var);
1453 
1454     Va_start(var, name);
1455     w = XmeVLCreateWidget(name,
1456                          xmMainWindowWidgetClass,
1457                          parent, True,
1458                          var, count);
1459     va_end(var);
1460     return w;
1461 }
1462