/***************************** LICENSE START ***********************************

 Copyright 2012 ECMWF and INPE. This software is distributed under the terms
 of the Apache License version 2.0. In applying this license, ECMWF does not
 waive the privileges and immunities granted to it by virtue of its status as
 an Intergovernmental Organization or submit itself to any jurisdiction.

 ***************************** LICENSE END *************************************/

#include <MMotifOnly.hpp>
#include <Xm/Protocols.h>
#include <Xm/AtomMgr.h>
#include <Xm/FileSB.h>
extern "C"
{
#include <xec.h>
#include <X11/xpm.h>
Boolean _XmInstallPixmap (Pixmap pixmap, Screen *screen, char *image_name,
						  Pixel foreground, Pixel background);

}

#define WIN_ENTER	0
#define WIN_EXIT	1
#define B1_DOWN		2
#define B2_DOWN		3
#define B3_DOWN		4
#define B1_UP		5
#define B2_UP		6
#define B3_UP		7
#define B1_DRAG		8
#define B2_DRAG		9
#define B3_DRAG		10
#define M_MOVE		11
#define ASCII		12

extern "C"
{
//Prototypes forgotten in the Include Files.
void exit(int);
};


bool isStringArgument( const char* argname )
{
  if( !strcmp(argname, XmNlabelString)    ||
      !strcmp(argname, XmNtitleString)     ||
      !strcmp(argname, XmNapplyLabelString) ||
      !strcmp(argname, XmNcancelLabelString) ||
      !strcmp(argname, XmNhelpLabelString   ) ||
      !strcmp(argname, XmNlistLabelString)     ||
      !strcmp(argname, XmNokLabelString)        ||
      !strcmp(argname, XmNselectionLabelString)  ||
      !strcmp(argname, XmNacceleratorText) )
    {
      return true;
    }
  else
    {
      return false;
    }
}

void Mmanage_link (Widget, MWidget *cd, caddr_t)
{
    	Widget *childs;
	int    num;

	if (XtIsTopLevelShell(cd->widget))
		XtMapWidget(cd->widget);
    	else if (!XmIsForm(cd->widget) && 
	    !XmIsMessageBox(cd->widget) )
    	{
		num = cd->returnChildren(&childs);
		int i = 0;
		while(!XtIsComposite(childs[i])) i++;
    		XtManageChild ( childs[i]);
	}	
    	else XtManageChild ( cd->widget );
}

void Munmanage_link (Widget, MWidget *cd, caddr_t)
{
        Widget *childs;
        int    num;

	if (XtIsTopLevelShell(cd->widget))
		XtUnmapWidget(cd->widget);
        else if (!XmIsForm(cd->widget))
        {
                num = cd->returnChildren(&childs);
                int i = 0;
                while(!XtIsComposite(childs[i])) i++;
                XtUnmanageChild ( childs[i]);
        }
        else XtUnmanageChild ( cd->widget );

}

void Mdisable_link(Widget, MWidget *cd, caddr_t)
{
    XtSetSensitive (cd->widget, FALSE);
}

void Menable_link (Widget, MWidget *cd, caddr_t)
{
    XtSetSensitive (cd->widget, TRUE);
}



int MInitArgs(Arg*al, const char* arg_name, va_list argptr)
{
    XtArgVal argvalue;
    const char    *argname;
    int ac = 0;      // Arg Count
    XmString xmstrings;

    argname = (arg_name ? arg_name : va_arg(argptr, char*));

    while (argname != NULL )
    {
        argvalue = va_arg(argptr, XtArgVal);
	if( isStringArgument( argname ) )
	{
		xmstrings = Mstoxs((char *)argvalue);
       		XtSetArg(al[ac], (char*)argname, xmstrings); ac++;
    	}
	else 
	{
		XtSetArg(al[ac], (char*)argname, argvalue); 
		ac++;
	}
    	argname = va_arg(argptr, char*);
    }

    return ac;
}

void MFreeArgs(Arg*al, int ac)
{
    XtArgVal argvalue;
    char    *argname;

   	for (int ind = 0; ind < ac; ind++)
	{
		argname = al[ind].name ;
		argvalue = al[ind].value; 
		if( isStringArgument( argname ) )
		  {
			XmStringFree((XmString) argvalue);
		  }
	}
}

char * Mxstos(XmString xs)

{
	char *s;

	XmStringGetLtoR(xs,(XmStringCharSet)XmSTRING_DEFAULT_CHARSET,&s);
	return s;
}

XmString Mstoxs(const char *s)

{
	return XmStringCreateLtoR((char*)s,(XmStringCharSet)XmSTRING_DEFAULT_CHARSET);
}

void MSetResource(Widget w, XtResource resource, char* resource_name, char* resource_value)
{
	Arg al[64];
	register int ac = 0;
	int j;
	XmString slist[64];
	int nslist = 0;

	if (!strcmp("String", resource.resource_type))
	{
		XtSetArg(al[ac], resource_name, resource_value); ac++;
	}
	else if (!strcmp(XmRString, resource.resource_type))
	{
		slist[nslist] =  XmStringCreateLtoR(resource_value,
			(XmStringCharSet)XmSTRING_DEFAULT_CHARSET);
		XtSetArg(al[ac], resource_name, slist[nslist]); ac++;
		nslist++;
	}
	else
	{		
		char buf[1024];
		XrmValue from, converted_value;
		from.size = strlen(resource_value) + 1;
		from.addr = resource_value;
		converted_value.size = resource.resource_size;
		converted_value.addr = buf;
		if (XtConvertAndStore(w,"String", &from, resource.resource_type, &converted_value))
		{
			if (!strcmp(resource.resource_class, "IntArray"))
				XtSetArg(al[ac], resource_name, (int *) converted_value.addr);
			
			else if (resource.resource_size == sizeof(Boolean))
				XtSetArg(al[ac], resource_name, *(Boolean *) converted_value.addr);
			else if (resource.resource_size == sizeof(Dimension))
				XtSetArg(al[ac], resource_name, *(Dimension *) converted_value.addr);
			else
				XtSetArg(al[ac], resource_name, *(XtArgVal *) converted_value.addr);
			ac++;
		}
		else
			printf("Conversion failed for %s\n",resource_value);
	}
	if (ac) XtSetValues(w, al, ac); ac = 0;

	for (j = 0; j < nslist; j++)
		XmStringFree(slist[j]);
}

void MSetResources(Widget w, char* wname, va_list argptr)
{
	XtResourceList resourcelist;
	Cardinal nresources;
	char* widget_name = wname;
	char *resource_value, *resource_name;

	XtGetResourceList(XtClass(w),&resourcelist, &nresources);
	while (widget_name)
	{
		resource_name = va_arg(argptr, char*);
		resource_value = va_arg(argptr, char*);
		
		if (!strcmp(widget_name,"*") || !strcmp(widget_name,XtName(w)))
		{
			for (int i = 0; i < nresources; i++)
			{
				if (!strcmp(resource_name,resourcelist[i].resource_name))
				{
/* printf("Name = %s, resource = %s, value = %s\n", widget_name,resource_name, resource_value);
*/
					MSetResource(w,resourcelist[i], resource_name, resource_value);
					break;
				}
			}
		}
		widget_name = va_arg(argptr, char*);
	}
	XtFree((char*)resourcelist);
}

void MSetValuesToAllAux(Widget w, char* widget_name, va_list argptr)
{
	MSetResources(w, widget_name,argptr);

	if (XtIsComposite(w))
	{
		WidgetList wlist;
		int num;
		Arg al[5];
		int ac = 0;
	
		XtSetArg(al[ac],XmNnumChildren,(XtPointer)&num); ac++;
		XtSetArg(al[ac],XmNchildren,(XtPointer)&wlist); ac++;
		XtGetValues(w, al, ac);

		for (int i = 0; i < num; i++)
			MSetValuesToAllAux(wlist[i], widget_name, argptr);
	}
}

void MAppContext::init(int& argc, char* argv[],int dontfail)

{
        XtToolkitInitialize ();

        app_context = XtCreateApplicationContext ();

#if (XmVersion >= 1002)
        display = XtOpenDisplay (app_context, NULL, argv[0], "Metview",
                                 NULL, 0, &argc, argv);
#else
	Cardinal cargc = argc;
        display = XtOpenDisplay (app_context, NULL, argv[0], "Metview",
                                 NULL, 0, &cargc, argv);
	argc = (int) cargc;
#endif
        if (!display )

        {
			if(!dontfail)
			{
				printf("%s: can't open display, exiting...\n", argv[0]);
				exit (0);
			}
			else printf("Warning: can't open display\n");
        }

/*
	XmRegisterConverters();
        XtAddConverter( XmRString, XmRUnitType, XmCvtStringToUnitType, NULL, 0);
*/

}

void MWidget::setValue(const char* argname, XtPointer argvalue)
{
    	Arg al[1];

    	XtSetArg(al[0], (char*)argname, argvalue);

    	XtSetValues(widget, al, 1);
}

void MWidget::setValuesToAll(const char* widget_name, ...)
{
	if (!widget) return;

	va_list argptr;
	va_start(argptr,widget_name);
	MSetResources(widget,(char*)widget_name,argptr);

	if (XtIsComposite(widget))
	{
		WidgetList wlist;
		int num = returnChildren(&wlist);

		for (int i = 0; i < num; i++)
			MSetValuesToAllAux(wlist[i], (char*)widget_name, argptr);
	}
}

void MWidget::putResources(const char* cl, const char* name,const char*  val)
{
    if (!val) return;
    static XrmDatabase database = XtDatabase(XtDisplay(widget));
 
    char res[1024];
    sprintf(res, "Metview*%s.%s", cl, name);
    XrmPutStringResource(&database, res, val);
}

void MWidget::setValues(const char *first, ...)
{   
	va_list argptr;
	Arg al[64];           // Arg List
	register int ac = 0;  // Arg Count

if (!first) return; // Just in case there is no atributes defined after...
	va_start(argptr, first);

	ac = MInitArgs(al, (char*)first, argptr);
	XtSetValues(widget, al, ac);
	MFreeArgs(al, ac);
}

void MWidget::getValue(const char * argname, XtPointer argvalue)
{
	Arg  al[1];

	XtSetArg(al[0],(char*)argname,argvalue);
	XtGetValues(widget, al, 1);
}

MWidget * MWidget::returnObject(Widget widget)
{
	MWidget *object;
        Arg      al[1];
        int      ac = 0;

    XtSetArg(al[ac],XmNuserData,(XtPointer)&object); ac++;
    XtGetValues(widget, al, ac);

	return object;
}

MWidget *MWidget::returnParent()
{
	MWidget *mw = NULL;
	Widget   w  = XtParent(widget);
	
	while (!mw && w && !XtIsApplicationShell(w) && !XtIsTopLevelShell(w)) { 
	   	mw = returnObject(w);
		w  = XtParent(w);
	}

	return mw;
}

int  MWidget::returnChildren(Widget **children)
{
   	int num;

	getValue(XmNnumChildren, (XtPointer)&num); 
	getValue(XmNchildren, (XtPointer)children);
	
	return num;
}

int  MWidget :: manageItsChildren()
{
	Widget *children;
	int num;

	if (!XtIsComposite(widget)) return 0;
	num = returnChildren(&children);

	XtManageChildren(children,num);

	return 1;
}

int  MWidget::x()
{
   	int num;

	getValue(XmNx, (XtPointer)&num); 
	
	return num;
}

int  MWidget::y()
{
   	int num;

	getValue(XmNy, (XtPointer)&num); 
	
	return num;
}

int  MWidget::width() 
{
    Dimension w;

    getValue(XmNwidth, (XtPointer)&w);
    return (int)w;

}

int  MWidget::height() 
{
    Dimension h;

    getValue(XmNheight, (XtPointer)&h);
    return (int)h;
}

char * MWidget::getLabel()
{
        XmString xmstrings;
	char 	 *s;

        getValue(XmNlabelString, (XtPointer)&xmstrings);

        s =  Mxstos(xmstrings);

	XmStringFree(xmstrings);

	return s;
}

MWidget *MWidget::returnChild(const char * name)
{       
/*
	Widget *children;
        int num = returnChildren(&children);
	int ind;

	if (num <= 0) return NULL;

	for ( ind = 0; ind < num ; ind++)
                if (!strcmp(name, XtName(children[ind])))
                        break;
*/
 
	Widget c = XtNameToWidget(widget, name);
 
        return (c) ? returnObject(c) : NULL;

}
void MWidget::addEventProc(EventMask event_mask, XtEventHandler proc,
                         XtPointer data)
{
	XtAddEventHandler(widget, event_mask, False, proc, data);
}

void MWidget::removeEventProc(EventMask event_mask, XtEventHandler proc,
                                XtPointer data)
{
    XtRemoveEventHandler(widget, event_mask, False, proc, data);

}
void MWidget::addProc(const char* cb_name, ...)
{
   va_list 	  argptr;
   const char 	  *cbname;
   XtCallbackProc cbproc;
   XtPointer 	  cbdata;

   // get first callback name

   va_start(argptr, cb_name);
   cbname = cb_name;

   // remaining callbacks

    while (cbname != NULL)
    {
        // add callback

        cbproc = va_arg(argptr, XtCallbackProc);
        cbdata = va_arg(argptr, XtPointer);
	XtAddCallback(widget, cbname, cbproc, cbdata);

      	// get next callback name

	cbname = va_arg(argptr, char *);
    }

   va_end(argptr);
	
}
void MWidget::removeProc(const char* cb_name, ...)
{
   va_list 	  argptr;
   const char 	  *cbname;
   XtCallbackProc cbproc;
   XtPointer 	  cbdata;

   // get first callback name

   va_start(argptr, cb_name);
   cbname = cb_name;

   // remaining callbacks

    while (cbname != NULL)
    {
        // add callback

        cbproc = va_arg(argptr, XtCallbackProc);
        cbdata = va_arg(argptr, XtPointer);
	XtRemoveCallback(widget, cbname, cbproc, cbdata);

      	// get next callback name

	cbname = va_arg(argptr, char *);
    }

   va_end(argptr);
	
}

void MWidget::setFont(const char *font, ...)
 
{       
	va_list argptr;
        Arg al[64];           // Arg List
        register int ac = 0;  // Arg Count
        char *argname, *argvalue;
	char from_s [256];    // For font list conversion 
	XrmValue from_value, to_value; 

 
        va_start(argptr, font);
       
        ac = 0;
 
        while ((argname = va_arg(argptr, char *)) != NULL )
        {
                argvalue = va_arg(argptr, char*);
		sprintf ( from_s, argvalue );
		from_value.size = strlen(from_s)+1;
		from_value.addr = from_s;
		XtConvert(widget, XmRString, &from_value, XmRFontList, &to_value);
		if (to_value.size)
			XtSetArg(al[ac], argname, *(int *)to_value.addr); ac++;
        }
        XtSetValues ( widget,al, ac );
}

struct pcache {
	pcache *next;
	char   *name;
	Pixmap pixmap;
	Pixel  fg;
	Pixel  bg;
};

static pcache *pix;

Pixmap MWidget::getPixmapFromFile(const char *file)
{   
    Arg al[64];           // Arg List
    register int ac = 0;  // Arg Count
    Pixel fg, bg;

	if(file == NULL) return XmUNSPECIFIED_PIXMAP;
       
    XtSetArg(al[ac], XmNforeground, &fg ); ac++;
    XtSetArg(al[ac], XmNbackground, &bg ); ac++;
    XtGetValues(widget, al, ac );

	// look if the pixmap is cached

	pcache *p = pix;

	while(p)
	{
		if(p->fg == fg && p->bg == bg && strcmp(file,p->name) == 0)
			return p->pixmap;
		p = p->next;
	}


 
	Pixmap pixmap;
	pixmap = XmGetPixmap(XtScreen(widget),(char*)file,fg,bg);

	if(pixmap == XmUNSPECIFIED_PIXMAP)
	{
		Display *dpy = XtDisplay(widget);
		int     screen = DefaultScreen(dpy);
		Window  root   = RootWindow(dpy,screen);
		Pixmap shape;
		XpmAttributes atrib;

		atrib.valuemask = XpmExactColors | XpmCloseness;
		atrib.exactColors = 0;
		atrib.closeness = 65535;

		if(XpmReadFileToPixmap(dpy,root,(char*)file,
			&pixmap,&shape,&atrib) == PixmapSuccess)
			_XmInstallPixmap(pixmap,XtScreen(widget),(char*)file, fg,bg);
		else 
			pixmap = XmUNSPECIFIED_PIXMAP;

	}

	// Add to cache

	p         = XtNew(pcache);
	p->pixmap = pixmap;
	p->fg     = fg;
	p->bg     = bg;
	p->name   = XtNewString(file);
	p->next   = pix;
	pix       = p;


	return pixmap;
}
void MWidget::overlayButtonPixmaps(const char*file)
{
	Arg al[64];           // Arg List
    register int ac = 0;  // Arg Count

	Pixmap upper, lower, pixmap;
    upper = getPixmapFromFile(file);

	if(upper==XmUNSPECIFIED_PIXMAP)
		return;

	getValue(XmNlabelPixmap, (XtPointer) &lower);

	if(lower==XmUNSPECIFIED_PIXMAP)
		return;

	pixmap = OverlayPixmaps(widget, lower, upper, -1, -1); /* centered */

	XtSetArg(al[ac],XmNlabelPixmap,pixmap); ac++;

    if(pixmap != XmUNSPECIFIED_PIXMAP)
    {
        Pixmap disabled = MakeDisabledPixmap(widget,pixmap);
        XtSetArg(al[ac],XmNlabelInsensitivePixmap,disabled); ac++;
    }
    XtSetValues ( widget,al, ac );
}

void  MWidget::setButtonPixmaps(Pixmap pixmap) 
{
	Arg al[64];           // Arg List
	register int ac = 0;  // Arg Count

	// Set pixmap background to widget background
	if(pixmap != XmUNSPECIFIED_PIXMAP)
		pixmap = CopyBackground(widget,pixmap);

	XtSetArg(al[ac],XmNlabelPixmap,pixmap); ac++;

	if(pixmap != XmUNSPECIFIED_PIXMAP)
	{
		Pixmap disabled = MakeDisabledPixmap(widget,pixmap);
		XtSetArg(al[ac],XmNlabelInsensitivePixmap,disabled); ac++;
	}
	XtSetValues ( widget,al, ac );
}


void MWidget::setButtonPixmaps(const char *file)
{

	Pixmap pixmap = getPixmapFromFile(file);

	setButtonPixmaps(pixmap);

}

void MWidget::setPixmap(const char *pixmap, ...)
{   
	va_list argptr;
    Arg al[64];           // Arg List
    register int ac = 0;  // Arg Count
    char *argname, *argvalue;
 
    va_start(argptr, pixmap);
       
 
    while ((argname = va_arg(argptr, char *)) != NULL )
	{
		argvalue = va_arg(argptr, char*);
		Pixmap pixmap = getPixmapFromFile(argvalue);
		XtSetArg(al[ac],argname, pixmap);
		ac++;
	}
    XtSetValues ( widget,al, ac );
	va_end(argptr);
}

void MWidget::setHalfPixmap(const char *pixmap, ...)
{   
	va_list argptr;
    Arg al[64];           // Arg List
    register int ac = 0;  // Arg Count
    char *argname, *argvalue;
 
    va_start(argptr, pixmap);
       
 
    while ((argname = va_arg(argptr, char *)) != NULL )
	{
		argvalue = va_arg(argptr, char*);
		Pixmap pixmap = getPixmapFromFile(argvalue);
		pixmap = MakeHalfPixmap(widget, pixmap);	
		XtSetArg(al[ac],argname, pixmap);
		ac++;
	}
    XtSetValues ( widget,al, ac );
	va_end(argptr);
}


void MWidget::setColor(const char *pixmap, ...)
 
{   
    va_list argptr;
    Arg al[64];           // Arg List
    register int ac = 0;  // Arg Count
    char from_s [256];
    XrmValue from_value, to_value;
    char *argname, *argvalue;
	
 
    //if (DefaultDepthOfScreen(DefaultScreenOfDisplay(XtDisplay(widget))) != 1) return;

    va_start(argptr, pixmap);
       
    ac = 0;

 
    while ((argname = va_arg(argptr, char *)) != NULL )
    {
         argvalue = va_arg(argptr, char*);
         sprintf ( from_s, argvalue );
         from_value.size = strlen(from_s)+1;
         from_value.addr = from_s;
         XtConvert(widget, XmRString, &from_value, XmRPixel, &to_value);
         if (!to_value.addr) {
			sprintf ( from_s, "black" );
         	from_value.size = strlen(from_s)+1;
         	from_value.addr = from_s;
			XtConvert(widget, XmRString, &from_value, XmRPixel, &to_value);
		}
		XtSetArg(al[ac], argname, *(int *)to_value.addr);
		
        ac++;
    }
    XtSetValues ( widget,al, ac );
      
}


Boolean MWidget::isSensitive() 

{
	Boolean sensitive;

	getValue(XmNsensitive, &sensitive);

	return sensitive;
}

void MWidget::setCursor(unsigned int cursor)
{
	Widget parent;

	parent = widget;
	while ( !XtIsApplicationShell(parent)) parent = XtParent(parent);

	XDefineCursor (XtDisplay(parent), XtWindow(parent),
		       XCreateFontCursor (XtDisplay(parent), cursor) );

	XDefineCursor (XtDisplay(widget), XtWindow(widget),
		       XCreateFontCursor (XtDisplay(widget), cursor) );
	XFlush(XtDisplay(widget));
}

void MWidget::resetCursor()
{
	Widget parent;

	parent = widget;
	while ( !XtIsApplicationShell(parent)) parent = XtParent(parent);
	XUndefineCursor(XtDisplay(parent),XtWindow(parent));

	XUndefineCursor(XtDisplay(widget),XtWindow(widget));
}
	
void MShell::init(Display *display, const char *app_name, int app_argc, 
		  char **app_argv, ...)
{   va_list argptr;
    Arg al[64];           // Arg List
    register int ac = 0;  // Arg Count

    va_start(argptr, app_argv);
    ac = MInitArgs(al, (const char*)NULL, argptr);
    XtSetArg(al[ac], XmNargc, app_argc); ac++;
    XtSetArg(al[ac], XmNargv, app_argv); ac++;
    widget = XtAppCreateShell ( app_name, "Metview",
		 applicationShellWidgetClass, display, al, ac );
	
    attachObject();
    ident = mShell;
	MFreeArgs(al, ac);
}

void MShell::init(MWidget* parent, const char *name, ...)
{   va_list argptr;
    Arg al[64];           // Arg List
    register int ac = 0;  // Arg Count

    va_start(argptr, name);
    ac = MInitArgs(al, (const char*)NULL, argptr);
    if (dialog)
    	widget = XmCreateDialogShell( parent->widget, (char*)name, al, ac);
    else
    	widget = XtCreateWidget(name, topLevelShellWidgetClass, parent->widget, al, ac);
    attachObject();
    ident = mShell;
	MFreeArgs(al, ac);
}

void MShell :: addWMProc(const char* atom_name, XtCallbackProc proc, XtPointer mydata)
{
	// Examples of atom names:
	// "XM_DELETE_WINDOW"
	// "XM_TAKE_FOCUS"

	Atom protocol = XmInternAtom (XtDisplay(widget), (char*)atom_name, FALSE);

	XmAddWMProtocolCallback(widget, protocol, proc, (caddr_t) mydata);
}

void MForm::init(MWidget *parent, const char *name, ...)
{
        va_list argptr;
        Arg al[64];           /* Arg List */
        int ac = 0;      /* Arg Count */
 
        va_start(argptr, name);
        ac = MInitArgs(al, (const char*)NULL, argptr);
        widget = XmCreateForm ( parent->widget, (char*)name, al, ac);
        attachObject();
	MFreeArgs(al, ac);
        ident = mForm;
}
 
void MPushButton::init(MWidget *parent, const char *name, ...)
{
        va_list argptr;
        Arg al[64];           /* Arg List */
        register int ac = 0;      /* Arg Count */
 
        va_start(argptr, name);
        ac = MInitArgs(al, (const char*)NULL, argptr);
        widget = XmCreatePushButton( parent->widget, (char*)name, al, ac);
        attachObject();
        ident = mPushButton;
	MFreeArgs(al, ac);
}

void MPushButton::init(Boolean gadget, MWidget *parent, const char *name, ...)
{
        va_list argptr;
        Arg al[64];           /* Arg List */
        register int ac = 0;      /* Arg Count */
 
        va_start(argptr, name);
        ac = MInitArgs(al, (const char*)NULL, argptr);
        if (gadget) 
			widget = XmCreatePushButtonGadget( parent->widget, (char*)name, al, ac);
		else
			widget = XmCreatePushButton( parent->widget, (char*)name, al, ac);
        attachObject();
        ident = mPushButton;
        MFreeArgs(al, ac);
}

 
void MRowColumn::init(MWidget *parent, const char *name, ...)
{
        va_list argptr;
        Arg al[64];           /* Arg List */
        register int ac = 0;      /* Arg Count */
 
        va_start(argptr, name);
        ac = MInitArgs(al, (const char*)NULL, argptr);
        widget = XmCreateRowColumn( parent->widget, (char*)name, al, ac);
        attachObject();
        ident = mRowColumn;
	MFreeArgs(al, ac);
}


void MRowColumn::clear()
{

    Widget *childs;
    int num;

    num = returnChildren(&childs);

    for (int i = num-1; i >=0 ; i--) 
// <**Sylvie(28/09/93)**> XtUnmanageChild(childs[i]);
		XtDestroyWidget(childs[i]);

}

void MRowColumn::addChildrenProc(const char *cb_name, ...) 
{
    va_list argptr;
    const char *cbname;
    XtCallbackProc cbproc;
    XtPointer cbdata;
    Widget *childs;
    int num;
 
    num = returnChildren(&childs);
  
    // get first callback name

    va_start(argptr, cb_name);
    cbname = cb_name;
 
    while (cbname != NULL)
    {
       // add callback to all children
       cbproc = va_arg(argptr, XtCallbackProc);
       cbdata = va_arg(argptr, XtPointer);
       
       for (int i = num-1; i >=0 ; i--) XtAddCallback(childs[i], 
			cbname, cbproc, cbdata);


       // get next callback
       cbname = va_arg(argptr, char*);
    }
}

void MRowColumn::addItem(short sort, const char *name, ...)

{   va_list argptr;
    Arg al[64];           // Arg List
    register int ac = 0;  // Arg Count

    va_start(argptr, name);
    switch (sort)
    {
		case mPushButton: 
		{
			MPushButton *button = new MPushButton;
			button->init(False, (MWidget *)this, name, XmNlabelString, name, NULL);
			ac = MInitArgs(al, (const char*)NULL, argptr);
        		XtSetValues(button->widget, al, ac);
			MFreeArgs(al, ac);
//<**Sylvie(27/09/93)**> button->manage();
			break;
		}
		case mToggleButton:
		{
			MToggleButton *button = new MToggleButton;
			button->init(True, (MWidget *)this, name, XmNlabelString, name, NULL );
			ac = MInitArgs(al, (const char*)NULL, argptr);
        		XtSetValues(button->widget, al, ac);
//<**Sylvie(27/09/93)**>  button->manage();
			MFreeArgs(al, ac);
			break;
		}
     }

}
		
			
void MRowColumn::select(const char *name)
{
	MWidget  *child = returnChild(name);

	if (child) ( (MToggleButton *) child)->select(True);
}

void MRowColumn::unselect(const char *name)
{
	MWidget  *child = returnChild(name);

	if (child) XmToggleButtonSetState(child->widget, False, True);
}
	
void MRowColumn::select()
 
{
        Widget  *children;
        int num = returnChildren(&children);
 
        for (int i = 0; i < num; i++)
                select(XtName(children[i]));
 
}
void MRowColumn::unselect()
 
{
        Widget  *children;
        int num = returnChildren(&children);
 
        for (int i = 0; i < num; i++)
                unselect(XtName(children[i]));
}

void MRowColumn::sensitive()
 
{
        Widget  *children;
        int num = returnChildren(&children);
 
        for (int i = 0; i < num; i++)
                sensitive(XtName(children[i]));
 
}
void MRowColumn::insensitive()
 
{
        Widget  *children;
        int num = returnChildren(&children);
 
        for (int i = 0; i < num; i++)
                insensitive(XtName(children[i]));
}

int MRowColumn::returnSelectedItems(MWidget **items)

{
	int 	nb;
	int 	count = 0;
	Widget  *children;
	Arg 	 al[1];
	int	 ac = 0;
	Boolean  code;

	nb = returnChildren(&children);

	for (int i = 0; i < nb; i++)
	{	
		XtSetArg(al[ac],XmNset,&code); ac++;
		XtGetValues(children[i], al, ac);
		if (code) items[count++] = returnObject(children[i]);
		ac = 0;
	}
	return count; 

}

int MRowColumn::returnSelectedItems(Widget *items)
{
	int 	nb;
	int 	count = 0;
	Widget  *children;
	Arg 	 al[1];
	int	 ac = 0;
	Boolean  code;

	nb = returnChildren(&children);

	for (int i = 0; i < nb; i++)
	{	
		XtSetArg(al[ac],XmNset,&code); ac++;
		XtGetValues(children[i], al, ac);
		if (code) items[count++] = children[i];
		ac = 0;
	}
	return count; 

}

int MRowColumn::returnSelectedItems(char **items)
{
	Widget  item[200];
	int 	count = returnSelectedItems(item);

	if (count > 200) 
	{
		printf("Warning returnSelectedItems : list truncated to 200\n");
		count = 200;
	}
	for (int i = 0; i < count; i++) items[i] = XtName(item[i]);

	return count; 
}

char * MRowColumn::returnSelectedItemLabel()
{
	Widget	 w[200];
	Arg	 al[1];
	int 	 ac = 0;
	XmString xmstrings;
	char     *string;
	int      count = returnSelectedItems(w);

	if (count)
	{
		XtSetArg(al[ac], XmNlabelString, (XtPointer) &xmstrings); ac++;
		XtGetValues(w[0], al, ac);
		string = Mxstos(xmstrings);
		XmStringFree(xmstrings);

		return string;
	}
	else
		return NULL;
}

void MRowColumn::sensitive(const char *name)
{
	MWidget  *child = returnChild(name);
	if (child) child->sensitive();
}

void MRowColumn::insensitive(const char *name)
{
	MWidget  *child = returnChild(name);
	if (child) child->insensitive();
}

Boolean MRowColumn::isSensitive(const char *name)
{
	MWidget  *child = returnChild(name);
	if (child) return child->isSensitive();
	else return 0;
}

void MLabel::init(MWidget* parent, const char *name, ...)
{   
	va_list argptr;
	Arg al[64];           // Arg List
	register int ac = 0;  // Arg Count

	va_start(argptr, name);
	ac = MInitArgs(al, (const char*)NULL, argptr);
	if (parent->isMOptionMenu()) 
	{
		widget = XmOptionLabelGadget ( parent->widget);
		attachObject();
		XtSetValues(widget, al, ac);
	}
	else
	{
        	widget = XmCreateLabel( parent->widget, (char*)name, al, ac);
		attachObject();
	}
	ident = mLabel;
	MFreeArgs(al, ac);
}

void MLabel::init(Boolean gadget, MWidget* parent, const char *name, ...)
{
	va_list argptr;
	Arg al[64];           // Arg List
	register int ac = 0;  // Arg Count

	va_start(argptr, name);
	ac = MInitArgs(al, (const char*)NULL, argptr);
    if (gadget) widget = XmCreateLabelGadget( parent->widget, (char*)name, al, ac);
    else widget = XmCreateLabel( parent->widget, (char*)name, al, ac);
	attachObject();
	ident = mLabel;
	MFreeArgs(al, ac);
}

void MScrolledList::init(MWidget* parent, const char *name, ...)
{   
	va_list argptr;
	Arg al[64];           // Arg List
	register int ac = 0;  // Arg Count
	
	va_start(argptr, name);
	ac = MInitArgs(al, (const char*)NULL, argptr);
	widget = XmCreateScrolledList( parent->widget, (char*)name, al, ac);
	attachObject();
	ident = mScrolledList;
	MFreeArgs(al, ac);
}

void MScrollBar::init(MWidget* parent, const char *name, ...)
{   
	va_list argptr;
	Arg al[64];           // Arg List
	register int ac = 0;  // Arg Count

	if(!strcmp(name, "hScrollBar"))
		parent->getValue(XmNhorizontalScrollBar, (XtPointer)&widget);
	else if (!strcmp(name, "VscrollBar"))
		parent->getValue(XmNverticalScrollBar, (XtPointer)&widget);
	else
	{
    	va_start(argptr, name);
        widget = XmCreateScrollBar( parent->widget, (char*)name, al, ac);
	}
	attachObject();
	ident = mScrollBar;
}
	
void MScrollBar::scrollWH(MWidget *parent)
{
	parent->getValue(XmNhorizontalScrollBar, (XtPointer)&widget);
	attachObject();
	ident = mScrollBar;
}

void MScrollBar::scrollWV(MWidget *parent)
{
	parent->getValue(XmNverticalScrollBar, (XtPointer)&widget);
	attachObject();
	ident = mScrollBar;
}

void MScrolledWindow::init(MWidget* parent, const char *name, ...)
{   
	va_list argptr;
    	Arg al[64];           // Arg List
    	register int ac = 0;  // Arg Count

    	va_start(argptr, name);
    	ac = MInitArgs(al, (const char*)NULL, argptr);
    	widget = XmCreateScrolledWindow( parent->widget, (char*)name, al, ac);
    	attachObject();
	
   	ident = mScrolledWindow;
	MFreeArgs(al, ac);
}

void MScrolledWindow::manage(MWidget *h, MWidget *v, MWidget *w)
{
	XmScrolledWindowSetAreas(widget, h->widget, v->widget, w->widget );
	XtManageChild ( widget);
}

void MScrolledWindow::manage(MWidget *w)
{
	Widget h,v;
	XtVaGetValues(widget,
		XmNverticalScrollBar,  &v,
		XmNhorizontalScrollBar,&h,
		NULL);
	XmScrolledWindowSetAreas(widget, h, v, w->widget );
	XtManageChild ( widget);
}

void MList::init(MWidget* parent, const char *name, ...)
{   
	va_list argptr;
    	Arg	 al[64];           // Arg List
    	register int ac = 0;  // Arg Count

    	va_start(argptr, name);
    	ac = MInitArgs(al, (const char*)NULL, argptr);
    	widget = XmCreateScrolledList( parent->widget, (char*)name, al, ac);
    	attachObject();
    	ident = mList;
	MFreeArgs(al, ac);
}

void MList::setValues(const char* proc, ...)
{   
	va_list argptr;
   	Arg al[64];          
  	register int ac = 0;

   	va_start(argptr, proc);

   	ac = MInitArgs(al, (char*)proc, argptr);
  	XtSetValues(XtParent(widget), al, ac);
	MFreeArgs(al, ac);
}
void MList::addListMax(int n, const char *name)
{
	xec_AddListMax(widget, n, name);
}

void MList::addListMax(const char *name)
{
	int count;

	getValue(XmNvisibleItemCount, (XtPointer) &count);

	xec_AddListMax(widget, count, name);
}

void MList::addItem(int n, const char *name)

{
      	XmString item; /* For item */

        item = Mstoxs(name);

	XmListAddItem(widget, item, n+1);

	XmStringFree(item);
}

void MList::addItem(int n, XmString item)
{
	XmListAddItem(widget, item, n+1);
}

void MList::addItemUnselected(int n, const char *name)
{
    XmString item = Mstoxs(name); /* For item */

	XmListAddItemUnselected(widget, item, n+1);

	XmStringFree(item);
}

void MList::addItemUnselected(int n, XmString item)
{
	XmListAddItemUnselected(widget, item, n+1);
}

void MList::addItems(int n, int count, XmStringTable items)
{
	XmListAddItems(widget, items, count, n+1);
}

void MList::clear()
{
	XmListDeleteAllItems(widget);
}

void MList::selectItem(const char * item, Boolean notify)
{
	XmString xs;

	xs = Mstoxs(item);
	XmListSelectItem(widget, xs, notify);
	XmStringFree(xs);
}

void MList::selectItem(int item, Boolean notify)
{
	XmListSelectPos(widget, item+1, notify);
}

void MList::unselectItem(const char * item)
{
	XmString xs;

	xs = Mstoxs(item);
	XmListDeselectItem(widget, xs);
	XmStringFree(xs);
}

void MList::unselectItem(int item)
{
	
	XmListDeselectPos(widget, item+1);
}

void MList::unselectAllItems()
{
	XmListDeselectAllItems(widget);
}

int MList::returnSelectedItems(XmStringTable *items)
{
	int     count;
	getValue(XmNselectedItemCount, (XtPointer)&count);
	getValue(XmNselectedItems, (XtPointer)items);
	return count;
}


int MList::returnSelectedItems(char **items)
{
	int 	count;
	getValue(XmNselectedItemCount, (XtPointer)&count); 

	XmString *sel;
	getValue(XmNselectedItems, (XtPointer)&sel);

	for (int i = 0; i < count; i++)
		items[i] = Mxstos(sel[i]);
	return count;
}

int MList::returnSelectedItems(int **items)
{
	int 	count;
	if (!XmListGetSelectedPos(widget, items, &count))
		return 0; 
	for (int i = 0; i < count; i++) ((*items)[i])--; 
	return count;
}

int MList::selected()
{
    int     count;

    getValue(XmNselectedItemCount, (XtPointer)&count);
    return count;
}

int MList::listed()
{
	int     count;
	getValue(XmNitemCount, (XtPointer)&count);
	return count;
}

int MList::returnItems(XmStringTable *items)
{
	int count;
	getValue(XmNitems, (XtPointer) items);
	getValue(XmNitemCount, (XtPointer) &count);
	return count;
}

void MList::setSelectedItems(XmStringTable items, int item_cnt)
{
	setValues(XmNselectedItems, items, XmNselectedItemCount, item_cnt, 0);
}


void MToggleButton::init(MWidget* parent, const char *name, ...)
{   
	va_list argptr;
    	Arg al[64];           // Arg List
   	 register int ac = 0;  // Arg Count

    va_start(argptr, name);
    ac = MInitArgs(al, (const char*)NULL, argptr);
    widget = XmCreateToggleButton( parent->widget, (char*)name, al, ac);
    attachObject();
    ident = mToggleButton;
	MFreeArgs(al, ac);
}

void MToggleButton::init(Boolean gadget, MWidget* parent, const char *name, ...)
{   
	va_list argptr;
    	Arg al[64];           // Arg List
   	 register int ac = 0;  // Arg Count

    va_start(argptr, name);
    ac = MInitArgs(al, (const char*)NULL, argptr);
    if (gadget) 
		widget = XmCreateToggleButtonGadget( parent->widget, (char*)name, al, ac);
    else widget = XmCreateToggleButton( parent->widget, (char*)name, al, ac);
    attachObject();
    ident = mToggleButton;
	MFreeArgs(al, ac);
}

Boolean  MToggleButton::isSelected()
{
	return XmToggleButtonGetState(widget);
}

void MToggleButton::select(Boolean notify)
{
	XmToggleButtonSetState(widget, True, notify);
}
void MToggleButton::unselect()
{
	XmToggleButtonSetState(widget, False, False);
}

void MTextField::init(MWidget* parent, const char *name, ...)
{   va_list argptr;
    Arg al[64];           // Arg List
    register int ac = 0;  // Arg Count

    va_start(argptr, name);
    ac = MInitArgs(al, (const char*)NULL, argptr);
    widget = XmCreateTextField( parent->widget, (char*)name, al, ac);
    attachObject();
    ident = mTextField;
	MFreeArgs(al, ac);
}

void MTextField::setValue(float v)
{
    char str[30];

    sprintf(str, "%f", v);
    MWidget :: setValue(XmNvalue, str);
}

void MTextField::setValue(double v)
{
    char str[30];

    sprintf(str, "%g", v);
    MWidget :: setValue(XmNvalue, str);
}

void MTextField::setValue(int v)
{
    char str[30];

    sprintf(str, "%d", v);
    MWidget :: setValue(XmNvalue, str);
}

char * MTextField::returnValue()
{
	char *value;
	getValue(XmNvalue, (XtPointer) &value);

	return value;
}
void MMenuBar::init(MWidget *parent, const char *name, ...)
{
        va_list argptr;
        Arg al[64];           /* Arg List */
        register int ac = 0;      /* Arg Count */
 
        va_start(argptr, name);
        ac = MInitArgs(al, (const char*)NULL, argptr);
        widget = XmCreateMenuBar( parent->widget, (char*)name, al, ac);
        attachObject();
        ident = mSeparator;
	MFreeArgs(al, ac);
}
void MSeparator::init(MWidget *parent, const char *name, ...)
{
        va_list argptr;
        Arg al[64];           /* Arg List */
        register int ac = 0;      /* Arg Count */
 
        va_start(argptr, name);
        ac = MInitArgs(al, (const char*)NULL, argptr);
        widget = XmCreateSeparator( parent->widget, (char*)name, al, ac);
        attachObject();
        ident = mSeparator;
	MFreeArgs(al, ac);
}
void MOptionMenu::init(MWidget *parent, const char *name, ...)
{
        va_list argptr;
        Arg al[64];           /* Arg List */
        register int ac = 0;      /* Arg Count */
 
        va_start(argptr, name);
        ac = MInitArgs(al, (const char*)NULL, argptr);
        widget = XmCreateOptionMenu( parent->widget, (char*)name, al, ac);
        attachObject();
        ident = mOptionMenu;
	MFreeArgs(al, ac);
}

void MOptionMenu::manage(MWidget *menu)
{
	setValues(XmNsubMenuId, menu->widget, NULL);
	XtManageChild(widget);
}

void MOptionMenu::addItem(const char * name)
{
	Widget menu;
	MWidget *Menu;
	MPushButton *button = new MPushButton;

	getValue(XmNsubMenuId, (XtPointer) &menu);
	Menu = returnObject(menu);
	
	button->init(Menu, name, 
		XmNlabelString, (XtArgVal) name,
		NULL);
//<**Sylvie(27/09/93)**> button->manage();
	
}

void MOptionMenu::clear()
{
	Widget menu;
	MWidget *Menu;
    	Widget *childs;
	int num;

	getValue(XmNsubMenuId, (XtPointer) &menu);
	Menu = returnObject(menu);

	num = Menu->returnChildren(&childs);

	for (int i = num-1; i >=0 ; i--) XtDestroyWidget(childs[i]);
}

void MOptionMenu::selectItem(const char * item)
{
	Widget menu;
	MWidget *Menu;
    	MWidget *child;

	getValue(XmNsubMenuId, (XtPointer) &menu);
	Menu = returnObject(menu);

	child  = Menu->returnChild(item);
	if (child)
		setValues(XmNmenuHistory, child->widget, NULL);

}

void MOptionMenu::selectItem(int position)
{
	Widget menu;
	MWidget *Menu;
    	Widget *children;
	int num;

	getValue(XmNsubMenuId, (XtPointer) &menu);
	Menu = returnObject(menu);

	num = Menu->returnChildren(&children);

	if (position < num)
		setValues(XmNmenuHistory, children[position], NULL);
}

int MOptionMenu::returnSelectedItems(char **items)
{
	Widget widget;

	getValue(XmNmenuHistory, (XtPointer) &widget);
	items[0] = XtName(widget);
	return 1;
}

char * MOptionMenu::returnSelectedItemLabel()
{
    	Widget w;
    	Arg al[1];
    	int ac = 0;
    	XmString xmstrings;
    	char*   s;

    	getValue(XmNmenuHistory, (XtPointer) &w);
    	XtSetArg(al[ac], XmNlabelString, (XtPointer) &xmstrings); ac++;
    	XtGetValues(w, al, ac);

    	s = Mxstos(xmstrings);
    	XmStringFree(xmstrings);

    	return s;
}

MWidget* MOptionMenu::returnSelectedItem()
{
    	Widget w;

    	getValue(XmNmenuHistory, (XtPointer) &w);
    	return returnObject(w);
}

void MCascadeButton::init(MWidget* parent, const char *name, ...)
{   
	va_list argptr;
    	Arg	 al[64];           // Arg List
    	register int ac = 0;  // Arg Count

    	va_start(argptr, name);
    	ac = MInitArgs(al, (const char*)NULL, argptr);
    	if (parent->isMOptionMenu()) 
    	{
        	widget = XmOptionButtonGadget ( parent->widget);
        	XtSetValues(widget, al, ac);
    	}
    	else widget = XmCreateCascadeButton( parent->widget, (char*)name, al, ac);
	
    	attachObject();
    	ident = mCascadeButton;
	MFreeArgs(al, ac);
}
void MCascadeButton::init(Boolean gadget, MWidget* parent, const char *name, ...)
{   
	va_list argptr;
    	Arg	 al[64];           // Arg List
    	register int ac = 0;  // Arg Count

    	va_start(argptr, name);
    	ac = MInitArgs(al, (const char*)NULL, argptr);
    	if (gadget)  widget = XmCreateCascadeButtonGadget( parent->widget, (char*)name, al, ac);
    	else widget = XmCreateCascadeButton( parent->widget, (char*)name, al, ac);
	
    	attachObject();
    	ident = mCascadeButton;
	MFreeArgs(al, ac);
}


void MCascadeButton::manage(MWidget *child)
{
	MWidget*  parent = returnParent();

	if (!parent->isMOptionMenu()) 
		setValues(XmNsubMenuId, child->widget, NULL);
	XtManageChild(widget);
}

void MPulldownMenu::init(MWidget* parent, const char *name, ...)
{   
	va_list argptr;
    	Arg al[64];           // Arg List
    	register int ac = 0;  // Arg Count
    	Widget menu;

    	menu = parent->widget;

    	while (!XmIsRowColumn(menu) && !XmIsForm(menu)) menu = XtParent(menu);

    	va_start(argptr, name);
    	ac = MInitArgs(al, (const char*)NULL, argptr);
    	ident = mPulldownMenu;
    	widget = XmCreatePulldownMenu( menu, (char*)name, al, ac);
    	attachObject();
	MFreeArgs(al, ac);
}

void MFrame::init(MWidget *parent, const char *name, ...)
{
        va_list argptr;
        Arg al[64];           /* Arg List */
        register int ac = 0;      /* Arg Count */
 
        va_start(argptr, name);
        ac = MInitArgs(al, (const char*)NULL, argptr);
        ident = mFrame;
        widget = XmCreateFrame( parent->widget, (char*)name, al, ac);
        attachObject();
	MFreeArgs(al, ac);
}

void MDrawingArea::init(MWidget *parent, const char *name, ...)
{
        va_list argptr;
        Arg al[64];           /* Arg List */
        register int ac = 0;      /* Arg Count */
 
        va_start(argptr, name);
        ac = MInitArgs(al, (const char*)NULL, argptr);
        ident = mDrawingArea;
        widget = XmCreateDrawingArea( parent->widget, (char*)name, al, ac);
        attachObject();
	MFreeArgs(al, ac);
}

void MDrawingArea::mouseXY(int *x, int *y)
{
	
    Window  root, child;
    int     root_x, root_y;
    unsigned int keys;

    XQueryPointer(XtDisplay(widget), XtWindow(widget), &root, &child,
                  &root_x, &root_y, x, y, &keys);
}

int  MDrawingArea::treatEvent(XEvent *event, int *x, int *y)
{

    mouseXY(x, y);

    switch (event->type)
    {
        case EnterNotify:
            return WIN_ENTER;
        case LeaveNotify:
            return WIN_EXIT;
        case ButtonPress:
            if (event->xbutton.button == Button1)
                return B1_DOWN;
            if (event->xbutton.button == Button2)
                return B2_DOWN;
            if (event->xbutton.button == Button3)
                return B3_DOWN;
	    break;
        case ButtonRelease:
            if (event->xbutton.button == Button1)
                return B1_UP;
            if (event->xbutton.button == Button2)
                return B2_UP;
            if (event->xbutton.button == Button3)
                return B3_UP;
            break;
        case MotionNotify:
            if (event->xmotion.state & Button1Mask)
                return B1_DRAG;
            else if(event->xmotion.state & Button2Mask)
			return B2_DRAG;
            	else if(event->xmotion.state & Button3Mask)
			return B3_DRAG;
            else
		return M_MOVE;
	    //break;
        case KeyPress:
            return ASCII;
    }
	return 0;
}

char *MDrawingArea::keyPressed( XEvent *event) 
{
        static char buffer[1];
        int count;
        KeySym keysym;

        count = XLookupString((XKeyEvent *) event, buffer, 1, &keysym, NULL);
	return buffer;
}


void MDrawingArea::addTimer(void *canvas, XtTimerCallbackProc Timer, 
							int interval)
{
	if (interval > 0)  speed = (unsigned long) interval;
	if (speed) XtAppAddTimeOut(XtWidgetToApplicationContext(widget),
				(unsigned long) speed,
				Timer,
				(XtPointer) canvas);
}

void MDrawingArea::removeTimer()
{
	speed = 0;
}

void  MDrawingArea::resize(int width, int height) 
{
	setValues(XmNwidth, width, XmNheight, height,
		  NULL);
}

void MScale::init(MWidget *parent, const char *name, ...)
{
        va_list argptr;
        Arg al[64];           /* Arg List */
        register int ac = 0;      /* Arg Count */
 
        va_start(argptr, name);
        ac = MInitArgs(al, (const char*)NULL, argptr);
        ident = mScale;
        widget = XmCreateScale( parent->widget, (char*)name, al, ac);
        attachObject();
	MFreeArgs(al, ac);
}

int MScale::returnValue()
{
	int value;

	getValue(XmNvalue, (XtPointer) &value);

	return value;
}

void MMessageBox::init(MWidget *parent, const char *name, ...)

{
        va_list argptr;
        Arg al[64];           /* Arg List */
        register int ac = 0;      /* Arg Count */
 
        va_start(argptr, name);
        ac = MInitArgs(al, (const char*)NULL, argptr);
        ident = mMessageBox;
        widget = XmCreateMessageBox( parent->widget, (char*)name, al, ac);
        attachObject();
	MFreeArgs(al, ac);
}

void MMessageBox::deleteCancel()
{
	Widget cancel;

	getValue(XmNcancelButton, (XtPointer)&cancel);

	XtDestroyWidget(cancel);

}

void MMessageBox::deleteOk()
{
	XmString xmstrings;

	deleteCancel();

	xmstrings = Mstoxs("Cancel");
	setValues(XmNokLabelString, xmstrings, NULL);
	XmStringFree(xmstrings);
}

void MMessageBox::manage(const char * message, XtArgVal cat = -1)
{
	
	XmString xmstrings;

	xmstrings = Mstoxs(message);
	setValues(XmNmessageString, xmstrings, NULL);
	if ( cat != -1 )  setValues(XmNdialogType, cat, NULL);
	manage();
	XmStringFree(xmstrings);
	
}

MWidget *MMessageBox::getChild(int nchild)
{
    Widget wchild = XmMessageBoxGetChild(widget, (unsigned char) nchild);

	switch (nchild) {
		case XmDIALOG_CANCEL_BUTTON :
		case XmDIALOG_HELP_BUTTON   :
		case XmDIALOG_OK_BUTTON     :
		{	MPushButton *button = new MPushButton;
			button->widget 		= wchild;
			button->ident       = mPushButton;
			button->attachObject();
			return (MWidget *) button; 
		}
		case XmDIALOG_MESSAGE_LABEL :
		{	MLabel 		*label	= new MLabel;
			label->widget		= wchild;
			label->ident		= mLabel;
			label->attachObject();
			return (MWidget *) label;
		}
		case XmDIALOG_SEPARATOR		  :
		{	MSeparator  *sep	= new MSeparator;
			sep->widget			= widget;
			sep->ident			= mSeparator;
			sep->attachObject();
			return (MWidget *) sep;
		}
	}
	return 0;
}	
	
void MSelectionBox::init(MWidget *parent, const char *name, ...)
{
        va_list argptr;
        Arg al[64];           /* Arg List */
        register int ac = 0;      /* Arg Count */
 
        va_start(argptr, name);
        ac = MInitArgs(al, (const char*)NULL, argptr);
        ident = mSelectionBox;
        widget = XmCreateFileSelectionBox( parent->widget, (char*)name, al, ac);
        attachObject();
	MFreeArgs(al, ac);
}

MWidget *MSelectionBox::getChild(int nchild)
{
    Widget wchild = XmSelectionBoxGetChild(widget, (unsigned char) nchild);

	switch (nchild) {
		case XmDIALOG_APPLY_BUTTON  :
		case XmDIALOG_CANCEL_BUTTON :
		case XmDIALOG_HELP_BUTTON   :
		case XmDIALOG_OK_BUTTON		:
		{	MPushButton *button = new MPushButton;
			button->widget 		= wchild;
			button->ident       = mPushButton;
			button->attachObject();
			return (MWidget *) button; 
		}
		case XmDIALOG_LIST			:
		{	MList       *list   = new MList;
			list->widget		= wchild;
			list->ident         = mList;
			list->attachObject();
			return (MWidget *) list;
		}
		case XmDIALOG_LIST_LABEL	  :
		case XmDIALOG_SELECTION_LABEL :
		{	MLabel 		*label	= new MLabel;
			label->widget		= wchild;
			label->ident		= mLabel;
			label->attachObject();
			return (MWidget *) label;
		}
		case XmDIALOG_SEPARATOR		  :
		{	MSeparator  *sep	= new MSeparator;
			sep->widget			= widget;
			sep->ident			= mSeparator;
			sep->attachObject();
			return (MWidget *) sep;
		}
		case XmDIALOG_TEXT			  :
		{	MText		*text	= new MText;
			text->widget 		= wchild;
			text->ident			= mText;
			text->attachObject();
			return (MWidget *) text;
		}
	}
	return 0;
}	
	
void MScrolledText::init(MWidget* parent, const char *name, ...)
{
	va_list argptr;
	Arg al[64];           // Arg List
	register int ac = 0;  // Arg Count
    va_start(argptr, name);
    ac = MInitArgs(al, (const char*)NULL, argptr);
    widget = XmCreateScrolledText( parent->widget, (char*)name, al, ac);
    ident = mText;
    MFreeArgs(al, ac);
}
		
void MText::init(MWidget *parent, const char *name, ...)
{
        va_list argptr;
        Arg al[64];           /* Arg List */
        register int ac = 0;      /* Arg Count */
 
        va_start(argptr, name);
        ac = MInitArgs(al, (const char*)NULL, argptr);
        ident = mText;
 		widget = XmCreateText( parent->widget, (char*)name, al, ac);
        attachObject();
	MFreeArgs(al, ac);
}

void MText::moveToEnd()
{
	XmTextPosition pos  = XmTextGetLastPosition(widget);
	XmTextSetInsertionPosition(widget,pos);
	XmTextSetSelection(widget,pos,pos,CurrentTime);
	XmTextShowPosition(widget,pos);
}

char * MText::returnValue()
{

	return XmTextGetString(widget);
}
 
void MText::setValue(const char *s)
{
//<**Sylvie(27/09/93)**> xsetValues(XmNvalue, s, XmNcursorPosition, strlen(s), NULL);
	XmTextSetString(widget, (char*)s);
	
}

void MText::loadText(const char* tmp, Boolean b)
{
	xec_LoadText(widget, tmp, b);
}

void MText::saveText(const char* tmp)
{
	xec_SaveText(widget, tmp);
}

void MText::replaceSelection(const char *txt)
{
	xec_ReplaceTextSelection(widget,txt,0);
}

void MText::replaceSelection(char c)
{
	char x[2];
	x[0] = c;
	x[1] = 0;
	replaceSelection(x);
}

extern "C" {
void _XmTextDisableRedisplay(Widget,Boolean);
void _XmTextEnableRedisplay(Widget);
};


void MText::selectLine(int line)
{
	char *p              = XmTextGetString(widget);
	char *q              = p;
	XmTextPosition start = 0;
	XmTextPosition end   = XmTextGetLastPosition(widget);
	int    n             = 0;

	if(line<=0) line = 1;

	while(*p)
	{
		if(*p == '\n') 
		{ 
			n++;
			if(n == line)  
			{
				end = p - q;
				break;
			}
			start = p - q + 1;
		}
		p++;
	}

	XmTextSetSelection(widget,start,end,CurrentTime);
	XmTextShowPosition(widget,start);

	XtFree((char*)q);
}

void MRadioBox::init(MWidget *parent, const char *name, ...)
{
        va_list argptr;
        Arg al[64];           /* Arg List */
        register int ac = 0;      /* Arg Count */
 
        va_start(argptr, name);
        ac = MInitArgs(al, (const char*)NULL, argptr);
        ident = mDragWidget;
        widget = XmCreateRadioBox( parent->widget, (char*)name, al, ac);
        attachObject();
	MFreeArgs(al, ac);
}

void MRadioBox::addItem(char *name, ...)
{
        va_list argptr;
        Arg al[64];           /* Arg List */
        register int ac = 0;      /* Arg Count */
 
        va_start(argptr, name);
        MToggleButton *button = new MToggleButton;
        button->init((MWidget *)this, name, XmNlabelString, name, NULL );
        ac = MInitArgs(al, (const char*)NULL, argptr);
        XtSetValues(button->widget, al, ac);
        button->manage();
	MFreeArgs(al, ac);
}
 
//void MRadioBox::select(char *name)
//{
        //MWidget  *child = returnChild(name);
 
        //if (child) ((MToggleButton *)child)->select(True);
 
//}

//void MRadioBox::unselect(char *name)
//{
        //MWidget  *child = returnChild(name);
 
        //if (child) child->setValues(XmNset, FALSE, NULL);
//}


void MBulletinBoard::init(MWidget *parent, const char *name, ...)
{
   	va_list argptr;
   	Arg al[64];           /* Arg List */
   	register int ac = 0;      /* Arg Count */
 
   	va_start(argptr, name);
   	ac = MInitArgs(al, (const char*)NULL, argptr);
   	ident = mBulletinBoard;
   	widget = XmCreateBulletinBoard( parent->widget, (char*)name, al, ac);
   	attachObject();
	MFreeArgs(al, ac);
}

void MPopupMenu::init(MWidget* parent, const char *name, ...)
{
	va_list argptr;
    Arg al[64];           /* Arg List */
    register int ac = 0;      /* Arg Count */
 
    va_start(argptr, name);
    ac = MInitArgs(al, (const char*)NULL, argptr);
	ident = mPulldownMenu;
    widget = XmCreatePopupMenu( parent->widget, (char*)name, al, ac);
    attachObject();
    MFreeArgs(al, ac);

}

Boolean MPopupMenu::map(XEvent *event)
{
	if (event->xany.type != ButtonPress || 
		event->xbutton.button != 3)
			return False;

	XmMenuPosition(widget, (XButtonPressedEvent *)event);
	XtManageChild(widget);
	return True;
	
}
void MPopupMenu::manage()
{
}
void MArrowButton::init(MWidget* parent, const char *name, ...)
{
	va_list argptr;
    Arg al[64];           /* Arg List */
    register int ac = 0;      /* Arg Count */
 
    va_start(argptr, name);
    ac = MInitArgs(al, (const char*)NULL, argptr);
	ident = mArrowButton;
    widget = XmCreateArrowButton( parent->widget, (char*)name, al, ac);
    attachObject();
    MFreeArgs(al, ac);

}
void MArrowButton::init(Boolean gadget, MWidget* parent, const char *name, ...)
{
	va_list argptr;
    Arg al[64];           /* Arg List */
    register int ac = 0;      /* Arg Count */
 
    va_start(argptr, name);
    ac = MInitArgs(al, (const char*)NULL, argptr);
	ident = mArrowButton;
    if (gadget) widget = XmCreateArrowButtonGadget( parent->widget, (char*)name, al, ac);
    else widget = XmCreateArrowButton( parent->widget, (char*)name, al, ac);
    attachObject();
    MFreeArgs(al, ac);

}
void MPanedWindow::init(MWidget* parent, const char *name, ...)
{
	va_list argptr;
    Arg al[64];           /* Arg List */
    register int ac = 0;      /* Arg Count */
 
    va_start(argptr, name);
    ac = MInitArgs(al, (const char*)NULL, argptr);
	ident = mPanedWindow;
    widget = XmCreatePanedWindow( parent->widget, (char*)name, al, ac);
    attachObject();
    MFreeArgs(al, ac);
}
