Blame lib/Xm/DialogS.c

Packit b099d7
/* 
Packit b099d7
 * Motif
Packit b099d7
 *
Packit b099d7
 * Copyright (c) 1987-2012, The Open Group. All rights reserved.
Packit b099d7
 *
Packit b099d7
 * These libraries and programs are free software; you can
Packit b099d7
 * redistribute them and/or modify them under the terms of the GNU
Packit b099d7
 * Lesser General Public License as published by the Free Software
Packit b099d7
 * Foundation; either version 2 of the License, or (at your option)
Packit b099d7
 * any later version.
Packit b099d7
 *
Packit b099d7
 * These libraries and programs are distributed in the hope that
Packit b099d7
 * they will be useful, but WITHOUT ANY WARRANTY; without even the
Packit b099d7
 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
Packit b099d7
 * PURPOSE. See the GNU Lesser General Public License for more
Packit b099d7
 * details.
Packit b099d7
 *
Packit b099d7
 * You should have received a copy of the GNU Lesser General Public
Packit b099d7
 * License along with these librararies and programs; if not, write
Packit b099d7
 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
Packit b099d7
 * Floor, Boston, MA 02110-1301 USA
Packit b099d7
*/ 
Packit b099d7
/* 
Packit b099d7
 * HISTORY
Packit b099d7
*/ 
Packit b099d7
#ifdef REV_INFO
Packit b099d7
#ifndef lint
Packit b099d7
static char rcsid[] = "$XConsortium: DialogS.c /main/17 1996/03/25 17:50:11 barstow $"
Packit b099d7
#endif
Packit b099d7
#endif
Packit b099d7
/* (c) Copyright 1989, DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS. */
Packit b099d7
/* (c) Copyright 1987, 1988, 1989, 1990, 1991, 1992 HEWLETT-PACKARD COMPANY */
Packit b099d7
/* (c) Copyright 1988 MASSACHUSETTS INSTITUTE OF TECHNOLOGY  */
Packit b099d7
Packit b099d7
#ifdef HAVE_CONFIG_H
Packit b099d7
#include <config.h>
Packit b099d7
#endif
Packit b099d7
Packit b099d7
Packit b099d7
#include "XmI.h"
Packit b099d7
#include <Xm/DialogSP.h>
Packit b099d7
#include <Xm/DialogSEP.h>
Packit b099d7
#include <Xm/BaseClassP.h>
Packit b099d7
#include <Xm/DialogSavvyT.h>
Packit b099d7
#include <Xm/TraitP.h>
Packit b099d7
#include "BaseClassI.h"
Packit b099d7
#include "MessagesI.h"
Packit b099d7
#include "XmImI.h"
Packit b099d7
Packit b099d7
Packit b099d7
#define MSG1	_XmMMsgDialogS_0000
Packit b099d7
Packit b099d7
Packit b099d7
#define HALFDIFF(a, b) ((((Position)a) - ((Position)b))/2)
Packit b099d7
Packit b099d7
#define TotalWidth(w)   (XtWidth  (w) + (2 * (XtBorderWidth (w))))
Packit b099d7
#define TotalHeight(w)  (XtHeight (w) + (2 *(XtBorderWidth (w))))
Packit b099d7
Packit b099d7
Packit b099d7
Packit b099d7
/********    Static Function Declarations    ********/
Packit b099d7
Packit b099d7
static void ClassInitialize( void ) ;
Packit b099d7
static void ClassPartInit( 
Packit b099d7
                        WidgetClass wc) ;
Packit b099d7
static Widget GetRectObjKid( 
Packit b099d7
                        CompositeWidget p) ;
Packit b099d7
static void Initialize( 
Packit b099d7
                        Widget request,
Packit b099d7
                        Widget new_w,
Packit b099d7
                        ArgList args,
Packit b099d7
                        Cardinal *num_args) ;
Packit b099d7
static Boolean SetValues( 
Packit b099d7
                        Widget current,
Packit b099d7
                        Widget request,
Packit b099d7
                        Widget new_w,
Packit b099d7
                        ArgList args,
Packit b099d7
                        Cardinal *num_args) ;
Packit b099d7
static void InsertChild( 
Packit b099d7
                        Widget w) ;
Packit b099d7
static void GetDefaultPosition( 
Packit b099d7
                        Widget child,
Packit b099d7
                        Widget parent,
Packit b099d7
                        Position *xRtn,
Packit b099d7
                        Position *yRtn) ;
Packit b099d7
static void ChangeManaged( 
Packit b099d7
                        Widget wid) ;
Packit b099d7
static XtGeometryResult GeometryManager( 
Packit b099d7
                        Widget wid,
Packit b099d7
                        XtWidgetGeometry *request,
Packit b099d7
                        XtWidgetGeometry *reply) ;
Packit b099d7
Packit b099d7
/********    End Static Function Declarations    ********/
Packit b099d7
Packit b099d7
Packit b099d7
static XmBaseClassExtRec	myBaseClassExtRec = {
Packit b099d7
    NULL,				/* Next extension	*/
Packit b099d7
    NULLQUARK,				/* record type XmQmotif	*/
Packit b099d7
    XmBaseClassExtVersion,		/* version		*/
Packit b099d7
    sizeof(XmBaseClassExtRec),		/* size			*/
Packit b099d7
    XmInheritInitializePrehook,		/* initialize prehook	*/
Packit b099d7
    XmInheritSetValuesPrehook,		/* set_values prehook	*/
Packit b099d7
    XmInheritInitializePosthook,	/* initialize posthook	*/
Packit b099d7
    XmInheritSetValuesPosthook,		/* set_values posthook	*/
Packit b099d7
    (WidgetClass)&xmDialogShellExtClassRec,/* secondary class	*/
Packit b099d7
    XmInheritSecObjectCreate,		/* secondary create	*/
Packit b099d7
    NULL,				/* getSecRes data	*/
Packit b099d7
    {0}				/* fast subclass	*/
Packit b099d7
};
Packit b099d7
Packit b099d7
Packit b099d7
externaldef(xmdialogshellclassrec)
Packit b099d7
XmDialogShellClassRec xmDialogShellClassRec = {
Packit b099d7
    {					    /* core class record */
Packit b099d7
	
Packit b099d7
	(WidgetClass) & transientShellClassRec,	/* superclass */
Packit b099d7
	"XmDialogShell", 		/* class_name */
Packit b099d7
	sizeof(XmDialogShellWidgetRec), /* widget_size */
Packit b099d7
	ClassInitialize,		/* class_initialize proc */
Packit b099d7
	ClassPartInit,			/* class_part_initialize proc */
Packit b099d7
	FALSE, 				/* class_inited flag */
Packit b099d7
	Initialize, 			/* instance initialize proc */
Packit b099d7
	NULL, 				/* init_hook proc */
Packit b099d7
	XtInheritRealize,		/* realize widget proc */
Packit b099d7
	NULL, 				/* action table for class */
Packit b099d7
	0, 				/* num_actions */
Packit b099d7
	NULL,	 			/* resource list of class */
Packit b099d7
	0,		 		/* num_resources in list */
Packit b099d7
	NULLQUARK, 			/* xrm_class ? */
Packit b099d7
	FALSE, 				/* don't compress_motion */
Packit b099d7
        XtExposeCompressSeries,	 	/* compressed exposure */
Packit b099d7
	FALSE, 				/* do compress enter-leave */
Packit b099d7
	FALSE, 				/* do have visible_interest */
Packit b099d7
	NULL, 				/* destroy widget proc */
Packit b099d7
	XtInheritResize, 		/* resize widget proc */
Packit b099d7
	NULL, 				/* expose proc */
Packit b099d7
	SetValues, 			/* set_values proc */
Packit b099d7
	NULL, 				/* set_values_hook proc */
Packit b099d7
	XtInheritSetValuesAlmost, 	/* set_values_almost proc */
Packit b099d7
	NULL, 				/* get_values_hook */
Packit b099d7
	NULL, 				/* accept_focus proc */
Packit b099d7
	XtVersion, 			/* current version */
Packit b099d7
	NULL, 				/* callback offset    */
Packit b099d7
	XtInheritTranslations, 		/* default translation table */
Packit b099d7
	XtInheritQueryGeometry, 	/* query geometry widget proc */
Packit b099d7
	NULL, 				/* display accelerator    */
Packit b099d7
	(XtPointer)&myBaseClassExtRec,	/* extension record      */
Packit b099d7
    },
Packit b099d7
    { 					/* composite class record */
Packit b099d7
	GeometryManager,                /* geometry_manager */
Packit b099d7
	ChangeManaged, 			/* change_managed		*/
Packit b099d7
	InsertChild,			/* insert_child			*/
Packit b099d7
	XtInheritDeleteChild, 		/* from the shell */
Packit b099d7
	NULL, 				/* extension record      */
Packit b099d7
    },
Packit b099d7
    { 					/* shell class record */
Packit b099d7
	NULL, 				/* extension record      */
Packit b099d7
    },
Packit b099d7
    { 					/* wm shell class record */
Packit b099d7
	NULL, 				/* extension record      */
Packit b099d7
    },
Packit b099d7
    { 					/* vendor shell class record */
Packit b099d7
	NULL,				/* extension record      */
Packit b099d7
    },
Packit b099d7
    { 					/* transient class record */
Packit b099d7
	NULL, 				/* extension record      */
Packit b099d7
    },
Packit b099d7
    { 					/* our class record */
Packit b099d7
	NULL, 				/* extension record      */
Packit b099d7
    },
Packit b099d7
};
Packit b099d7
Packit b099d7
Packit b099d7
/*
Packit b099d7
 * now make a public symbol that points to this class record
Packit b099d7
 */
Packit b099d7
Packit b099d7
externaldef(xmdialogshellwidgetclass)
Packit b099d7
    WidgetClass xmDialogShellWidgetClass = (WidgetClass)&xmDialogShellClassRec;
Packit b099d7
    
Packit b099d7
Packit b099d7
static void 
Packit b099d7
ClassInitialize( void )
Packit b099d7
{
Packit b099d7
  Cardinal                    wc_num_res, sc_num_res, wc_unique_res;
Packit b099d7
  XtResource                  *merged_list;
Packit b099d7
  int                         i, j, k;
Packit b099d7
  XtResourceList              uncompiled, res_list;
Packit b099d7
  Cardinal                    num;
Packit b099d7
Packit b099d7
/**************************************************************************
Packit b099d7
   VendorExt and  DialogExt resource lists are being merged into one
Packit b099d7
   and assigned to xmDialogShellExtClassRec. This is for performance
Packit b099d7
   reasons, since, instead of two calls to XtGetSubResources() XtGetSubvaluse()
Packit b099d7
   and XtSetSubvalues() for both the superclass and the widget class, now
Packit b099d7
   we have just one call with a merged resource list.
Packit b099d7
Packit b099d7
****************************************************************************/
Packit b099d7
Packit b099d7
  wc_num_res = xmDialogShellExtClassRec.object_class.num_resources ;
Packit b099d7
Packit b099d7
  wc_unique_res = wc_num_res - 1; /* XmNdeleteResponse has been defined */
Packit b099d7
                                  /* in VendorSE  */
Packit b099d7
Packit b099d7
  sc_num_res = xmVendorShellExtClassRec.object_class.num_resources;
Packit b099d7
Packit b099d7
  merged_list = (XtResource *)XtMalloc((sizeof(XtResource) * (wc_unique_res +
Packit b099d7
                                                                 sc_num_res)));
Packit b099d7
Packit b099d7
  _XmTransformSubResources(xmVendorShellExtClassRec.object_class.resources,
Packit b099d7
                           sc_num_res, &uncompiled, &num);
Packit b099d7
Packit b099d7
  for (i = 0; i < num; i++)
Packit b099d7
  {
Packit b099d7
Packit b099d7
  merged_list[i] = uncompiled[i];
Packit b099d7
Packit b099d7
  }
Packit b099d7
Packit b099d7
  XtFree((char *)uncompiled);
Packit b099d7
Packit b099d7
  res_list = xmDialogShellExtClassRec.object_class.resources;
Packit b099d7
Packit b099d7
  for (i = 0, j = num; i < wc_num_res; i++)
Packit b099d7
  {
Packit b099d7
Packit b099d7
   k = 0; 
Packit b099d7
   while ((k < sc_num_res) &&
Packit b099d7
	  (strcmp(merged_list[k].resource_name,res_list[i].resource_name) != 0))
Packit b099d7
     k++;
Packit b099d7
   if ((k < sc_num_res) &&
Packit b099d7
       (strcmp(merged_list[k].resource_name, res_list[i].resource_name) == 0))
Packit b099d7
     merged_list[k] = res_list[i];
Packit b099d7
   else
Packit b099d7
   {
Packit b099d7
     merged_list[j] =
Packit b099d7
        xmDialogShellExtClassRec.object_class.resources[i];
Packit b099d7
     j++;
Packit b099d7
   }
Packit b099d7
  }
Packit b099d7
Packit b099d7
  xmDialogShellExtClassRec.object_class.resources = merged_list;
Packit b099d7
  xmDialogShellExtClassRec.object_class.num_resources =
Packit b099d7
                wc_unique_res + sc_num_res ;
Packit b099d7
Packit b099d7
  xmDialogShellExtObjectClass->core_class.class_initialize();
Packit b099d7
Packit b099d7
  myBaseClassExtRec.record_type = XmQmotif;
Packit b099d7
}
Packit b099d7
Packit b099d7
/************************************************************************
Packit b099d7
 *
Packit b099d7
 *  ClassPartInit
Packit b099d7
 *    Set up the fast subclassing for the widget.
Packit b099d7
 *
Packit b099d7
 ************************************************************************/
Packit b099d7
static void 
Packit b099d7
ClassPartInit(
Packit b099d7
        WidgetClass wc )
Packit b099d7
{
Packit b099d7
   _XmFastSubclassInit(wc, XmDIALOG_SHELL_BIT);
Packit b099d7
}
Packit b099d7
Packit b099d7
static Widget 
Packit b099d7
GetRectObjKid(
Packit b099d7
        CompositeWidget p )
Packit b099d7
{
Packit b099d7
    Cardinal	i;
Packit b099d7
    Widget	*currKid;
Packit b099d7
Packit b099d7
    for (i = 0, currKid = p->composite.children;
Packit b099d7
	 i < p->composite.num_children; i++, currKid++) {
Packit b099d7
	if ((XtIsRectObj( *currKid)
Packit b099d7
	     /* The Input Method child is a CoreClass object; ignore it. */
Packit b099d7
	     && ((*currKid)->core.widget_class != coreWidgetClass)) ||
Packit b099d7
	    XmeTraitGet((XtPointer) XtClass(*currKid), XmQTdialogShellSavvy)) {
Packit b099d7
	    return (*currKid);
Packit b099d7
	} 
Packit b099d7
    }
Packit b099d7
    return NULL;
Packit b099d7
}
Packit b099d7
Packit b099d7
Packit b099d7
/************************************************************************
Packit b099d7
 *
Packit b099d7
 *  Initialize
Packit b099d7
 *
Packit b099d7
 ************************************************************************/
Packit b099d7
/*ARGSUSED*/
Packit b099d7
static void 
Packit b099d7
Initialize(
Packit b099d7
        Widget request,		/* unused */
Packit b099d7
        Widget new_w,
Packit b099d7
        ArgList args,		/* unused */
Packit b099d7
        Cardinal *num_args )	/* unused */
Packit b099d7
{
Packit b099d7
    if (XtWidth  (new_w) <= 0)  XtWidth  (new_w) = 5;
Packit b099d7
    if (XtHeight (new_w) <= 0)  XtHeight (new_w) = 5;
Packit b099d7
}
Packit b099d7
Packit b099d7
Packit b099d7
Packit b099d7
Packit b099d7
/************************************************************************
Packit b099d7
 *
Packit b099d7
 *  SetValues
Packit b099d7
 *
Packit b099d7
 ************************************************************************/
Packit b099d7
/*ARGSUSED*/
Packit b099d7
static Boolean 
Packit b099d7
SetValues(
Packit b099d7
        Widget current,
Packit b099d7
        Widget request,		/* unused */
Packit b099d7
        Widget new_w,
Packit b099d7
        ArgList args,		/* unused */
Packit b099d7
        Cardinal *num_args )	/* unused */
Packit b099d7
{
Packit b099d7
    Widget child ;
Packit b099d7
    XmDialogSavvyTrait trait ;
Packit b099d7
Packit b099d7
    if(!current->core.mapped_when_managed 
Packit b099d7
       && new_w->core.mapped_when_managed) {   
Packit b099d7
        if((child = GetRectObjKid ((CompositeWidget) new_w))
Packit b099d7
	   && !child->core.being_destroyed    ) {   
Packit b099d7
	    if ((trait = (XmDialogSavvyTrait)
Packit b099d7
		 XmeTraitGet((XtPointer) XtClass(child), 
Packit b099d7
			     XmQTdialogShellSavvy)) != NULL) {
Packit b099d7
		trait->callMapUnmapCB(child, True);	/* call Map callback */
Packit b099d7
	    }
Packit b099d7
            XtPopup(new_w, XtGrabNone) ;
Packit b099d7
	} 
Packit b099d7
    } 
Packit b099d7
Packit b099d7
    return (FALSE);
Packit b099d7
}
Packit b099d7
Packit b099d7
static void 
Packit b099d7
InsertChild(
Packit b099d7
        Widget w )
Packit b099d7
{
Packit b099d7
    CompositeWidget p = (CompositeWidget) XtParent (w);
Packit b099d7
    XtWidgetProc insert_child;
Packit b099d7
   
Packit b099d7
    /*
Packit b099d7
     * Make sure we only have a rectObj, a VendorObject, and
Packit b099d7
     *   maybe an Input Method (CoreClass) object as children.
Packit b099d7
     */
Packit b099d7
    if (!XtIsRectObj(w)) return;
Packit b099d7
    else
Packit b099d7
	{
Packit b099d7
	    if(    (w->core.widget_class != coreWidgetClass)
Packit b099d7
                /* The Input Method child is a CoreClass object. */
Packit b099d7
                && GetRectObjKid( p)    )
Packit b099d7
	      {
Packit b099d7
		/* we need _XmError() too! */
Packit b099d7
		  XtError(MSG1);
Packit b099d7
	      }
Packit b099d7
	    else
Packit b099d7
	      {   /*
Packit b099d7
		   * make sure we're realized so people won't core dump when 
Packit b099d7
		   *   doing incorrect managing prior to realize
Packit b099d7
		   */
Packit b099d7
		  XtRealizeWidget((Widget) p);
Packit b099d7
	      }
Packit b099d7
	}
Packit b099d7
    _XmProcessLock();
Packit b099d7
    insert_child = ((CompositeWidgetClass) compositeWidgetClass)
Packit b099d7
				      ->composite_class.insert_child;
Packit b099d7
    _XmProcessUnlock();
Packit b099d7
    (*insert_child)(w);
Packit b099d7
    return ;
Packit b099d7
}
Packit b099d7
Packit b099d7
static void 
Packit b099d7
GetDefaultPosition(
Packit b099d7
        Widget child,
Packit b099d7
        Widget parent,
Packit b099d7
        Position *xRtn,
Packit b099d7
        Position *yRtn )
Packit b099d7
{
Packit b099d7
    Display 	*disp;
Packit b099d7
    int 	max_w, max_h;
Packit b099d7
    Position 	x, y;
Packit b099d7
Packit b099d7
    x = HALFDIFF(XtWidth(parent), XtWidth(child));
Packit b099d7
    y = HALFDIFF(XtHeight(parent), XtHeight(child));
Packit b099d7
    
Packit b099d7
    /* 
Packit b099d7
     * find root co-ords of the parent's center
Packit b099d7
     */
Packit b099d7
    if (XtIsRealized (parent))
Packit b099d7
      XtTranslateCoords(parent, x, y, &x, &y);
Packit b099d7
    
Packit b099d7
    /*
Packit b099d7
     * try to keep the popup from dribbling off the display
Packit b099d7
     */
Packit b099d7
    disp = XtDisplay (child);
Packit b099d7
    max_w = DisplayWidth  (disp, DefaultScreen (disp));
Packit b099d7
    max_h = DisplayHeight (disp, DefaultScreen (disp));
Packit b099d7
    
Packit b099d7
    if ((x + (int)TotalWidth  (child)) > max_w) 
Packit b099d7
      x = max_w - TotalWidth  (child);
Packit b099d7
    if ((y + (int)TotalHeight (child)) > max_h) 
Packit b099d7
      y = max_h - TotalHeight (child);
Packit b099d7
    if (x < 0) x = 0;
Packit b099d7
    if (y < 0) y = 0;
Packit b099d7
Packit b099d7
    *xRtn = x;
Packit b099d7
    *yRtn = y;
Packit b099d7
}
Packit b099d7
Packit b099d7
Packit b099d7
Packit b099d7
/*
Packit b099d7
 * border width and size and location are ty...
Packit b099d7
 *
Packit b099d7
 * 1. We allow the border width of a XmDialogShell child to change
Packit b099d7
 *    size arbitrarily.
Packit b099d7
 *
Packit b099d7
 * 2. The border width of the shell widget tracks the child's
Packit b099d7
 *    at all times, exactly.
Packit b099d7
 *
Packit b099d7
 * 3. The width of the shell is kept exactly the same as the
Packit b099d7
 *    width of the child at all times.
Packit b099d7
 *
Packit b099d7
 * 4. The child is always positioned at the location
Packit b099d7
 *    (- child_border, - child_border).
Packit b099d7
 *
Packit b099d7
 * the net result is the child has a border width which is always
Packit b099d7
 * what the user asked for;  but none of it is ever seen, it's all
Packit b099d7
 * clipped by the shell (parent).  The user sees the border
Packit b099d7
 * of the shell which is the size he set the child's border to.
Packit b099d7
 *
Packit b099d7
 * In the DEC window manager world the window manager does
Packit b099d7
 * exactly the same thing with the window it puts around the shell.
Packit b099d7
 * Hence the shell and child have a border width just as the user
Packit b099d7
 * set but the window manager overrides that and only a single
Packit b099d7
 * pixel border is displayed.  In a non-wm environment the child 
Packit b099d7
 * appears to have a border width, in reality this is the shell
Packit b099d7
 * widget border.  You wanted to know...
Packit b099d7
 */
Packit b099d7
static void 
Packit b099d7
ChangeManaged(
Packit b099d7
        Widget wid )
Packit b099d7
{
Packit b099d7
    XmDialogShellWidget shell = (XmDialogShellWidget) wid ;
Packit b099d7
    /*
Packit b099d7
     *  If the child went to unmanaged, call XtPopdown.
Packit b099d7
     *  If the child went to managed, call XtPopup.
Packit b099d7
     */
Packit b099d7
    
Packit b099d7
    Widget	 child;
Packit b099d7
    XmWidgetExtData		extData = 
Packit b099d7
	_XmGetWidgetExtData((Widget) shell, XmSHELL_EXTENSION);
Packit b099d7
    XmVendorShellExtObject ve;
Packit b099d7
    XmDialogSavvyTrait trait ;
Packit b099d7
Packit b099d7
    if(extData==NULL)
Packit b099d7
    {
Packit b099d7
#ifdef DEBUG
Packit b099d7
        XmeWarning(NULL, "_XmGetWidgetExtData() returned NULL pointer.");
Packit b099d7
#endif
Packit b099d7
        return;
Packit b099d7
    }
Packit b099d7
Packit b099d7
    ve = (XmVendorShellExtObject)extData->widget;
Packit b099d7
Packit b099d7
    if (((child = GetRectObjKid((CompositeWidget) shell)) == NULL) ||
Packit b099d7
	(child->core.being_destroyed))
Packit b099d7
	return;
Packit b099d7
Packit b099d7
Packit b099d7
Packit b099d7
    trait = (XmDialogSavvyTrait) 
Packit b099d7
      XmeTraitGet((XtPointer) XtClass(child), XmQTdialogShellSavvy) ;
Packit b099d7
    
Packit b099d7
    /* MANAGED Case first ********/
Packit b099d7
    if (child->core.managed)  {
Packit b099d7
	XtWidgetGeometry	request;
Packit b099d7
	Position		kidX, kidY;
Packit b099d7
	Dimension		kidBW;
Packit b099d7
	Boolean		defaultPosition = True;
Packit b099d7
Packit b099d7
	/*
Packit b099d7
	 * temporary workaround for setkeyboard focus |||
Packit b099d7
	 */
Packit b099d7
	if (child != ve->vendor.old_managed)
Packit b099d7
	    {
Packit b099d7
		XtSetKeyboardFocus((Widget)shell, (Widget)child);
Packit b099d7
		ve->vendor.old_managed = (Widget)child;
Packit b099d7
	    }
Packit b099d7
Packit b099d7
	/* 
Packit b099d7
	 * if the child isn't realized, then we need to realize it
Packit b099d7
	 * so we have a valid size. It will get created as a result
Packit b099d7
	 * so we  zero out it's position info so it'll
Packit b099d7
	 * be okay and then restore it.
Packit b099d7
	 */
Packit b099d7
	if (!XtIsRealized(child)) {
Packit b099d7
	    kidX = XtX(child);
Packit b099d7
	    kidY = XtY(child);
Packit b099d7
	    kidBW = XtBorderWidth(child);
Packit b099d7
		
Packit b099d7
	    XtX(child) = 0;
Packit b099d7
	    XtY(child) = 0;
Packit b099d7
	    XtBorderWidth(child) = 0;
Packit b099d7
		
Packit b099d7
	    XtRealizeWidget(child);
Packit b099d7
		
Packit b099d7
	    XtX(child) = kidX;
Packit b099d7
	    XtY(child) = kidY;
Packit b099d7
	    XtBorderWidth(child) = kidBW;
Packit b099d7
	}
Packit b099d7
	  
Packit b099d7
	else if (trait) {
Packit b099d7
	    /*  
Packit b099d7
	     *  Move the window to 0,0
Packit b099d7
	     *  but don't tell the widget.  It thinks it's where
Packit b099d7
	     *  the shell is...
Packit b099d7
	     */
Packit b099d7
	    if ((XtX(child) != 0) || (XtY(child) != 0))
Packit b099d7
		XMoveWindow (XtDisplay(child), XtWindow(child), 0, 0);
Packit b099d7
	}
Packit b099d7
Packit b099d7
	/*
Packit b099d7
	 * map callback should occur BEFORE child default positioning
Packit b099d7
	 * otherwise, widgets such as fileselection using map callback for
Packit b099d7
	 * correct sizing have default positioning done before the widget 
Packit b099d7
	 * grows to its correct dimensions
Packit b099d7
	 */
Packit b099d7
Packit b099d7
	if(shell->core.mapped_when_managed && trait ) { 
Packit b099d7
	    trait->callMapUnmapCB(child, True);	 /* call Map callback */
Packit b099d7
	}	
Packit b099d7
Packit b099d7
	/* 
Packit b099d7
	 * Make sure that the shell has the same common parameters as 
Packit b099d7
	 * its child.  Then move the child so that the shell will 
Packit b099d7
	 * correctly surround it.
Packit b099d7
	 */
Packit b099d7
	request.request_mode = 0;
Packit b099d7
	
Packit b099d7
	if (trait) {
Packit b099d7
	    XtVaGetValues(child, XmNdefaultPosition, &defaultPosition, NULL);
Packit b099d7
Packit b099d7
	    if (defaultPosition && (ve->vendor.externalReposition)) {
Packit b099d7
		defaultPosition = False;
Packit b099d7
		XtVaSetValues(child, XmNdefaultPosition, False, NULL);
Packit b099d7
	    }
Packit b099d7
	}
Packit b099d7
Packit b099d7
	if (XtX(child) && trait) {
Packit b099d7
	    kidX = XtX(child);
Packit b099d7
	    XtX(child) = 0;
Packit b099d7
	} else
Packit b099d7
	    kidX = XtX(shell);
Packit b099d7
	
Packit b099d7
	if (XtY(child) && trait) {
Packit b099d7
	    kidY = XtY(child);
Packit b099d7
	    XtY(child) = 0;
Packit b099d7
	} else
Packit b099d7
	    kidY = XtY(shell);
Packit b099d7
Packit b099d7
	if (XtBorderWidth(child) && trait) {
Packit b099d7
	    kidBW = XtBorderWidth(child);
Packit b099d7
	    XtBorderWidth(child) = 0;
Packit b099d7
	} else
Packit b099d7
	    kidBW = XtBorderWidth(shell);
Packit b099d7
	
Packit b099d7
Packit b099d7
	if (XtWidth (child) != XtWidth (shell)) {
Packit b099d7
	    request.request_mode |= CWWidth;
Packit b099d7
	    request.width = XtWidth(child);
Packit b099d7
	}
Packit b099d7
Packit b099d7
	if (XtHeight (child) + ve->vendor.im_height != XtHeight (shell)) {
Packit b099d7
	    request.request_mode |= CWHeight;
Packit b099d7
	    request.height = XtHeight(child) + ve->vendor.im_height;
Packit b099d7
	}
Packit b099d7
	
Packit b099d7
	if (trait) {
Packit b099d7
	    if (defaultPosition)  {
Packit b099d7
		GetDefaultPosition(child,
Packit b099d7
				   XtParent(shell),
Packit b099d7
				   &request.x,
Packit b099d7
				   &request.y);
Packit b099d7
		if (request.x != kidX) request.request_mode |= CWX;
Packit b099d7
		if (request.y != kidY) request.request_mode |= CWY;
Packit b099d7
	    } else {
Packit b099d7
		if (kidX != XtX(shell)) {
Packit b099d7
		    request.request_mode |= CWX;
Packit b099d7
		    if (kidX == XmDIALOG_SAVVY_FORCE_ORIGIN)
Packit b099d7
			request.x = 0;
Packit b099d7
		    else
Packit b099d7
			request.x = kidX;
Packit b099d7
		}
Packit b099d7
		if (kidY != XtY(shell)) {
Packit b099d7
		    request.request_mode |= CWY;
Packit b099d7
		    if (kidY == XmDIALOG_SAVVY_FORCE_ORIGIN)
Packit b099d7
			request.y = 0;
Packit b099d7
		    else
Packit b099d7
			request.y = kidY;
Packit b099d7
		}
Packit b099d7
	    }
Packit b099d7
	} else {
Packit b099d7
	    if (kidX != XtX(shell)) {
Packit b099d7
		request.request_mode |= CWX;
Packit b099d7
		request.x = kidX;
Packit b099d7
	    }
Packit b099d7
	    if (kidY != XtY(shell)) {
Packit b099d7
		request.request_mode |= CWY;
Packit b099d7
		request.y = kidY;
Packit b099d7
	    }
Packit b099d7
	    if (kidBW != XtBorderWidth(shell)) {
Packit b099d7
		request.request_mode |= CWBorderWidth;
Packit b099d7
		request.border_width = kidBW;
Packit b099d7
	    }
Packit b099d7
	}
Packit b099d7
Packit b099d7
	if (request.request_mode) {
Packit b099d7
	    unsigned int old_height = ve->vendor.im_height;
Packit b099d7
	    XtMakeGeometryRequest((Widget) shell, &request, &request);
Packit b099d7
	    _XmImResize((Widget)shell);
Packit b099d7
            if (ve->vendor.im_height != old_height)
Packit b099d7
            {
Packit b099d7
               request.request_mode = CWHeight;
Packit b099d7
               request.height = XtHeight(child) + ve->vendor.im_height;
Packit b099d7
               XtMakeGeometryRequest((Widget) shell, &request, &request);
Packit b099d7
               _XmImResize((Widget)shell);
Packit b099d7
            }
Packit b099d7
	}
Packit b099d7
	
Packit b099d7
	/*
Packit b099d7
	 * the grab_kind is handled in the popup_callback
Packit b099d7
	 */
Packit b099d7
	if(shell->core.mapped_when_managed    ) {   
Packit b099d7
	    XtPopup  ((Widget) shell, XtGrabNone);
Packit b099d7
	} 
Packit b099d7
    }
Packit b099d7
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     * CHILD BEING UNMANAGED
Packit b099d7
     */
Packit b099d7
    else {
Packit b099d7
        int i, j;
Packit b099d7
	/*
Packit b099d7
	 * Fix for CR5043, CR5758 and CR8825 -
Packit b099d7
	 * For nested Dialog Shells, it is necessary to unmanage
Packit b099d7
	 * dialog shell popups of the child of this dialog shell.
Packit b099d7
	 */
Packit b099d7
	for (i = 0; i < child->core.num_popups; i++) {
Packit b099d7
	  if (XmIsDialogShell(child->core.popup_list[i])) {
Packit b099d7
	    XmDialogShellWidget next_shell = 
Packit b099d7
	      (XmDialogShellWidget)(child->core.popup_list[i]);
Packit b099d7
Packit b099d7
	    for (j = 0; j < next_shell->composite.num_children; j++) {
Packit b099d7
	      XtUnmanageChild(next_shell->composite.children[j]);
Packit b099d7
	    }
Packit b099d7
	  }
Packit b099d7
	}
Packit b099d7
	/* End Fix CR5043, CR5758 and CR8825 */
Packit b099d7
	    
Packit b099d7
	/*
Packit b099d7
	 * take it down and then tell user
Packit b099d7
	 */
Packit b099d7
	    
Packit b099d7
	XtPopdown((Widget) shell);
Packit b099d7
	    
Packit b099d7
	if(trait ) { 
Packit b099d7
	    trait->callMapUnmapCB(child, False); /* call UnMap callback */
Packit b099d7
	}	
Packit b099d7
    }
Packit b099d7
Packit b099d7
    XmeNavigChangeManaged((Widget) shell);
Packit b099d7
}                       
Packit b099d7
Packit b099d7
Packit b099d7
/************************************************************************
Packit b099d7
 *
Packit b099d7
 *  GeometryManager
Packit b099d7
 *
Packit b099d7
 ************************************************************************/
Packit b099d7
/*ARGSUSED*/
Packit b099d7
static XtGeometryResult 
Packit b099d7
GeometryManager(
Packit b099d7
        Widget wid,
Packit b099d7
        XtWidgetGeometry *request,
Packit b099d7
        XtWidgetGeometry *reply ) /* unused */
Packit b099d7
{
Packit b099d7
    ShellWidget 	shell = (ShellWidget)(wid->core.parent);
Packit b099d7
    XtWidgetGeometry 	my_request;
Packit b099d7
    XmVendorShellExtObject ve;
Packit b099d7
    XmWidgetExtData   extData;
Packit b099d7
Packit b099d7
    extData = _XmGetWidgetExtData((Widget)shell, XmSHELL_EXTENSION);
Packit b099d7
    if(extData==NULL)
Packit b099d7
    {
Packit b099d7
#ifdef DEBUG
Packit b099d7
        XmeWarning(NULL, "_XmGetWidgetExtData() returning NULL pointer.");
Packit b099d7
#endif
Packit b099d7
        return XtGeometryNo;
Packit b099d7
    }
Packit b099d7
Packit b099d7
    ve = (XmVendorShellExtObject) extData->widget;
Packit b099d7
Packit b099d7
    if(!(shell->shell.allow_shell_resize) && XtIsRealized(wid) &&
Packit b099d7
       (request->request_mode & (CWWidth | CWHeight | CWBorderWidth)))
Packit b099d7
      return(XtGeometryNo);
Packit b099d7
Packit b099d7
    
Packit b099d7
    /*
Packit b099d7
     * Because of our klutzy API we mimic position requests on the
Packit b099d7
     * dialog to ourselves. 
Packit b099d7
     * We cannot check for the trait here since it isn't done only for 
Packit b099d7
     * BB. DialogShell GM behavior is to always follow position requests
Packit b099d7
     * even if the child is not dialogShellSavvy.
Packit b099d7
     */
Packit b099d7
Packit b099d7
    my_request.request_mode = 0;
Packit b099d7
Packit b099d7
    /* %%% worry about XtCWQueryOnly */
Packit b099d7
    if (request->request_mode & XtCWQueryOnly)
Packit b099d7
      my_request.request_mode |= XtCWQueryOnly;
Packit b099d7
Packit b099d7
    /* Here we have a tricky bit of code.
Packit b099d7
       If the SetValues on the bb child position was 0,
Packit b099d7
       which is always the current position of the bb, Xt will
Packit b099d7
       not see a change and therefore not trigerred a geometry request.
Packit b099d7
       So BB (or any dialogShellSavvy child) has to catch this case
Packit b099d7
       and change the position request to use a special value,
Packit b099d7
       XmDIALOG_SAVVY_FORCE_ORIGIN, to notify the Dialog that it wants
Packit b099d7
       to move in 0 */
Packit b099d7
Packit b099d7
    if (request->request_mode & CWX) {
Packit b099d7
	if (request->x == XmDIALOG_SAVVY_FORCE_ORIGIN)
Packit b099d7
	  my_request.x = 0;
Packit b099d7
	else
Packit b099d7
	  my_request.x = request->x;
Packit b099d7
	my_request.request_mode |= CWX;
Packit b099d7
    }
Packit b099d7
    if (request->request_mode & CWY) {
Packit b099d7
	if (request->y == XmDIALOG_SAVVY_FORCE_ORIGIN)
Packit b099d7
	  my_request.y = 0;
Packit b099d7
	else
Packit b099d7
	  my_request.y = request->y;
Packit b099d7
	my_request.request_mode |= CWY;
Packit b099d7
    }
Packit b099d7
Packit b099d7
    if (request->request_mode & CWWidth) {
Packit b099d7
	my_request.width = request->width;
Packit b099d7
	my_request.request_mode |= CWWidth;
Packit b099d7
    }
Packit b099d7
    if (request->request_mode & CWHeight) {
Packit b099d7
        if (!ve->vendor.im_height)
Packit b099d7
          _XmImResize((Widget)shell); /* updates im_height */
Packit b099d7
	my_request.height = request->height + ve->vendor.im_height;
Packit b099d7
	my_request.request_mode |= CWHeight;
Packit b099d7
    }
Packit b099d7
    if (request->request_mode & CWBorderWidth) {
Packit b099d7
	my_request.border_width = request->border_width;
Packit b099d7
	my_request.request_mode |= CWBorderWidth;
Packit b099d7
    }
Packit b099d7
Packit b099d7
    if (XtMakeGeometryRequest((Widget)shell, &my_request, NULL)
Packit b099d7
	== XtGeometryYes) {
Packit b099d7
          if (!(request->request_mode & XtCWQueryOnly)) {
Packit b099d7
	      /* just report the size changes to the kid, not
Packit b099d7
		 the dialog position itself, but reply yes
Packit b099d7
		 anyway */
Packit b099d7
	      if (my_request.request_mode & CWWidth)
Packit b099d7
		  wid->core.width = my_request.width ;
Packit b099d7
	      _XmImResize((Widget)shell);
Packit b099d7
	      if (my_request.request_mode & CWHeight)
Packit b099d7
		  wid->core.height = my_request.height - ve->vendor.im_height;
Packit b099d7
	  }
Packit b099d7
	  return XtGeometryYes;
Packit b099d7
      } else 
Packit b099d7
	  return XtGeometryNo;
Packit b099d7
}
Packit b099d7
Packit b099d7
Packit b099d7
/*
Packit b099d7
 *************************************************************************
Packit b099d7
 *
Packit b099d7
 * Public creation entry points
Packit b099d7
 *
Packit b099d7
 *************************************************************************
Packit b099d7
 */
Packit b099d7
/*
Packit b099d7
 * low level create entry points
Packit b099d7
 */
Packit b099d7
Widget 
Packit b099d7
XmCreateDialogShell(
Packit b099d7
        Widget p,
Packit b099d7
        char *name,
Packit b099d7
        ArgList al,
Packit b099d7
        Cardinal ac )
Packit b099d7
{
Packit b099d7
    return (XtCreatePopupShell(name, xmDialogShellWidgetClass, p, al, ac));
Packit b099d7
}
Packit b099d7
Packit b099d7
/****************************************************************************
Packit b099d7
 * this suffix is added to dialog shells created by Xm convenience routines *
Packit b099d7
 * so that, for example, a call to create a form dialog named f generates a *
Packit b099d7
 * dialog shell named f_popup in addition to a form named f                 *
Packit b099d7
 ****************************************************************************/
Packit b099d7
Packit b099d7
#define XmDIALOG_SUFFIX		"_popup"
Packit b099d7
#define XmDIALOG_SUFFIX_SIZE	6
Packit b099d7
Packit b099d7
Packit b099d7
/****************************************************************
Packit b099d7
 * This convenience function creates a DialogShell and a given class
Packit b099d7
 *   child of the shell; returns the child widget.
Packit b099d7
 ****************/
Packit b099d7
Widget 
Packit b099d7
XmeCreateClassDialog(
Packit b099d7
	WidgetClass w_class,
Packit b099d7
	Widget ds_p,
Packit b099d7
        String name,
Packit b099d7
        ArgList bb_args,
Packit b099d7
        Cardinal bb_n )
Packit b099d7
{   
Packit b099d7
    Widget		bb ;		/*  child	*/
Packit b099d7
    Widget		ds ;		/*  DialogShell		*/
Packit b099d7
    ArgList		ds_args ;	/*  arglist for shell	*/
Packit b099d7
    char *              ds_name ;
Packit b099d7
Packit b099d7
    if (!name) name = "";
Packit b099d7
Packit b099d7
    /*	Create DialogShell parent.
Packit b099d7
    */
Packit b099d7
    ds_name = XtMalloc( (strlen(name)+XmDIALOG_SUFFIX_SIZE+1) * sizeof(char) ) ;
Packit b099d7
    strcpy( ds_name, name) ;
Packit b099d7
    strcat( ds_name, XmDIALOG_SUFFIX) ;
Packit b099d7
Packit b099d7
    ds_args = (ArgList) XtMalloc( sizeof( Arg) * (bb_n + 1)) ;
Packit b099d7
    memcpy( ds_args, bb_args, (sizeof( Arg) * bb_n)) ;
Packit b099d7
    XtSetArg( ds_args[bb_n], XmNallowShellResize, True) ; 
Packit b099d7
    ds = XmCreateDialogShell( ds_p, ds_name, ds_args, bb_n + 1) ;
Packit b099d7
Packit b099d7
    XtFree( (char *) ds_args);
Packit b099d7
    XtFree( ds_name) ;
Packit b099d7
Packit b099d7
    /*	Create the widget.
Packit b099d7
    */
Packit b099d7
    bb = XtCreateWidget(name, w_class, ds, bb_args, bb_n) ;
Packit b099d7
Packit b099d7
    /*	Add callback to destroy DialogShell parent.
Packit b099d7
    */
Packit b099d7
    XtAddCallback(bb, XmNdestroyCallback, _XmDestroyParentCallback, 
Packit b099d7
		  (XtPointer) NULL) ;
Packit b099d7
    /*	Return child.
Packit b099d7
    */
Packit b099d7
    return( bb) ;
Packit b099d7
}
Packit b099d7
Packit b099d7