/*---------------------------------------------------------------------
 * 
 *
 *             Copyright (c) 1992, Visual Edge Software Ltd.
 *
 * ALL  RIGHTS  RESERVED.  Permission  to  use,  copy,  modify,  and
 * distribute  this  software  and its documentation for any purpose
 * and  without  fee  is  hereby  granted,  provided  that the above
 * copyright  notice  appear  in  all  copies  and  that  both  that
 * copyright  notice and this permission notice appear in supporting
 * documentation,  and that  the name of Visual Edge Software not be
 * used  in advertising  or publicity  pertaining to distribution of
 * the software without specific, written prior permission. The year
 * included in the notice is the year of the creation of the work.
 *-------------------------------------------------------------------*/
/*---------------------------------------------------------------------
 DESCRIPTION:	Motif-specific widget creation support functions.
		This file is included by <uimx.c> during compilation.

		Special checks are performed during widget creation to
		determine if dialog or menu shells must be created instead of
		the normal shells.

 CREATION:	27 July 1989

 090818		last modif

 *--------------------------------------------------------------------*/

/*--- include files ---*/
#include "version.h"

#include <stdlib.h>

/******* Included so that the WidgetClass pointers can be used.  *******/
#include <Xm/MainW.h>
#include <Xm/RowColumn.h>
#include <Xm/BulletinB.h>
#include <Xm/MenuShell.h>
#include <Xm/DialogS.h>
#include <Xm/Protocols.h>
#include <X11/Shell.h>
 
#include <X11/Intrinsic.h>
#include <X11/IntrinsicP.h>
#include <X11/RectObjP.h>


/*--- macro symbolic constants ---*/

/*--- macro functions ---*/

/*--- types ---*/

/*--- external functions ---*/

extern int   UxFindValue();

extern void XmScrolledWindowSetAreas();


/*--- external variables ---*/

/*--- global variables ---*/

/*--- file global variables ---*/
M_FILE_VERSION("$Header")

/*--- forward declaration of static functions ---*/
static void InstallMwmCloseCallback();
#ifdef decstation
static void UpdateShadowThickness ();
#endif	/* decstation */

/*------------------------------------------------------------
 * COMMENT_BOX
 *-----------------------------------------------------------*/

 
/******************************************************************************
NAME:		int		NeedsMenuShell (arg_list, size)

INPUT:		ArgList		arg_list	- widget argument list
		int		size		- size of argument list
		WidgetClass	widget_class	- class of widget

RETURN:		Boolean

DESCRIPTION:	Checks if the widget is a rowColumn and if its type is set to
		be a popup or pulldown menu; if these conditions are met, then
		the rowColumn widget is being used as a menu and needs a
		menuShell.

CREATION:	Jul 27/1989
REVISIONS:	--
-----------------------------------------------------------------------------*/

static	int	NeedsMenuShell (arg_list, size, widget_class)
ArgList		arg_list;
int		size;
WidgetClass	widget_class;
{
	int	i;

	/* first compare the class of the widget */

	if (widget_class != xmRowColumnWidgetClass)
		return 0;

	/* loop through the argument list and search for the rowColumnType
	   property; if it is set to be a popup or pulldown menu, then a
	   menuShell is needed */

	for (i = 0; i < size; i++)
	{
		if (strcmp (arg_list[i].name, XmNrowColumnType) == 0
		    && (arg_list[i].value == XmMENU_POPUP
			|| arg_list[i].value == XmMENU_PULLDOWN))
			return 1;
	}

	/* no match was found */

	return 0;
}

/******************************************************************************
NAME:		int		IsPopupMenu (arg_list, size, widget_class)

INPUT:		ArgList		arg_list	- widget argument list
		int		size		- size of argument list
		WidgetClass	widget_class	- class of widget

RETURN:		Boolean

DESCRIPTION:	Checks if the widget is a rowColumn and if its type is set to
		be a popup menu.

CREATION:	Aug 16/1989
REVISIONS:	--
-----------------------------------------------------------------------------*/

static	int	IsPopupMenu (arg_list, size, widget_class)
ArgList		arg_list;
int		size;
WidgetClass	widget_class;
{
	int	i;

	/* first compare the class of the widget */

	if (widget_class != xmRowColumnWidgetClass)
		return 0;

	/* loop through the argument list and search for the rowColumnType
	   property; if it is set to be a popup menu, then return 'true' */

	for (i = 0; i < size; i++)
	{
		if (strcmp (arg_list[i].name, XmNrowColumnType) == 0
		    && arg_list[i].value == XmMENU_POPUP)
			return 1;
	}
	
	/* no match was found */

	return 0;
}

/*----------------------------------------------------------------------------
NAME:		void	UxDealWithShellTitleAndIconName (shl, name)
INPUT:		Widget  shl		the shell widget.
		char *name	the name to set.
RETURN:		void
DESCRIPTION:	Set the title and iconName of an implicit shell.
CREATION:	Oct/16/91	fix3059
------------------------------------------------------------------------------*/

void	UxDealWithShellTitleAndIconName (shl, name)
Widget	shl;
char	*name;
{
	Arg	 args[5];
	int	 i = 0;
       /* 
	* For all shells subclass of wmShellWidgetClass
	* (this excludes overrideShellWidgetClass)
	* set the title of implicit shell to be
	* the name of its child by default. For shells
	* subclass of topLevel shells, also set the 
	* iconName.
	*/
	if (XtIsSubclass (shl, wmShellWidgetClass)) {
	    XtSetArg (args[i], XtNtitle, name);
	    i++;
	}
	if (XtIsSubclass (shl, topLevelShellWidgetClass)) {
	    XtSetArg (args[i], XtNiconName, name);
	    i++;
	}
	if (i > 0) 
		XtSetValues (shl, args, i);

}

/*******************************************************************************
NAME:		static swidget	CreateImplicitShell (sw, name, class)

INPUT:		swidget		sw		- swidget
		char		*name		- widget name
		WidgetClass	widget_class	- class of widget

RETURN:		Widget

DESCRIPTION:	Create implicit shell

CREATION:	July 1990	(see bug710)
LAST REV:	May 92	fix3571	-- rewrite for pointer swidget type.
-----------------------------------------------------------------------------*/

static 	Widget CreateImplicitShell(sw, name, shell_class, parent)
swidget	sw;
char	*name;
WidgetClass shell_class;
Widget	parent;
{
	char 		shellname[256];
	Arg		pa[10];
	Widget  	rtn;
	int		i=0;
	XtArgVal	value;

    	strncpy(shellname, name, 256);
	strncat(shellname, "_shell", 256);
		    
       /*
	* Don't set XmShellUnitType if a mainWindow is parented
	* on a dialogShell.
	*/
	if (!(shell_class == xmDialogShellWidgetClass &&
		 UxGetClass(sw) == xmMainWindowWidgetClass)) {

	        if (UxFindValue (sw, XmNunitType, &value)){
               		if (value != XmPIXELS) {
                  		XtSetArg(pa[i], XmNshellUnitType, value); 
				i++;
	       		}
	    	}
	}

	if(UxFindValue (sw, XtNx, &value)) {
		XtSetArg(pa[i], XtNx, value);
		i++;
	}
	if(UxFindValue (sw, XtNy, &value)) {
		XtSetArg(pa[i], XtNy, value);
		i++;
	}
	if(UxFindValue (sw, XtNheight, &value)) {
		XtSetArg(pa[i], XtNheight, value);
		i++;
	}
	if(UxFindValue (sw, XtNwidth, &value)) {
		XtSetArg(pa[i], XtNwidth, value);
		i++;
	}
	if (UxFindValue (sw, XtNallowShellResize, &value)) {
		XtSetArg(pa[i], XtNallowShellResize, value); 
		i++ ;
	}
	rtn =  XtCreatePopupShell(shellname, shell_class, parent, pa, i);
       /*
	* set the shell title and iconName after creation so
	* that these values can be set to the appropriate shell
	* classes.
	*/	
	if (rtn)
		UxDealWithShellTitleAndIconName (rtn, UxGetName (sw));

	return rtn;
}

/*******************************************************************************
NAME:		static WidgetClass	DetermineImplicitShellClass (sw)
INPUT:		swidget		sw		- swidget
RETURN:		WidgetClass
DESCRIPTION:	Determine implicit shell class
CREATION:	July 1990	(see bug710)
LAST REV:	May 92	fix3571	-- rewrite for pointer swidget type.
-----------------------------------------------------------------------------*/
	
static 	WidgetClass DetermineImplicitShellClass(sw)
swidget sw;
{
	WidgetClass	shell_class;

	if (UxSwidgetGetFlag(sw, UXDIALOG_FLAG))
		return xmDialogShellWidgetClass;
	else if ((shell_class = (WidgetClass)UxGetDefaultShell(sw)))
		return shell_class;
        else
	    	return (WidgetClass)UxUserShell;
}		
	
/*******************************************************************************
NAME:		static swidget	CreateMenuShell (name, pwidget, class, list, sz)

INPUT:		char		*name		- widget name
		WidgetClass	class		- class of widget
		Widget		pwidget		- parent
		ArgList		list		- argument list
		int		sz		- size of argument list

RETURN:		Widget

DESCRIPTION:	create a menu shell 

CREATION:	July 1990  (see bug710)
REVISIONS:	--
-----------------------------------------------------------------------------*/
	
static	Widget CreateMenuShell(name, pwidget, w_class, list, sz)
char	*name;
Widget  pwidget;
WidgetClass w_class;
ArgList list;
int	sz;
{
	Arg	pa[5];
	int	i=0;
	char    shellname[256];

	strncpy(shellname, name, 256);
	strncat(shellname, "_shell", 256);
				
	XtSetArg (pa[i], XmNwidth, (Dimension) 1);
	i++;
	XtSetArg (pa[i], XmNheight, (Dimension) 1);
	i++;
	XtSetArg (pa[i], XmNallowShellResize, TRUE);
	i++;
	XtSetArg (pa[i], XmNoverrideRedirect, TRUE);
	i++;
				
	if (IsPopupMenu (list, sz, w_class)) {	
		if (! pwidget)
			pwidget= UxTopLevel;
        }
        else if((XtParent(pwidget)) && (XmIsMenuShell(XtParent(pwidget))))
		pwidget = XtParent (pwidget);
				
	return XtCreatePopupShell(shellname, xmMenuShellWidgetClass, pwidget, pa, i);
}
/******************************************************************************
NAME:		Widget		UxCreateWidget(sw)

INPUT:		swidget		sw	- swidget whose xwidget to create

RETURN:		Widget	*	- xwidget created from the swidget

DESCRIPTION:	Creates the xwidget using the values from the swidget.
		Dialogs are given dialog shells, and a check is made for the
		dialog convenience classes so that the 'dialogType' resource
		can be set properly.

CREATION:	Mar 14/1989
LAST REV:	March 93    fix3963	UxIsSwidget now called.
-----------------------------------------------------------------------------*/

Widget  UxCreateWidget(sw)
swidget      sw;
{
	String		name;
	WidgetClass	w_class, shell_class;
	swidget		parent;
	ArgList		list;
	int		sz, real_shell = 0, is_menu = 0;
	int		is_parent_dialog=0, needs_implicit_shell=0;
	char		*tr;
	Widget		pwidget;
	Widget		w = UxGetWidget(sw);

	if (w)
		return w;

	if (UxIsSwidget(sw))
	{
	    parent  = UxGetParent(sw);
	    pwidget = UxGetWidget(parent);
	    w_class   = UxGetClass(sw);
	    name    = UxGetName(sw);
	    real_shell = UxIsShellClass(w_class);
	    sz 	=  sw->NumValues;
	    list = sw->Values;

	    if (real_shell)
	    {
		w = XtCreatePopupShell(name, w_class,
			(pwidget ? pwidget : UxTopLevel), list, sz);

		InstallMwmCloseCallback(w);
	    }
	    else
	    {
		needs_implicit_shell = UxSwidgetGetFlag(sw, UXDIALOG_FLAG) 
					|| (!pwidget);

		if ( needs_implicit_shell )
		{
			shell_class = DetermineImplicitShellClass(sw);
			pwidget = CreateImplicitShell(sw, name, shell_class,
				           (pwidget ? pwidget : UxTopLevel));

			InstallMwmCloseCallback(pwidget);
			RecordWidget(pwidget, sw);
		}

		/* menu rowColumn widgets need a menuShell */
		is_menu = NeedsMenuShell (list, sz, w_class);
		if (is_menu)
		    pwidget = CreateMenuShell(name, pwidget, w_class, list, sz);

		is_parent_dialog=XtIsSubclass(pwidget, xmDialogShellWidgetClass);

		if (   is_menu 
		    || is_parent_dialog 
		    || (strcmp(UxGetCreateManaged(sw), "false") == 0)
		   )
		{
		    w = XtCreateWidget (name, w_class, pwidget, list, sz);
		}
		else
		{
		    w = XtCreateManagedWidget (name, w_class, pwidget, list, sz);
		}
	    }

	    sw->ItsWidget = w;
	    RecordWidget(w, sw);

#ifdef decstation
	    /*  Fixes a Motif bug on the decstation where menu buttons are
             *  fat since the default value of the shadowThickness resource is
             *  way too large for unitType other than pixels.
	     */
	    UpdateShadowThickness (sw, list, sz);
#endif

	    if ((tr = UxGetTranslations(sw)))
	         UxAddTranslations(sw, tr);

            if((tr = UxGetAccelerators(sw)))
	         UxAddAccelerators(sw, tr);

	    UxSwidgetFreeArgs(sw);
	}
	return w;
}

/******************************************************************************
NAME:		void		PostPopupMenu (w, client_data, event, cont)

INPUT:		Widget		w		- widget where event occured
		XtPointer	client_data	- popup menu widget as closure
		XEvent		*event		- pointer X Event structure
		Boolean		*cont		- not used

DESCRIPTION:	Post a popup menu by first positioning it, then managing it.

CREATION:	Aug 1/1989
-----------------------------------------------------------------------------*/

static	void	PostPopupMenu (w, client_data, event, cont)
Widget		w;
XtPointer 	client_data;
XEvent		*event;
Boolean		*cont;		
{
	Widget popup = (Widget) client_data;
	XButtonPressedEvent *button_event = (XButtonPressedEvent *) event;
        extern  WidgetClass xmRowColumnWidgetClass;

        if (popup && (XtClass(popup) == xmRowColumnWidgetClass))
        {
           Arg  a[1];
           int which_button;
           XtSetArg(a[0], XmNwhichButton, &which_button);
           XtGetValues(popup, a, 1);
           if(button_event->button != which_button)
           {
                return;
           }
        }
        else
        {
            if(button_event->button != Button3)
            {
                return;

            }
        }
	XmMenuPosition (popup,  button_event);
	XtManageChild (popup);
}

/******************************************************************************
NAME:		void		UxRegisterPopupMenuHandler (wid, popup_wid)

INPUT:		Widget		wid		- menu parent widget
				popup_wid	- popup menu widget

DESCRIPTION:	Adds the popup menu event handler to position and popup the
		menu on the parent widget.

CREATION:	Aug 1/1989
REVISIONS:	--
-----------------------------------------------------------------------------*/

void	UxRegisterPopupMenuHandler (wid, popup_wid)
swidget	wid, popup_wid;
{
	XtAddEventHandler (UxGetWidget(wid), ButtonPressMask, False,
			   PostPopupMenu, (XtPointer)UxGetWidget(popup_wid));
}

/*--------------------------------------------------------------------------
NAME:	  	UxPostMenu(widget, event, pars, npars)	
INPUT:		Widget widget, XEvent *event, String *pars, Cardinal *npars 	
RETURN:
DESCRIPTION: 	Post a popup menu	
CREATION:	Sept . 15, 89 
REVISIONS:	March 93    fix3963	UxIsSwidget now called.
--------------------------------------------------------------------------*/

static void nothing(widget, event, pars, npars)
 Widget widget;
 XEvent *event;
 String *pars;
 Cardinal *npars;
{
}

static XtActionsRec     action_list[]={{"nothing", nothing},
                                       {"UxPostMenu", UxPostMenu}};

static Widget post_widget;


void UxPostMenu(widget, event, pars, npars)
 Widget widget;
 XEvent *event;
 String *pars;
 Cardinal *npars;
{
    swidget mmgr;		/*menu manager*/
    Widget   menu_manager;	/*X menu manager*/


    post_widget = widget;
    mmgr = UxFindSwidget(pars[0]);

    if ((UxIsSwidget(mmgr))  && (menu_manager = UxGetWidget(mmgr)) )
    {
	    XmMenuPosition (menu_manager, (XButtonPressedEvent *) event);
	    XtManageChild (menu_manager);
    }
}

/*--------------------------------------------------------------------------
NAME:	  	UxScrolledWindowSetAreas(mwe, hsb, vsb, ww)
INPUT:		swidget mwe, hsb, vsb, ww;
RETURN:
DESCRIPTION: 	Call the XmScrolledWindowSetAreas function.
CREATION:	Sept 22, 90
REVISIONS:	--
--------------------------------------------------------------------------*/

void	UxScrolledWindowSetAreas (sw, hsb, vsb, ww)
	swidget	sw, hsb, vsb, ww;
{
	Widget	wsw 	= UxGetWidget(sw);

	if (! wsw)
		return;

	XmScrolledWindowSetAreas(wsw, UxGetWidget(hsb),
				      UxGetWidget(vsb),
				      UxGetWidget(ww));
}

/*--------------------------------------------------------------------------
NAME:	  	UxMainWindowSetMessageWindow(mw, msgw)
INPUT:		swidget mw, msgw;
		mw - The Main Window Widget.
		msgw - The Message Window Widget.
RETURN:
DESCRIPTION: 	This function  is added to complement UxMainWindowSetAreas
		Which does not contain a mechanism to add a Message Window
		to a Main Window. We did not change the UxMainWindowSetAreas
		to stay compatible with already released UIM/X.

CREATION:	4 Fevrier 1991		(bug2045)
REVISIONS:	
--------------------------------------------------------------------------*/

void	UxMainWindowSetMessageWindow(mw, msgw)
	swidget	mw, msgw;
{
	Widget	wmw 	= UxGetWidget(mw);

	if (! wmw)
		return;

	XtVaSetValues(wmw, XmNmessageWindow, UxGetWidget(msgw), NULL); /* 0,NULL); */
        /* P.Ballester 2012-04-30. The above line must be NULL terminated, not 0,NULL */ 
}

/*--------------------------------------------------------------------------
NAME:	  	UxMainWindowSetAreas(mw, pdm, c, hsb, vsb, ww)
INPUT:		swidget mw, pdm, cmd, hsp, vsb, ww
RETURN:
DESCRIPTION: 	Call the XtMainWindowSetAreas function.
CREATION:	Sept 26, 89 
REVISIONS:	
--------------------------------------------------------------------------*/

void	UxMainWindowSetAreas(mw, pdm, cmd, hsb, vsb, ww)
	swidget	mw, pdm, cmd, hsb, vsb, ww;
{
	Widget	wmw = UxGetWidget(mw);

	if (! wmw)
		return;

	XmMainWindowSetAreas(wmw, UxGetWidget(pdm),
				  UxGetWidget(cmd),
				  UxGetWidget(hsb),
				  UxGetWidget(vsb),
				  UxGetWidget(ww));
}

/*--------------------------------------------------------------------------
NAME:	  	void UxAddAccelerators(s, t)
INPUT:		swidget s, t;
RETURN:
DESCRIPTION: 	given swidget s add accelerator property 
CREATION:       23, Nov. 1989	
REVISIONS:	September 06 1990 -- Call XtParseAcceleratorTable() instead of
		   			XtParseTranslationTable().
--------------------------------------------------------------------------*/

void UxAddAccelerators(s, t)
swidget s;
String t;
{
    Widget w;
    XtAccelerators acc;
    Arg arg[2]; 
      
    if((w = UxGetWidget(s)) && t){
        acc = XtParseAcceleratorTable(t);
        XtSetArg(arg[0], XmNaccelerators, acc);
        XtSetValues(w, arg, 1);
    }
}

/******************************************************************************
NAME:		Widget		UxAddTabGroup(sw)

INPUT:		swidget		sw	- swidget whose xwidget gets
					  XmAddTabGroup'ed

RETURN:		void

DESCRIPTION:	Performs a XmAddTabGroup on the widget associated with the
		swidget.

CREATION:	Jul 20/1990   	(see bug804)
REVISIONS:
-----------------------------------------------------------------------------*/
void  UxAddTabGroup(sw)
swidget      sw;
{
	Widget	w = UxGetWidget(sw);

	if (w)
		XmAddTabGroup(w);
}

/******************************************************************************
NAME:		Widget		UxRemoveTabGroup(sw)

INPUT:		swidget		sw	- swidget whose xwidget gets
					  XmRemoveTabGroup'ed

RETURN:		void

DESCRIPTION:	Performs a XmRemoveTabGroup on the widget associated with the
		swidget.
CREATION:	Jul 20/1990   	(see bug804)
REVISIONS:
-----------------------------------------------------------------------------*/

void  UxRemoveTabGroup(sw)
swidget      sw;
{
	Widget w = UxGetWidget(sw);

	if (w)
		XmRemoveTabGroup(w);
}

/******************************************************************************
NAME:		Atom		GetProtocolsAtom()

RETURN:		atom

DESCRIPTION:	Return the WM_PROTOCOLS atom to the caller.

CREATION:	Aug 01/1990
REVISIONS:	--
-----------------------------------------------------------------------------*/

static Atom GetProtocolsAtom()
{
	static Atom	prot;
	static int	init= 0;

	if(!init)
	{	prot= XmInternAtom(UxDisplay, "WM_PROTOCOLS", FALSE);
		init= 1;
	}

	return(prot);
}

/******************************************************************************
NAME:		Atom		GetDeleteWindowAtom()

RETURN:		delete atom

DESCRIPTION:	Return the WM_DELETE_WINDOW atom to the caller.

CREATION:	Aug 01/1990
REVISIONS:	--
-----------------------------------------------------------------------------*/

static Atom GetDeleteWindowAtom()
{
	static Atom	del_atom;
	static int	init= 0;

	if(!init)
	{	del_atom= XmInternAtom(UxDisplay, "WM_DELETE_WINDOW", FALSE);
		init= 1;
	}

	return(del_atom);
}

/******************************************************************************
NAME:		void		CloseButtonCallback(wid, unused,
					call_data)

INPUT:		Widget		wid		- widget
		caddr_t		unused		- unused info
		XmAnyCallbackStruct*call_data	- callback data

DESCRIPTION:	Mwm close button callback function.

CREATION:	Aug 01/1990
REVISIONS:	November 21 1990        [bug1159]
		-- Get the shell widget from the client data.
		   Some window managers do not pass back the right wid.
-----------------------------------------------------------------------------*/

static void CloseButtonCallback(wid, client_data, call_data)
	Widget			wid;
	XtPointer		client_data;
	XtPointer		call_data;
{
	Atom			dwa;
	Widget                  shell;
	XmAnyCallbackStruct	*cbstruct = (XmAnyCallbackStruct *) call_data;

	dwa= GetProtocolsAtom();
	shell = (Widget) client_data;
 
	if(cbstruct->event->xclient.message_type == dwa)
	{
		unsigned char	dr;
		swidget		sw;

		if (!XmIsVendorShell(shell))
			return;

		XtVaGetValues(shell, 
				XmNdeleteResponse, &dr,
				0,NULL);


		sw= UxWidgetToSwidget(shell);

		if (dr == XmDESTROY)
		{	if(XtIsSubclass(shell, applicationShellWidgetClass))
				exit(0);
			else
				UxDestroyInterface(sw);
		}
		else if (dr == XmUNMAP)
			UxPopdownInterface(sw);
	}
}

/******************************************************************************
NAME:		void		InstallMwmCloseCallback(shell)

INPUT:		Widget		shell		- shell to add callback to.

DESCRIPTION:	Add a callback for the close button on subclasses of
		vendor shell.

CREATION:	Aug 01/1990
REVISIONS:      November 21 1990        [bug1159]
		-- Pass the shell widget as the client data.
-----------------------------------------------------------------------------*/

static void InstallMwmCloseCallback(shell)
	Widget		shell;
{
	if(XmIsVendorShell(shell))
	{
		Atom		dwa;

		dwa= GetDeleteWindowAtom();

		XmAddWMProtocols(shell, &dwa, 1);
		XmAddWMProtocolCallback(shell, dwa, CloseButtonCallback, (XtPointer) shell);
	}
}


/*----------------------------------------------------------------------
 * NAME:	<char *UxGetText (sw)>
 * DESCRIPTION:	<Get the char string of the value resource associated with the
 *		 specified widget>
   A rotating buffer will contain the strings. For the first pass, the buffer
   is filled up to its size and for the subsequent strings to be stored, the
  location is first reallocated before the new string takes its place.
   Every time the buffer index reaches the size of the buffer, it is reset
   to 0 to create the rotating buffer. This way, we avoid system crashes
   because the pointer will always point to valid memory addresses but
   the memory content may not be the right one if the user waited too long
   (more than <size of buffer> calls to this converter) before using the
   value returned.
 * PARAMETERS:  Widget sw	- swidget to get resource from
 * RETURN:	char * 		- value resource 	
 * EXT REFS:	globals_used
 * EXT EFFECTS:	globals or other things altered
 * ASSUMPTIONS:
 * REVISIONS:	14/12/90	creation	
 *		dd/mm/yy	fix#	fix_description
 *--------------------------------------------------------------------*/
char    *UxGetText (sw)
        swidget sw;
{

   Widget	w = UxGetWidget(sw);
   char		*s = 0;
   static char  **RotatingBuffer;
   static int   BufferIndex = -1;

   if (w) 
   {
      Arg             	arg[1];
      XtSetArg (arg[0], XmNvalue, &s);
      XtGetValues (w, arg, 1);
#ifdef _IBMR2
      s = strdup(s);
#endif

      UxUpdateRotatingBuffer(&BufferIndex, &RotatingBuffer, s, XtFree);
      return(RotatingBuffer[BufferIndex]);
   }
   else
      return (NULL);
}

#ifdef decstation
/******************************************************************************
NAME:		Boolean	CheckForPresenceInArgumentList( arg, a, cnt )

INPUT:		char	*Argument;	The argument we are looking for 
		Arg	*a;		The argument list 
		int	cnt;		How many arguments in the list 

DESCRIPTION:	Finds out if the arguments (XmNshadowThickness for example)
		is in the list of values being passed for the creation of this 
		Widget.

CREATION:	8 Oct 1991	(fix2993)
-----------------------------------------------------------------------------*/

static	Boolean	CheckForPresenceInArgumentList (Argument, a, cnt)
	char	*Argument;
	Arg	*a;
	int	cnt;
{
	int	i=0;

	for (i=0;i<cnt;i++)
		if (UxStrEqual(Argument, a[i].name))
			return( True );

	return( False );
}
#endif  /* decstation */

#ifdef decstation
/******************************************************************************
NAME:		Boolean	IsInMenu (w)

INPUT:		Widget	w;		The widget to apply the test on.

DESCRIPTION:	Finds out if a widget is in a menu.

CREATION:	8 Oct 1991		fix3033
-----------------------------------------------------------------------------*/

static	Boolean	IsInMenu (w)
	Widget w;
{
	unsigned char	menuType;

	if (! w)
	    return (False);

	if (XtIsSubclass (w, xmRowColumnWidgetClass)) {
		XtVaGetValues (w, XmNrowColumnType, &menuType, 0);
		if (menuType == XmMENU_POPUP ||
		    menuType == XmMENU_BAR ||
		    menuType == XmMENU_OPTION) {
			return (True);
		}
	}
	return (IsInMenu (XtParent (w)));
}
#endif  /* decstation */

#ifdef decstation
/******************************************************************************
NAME:		static void	UpdateShadowThickness (sw, list, sz)

INPUT:		swidget	sw;	The swidget to apply the update to.
		ArgList list;	Argument list for the swidget.
		int	sz;	Size of the argument list.

DESCRIPTION:	Apply a correction on the buttonShadowThickness resource
		of all menus and its children if no UxPut calls were made and
		if the user has not set the resource in a resource file.
                It fixes a Motif bug on the decstation where menu buttons are
                fat since the default value of the shadowThickness resource is
                way too large for unitType values other than pixels.

CREATION:	8 Oct 1991		fix3033
-----------------------------------------------------------------------------*/
static void	UpdateShadowThickness (sw, list, sz)
	swidget	sw;
	ArgList	list;
	int	sz;
{
	Widget w;

	w = UxGetWidget (sw);

	if (IsInMenu (w))
	{
	    extern char	*UxProgramName;

	    /*  If the user has not done a UxPut call and
	     *  if the resource was not set in a resource file
	     *  then change the default value of shadowThickness.
	     */
	    if (CheckForPresenceInArgumentList (
			XmNshadowThickness, list, sz) == False &&
		!UxGetResource (UxProgramName, "shadowThickness"))
	    {
	    	extern unsigned char	UxFindUnitType ();

		/* Set the default value of the ShadowThickness resource */
		switch (UxFindUnitType (w))
		{
		    /*  Default value for ShadowThickness resource of a
		     *  Menu RowColumn and its children is 2 pixels.
		     */
		    case Xm100TH_MILLIMETERS:
			    UxPutShadowThickness (sw, 64);
			    break;
		    case Xm1000TH_INCHES:
			    UxPutShadowThickness (sw, 26);
			    break;
		    case Xm100TH_POINTS:
			    UxPutShadowThickness (sw, 200);
			    break;
		    case Xm100TH_FONT_UNITS:
			    UxPutShadowThickness (sw, 33);
			    break;
		    default:
			    break;
		}
	    }
	}
}
#endif /* decstation */
