/* 
 * $Id: x11axis.c,v 1.10 2003/02/16 12:43:37 isizaka Exp isizaka $
 * 
 * This file is part of "Ngraph for X11".
 * 
 * Copyright (C) 2002, Satoshi ISHIZAKA. isizaka@msa.biglobe.ne.jp
 * 
 * "Ngraph for X11" is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 * 
 * "Ngraph for X11" is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 * 
 */

/**
 *
 * $Log: x11axis.c,v $
 * Revision 1.10  2003/02/16 12:43:37  isizaka
 * for release 6.13.18
 *
 * Revision 1.9  2002/07/06 08:57:25  isizaka
 * change to GPL.
 *
 * Revision 1.8  2001/03/23 12:17:43  isizaka
 * for 6.3.13
 *
 * Revision 1.7  2000/10/28 14:48:05  isizaka
 * AxisDialogFile: type is preserved.
 *
 * Revision 1.6  1999/05/08 13:31:30  isizaka
 * for release 6.03.02
 *
 * Revision 1.5  1999/04/15 12:14:26  isizaka
 * for release 6.03.01
 *
 * Revision 1.4  1999/04/11 06:09:20  isizaka
 * *** empty log message ***
 *
 * Revision 1.3  1999/03/21 12:51:03  isizaka
 * change axis initialization
 *
 * Revision 1.2  1999/03/20 12:32:54  isizaka
 * use ComboBox for axis setting
 *
 * Revision 1.1  1999/03/17 13:28:29  isizaka
 * Initial revision
 *
 *
 **/

#include <Xm/XmAll.h>
#include <X11/keysym.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>

#include "motif12.h"

#include "ngraph.h"
#include "object.h"
#include "nstring.h"

#include "x11gui.h"
#include "x11dialg.h"
#include "x11menu.h"
#include "ox11menu.h"
#include "x11graph.h"
#include "x11file.h"
#include "x11view.h"
#include "x11axis.h"
#include "x11commn.h"

char *AxisCB(struct objlist *obj,int id)
{
  char *s;
  int dir;
  char *valstr;
  char *name;

  if ((s=(char *)memalloc(128))==NULL) return NULL;
  getobj(obj,"direction",id,0,NULL,&dir);
  getobj(obj,"group",id,0,NULL,&name);
  if (name==NULL) name="";
  sgetobjfield(obj,id,"type",NULL,&valstr,FALSE,FALSE,FALSE);
  sprintf(s,"%-5d %-10s %.6s dir:%d",id,name,valstr,dir);
  memfree(valstr);
  return s;
}

char *GridCB(struct objlist *obj,int id)
{
  char *s,*s1,*s2;

  if ((s=(char *)memalloc(128))==NULL) return NULL;
  getobj(obj,"axis_x",id,0,NULL,&s1);
  getobj(obj,"axis_y",id,0,NULL,&s2);
  sprintf(s,"%-5d %.8s %.8s",id,s1,s2);
  return s;
}

void GridDialogSetupItem(Widget w,struct GridDialog *d,int id)
{
  char *valstr;
  int i,j;
  int lastinst;
  struct objlist *aobj;
  char *name;
  XmString xs;

  aobj=getobject("axis");
  lastinst=chkobjlastinst(aobj);
  XmListDeleteAllItems(GetComboBoxList(w,"*axisx"));
  XmListDeleteAllItems(GetComboBoxList(w,"*axisy"));
  for (j=0;j<=lastinst;j++) {
    getobj(aobj,"group",j,0,NULL,&name);
    if (name==NULL) name="";
    xs=XmStringCreateLocalized(name);
    XmListAddItem(GetComboBoxList(w,"*axisx"),xs,0);
    XmListAddItem(GetComboBoxList(w,"*axisy"),xs,0);
    XmStringFree(xs);
  }
  SetComboBoxVisibleItemCount(w,"*axisx",j);
  SetComboBoxVisibleItemCount(w,"*axisy",j);
  sgetobjfield(d->Obj,id,"axis_x",NULL,&valstr,FALSE,FALSE,FALSE);
  for (i=0;(valstr[i]!='\0') && (valstr[i]!=':');i++);
  if (valstr[i]==':') i++;
  XtVaSetValues(GetComboBoxText(w,"*axisx"),XmNvalue,valstr+i,NULL);
  memfree(valstr);
  sgetobjfield(d->Obj,id,"axis_y",NULL,&valstr,FALSE,FALSE,FALSE);
  for (i=0;(valstr[i]!='\0') && (valstr[i]!=':');i++);
  if (valstr[i]==':') i++;
  XtVaSetValues(GetComboBoxText(w,"*axisy"),XmNvalue,valstr+i,NULL);
  memfree(valstr);
  SetStyleFromObjField(w,"*style1",d->Obj,id,"style1");
  SetStyleFromObjField(w,"*style2",d->Obj,id,"style2");
  SetStyleFromObjField(w,"*style3",d->Obj,id,"style3");
  SetComboList(w,"*wid1",cblinewidth,CBLINEWIDTH);
  SetTextFromObjField(GetComboBoxText(w,"*wid1"),NULL,d->Obj,id,"width1");
  SetComboListFromObjField(GetComboBoxList(w,"*wid1"),NULL,d->Obj,id,"width1");
  SetComboList(w,"*wid2",cblinewidth,CBLINEWIDTH);
  SetTextFromObjField(GetComboBoxText(w,"*wid2"),NULL,d->Obj,id,"width2");
  SetComboListFromObjField(GetComboBoxList(w,"*wid2"),NULL,d->Obj,id,"width2");
  SetComboList(w,"*wid3",cblinewidth,CBLINEWIDTH);
  SetTextFromObjField(GetComboBoxText(w,"*wid3"),NULL,d->Obj,id,"width3");
  SetComboListFromObjField(GetComboBoxList(w,"*wid3"),NULL,d->Obj,id,"width3");
  SetToggleFromObjField(w,"*Background",d->Obj,id,"background");
  getobj(d->Obj,"R",id,0,NULL,&d->R);
  getobj(d->Obj,"G",id,0,NULL,&d->G);
  getobj(d->Obj,"B",id,0,NULL,&d->B);
  XtVaSetValues(XtNameToWidget(w,"*col"),XmNbackground,RGB(d->R,d->G,d->B),NULL);
  getobj(d->Obj,"BR",id,0,NULL,&d->R2);
  getobj(d->Obj,"BG",id,0,NULL,&d->G2);
  getobj(d->Obj,"BB",id,0,NULL,&d->B2);
  XtVaSetValues(XtNameToWidget(w,"*colb"),XmNbackground,RGB(d->R2,d->G2,d->B2),NULL);
}

void GridDialogCopy(Widget w,XtPointer client_data,XtPointer call_data)
{
  struct GridDialog *d;
  int sel;

  d=(struct GridDialog *)client_data;
  if ((sel=CopyClick(d->widget,d->Obj,d->Id,GridCB))!=-1)
    GridDialogSetupItem(d->widget,d,sel);
}

void GridDialogDelete(Widget w,XtPointer client_data,XtPointer call_data)
{
  struct GridDialog *d;

  d=(struct GridDialog *)client_data;
  d->ret=IDDELETE;
}

void GridDialogAxisX(Widget w,XtPointer client_data,XtPointer call_data)
{
  struct GridDialog *d;
  XmComboBoxCallbackStruct *dd;
  char buf[10];
  int a,oid;
  struct objlist *aobj;

  aobj=getobject("axis");
  d=(struct GridDialog *)client_data;
  dd=(XmComboBoxCallbackStruct *)call_data;
#ifdef ZEROBASECOMBOBOX
  a=dd->item_position;
#else
  a=dd->item_position-1;
#endif
  if (a<0) return;
  getobj(aobj,"oid",a,0,NULL,&oid);
  sprintf(buf,"^%d",oid); 
  XtVaSetValues(GetComboBoxText(d->widget,"*axisx"),XmNvalue,buf,NULL);
}

void GridDialogAxisY(Widget w,XtPointer client_data,XtPointer call_data)
{
  struct GridDialog *d;
  XmComboBoxCallbackStruct *dd;
  char buf[10];
  int a,oid;
  struct objlist *aobj;

  aobj=getobject("axis");
  d=(struct GridDialog *)client_data;
  dd=(XmComboBoxCallbackStruct *)call_data;
#ifdef ZEROBASECOMBOBOX
  a=dd->item_position;
#else
  a=dd->item_position-1;
#endif
  if (a<0) return;
  getobj(aobj,"oid",a,0,NULL,&oid);
  sprintf(buf,"^%d",oid); 
  XtVaSetValues(GetComboBoxText(d->widget,"*axisy"),XmNvalue,buf,NULL);
}

void GridDialogColor(Widget w,XtPointer client_data,XtPointer call_data)
{
  struct GridDialog *d;

  d=(struct GridDialog *)client_data;
  GetColor(TopLevel,&d->R,&d->G,&d->B);
  XtVaSetValues(w,XmNbackground,RGB(d->R,d->G,d->B),NULL);
}

void GridDialogColorB(Widget w,XtPointer client_data,XtPointer call_data)
{
  struct GridDialog *d;

  d=(struct GridDialog *)client_data;
  GetColor(TopLevel,&d->R2,&d->G2,&d->B2);
  XtVaSetValues(w,XmNbackground,RGB(d->R2,d->G2,d->B2),NULL);
}

void GridDialogSetup(Widget w,void *data,int makewidget)
{
  Arg al[20];
  Cardinal ac;
  Widget rc,rc2,rc3,frame,button,combo;
  struct GridDialog *d;
  XmString xs;
  char title[25];
  
  d=(struct GridDialog *)data;
  sprintf(title,"Grid %d",d->Id);
  xs=XmStringCreateLocalized(title);
  XtVaSetValues(w,XmNdialogTitle,xs,NULL);
  XmStringFree(xs);

  d=(struct GridDialog *)data;
  if (makewidget) {
  ac=0;
  XtManageChild(button=XmCreatePushButton(w,"Delete",al,ac));
  XtAddCallback(button,XmNdisarmCallback,GridDialogDelete,d);
  ac=0;
  XtManageChild(button=XmCreatePushButton(w,"Copy",al,ac));
  XtAddCallback(button,XmNdisarmCallback,GridDialogCopy,d);

  ac=0;
  XtSetArg(al[ac],XmNorientation,XmVERTICAL); ac++;
  XtManageChild(rc=XmCreateRowColumn(w,"rc",al,ac));

  ac=0;
  XtManageChild(frame=XmCreateFrame(rc,"frame",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc2=XmCreateRowColumn(frame,"axisrc",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc2,"Axisx",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNcomboBoxType,XmDROP_DOWN_COMBO_BOX); ac++;
  XtManageChild(combo=XmCreateComboBox(rc2,"axisx",al,ac));
  XtAddCallback(combo,XmNselectionCallback,GridDialogAxisX,d);
  ac=0;
  XtManageChild(XmCreateLabel(rc2,"Axisy",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNcomboBoxType,XmDROP_DOWN_COMBO_BOX); ac++;
  XtManageChild(combo=XmCreateComboBox(rc2,"axisy",al,ac));
  XtAddCallback(combo,XmNselectionCallback,GridDialogAxisY,d);

  ac=0;
  XtManageChild(frame=XmCreateFrame(rc,"frame2",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNorientation,XmVERTICAL); ac++;
  XtManageChild(rc2=XmCreateRowColumn(frame,"rc2",al,ac));

  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc3=XmCreateRowColumn(rc2,"style1rc",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc3,"Style1",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNcomboBoxType,XmDROP_DOWN_COMBO_BOX); ac++;
  XtManageChild(XmCreateComboBox(rc3,"style1",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc3,"Width1",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNcomboBoxType,XmDROP_DOWN_COMBO_BOX); ac++;
  XtManageChild(XmCreateComboBox(rc3,"wid1",al,ac));

  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc3=XmCreateRowColumn(rc2,"style2rc",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc3,"Style2",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNcomboBoxType,XmDROP_DOWN_COMBO_BOX); ac++;
  XtManageChild(XmCreateComboBox(rc3,"style2",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc3,"Width2",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNcomboBoxType,XmDROP_DOWN_COMBO_BOX); ac++;
  XtManageChild(XmCreateComboBox(rc3,"wid2",al,ac));

  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc3=XmCreateRowColumn(rc2,"style3rc",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc3,"Style3",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNcomboBoxType,XmDROP_DOWN_COMBO_BOX); ac++;
  XtManageChild(XmCreateComboBox(rc3,"style3",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc3,"Width3",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNcomboBoxType,XmDROP_DOWN_COMBO_BOX); ac++;
  XtManageChild(XmCreateComboBox(rc3,"wid3",al,ac));

  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc3=XmCreateRowColumn(rc2,"colorrc",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc3,"Color",al,ac));
  ac=0;
  XtManageChild(button=XmCreateDrawnButton(rc3,"col",al,ac));
  XtAddCallback(button,XmNdisarmCallback,GridDialogColor,d);
  ac=0;
  XtManageChild(XmCreateToggleButton(rc3,"Background",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc3,"BackgroundColor",al,ac));
  ac=0;
  xs=XmStringCreateLocalized("   ");
  XtSetArg(al[ac],XmNlabelString,xs); ac++;
  XtManageChild(button=XmCreatePushButton(rc3,"colb",al,ac));
  XtAddCallback(button,XmNdisarmCallback,GridDialogColorB,d);
  XmStringFree(xs);
  }

  GridDialogSetupItem(w,d,d->Id);
}

void GridDialogClose(Widget w,void *data)
{
  struct GridDialog *d;
  int ret;
  char *s,*buf;
  int len;
  
  d=(struct GridDialog *)data;
  if (d->ret!=IDOK) return;
  ret=d->ret;
  d->ret=IDLOOP;
  XtVaGetValues(GetComboBoxText(w,"*axisx"),XmNvalue,&s,NULL);
  if ((s==NULL) || (strlen(s)==0)) {
    if (sputobjfield(d->Obj,d->Id,"axis_x",NULL)!=0) return;
  } else {
    len=strlen(s);
    if ((buf=(char *)memalloc(len+6))!=NULL) {
      strcpy(buf,"axis:");
      if (s!=NULL) strcat(buf,s);
      if (sputobjfield(d->Obj,d->Id,"axis_x",buf)!=0) {
        memfree(buf);
        return;
      }
      memfree(buf);
    }
  }
  XtFree(s);
  XtVaGetValues(GetComboBoxText(w,"*axisy"),XmNvalue,&s,NULL);
  if ((s==NULL) || (strlen(s)==0)) {
    if (sputobjfield(d->Obj,d->Id,"axis_y",NULL)!=0) return;
  } else {
    len=strlen(s);
    if ((buf=(char *)memalloc(len+6))!=NULL) {
      strcpy(buf,"axis:");
      if (s!=NULL) strcat(buf,s);
      if (sputobjfield(d->Obj,d->Id,"axis_y",buf)!=0) {
        memfree(buf);
        return;
      }
      memfree(buf);
    }
  }
  XtFree(s);
  if (SetObjFieldFromStyle(w,"*style1",d->Obj,d->Id,"style1")) return;
  if (SetObjFieldFromStyle(w,"*style2",d->Obj,d->Id,"style2")) return;
  if (SetObjFieldFromStyle(w,"*style3",d->Obj,d->Id,"style3")) return;
  if (SetObjFieldFromText(GetComboBoxText(w,"*wid1"),NULL,
                          d->Obj,d->Id,"width1")) return;
  if (SetObjFieldFromText(GetComboBoxText(w,"*wid2"),NULL,
                          d->Obj,d->Id,"width2")) return;
  if (SetObjFieldFromText(GetComboBoxText(w,"*wid3"),NULL,
                          d->Obj,d->Id,"width3")) return;
  if (SetObjFieldFromToggle(w,"*Background",d->Obj,d->Id,"background")) return;
  if (putobj(d->Obj,"R",d->Id,&(d->R))==-1) return;
  if (putobj(d->Obj,"G",d->Id,&(d->G))==-1) return;
  if (putobj(d->Obj,"B",d->Id,&(d->B))==-1) return;
  if (putobj(d->Obj,"BR",d->Id,&(d->R2))==-1) return;
  if (putobj(d->Obj,"BG",d->Id,&(d->G2))==-1) return;
  if (putobj(d->Obj,"BB",d->Id,&(d->B2))==-1) return;
  d->ret=ret;
}

void GridDialog(struct GridDialog *data,struct objlist *obj,int id)
{
  data->SetupWindow=GridDialogSetup;
  data->CloseWindow=GridDialogClose;
  data->Obj=obj;
  data->Id=id;
}


void SectionDialogSetupItem(Widget w,struct SectionDialog *d)
{
  char buf[256];
  XmString xs;

  sprintf(buf,"%d",d->X);
  XtVaSetValues(XtNameToWidget(w,"*x"),XmNvalue,buf,NULL);
  sprintf(buf,"%d",d->Y);
  XtVaSetValues(XtNameToWidget(w,"*y"),XmNvalue,buf,NULL);
  if (d->IDX!=-1) sprintf(buf,"id:%d",d->IDX);
  else buf[0]='\0';
  xs=XmStringCreateLocalized(buf);
  XtVaSetValues(XtNameToWidget(w,"*xid"),XmNlabelString,xs,NULL);
  XmStringFree(xs);
  if (d->IDY!=-1) sprintf(buf,"id:%d",d->IDY);
  else buf[0]='\0';
  xs=XmStringCreateLocalized(buf);
  XtVaSetValues(XtNameToWidget(w,"*yid"),XmNlabelString,xs,NULL);
  XmStringFree(xs);
  if (d->IDU!=-1) sprintf(buf,"id:%d",d->IDU);
  else buf[0]='\0';
  xs=XmStringCreateLocalized(buf);
  XtVaSetValues(XtNameToWidget(w,"*uid"),XmNlabelString,xs,NULL);
  XmStringFree(xs);
  if (d->IDR!=-1) sprintf(buf,"id:%d",d->IDR);
  else buf[0]='\0';
  xs=XmStringCreateLocalized(buf);
  XtVaSetValues(XtNameToWidget(w,"*rid"),XmNlabelString,xs,NULL);
  XmStringFree(xs);
  if (*(d->IDG)!=-1) sprintf(buf,"id:%d",*(d->IDG));
  else buf[0]='\0';
  xs=XmStringCreateLocalized(buf);
  XtVaSetValues(XtNameToWidget(w,"*gid"),XmNlabelString,xs,NULL);
  XmStringFree(xs);
  sprintf(buf,"%d",d->LenX);
  XtVaSetValues(XtNameToWidget(w,"*width"),XmNvalue,buf,NULL);
  sprintf(buf,"%d",d->LenY);
  XtVaSetValues(XtNameToWidget(w,"*height"),XmNvalue,buf,NULL);
}

void SectionDialogDelete(Widget w,XtPointer client_data,XtPointer call_data)
{
  struct SectionDialog *d;

  d=(struct SectionDialog *)client_data;
  d->ret=IDDELETE;
}

void SectionDialogAxisX(Widget w,XtPointer client_data,XtPointer call_data)
{
  struct SectionDialog *d;

  d=(struct SectionDialog *)client_data;
  if (d->IDX>=0) {
    AxisDialog(&DlgAxis,d->Obj,d->IDX,FALSE);
    DialogExecute(d->widget,&DlgAxis);
  }
}

void SectionDialogAxisY(Widget w,XtPointer client_data,XtPointer call_data)
{
  struct SectionDialog *d;

  d=(struct SectionDialog *)client_data;
  if (d->IDY>=0) {
    AxisDialog(&DlgAxis,d->Obj,d->IDY,FALSE);
    DialogExecute(d->widget,&DlgAxis);
  }
}

void SectionDialogAxisU(Widget w,XtPointer client_data,XtPointer call_data)
{
  struct SectionDialog *d;

  d=(struct SectionDialog *)client_data;
  if (d->IDU>=0) {
    AxisDialog(&DlgAxis,d->Obj,d->IDU,FALSE);
    DialogExecute(d->widget,&DlgAxis);
  }
}

void SectionDialogAxisR(Widget w,XtPointer client_data,XtPointer call_data)
{
  struct SectionDialog *d;

  d=(struct SectionDialog *)client_data;
  if (d->IDR>=0) {
    AxisDialog(&DlgAxis,d->Obj,d->IDR,FALSE);
    DialogExecute(d->widget,&DlgAxis);
  }
}

void SectionDialogGrid(Widget w,XtPointer client_data,XtPointer call_data)
{
  struct SectionDialog *d;
  char *ref;
  int oidx,oidy;

  d=(struct SectionDialog *)client_data;
  if (*(d->IDG)==-1) {
    if ((*(d->IDG)=newobj(d->Obj2))>=0) {
      if ((ref=(char *)memalloc(15))!=NULL) {
        getobj(d->Obj,"oid",d->IDX,0,NULL,&oidx);
        sprintf(ref,"axis:^%d",oidx);
        putobj(d->Obj2,"axis_x",*(d->IDG),ref);
      }
      if ((ref=(char *)memalloc(15))!=NULL) {
        getobj(d->Obj,"oid",d->IDY,0,NULL,&oidy);
        sprintf(ref,"axis:^%d",oidy);
        putobj(d->Obj2,"axis_y",*(d->IDG),ref);
      }
    }
  }
  if (*(d->IDG)>=0) {
    GridDialog(&DlgGrid,d->Obj2,*(d->IDG));
    if (DialogExecute(d->widget,&DlgGrid)==IDDELETE) {
      delobj(d->Obj2,*(d->IDG));
      *(d->IDG)=-1;
    }
  }
  SectionDialogSetupItem(d->widget,d);
  NgraphApp.Changed=TRUE;
}

void SectionDialogSetup(Widget w,void *data,int makewidget)
{
  Arg al[20];
  Cardinal ac;
  Widget rc,rc2,rc3,button;
  struct SectionDialog *d;
  XmString xs;
  
  d=(struct SectionDialog *)data;
  if (makewidget) {
  ac=0;
  XtManageChild(button=XmCreatePushButton(w,"Delete",al,ac));
  XtAddCallback(button,XmNdisarmCallback,SectionDialogDelete,d);

  ac=0;
  XtSetArg(al[ac],XmNorientation,XmVERTICAL); ac++;
  XtManageChild(rc=XmCreateRowColumn(w,"rc",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc2=XmCreateRowColumn(rc,"xrc",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc2,"X",al,ac));
  ac=0;
  XtManageChild(XmCreateTextField(rc2,"x",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc2,"Width",al,ac));
  ac=0;
  XtManageChild(XmCreateTextField(rc2,"width",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc2=XmCreateRowColumn(rc,"yrc",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc2,"Y",al,ac));
  ac=0;
  XtManageChild(XmCreateTextField(rc2,"y",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc2,"Height",al,ac));
  ac=0;
  XtManageChild(XmCreateTextField(rc2,"height",al,ac));

  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc2=XmCreateRowColumn(rc,"buttonrc",al,ac));

  ac=0;
  XtSetArg(al[ac],XmNorientation,XmVERTICAL); ac++;
  XtManageChild(rc3=XmCreateRowColumn(rc2,"bxrc",al,ac));
  ac=0;
  XtManageChild(button=XmCreatePushButton(rc3,"Xaxis",al,ac));
  XtAddCallback(button,XmNdisarmCallback,SectionDialogAxisX,d);
  ac=0;
  xs=XmStringCreateLocalized("      ");
  XtSetArg(al[ac],XmNlabelString,xs); ac++;
  XtManageChild(XmCreateLabel(rc3,"xid",al,ac));
  XmStringFree(xs);
  ac=0;
  XtSetArg(al[ac],XmNorientation,XmVERTICAL); ac++;
  XtManageChild(rc3=XmCreateRowColumn(rc2,"byrc",al,ac));
  ac=0;
  XtManageChild(button=XmCreatePushButton(rc3,"Yaxis",al,ac));
  XtAddCallback(button,XmNdisarmCallback,SectionDialogAxisY,d);
  ac=0;
  xs=XmStringCreateLocalized("      ");
  XtSetArg(al[ac],XmNlabelString,xs); ac++;
  XtManageChild(XmCreateLabel(rc3,"yid",al,ac));
  XmStringFree(xs);
  ac=0;
  XtSetArg(al[ac],XmNorientation,XmVERTICAL); ac++;
  XtManageChild(rc3=XmCreateRowColumn(rc2,"burc",al,ac));
  ac=0;
  XtManageChild(button=XmCreatePushButton(rc3,"Uaxis",al,ac));
  XtAddCallback(button,XmNdisarmCallback,SectionDialogAxisU,d);
  ac=0;
  xs=XmStringCreateLocalized("      ");
  XtSetArg(al[ac],XmNlabelString,xs); ac++;
  XtManageChild(XmCreateLabel(rc3,"uid",al,ac));
  XmStringFree(xs);
  ac=0;
  XtSetArg(al[ac],XmNorientation,XmVERTICAL); ac++;
  XtManageChild(rc3=XmCreateRowColumn(rc2,"brrc",al,ac));
  ac=0;
  XtManageChild(button=XmCreatePushButton(rc3,"Raxis",al,ac));
  XtAddCallback(button,XmNdisarmCallback,SectionDialogAxisR,d);
  ac=0;
  xs=XmStringCreateLocalized("      ");
  XtSetArg(al[ac],XmNlabelString,xs); ac++;
  XtManageChild(XmCreateLabel(rc3,"rid",al,ac));
  XmStringFree(xs);
  ac=0;
  XtSetArg(al[ac],XmNorientation,XmVERTICAL); ac++;
  XtManageChild(rc3=XmCreateRowColumn(rc2,"bgrc",al,ac));
  ac=0;
  XtManageChild(button=XmCreatePushButton(rc3,"Grid",al,ac));
  XtAddCallback(button,XmNdisarmCallback,SectionDialogGrid,d);
  ac=0;
  xs=XmStringCreateLocalized("      ");
  XtSetArg(al[ac],XmNlabelString,xs); ac++;
  XtManageChild(XmCreateLabel(rc3,"gid",al,ac));
  XmStringFree(xs);
  }

  SectionDialogSetupItem(w,d);
}

void SectionDialogClose(Widget w,void *data)
{
  struct SectionDialog *d;
  int ret;
  int type,a;
  char *buf,*endptr;
  struct narray group;
  char *argv[2];

  d=(struct SectionDialog *)data;
  if (d->ret!=IDOK) return;
  ret=d->ret;
  d->ret=IDLOOP;
  XtVaGetValues(XtNameToWidget(w,"*x"),XmNvalue,&buf,NULL);
  a=strtol(buf,&endptr,10);
  if (endptr[0]!='\0') {
    XtFree(buf);
    return;
  }
  d->X=a;
  XtFree(buf);
  XtVaGetValues(XtNameToWidget(w,"*y"),XmNvalue,&buf,NULL);
  a=strtol(buf,&endptr,10);
  if (endptr[0]!='\0') {
    XtFree(buf);
    return;
  }
  d->Y=a;
  XtFree(buf);
  XtVaGetValues(XtNameToWidget(w,"*width"),XmNvalue,&buf,NULL);
  a=strtol(buf,&endptr,10);
  if (endptr[0]!='\0') {
    XtFree(buf);
    return;
  }
  d->LenX=a;
  XtFree(buf);
  XtVaGetValues(XtNameToWidget(w,"*height"),XmNvalue,&buf,NULL);
  a=strtol(buf,&endptr,10);
  if (endptr[0]!='\0') {
    XtFree(buf);
    return;
  }
  d->LenY=a;
  XtFree(buf);
  if ((d->X!=d->X0) || (d->Y!=d->Y0)
  || (d->LenX0!=d->LenX) || (d->LenY0!=d->LenY)) {
    arrayinit(&group,sizeof(int));
    if (d->Section) type=2;
    else type=1;
    arrayadd(&group,&type);
    arrayadd(&group,&(d->IDX));
    arrayadd(&group,&(d->IDY));
    arrayadd(&group,&(d->IDU));
    arrayadd(&group,&(d->IDR));
    arrayadd(&group,&(d->X));
    arrayadd(&group,&(d->Y));
    arrayadd(&group,&(d->LenX));
    arrayadd(&group,&(d->LenY));
    argv[0]=(char *)&group;
    argv[1]=NULL;
    exeobj(d->Obj,"group_position",d->IDX,1,argv);
    arraydel(&group);
  }
  d->ret=ret;
}

void SectionDialog(struct SectionDialog *data,
                   int x,int y,int lenx,int leny,
                   struct objlist *obj,int idx,int idy,int idu,int idr,
                   struct objlist *obj2,int *idg,int section)
{
  data->SetupWindow=SectionDialogSetup;
  data->CloseWindow=SectionDialogClose;
  data->X0=data->X=x;
  data->Y0=data->Y=y;
  data->LenX0=data->LenX=lenx;
  data->LenY0=data->LenY=leny;
  data->Obj=obj;
  data->Obj2=obj2;
  data->IDX=idx;
  data->IDY=idy;
  data->IDU=idu;
  data->IDR=idr;
  data->IDG=idg;
  data->Section=section;
  data->MaxX=menulocal.PaperWidth*(10000.0/menulocal.PaperZoom);
  data->MaxY=menulocal.PaperHeight*(10000.0/menulocal.PaperZoom);
}

void CrossDialogSetupItem(Widget w,struct CrossDialog *d)
{
  char buf[256];
  XmString xs;

  sprintf(buf,"%d",d->X);
  XtVaSetValues(XtNameToWidget(w,"*x"),XmNvalue,buf,NULL);
  sprintf(buf,"%d",d->Y);
  XtVaSetValues(XtNameToWidget(w,"*y"),XmNvalue,buf,NULL);
  if (d->IDX!=-1) sprintf(buf,"id:%d",d->IDX);
  else buf[0]='\0';
  xs=XmStringCreateLocalized(buf);
  XtVaSetValues(XtNameToWidget(w,"*xid"),XmNlabelString,xs,NULL);
  XmStringFree(xs);
  if (d->IDY!=-1) sprintf(buf,"id:%d",d->IDY);
  else buf[0]='\0';
  xs=XmStringCreateLocalized(buf);
  XtVaSetValues(XtNameToWidget(w,"*yid"),XmNlabelString,xs,NULL);
  XmStringFree(xs);
  sprintf(buf,"%d",d->LenX);
  XtVaSetValues(XtNameToWidget(w,"*width"),XmNvalue,buf,NULL);
  sprintf(buf,"%d",d->LenY);
  XtVaSetValues(XtNameToWidget(w,"*height"),XmNvalue,buf,NULL);
}

void CrossDialogDelete(Widget w,XtPointer client_data,XtPointer call_data)
{
  struct CrossDialog *d;

  d=(struct CrossDialog *)client_data;
  d->ret=IDDELETE;
}

void CrossDialogAxisX(Widget w,XtPointer client_data,XtPointer call_data)
{
  struct CrossDialog *d;

  d=(struct CrossDialog *)client_data;
  if (d->IDX>=0) {
    AxisDialog(&DlgAxis,d->Obj,d->IDX,FALSE);
    DialogExecute(d->widget,&DlgAxis);
  }
}

void CrossDialogAxisY(Widget w,XtPointer client_data,XtPointer call_data)
{
  struct CrossDialog *d;

  d=(struct CrossDialog *)client_data;
  if (d->IDY>=0) {
    AxisDialog(&DlgAxis,d->Obj,d->IDY,FALSE);
    DialogExecute(d->widget,&DlgAxis);
  }
}

void CrossDialogSetup(Widget w,void *data,int makewidget)
{
  Arg al[20];
  Cardinal ac;
  Widget rc,rc2,rc3,button;
  struct CrossDialog *d;
  XmString xs;
  
  d=(struct CrossDialog *)data;
  if (makewidget) {
  ac=0;
  XtManageChild(button=XmCreatePushButton(w,"Delete",al,ac));
  XtAddCallback(button,XmNdisarmCallback,CrossDialogDelete,d);

  ac=0;
  XtSetArg(al[ac],XmNorientation,XmVERTICAL); ac++;
  XtManageChild(rc=XmCreateRowColumn(w,"rc",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc2=XmCreateRowColumn(rc,"xrc",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc2,"X",al,ac));
  ac=0;
  XtManageChild(XmCreateTextField(rc2,"x",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc2,"Width",al,ac));
  ac=0;
  XtManageChild(XmCreateTextField(rc2,"width",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc2=XmCreateRowColumn(rc,"yrc",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc2,"Y",al,ac));
  ac=0;
  XtManageChild(XmCreateTextField(rc2,"y",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc2,"Height",al,ac));
  ac=0;
  XtManageChild(XmCreateTextField(rc2,"height",al,ac));

  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc2=XmCreateRowColumn(rc,"buttonrc",al,ac));

  ac=0;
  XtSetArg(al[ac],XmNorientation,XmVERTICAL); ac++;
  XtManageChild(rc3=XmCreateRowColumn(rc2,"bxrc",al,ac));
  ac=0;
  XtManageChild(button=XmCreatePushButton(rc3,"Xaxis",al,ac));
  XtAddCallback(button,XmNdisarmCallback,CrossDialogAxisX,d);
  ac=0;
  xs=XmStringCreateLocalized("      ");
  XtSetArg(al[ac],XmNlabelString,xs); ac++;
  XtManageChild(XmCreateLabel(rc3,"xid",al,ac));
  XmStringFree(xs);
  ac=0;
  XtSetArg(al[ac],XmNorientation,XmVERTICAL); ac++;
  XtManageChild(rc3=XmCreateRowColumn(rc2,"byrc",al,ac));
  ac=0;
  XtManageChild(button=XmCreatePushButton(rc3,"Yaxis",al,ac));
  XtAddCallback(button,XmNdisarmCallback,CrossDialogAxisY,d);
  ac=0;
  xs=XmStringCreateLocalized("      ");
  XtSetArg(al[ac],XmNlabelString,xs); ac++;
  XtManageChild(XmCreateLabel(rc3,"yid",al,ac));
  XmStringFree(xs);
  }
  CrossDialogSetupItem(w,d);
}

void CrossDialogClose(Widget w,void *data)
{
  struct CrossDialog *d;
  int ret;
  int type,a;
  char *buf,*endptr;
  struct narray group;
  char *argv[2];

  d=(struct CrossDialog *)data;
  if (d->ret!=IDOK) return;
  ret=d->ret;
  d->ret=IDLOOP;
  XtVaGetValues(XtNameToWidget(w,"*x"),XmNvalue,&buf,NULL);
  a=strtol(buf,&endptr,10);
  if (endptr[0]!='\0') {
    XtFree(buf);
    return;
  }
  d->X=a;
  XtFree(buf);
  XtVaGetValues(XtNameToWidget(w,"*y"),XmNvalue,&buf,NULL);
  a=strtol(buf,&endptr,10);
  if (endptr[0]!='\0') {
    XtFree(buf);
    return;
  }
  d->Y=a;
  XtFree(buf);
  XtVaGetValues(XtNameToWidget(w,"*width"),XmNvalue,&buf,NULL);
  a=strtol(buf,&endptr,10);
  if (endptr[0]!='\0') {
    XtFree(buf);
    return;
  }
  d->LenX=a;
  XtFree(buf);
  XtVaGetValues(XtNameToWidget(w,"*height"),XmNvalue,&buf,NULL);
  a=strtol(buf,&endptr,10);
  if (endptr[0]!='\0') {
    XtFree(buf);
    return;
  }
  d->LenY=a;
  XtFree(buf);
  if ((d->X!=d->X0) || (d->Y!=d->Y0)
  || (d->LenX!=d->LenX0) || (d->LenY!=d->LenY0)) {
    arrayinit(&group,sizeof(int));
    type=3;
    arrayadd(&group,&type);
    arrayadd(&group,&(d->IDX));
    arrayadd(&group,&(d->IDY));
    arrayadd(&group,&(d->X));
    arrayadd(&group,&(d->Y));
    arrayadd(&group,&(d->LenX));
    arrayadd(&group,&(d->LenY));
    argv[0]=(char *)&group;
    argv[1]=NULL;
    exeobj(d->Obj,"group_position",d->IDX,1,argv);
    arraydel(&group);
  }
  if ((d->IDX!=-1) && (d->IDY!=-1)) {
    exeobj(d->Obj,"adjust",d->IDX,0,NULL);
    exeobj(d->Obj,"adjust",d->IDY,0,NULL);
  }
 d->ret=ret;
}

void CrossDialog(struct CrossDialog *data,
                 int x,int y,int lenx,int leny,
                 struct objlist *obj,int idx,int idy)
{
  data->SetupWindow=CrossDialogSetup;
  data->CloseWindow=CrossDialogClose;
  data->X0=data->X=x;
  data->Y0=data->Y=y;
  data->LenX0=data->LenX=lenx;
  data->LenY0=data->LenY=leny;
  data->Obj=obj;
  data->IDX=idx;
  data->IDY=idy;
  data->MaxX=menulocal.PaperWidth*(10000.0/menulocal.PaperZoom);
  data->MaxY=menulocal.PaperHeight*(10000.0/menulocal.PaperZoom);
}

void ZoomDialogSetupItem(Widget w,struct ZoomDialog *d)
{
  char buf[64];

  sprintf(buf,"%d",d->zoom);
  XtVaSetValues(XtNameToWidget(w,"*zoom"),XmNvalue,buf,NULL);
}

void ZoomDialogSetup(Widget w,void *data,int makewidget)
{
  Arg al[20];
  Cardinal ac;
  Widget rc;
  struct ZoomDialog *d;
  
  d=(struct ZoomDialog *)data;
  if (makewidget) {
  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc=XmCreateRowColumn(w,"rc",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc,"Zoom",al,ac));
  ac=0;
  XtManageChild(XmCreateTextField(rc,"zoom",al,ac));
  }
  ZoomDialogSetupItem(w,d);
}

void ZoomDialogClose(Widget w,void *data)
{
  struct ZoomDialog *d;
  int ret,a;
  char *buf,*endptr;
  
  d=(struct ZoomDialog *)data;
  if (d->ret!=IDOK) return;
  ret=d->ret;
  d->ret=IDLOOP;
  XtVaGetValues(XtNameToWidget(w,"*zoom"),XmNvalue,&buf,NULL);
  a=strtol(buf,&endptr,10);
  if (endptr[0]=='\0') d->zoom=a;
  else {
    XtFree(buf);
    return;
  }
  XtFree(buf);
  d->ret=ret;
}

void ZoomDialog(struct ZoomDialog *data)
{
  data->SetupWindow=ZoomDialogSetup;
  data->CloseWindow=ZoomDialogClose;
  data->zoom=20000;
}

void AxisBaseDialogSetupItem(Widget w,struct AxisBaseDialog *d,int id)
{
  SetStyleFromObjField(w,"*style",d->Obj,id,"style");
  SetComboList(w,"*width",cblinewidth,CBLINEWIDTH);
  SetTextFromObjField(GetComboBoxText(w,"*width"),NULL,d->Obj,id,"width");
  SetComboListFromObjField(GetComboBoxList(w,"*width"),NULL,d->Obj,id,"width");
  SetToggleFromObjField(w,"*Baseline",d->Obj,id,"baseline");
  SetListFromObjField(w,"*arrow",d->Obj,id,"arrow");
  SetTextFromObjField(w,"*arrowlen",d->Obj,id,"arrow_length");
  SetTextFromObjField(w,"*arrowwid",d->Obj,id,"arrow_width");
  SetListFromObjField(w,"*wave",d->Obj,id,"wave");
  SetTextFromObjField(w,"*wavelen",d->Obj,id,"wave_length");
  SetComboList(w,"*wavewid",cblinewidth,CBLINEWIDTH);
  SetTextFromObjField(GetComboBoxText(w,"*wavewid"),NULL,
                      d->Obj,id,"wave_width");
  SetComboListFromObjField(GetComboBoxList(w,"*wavewid"),NULL,
                      d->Obj,id,"wave_width");
  getobj(d->Obj,"R",id,0,NULL,&d->R);
  getobj(d->Obj,"G",id,0,NULL,&d->G);
  getobj(d->Obj,"B",id,0,NULL,&d->B);
  XtVaSetValues(XtNameToWidget(w,"*col"),XmNbackground,RGB(d->R,d->G,d->B),NULL);
}

void AxisBaseDialogColor(Widget w,XtPointer client_data,XtPointer call_data)
{
  struct AxisBaseDialog *d;

  d=(struct AxisBaseDialog *)client_data;
  GetColor(TopLevel,&d->R,&d->G,&d->B);
  XtVaSetValues(w,XmNbackground,RGB(d->R,d->G,d->B),NULL);
}

void AxisBaseDialogCopy(Widget w,XtPointer client_data,XtPointer call_data)
{
  struct AxisBaseDialog *d;
  int sel;

  d=(struct AxisBaseDialog *)client_data;
  if ((sel=CopyClick(d->widget,d->Obj,d->Id,AxisCB))!=-1) 
    AxisBaseDialogSetupItem(d->widget,d,sel);
}

void AxisBaseDialogSetup(Widget w,void *data,int makewidget)
{
  Arg al[20];
  Cardinal ac;
  Widget rc,rc2,button;
  struct AxisBaseDialog *d;
  
  d=(struct AxisBaseDialog *)data;
  if (makewidget) {
  ac=0;
  XtManageChild(button=XmCreatePushButton(w,"Copy",al,ac));
  XtAddCallback(button,XmNdisarmCallback,AxisBaseDialogCopy,d);
  ac=0;
  XtSetArg(al[ac],XmNorientation,XmVERTICAL); ac++;
  XtManageChild(rc=XmCreateRowColumn(w,"rc",al,ac));

  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc2=XmCreateRowColumn(rc,"baselinerc",al,ac));
  ac=0;
  XtManageChild(XmCreateToggleButton(rc2,"Baseline",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc2,"Style",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNcomboBoxType,XmDROP_DOWN_COMBO_BOX); ac++;
  XtManageChild(XmCreateComboBox(rc2,"style",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc2,"Width",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNcomboBoxType,XmDROP_DOWN_COMBO_BOX); ac++;
  XtManageChild(XmCreateComboBox(rc2,"width",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc2,"Color",al,ac));
  ac=0;
  XtManageChild(button=XmCreateDrawnButton(rc2,"col",al,ac));
  XtAddCallback(button,XmNdisarmCallback,AxisBaseDialogColor,d);

  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc2=XmCreateRowColumn(rc,"arrowrc",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc2,"Arrow",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNcomboBoxType,XmDROP_DOWN_LIST); ac++;
  XtManageChild(XmCreateComboBox(rc2,"arrow",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc2,"Length",al,ac));
  ac=0;
  XtManageChild(XmCreateTextField(rc2,"arrowlen",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc2,"Width",al,ac));
  ac=0;
  XtManageChild(XmCreateTextField(rc2,"arrowwid",al,ac));

  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc2=XmCreateRowColumn(rc,"waverc",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc2,"Wave",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNcomboBoxType,XmDROP_DOWN_LIST); ac++;
  XtManageChild(XmCreateComboBox(rc2,"wave",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc2,"Length",al,ac));
  ac=0;
  XtManageChild(XmCreateTextField(rc2,"wavelen",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc2,"Width",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNcomboBoxType,XmDROP_DOWN_COMBO_BOX); ac++;
  XtManageChild(XmCreateComboBox(rc2,"wavewid",al,ac));
  }
  AxisBaseDialogSetupItem(w,d,d->Id); 
}

void AxisBaseDialogClose(Widget w,void *data)
{
  struct AxisBaseDialog *d;
  int ret;
  
  d=(struct AxisBaseDialog *)data;
  if (d->ret!=IDOK) return;
  ret=d->ret;
  d->ret=IDLOOP;
  if (SetObjFieldFromStyle(w,"*style",d->Obj,d->Id,"style")) return;
  if (SetObjFieldFromText(GetComboBoxText(w,"*width"),NULL,
                          d->Obj,d->Id,"width")) return;
  if (SetObjFieldFromToggle(w,"*Baseline",d->Obj,d->Id,"baseline")) return;
  if (SetObjFieldFromList(w,"*arrow",d->Obj,d->Id,"arrow")) return;
  if (SetObjFieldFromText(w,"*arrowlen",d->Obj,d->Id,"arrow_length")) return;
  if (SetObjFieldFromText(w,"*arrowwid",d->Obj,d->Id,"arrow_width")) return;
  if (SetObjFieldFromList(w,"*wave",d->Obj,d->Id,"wave")) return;
  if (SetObjFieldFromText(w,"*wavelen",d->Obj,d->Id,"wave_length")) return;
  if (SetObjFieldFromText(GetComboBoxText(w,"*wavewid"),NULL,
                          d->Obj,d->Id,"wave_width")) return;
  if (putobj(d->Obj,"R",d->Id,&(d->R))==-1) return;
  if (putobj(d->Obj,"G",d->Id,&(d->G))==-1) return;
  if (putobj(d->Obj,"B",d->Id,&(d->B))==-1) return;
  d->ret=ret;
}

void AxisBaseDialog(struct AxisBaseDialog *data,struct objlist *obj,int id)
{
  data->SetupWindow=AxisBaseDialogSetup;
  data->CloseWindow=AxisBaseDialogClose;
  data->Obj=obj;
  data->Id=id;
}

void AxisPosDialogSetupItem(Widget w,struct AxisPosDialog *d,int id)
{
  char *valstr;
  int i,j;
  int lastinst;
  char *name;
  XmString xs;

  SetTextFromObjField(w,"*x",d->Obj,id,"x");
  SetTextFromObjField(w,"*y",d->Obj,id,"y");
  SetTextFromObjField(w,"*len",d->Obj,id,"length");
  SetComboList(w,"*direction",cbdirection,CBDIRECTION);
  SetTextFromObjField(GetComboBoxText(w,"*direction"),NULL,
                      d->Obj,id,"direction");
  SetComboListFromObjField(GetComboBoxList(w,"*direction"),NULL,
                      d->Obj,id,"direction");
  lastinst=chkobjlastinst(d->Obj);
  for (j=0;j<=lastinst;j++) {
    getobj(d->Obj,"group",j,0,NULL,&name);
    if (name==NULL) name="";
    xs=XmStringCreateLocalized(name);
    XmListAddItem(GetComboBoxList(w,"*adjust"),xs,0);
    XmStringFree(xs);
  }
  SetComboBoxVisibleItemCount(w,"*adjust",j);
  sgetobjfield(d->Obj,id,"adjust_axis",NULL,&valstr,FALSE,FALSE,FALSE);
  for (i=0;(valstr[i]!='\0') && (valstr[i]!=':');i++);
  if (valstr[i]==':') i++;
  XtVaSetValues(GetComboBoxText(w,"*adjust"),XmNvalue,valstr+i,NULL);
  memfree(valstr);
  SetTextFromObjField(w,"*adjustpos",d->Obj,id,"adjust_position");
}

void AxisPosDialogRef(Widget w,XtPointer client_data,XtPointer call_data)
{
  struct AxisPosDialog *d;
  XmComboBoxCallbackStruct *dd;
  char buf[10];
  int a,oid;

  d=(struct AxisPosDialog *)client_data;
  dd=(XmComboBoxCallbackStruct *)call_data;
#ifdef ZEROBASECOMBOBOX
  a=dd->item_position;
#else
  a=dd->item_position-1;
#endif
  if (a<0) return;
  getobj(d->Obj,"oid",a,0,NULL,&oid);
  sprintf(buf,"^%d",oid); 
  XtVaSetValues(GetComboBoxText(d->widget,"*adjust"),XmNvalue,buf,NULL);
}

void AxisPosDialogCopy(Widget w,XtPointer client_data,XtPointer call_data)
{
  struct AxisPosDialog *d;
  int sel;

  d=(struct AxisPosDialog *)client_data;
  if ((sel=CopyClick(d->widget,d->Obj,d->Id,AxisCB))!=-1) 
    AxisPosDialogSetupItem(d->widget,d,sel);
}

void AxisPosDialogSetup(Widget w,void *data,int makewidget)
{
  Arg al[20];
  Cardinal ac;
  Widget rc,rc2,button,combo;
  struct AxisPosDialog *d;

  d=(struct AxisPosDialog *)data;
  if (makewidget) {
  ac=0;
  XtManageChild(button=XmCreatePushButton(w,"Copy",al,ac));
  XtAddCallback(button,XmNdisarmCallback,AxisPosDialogCopy,d); 
  ac=0;
  XtSetArg(al[ac],XmNorientation,XmVERTICAL); ac++;
  XtManageChild(rc=XmCreateRowColumn(w,"rc",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc2=XmCreateRowColumn(rc,"rc1",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc2,"X",al,ac));
  ac=0;
  XtManageChild(XmCreateTextField(rc2,"x",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc2,"Y",al,ac));
  ac=0;
  XtManageChild(XmCreateTextField(rc2,"y",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc2,"Length",al,ac));
  ac=0;
  XtManageChild(XmCreateTextField(rc2,"len",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc2,"Dir",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNcomboBoxType,XmDROP_DOWN_COMBO_BOX); ac++;
  XtManageChild(XmCreateComboBox(rc2,"direction",al,ac));

  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc2=XmCreateRowColumn(rc,"rc2",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc2,"Adjust",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNcomboBoxType,XmDROP_DOWN_COMBO_BOX); ac++;
  XtManageChild(combo=XmCreateComboBox(rc2,"adjust",al,ac));
  XtAddCallback(combo,XmNselectionCallback,AxisPosDialogRef,d);
  ac=0;
  XtManageChild(XmCreateLabel(rc2,"AdjustPosition",al,ac));
  ac=0;
  XtManageChild(XmCreateTextField(rc2,"adjustpos",al,ac));
  }

  AxisPosDialogSetupItem(w,d,d->Id);
}

void AxisPosDialogClose(Widget w,void *data)
{
  struct AxisPosDialog *d;
  int ret;
  char *s,*buf;
  int len;
  
  d=(struct AxisPosDialog *)data;
  if (d->ret!=IDOK) return;
  ret=d->ret;
  d->ret=IDLOOP;
  if (SetObjFieldFromText(w,"*x",d->Obj,d->Id,"x")) return;
  if (SetObjFieldFromText(w,"*y",d->Obj,d->Id,"y")) return;
  if (SetObjFieldFromText(w,"*len",d->Obj,d->Id,"length")) return;
  if (SetObjFieldFromText(GetComboBoxText(w,"*direction"),NULL,
                          d->Obj,d->Id,"direction")) return;
  XtVaGetValues(GetComboBoxText(w,"*adjust"),XmNvalue,&s,NULL);
  if ((s==NULL) || (strlen(s)==0)) {
    if (sputobjfield(d->Obj,d->Id,"adjust_axis",NULL)!=0) return;
  } else {
    len=strlen(s);
    if ((buf=(char *)memalloc(len+6))!=NULL) {
      strcpy(buf,"axis:");
      if (s!=NULL) strcat(buf,s);
      if (sputobjfield(d->Obj,d->Id,"adjust_axis",buf)!=0) {
        memfree(buf);
        return;
      }
      memfree(buf);
    }
  }
  XtFree(s);
  if (SetObjFieldFromText(w,"*adjustpos",d->Obj,d->Id,"adjust_position"))
    return;
  d->ret=ret;
}

void AxisPosDialog(struct AxisPosDialog *data,struct objlist *obj,int id)
{
  data->SetupWindow=AxisPosDialogSetup;
  data->CloseWindow=AxisPosDialogClose;
  data->Obj=obj;
  data->Id=id;
}

void NumDialogSetupItem(Widget w,struct NumDialog *d,int id)
{
  char *format,*endptr;
  int j,a;
  XmString xs;

  SetListFromObjField(w,"*num",d->Obj,id,"num");
  SetTextFromObjField(w,"*begin",d->Obj,id,"num_begin");
  SetTextFromObjField(w,"*step",d->Obj,id,"num_step");
  SetTextFromObjField(w,"*numnum",d->Obj,id,"num_num");
  SetTextFromObjField(w,"*head",d->Obj,id,"num_head");
  XmListDeleteAllItems(GetComboBoxList(w,"*fraction"));
  for (j=0;j<CNUMSTYLE;j++) {
    xs=XmStringCreateLocalized(fwnumstyle[j]);
    XmListAddItem(GetComboBoxList(w,"*fraction"),xs,0);
    XmStringFree(xs);
  }
  SetComboBoxVisibleItemCount(w,"*fraction",j);
  getobj(d->Obj,"num_format",id,0,NULL,&format);
  if (strchr(format,'+')!=NULL)
     XmToggleButtonSetState(XtNameToWidget(w,"*Add_plus"),TRUE,TRUE);
  else
     XmToggleButtonSetState(XtNameToWidget(w,"*Add_plus"),FALSE,TRUE);
  if ((strchr(format,'f')==NULL) || (strchr(format,'.')==NULL)) a=0;
  else a=strtol(strchr(format,'.')+1,&endptr,10)+1;
  if (a<0) a=0;
  else if (a>10) a=10;
  XmListSelectPos(GetComboBoxList(w,"*fraction"),a+1,TRUE);
  SetTextFromObjField(w,"*tail",d->Obj,id,"num_tail");
  SetListFromObjField(w,"*align",d->Obj,id,"num_align");
  SetListFromObjField(w,"*direction",d->Obj,id,"num_direction");
  SetTextFromObjField(w,"*shiftp",d->Obj,id,"num_shift_p");
  SetTextFromObjField(w,"*shiftn",d->Obj,id,"num_shift_n");
  SetToggleFromObjField(w,"*Log_power",d->Obj,id,"num_log_pow");
  SetToggleFromObjField(w,"*No_zero",d->Obj,id,"num_no_zero");
  SetTextFromObjField(w,"*norm",d->Obj,id,"num_auto_norm");
}

void NumDialogCopy(Widget w,XtPointer client_data,XtPointer call_data)
{
  struct NumDialog *d;
  int sel;

  d=(struct NumDialog *)client_data;
  if ((sel=CopyClick(d->widget,d->Obj,d->Id,AxisCB))!=-1) 
    NumDialogSetupItem(d->widget,d,sel);
}

void NumDialogSetup(Widget w,void *data,int makewidget)
{
  Arg al[20];
  Cardinal ac;
  Widget rc,rc2,rc3,button,frame;
  struct NumDialog *d;
  
  d=(struct NumDialog *)data;
  if (makewidget) {
  ac=0;
  XtManageChild(button=XmCreatePushButton(w,"Copy",al,ac));
  XtAddCallback(button,XmNdisarmCallback,NumDialogCopy,d);
  
  ac=0;
  XtSetArg(al[ac],XmNorientation,XmVERTICAL); ac++;
  XtManageChild(rc=XmCreateRowColumn(w,"rc",al,ac));

  ac=0;
  XtManageChild(frame=XmCreateFrame(rc,"frame",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNorientation,XmVERTICAL); ac++;
  XtManageChild(rc3=XmCreateRowColumn(frame,"rc1",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc2=XmCreateRowColumn(rc3,"numberrc",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc2,"Numbering",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNcomboBoxType,XmDROP_DOWN_LIST); ac++;
  XtManageChild(XmCreateComboBox(rc2,"num",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc2=XmCreateRowColumn(rc3,"numrc",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc2,"Begin",al,ac));
  ac=0;
  XtManageChild(XmCreateTextField(rc2,"begin",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc2,"Step",al,ac));
  ac=0;
  XtManageChild(XmCreateTextField(rc2,"step",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc2,"Num",al,ac));
  ac=0;
  XtManageChild(XmCreateTextField(rc2,"numnum",al,ac));

  ac=0;
  XtManageChild(frame=XmCreateFrame(rc,"frame2",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNorientation,XmVERTICAL); ac++;
  XtManageChild(rc3=XmCreateRowColumn(frame,"rc2",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc2=XmCreateRowColumn(rc3,"formatrc",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc2,"Format",al,ac));
  ac=0;
  XtManageChild(XmCreateToggleButton(rc2,"Add_plus",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc2,"Fraction",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNcomboBoxType,XmDROP_DOWN_LIST); ac++;
  XtManageChild(XmCreateComboBox(rc2,"fraction",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc2=XmCreateRowColumn(rc3,"headrc",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc2,"Head",al,ac));
  ac=0;
  XtManageChild(XmCreateTextField(rc2,"head",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc2,"Tail",al,ac));
  ac=0;
  XtManageChild(XmCreateTextField(rc2,"tail",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc2=XmCreateRowColumn(rc3,"alignrc",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc2,"Align",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNcomboBoxType,XmDROP_DOWN_LIST); ac++;
  XtManageChild(XmCreateComboBox(rc2,"align",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc2,"Dir",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNcomboBoxType,XmDROP_DOWN_LIST); ac++;
  XtManageChild(XmCreateComboBox(rc2,"direction",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc2=XmCreateRowColumn(rc3,"shiftrc",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc2,"Shiftp",al,ac));
  ac=0;
  XtManageChild(XmCreateTextField(rc2,"shiftp",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc2,"Shiftn",al,ac));
  ac=0;
  XtManageChild(XmCreateTextField(rc2,"shiftn",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc2=XmCreateRowColumn(rc3,"logrc",al,ac));
  ac=0;
  XtManageChild(XmCreateToggleButton(rc2,"Log_power",al,ac));
  ac=0;
  XtManageChild(XmCreateToggleButton(rc2,"No_zero",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc2=XmCreateRowColumn(rc3,"autorc",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc2,"Norm",al,ac));
  ac=0;
  XtManageChild(XmCreateTextField(rc2,"norm",al,ac));
  }
  NumDialogSetupItem(w,d,d->Id);
}

void NumDialogClose(Widget w,void *data)
{
  struct NumDialog *d;
  int ret;
  int a,j,*pos,count;
  char *format;
  
  d=(struct NumDialog *)data;
  if (d->ret!=IDOK) return;
  ret=d->ret;
  d->ret=IDLOOP;
  if (SetObjFieldFromList(w,"*num",d->Obj,d->Id,"num")) return;
  if (SetObjFieldFromText(w,"*begin",d->Obj,d->Id,"num_begin")) return;
  if (SetObjFieldFromText(w,"*step",d->Obj,d->Id,"num_step")) return;
  if (SetObjFieldFromText(w,"*numnum",d->Obj,d->Id,"num_num")) return;
  if (SetObjFieldFromText(w,"*head",d->Obj,d->Id,"num_head")) return;
  if ((format=(char *)memalloc(10))==NULL) return;
  j=0;
  j+=sprintf(format+j,"%%");
  if (XmToggleButtonGetState(XtNameToWidget(w,"*Add_plus")))
    j+=sprintf(format+j,"%c",'+');
  XmListGetSelectedPos(GetComboBoxList(w,"*fraction"),&pos,&count);
  if (count!=0) {
    a=pos[0]-1;
    XtFree((char *)pos);
    if (a==0) j+=sprintf(format+j,"%c",'g');
    else j+=sprintf(format+j,".%df",a-1);
  }
  if (putobj(d->Obj,"num_format",d->Id,format)==-1) return;
  if (SetObjFieldFromText(w,"*tail",d->Obj,d->Id,"num_tail")) return;
  if (SetObjFieldFromList(w,"*align",d->Obj,d->Id,"num_align")) return;
  if (SetObjFieldFromList(w,"*direction",d->Obj,d->Id,"num_direction")) return;
  if (SetObjFieldFromText(w,"*shiftp",d->Obj,d->Id,"num_shift_p")) return;
  if (SetObjFieldFromText(w,"*shiftn",d->Obj,d->Id,"num_shift_n")) return;
  if (SetObjFieldFromToggle(w,"*Log_power",d->Obj,d->Id,"num_log_pow")) return;
  if (SetObjFieldFromToggle(w,"*No_zero",d->Obj,d->Id,"num_no_zero")) return;
  if (SetObjFieldFromText(w,"*norm",d->Obj,d->Id,"num_auto_norm")) return;
  d->ret=ret;
}

void NumDialog(struct NumDialog *data,struct objlist *obj,int id)
{
  data->SetupWindow=NumDialogSetup;
  data->CloseWindow=NumDialogClose;
  data->Obj=obj;
  data->Id=id;
}

void AxisFontDialogSetupItem(Widget w,struct AxisFontDialog *d,int id)
{
  int j,selfont;
  struct fontmap *fcur;
  char *font;
  XmString xs;

  SetTextFromObjField(w,"*space",d->Obj,id,"num_space");
  SetComboList(w,"*pt",cbtextpt,CBTEXTPT);
  SetTextFromObjField(GetComboBoxText(w,"*pt"),NULL,d->Obj,id,"num_pt");
  SetComboListFromObjField(GetComboBoxList(w,"*pt"),NULL,d->Obj,id,"num_pt");
  SetTextFromObjField(w,"*script",d->Obj,id,"num_script_size");
  getobj(d->Obj,"num_font",id,0,NULL,&font);
  XmListDeleteAllItems(GetComboBoxList(w,"*font"));
  fcur=mxlocal->fontmaproot;
  j=0;
  selfont=-1;
  while (fcur!=NULL) {
    if (!(fcur->twobyte)) {
      xs=XmStringCreateLocalized(fcur->fontalias);
      XmListAddItem(GetComboBoxList(w,"*font"),xs,0);
      XmStringFree(xs);
      if (strcmp(font,fcur->fontalias)==0) selfont=j;
      j++;
    }
    fcur=fcur->next;
  }
  SetComboBoxVisibleItemCount(w,"*font",j);
  if (selfont!=-1) 
    XmListSelectPos(GetComboBoxList(w,"*font"),selfont+1,TRUE);
#ifdef JAPANESE
  getobj(d->Obj,"num_jfont",id,0,NULL,&font);
  XmListDeleteAllItems(GetComboBoxList(w,"*jfont"));
  fcur=mxlocal->fontmaproot;
  j=0;
  selfont=-1;
  while (fcur!=NULL) {
    if (fcur->twobyte) {
      xs=XmStringCreateLocalized(fcur->fontalias);
      XmListAddItem(GetComboBoxList(w,"*jfont"),xs,0);
      XmStringFree(xs);
      if (strcmp(font,fcur->fontalias)==0) selfont=j;
      j++;
    }
    fcur=fcur->next;
  }
  SetComboBoxVisibleItemCount(w,"*jfont",j);
  if (selfont!=-1) 
    XmListSelectPos(GetComboBoxList(w,"*jfont"),selfont+1,TRUE);
#endif
  getobj(d->Obj,"num_R",id,0,NULL,&d->R);
  getobj(d->Obj,"num_G",id,0,NULL,&d->G);
  getobj(d->Obj,"num_B",id,0,NULL,&d->B);
  XtVaSetValues(XtNameToWidget(w,"*col"),XmNbackground,RGB(d->R,d->G,d->B),NULL); 
}

void AxisFontDialogColor(Widget w,XtPointer client_data,XtPointer call_data)
{
  struct AxisFontDialog *d;

  d=(struct AxisFontDialog *)client_data;
  GetColor(TopLevel,&d->R,&d->G,&d->B);
  XtVaSetValues(w,XmNbackground,RGB(d->R,d->G,d->B),NULL);
}

void AxisFontDialogCopy(Widget w,XtPointer client_data,XtPointer call_data)
{
  struct AxisFontDialog *d;
  int sel;

  d=(struct AxisFontDialog *)client_data;
  if ((sel=CopyClick(d->widget,d->Obj,d->Id,AxisCB))!=-1) 
    AxisFontDialogSetupItem(d->widget,d,sel);
}

void AxisFontDialogSetup(Widget w,void *data,int makewidget)
{
  Arg al[20];
  Cardinal ac;
  Widget rc,rc2,button;
  struct AxisFontDialog *d;
  
  d=(struct AxisFontDialog *)data;
  if (makewidget) {
  ac=0;
  XtManageChild(button=XmCreatePushButton(w,"Copy",al,ac));
  XtAddCallback(button,XmNdisarmCallback,AxisFontDialogCopy,d);
  
  ac=0;
  XtSetArg(al[ac],XmNorientation,XmVERTICAL); ac++;
  XtManageChild(rc=XmCreateRowColumn(w,"rc",al,ac));

  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc2=XmCreateRowColumn(rc,"ptrc",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc2,"Pt",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNcomboBoxType,XmDROP_DOWN_COMBO_BOX); ac++;
  XtManageChild(XmCreateComboBox(rc2,"pt",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc2,"Space",al,ac));
  ac=0;
  XtManageChild(XmCreateTextField(rc2,"space",al,ac));

  ac=0;
  XtManageChild(XmCreateLabel(rc2,"Script",al,ac));
  ac=0;
  XtManageChild(XmCreateTextField(rc2,"script",al,ac));

  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc2=XmCreateRowColumn(rc,"fontrc",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc2,"Font",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNcomboBoxType,XmDROP_DOWN_LIST); ac++;
  XtManageChild(XmCreateComboBox(rc2,"font",al,ac));
#ifdef JAPANESE
  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc2=XmCreateRowColumn(rc,"jfontrc",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc2,"Jfont",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNcomboBoxType,XmDROP_DOWN_LIST); ac++;
  XtManageChild(XmCreateComboBox(rc2,"jfont",al,ac));
#endif
  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc2=XmCreateRowColumn(rc,"colorrc",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc2,"Color",al,ac));
  ac=0;
  XtManageChild(button=XmCreateDrawnButton(rc2,"col",al,ac));
  XtAddCallback(button,XmNdisarmCallback,AxisFontDialogColor,d);
  }  
  AxisFontDialogSetupItem(w,d,d->Id);
}

void AxisFontDialogClose(Widget w,void *data)
{
  struct AxisFontDialog *d;
  int ret;
  struct fontmap *fcur;
  int *selected,num,a,j;

  d=(struct AxisFontDialog *)data;
  if (d->ret!=IDOK) return;
  ret=d->ret;
  d->ret=IDLOOP;
  if (SetObjFieldFromText(w,"*space",d->Obj,d->Id,"num_space")) return;
  if (SetObjFieldFromText(GetComboBoxText(w,"*pt"),NULL,
                          d->Obj,d->Id,"num_pt")) return;
  if (SetObjFieldFromText(w,"*script",d->Obj,d->Id,"num_script_size")) return;

  XmListGetSelectedPos(GetComboBoxList(w,"*font"),&selected,&num);
  if (num!=0) {
    a=selected[0];
    fcur=mxlocal->fontmaproot;
    j=0;
    while (fcur!=NULL) {
      if (!(fcur->twobyte)) {
        j++;
        if (j==a) {
          sputobjfield(d->Obj,d->Id,"num_font",fcur->fontalias);
          break;
        }
      }
      fcur=fcur->next;
    }
    XtFree((char *)selected);
  }
#ifdef JAPANESE
  XmListGetSelectedPos(GetComboBoxList(w,"*jfont"),&selected,&num);
  if (num!=0) {
    a=selected[0];
    fcur=mxlocal->fontmaproot;
    j=0;
    while (fcur!=NULL) {
      if (fcur->twobyte) {
        j++;
        if (j==a) {
          sputobjfield(d->Obj,d->Id,"num_jfont",fcur->fontalias);
          break;
        }
      }
      fcur=fcur->next;
    }
    XtFree((char *)selected);
  }
#endif
  if (putobj(d->Obj,"num_R",d->Id,&(d->R))==-1) return;
  if (putobj(d->Obj,"num_G",d->Id,&(d->G))==-1) return;
  if (putobj(d->Obj,"num_B",d->Id,&(d->B))==-1) return;
  d->ret=ret;
}

void AxisFontDialog(struct AxisFontDialog *data,struct objlist *obj,int id)
{
  data->SetupWindow=AxisFontDialogSetup;
  data->CloseWindow=AxisFontDialogClose;
  data->Obj=obj;
  data->Id=id;
}

void GaugeDialogSetupItem(Widget w,struct GaugeDialog *d,int id)
{
  SetListFromObjField(w,"*gauge",d->Obj,id,"gauge");
  SetTextFromObjField(w,"*min",d->Obj,id,"gauge_min");
  SetTextFromObjField(w,"*max",d->Obj,id,"gauge_max");
  SetStyleFromObjField(w,"*style",d->Obj,id,"gauge_style");
  SetTextFromObjField(w,"*len1",d->Obj,id,"gauge_length1");
  SetComboList(w,"*wid1",cblinewidth,CBLINEWIDTH);
  SetTextFromObjField(GetComboBoxText(w,"*wid1"),NULL,
                      d->Obj,id,"gauge_width1");
  SetComboListFromObjField(GetComboBoxList(w,"*wid1"),NULL,
                      d->Obj,id,"gauge_width1");
  SetTextFromObjField(w,"*len2",d->Obj,id,"gauge_length2");
  SetComboList(w,"*wid2",cblinewidth,CBLINEWIDTH);
  SetTextFromObjField(GetComboBoxText(w,"*wid2"),NULL,
                      d->Obj,id,"gauge_width2");
  SetComboListFromObjField(GetComboBoxList(w,"*wid2"),NULL,
                      d->Obj,id,"gauge_width2");
  SetTextFromObjField(w,"*len3",d->Obj,id,"gauge_length3");
  SetComboList(w,"*wid3",cblinewidth,CBLINEWIDTH);
  SetTextFromObjField(GetComboBoxText(w,"*wid3"),NULL,
                      d->Obj,id,"gauge_width3");
  SetComboListFromObjField(GetComboBoxList(w,"*wid3"),NULL,
                      d->Obj,id,"gauge_width3");
  getobj(d->Obj,"gauge_R",id,0,NULL,&d->R);
  getobj(d->Obj,"gauge_G",id,0,NULL,&d->G);
  getobj(d->Obj,"gauge_B",id,0,NULL,&d->B);
  XtVaSetValues(XtNameToWidget(w,"*col"),XmNbackground,RGB(d->R,d->G,d->B),NULL);
}

void GaugeDialogColor(Widget w,XtPointer client_data,XtPointer call_data)
{
  struct GaugeDialog *d;

  d=(struct GaugeDialog *)client_data;
  GetColor(TopLevel,&d->R,&d->G,&d->B);
  XtVaSetValues(w,XmNbackground,RGB(d->R,d->G,d->B),NULL);
}

void GaugeDialogCopy(Widget w,XtPointer client_data,XtPointer call_data)
{
  struct GaugeDialog *d;
  int sel;

  d=(struct GaugeDialog *)client_data;
  if ((sel=CopyClick(d->widget,d->Obj,d->Id,AxisCB))!=-1) 
    GaugeDialogSetupItem(d->widget,d,sel);
}

void GaugeDialogSetup(Widget w,void *data,int makewidget)
{
  Arg al[20];
  Cardinal ac;
  Widget rc,rc2,rc3,frame,button;
  struct GaugeDialog *d;
  
  d=(struct GaugeDialog *)data;
  if (makewidget) {
  ac=0;
  XtManageChild(button=XmCreatePushButton(w,"Copy",al,ac));
  XtAddCallback(button,XmNdisarmCallback,GaugeDialogCopy,d);
  
  ac=0;
  XtSetArg(al[ac],XmNorientation,XmVERTICAL); ac++;
  XtManageChild(rc=XmCreateRowColumn(w,"rc",al,ac));

  ac=0;
  XtManageChild(frame=XmCreateFrame(rc,"frame",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc2=XmCreateRowColumn(frame,"gaugerc",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc2,"Gauge",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNcomboBoxType,XmDROP_DOWN_LIST); ac++;
  XtManageChild(XmCreateComboBox(rc2,"gauge",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc2,"Min",al,ac));
  ac=0;
  XtManageChild(XmCreateTextField(rc2,"min",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc2,"Max",al,ac));
  ac=0;
  XtManageChild(XmCreateTextField(rc2,"max",al,ac));

  ac=0;
  XtManageChild(frame=XmCreateFrame(rc,"frame2",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNorientation,XmVERTICAL); ac++;
  XtManageChild(rc2=XmCreateRowColumn(frame,"rc2",al,ac));

  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc3=XmCreateRowColumn(rc2,"stylerc",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc3,"Style",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNcomboBoxType,XmDROP_DOWN_COMBO_BOX); ac++;
  XtManageChild(XmCreateComboBox(rc3,"style",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc3,"Color",al,ac));
  ac=0;
  XtManageChild(button=XmCreateDrawnButton(rc3,"col",al,ac));
  XtAddCallback(button,XmNdisarmCallback,GaugeDialogColor,d);
  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc3=XmCreateRowColumn(rc2,"len1rc",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc3,"Length1",al,ac));
  ac=0;
  XtManageChild(XmCreateTextField(rc3,"len1",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc3,"Width1",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNcomboBoxType,XmDROP_DOWN_COMBO_BOX); ac++;
  XtManageChild(XmCreateComboBox(rc3,"wid1",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc3=XmCreateRowColumn(rc2,"len2rc",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc3,"Length2",al,ac));
  ac=0;
  XtManageChild(XmCreateTextField(rc3,"len2",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc3,"Width2",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNcomboBoxType,XmDROP_DOWN_COMBO_BOX); ac++;
  XtManageChild(XmCreateComboBox(rc3,"wid2",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc3=XmCreateRowColumn(rc2,"len3rc",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc3,"Length3",al,ac));
  ac=0;
  XtManageChild(XmCreateTextField(rc3,"len3",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc3,"Width3",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNcomboBoxType,XmDROP_DOWN_COMBO_BOX); ac++;
  XtManageChild(XmCreateComboBox(rc3,"wid3",al,ac));
  }
  GaugeDialogSetupItem(w,d,d->Id);
}


void GaugeDialogClose(Widget w,void *data)
{
  struct GaugeDialog *d;
  int ret;
  
  d=(struct GaugeDialog *)data;
  if (d->ret!=IDOK) return;
  ret=d->ret;
  d->ret=IDLOOP;
  if (SetObjFieldFromList(w,"*gauge",d->Obj,d->Id,"gauge")) return;
  if (SetObjFieldFromText(w,"*min",d->Obj,d->Id,"gauge_min")) return;
  if (SetObjFieldFromText(w,"*max",d->Obj,d->Id,"gauge_max")) return;
  if (SetObjFieldFromStyle(w,"*style",d->Obj,d->Id,"gauge_style")) return;
  if (SetObjFieldFromText(w,"*len1",d->Obj,d->Id,"gauge_length1")) return;
  if (SetObjFieldFromText(GetComboBoxText(w,"*wid1"),NULL,
                          d->Obj,d->Id,"gauge_width1")) return;
  if (SetObjFieldFromText(w,"*len2",d->Obj,d->Id,"gauge_length2")) return;
  if (SetObjFieldFromText(GetComboBoxText(w,"*wid2"),NULL,
                          d->Obj,d->Id,"gauge_width2")) return;
  if (SetObjFieldFromText(w,"*len3",d->Obj,d->Id,"gauge_length3")) return;
  if (SetObjFieldFromText(GetComboBoxText(w,"*wid3"),NULL,
                          d->Obj,d->Id,"gauge_width3")) return;
  if (putobj(d->Obj,"gauge_R",d->Id,&(d->R))==-1) return;
  if (putobj(d->Obj,"gauge_G",d->Id,&(d->G))==-1) return;
  if (putobj(d->Obj,"gauge_B",d->Id,&(d->B))==-1) return;
  d->ret=ret;
}

void GaugeDialog(struct GaugeDialog *data,struct objlist *obj,int id)
{
  data->SetupWindow=GaugeDialogSetup;
  data->CloseWindow=GaugeDialogClose;
  data->Obj=obj;
  data->Id=id;
}

void AxisDialogSetupItem(Widget w,struct AxisDialog *d,int id)
{
  char *valstr;
  int i,j;
  double min,max,inc;
  int div,lastinst;
  XmString xs;
  char *name;
  struct narray *array;
  int num;
  double *data;
  char buf[30];

  XmListDeleteAllItems(GetComboBoxList(w,"*min"));
  XmListDeleteAllItems(GetComboBoxList(w,"*max"));
  XmListDeleteAllItems(GetComboBoxList(w,"*inc"));
  getobj(d->Obj,"scale_history",d->Id,0,NULL,&array);
  if (array!=NULL) {
    num=arraynum(array)/3;
    data=(double *)arraydata(array);
    for (j=0;j<num;j++) {
      sprintf(buf,"%.15g",data[0+j*3]);
      xs=XmStringCreateLocalized(buf);
      XmListAddItem(GetComboBoxList(w,"*min"),xs,0);
      XmStringFree(xs);
      sprintf(buf,"%.15g",data[1+j*3]);
      xs=XmStringCreateLocalized(buf);
      XmListAddItem(GetComboBoxList(w,"*max"),xs,0);
      XmStringFree(xs);
      sprintf(buf,"%.15g",data[2+j*3]);
      xs=XmStringCreateLocalized(buf);
      XmListAddItem(GetComboBoxList(w,"*inc"),xs,0);
      XmStringFree(xs);
    }
    SetComboBoxVisibleItemCount(w,"*min",j);
    SetComboBoxVisibleItemCount(w,"*max",j);
    SetComboBoxVisibleItemCount(w,"*inc",j);
  }
  getobj(d->Obj,"min",id,0,NULL,&min);
  getobj(d->Obj,"max",id,0,NULL,&max);
  getobj(d->Obj,"inc",id,0,NULL,&inc);
  if ((min==0) && (max==0) && (inc==0)) {
    XtVaSetValues(GetComboBoxText(w,"*min"),XmNvalue,"0",NULL);
    XtVaSetValues(GetComboBoxText(w,"*max"),XmNvalue,"0",NULL);
    XtVaSetValues(GetComboBoxText(w,"*inc"),XmNvalue,"0",NULL);
  } else {
    sprintf(buf,"%.15g",min);
    XtVaSetValues(GetComboBoxText(w,"*min"),XmNvalue,buf,NULL);
    sprintf(buf,"%.15g",max);
    XtVaSetValues(GetComboBoxText(w,"*max"),XmNvalue,buf,NULL);
    sprintf(buf,"%.15g",inc);
    XtVaSetValues(GetComboBoxText(w,"*inc"),XmNvalue,buf,NULL);
  }
  getobj(d->Obj,"div",id,0,NULL,&div);
  SetTextFromObjField(w,"*div",d->Obj,id,"div");
  SetListFromObjField(w,"*scale",d->Obj,id,"type");
  XmListDeleteAllItems(GetComboBoxList(w,"*ref"));
  lastinst=chkobjlastinst(d->Obj);
  for (j=0;j<=lastinst;j++) {
    getobj(d->Obj,"group",j,0,NULL,&name);
    if (name==NULL) name="";
    xs=XmStringCreateLocalized(name);
    XmListAddItem(GetComboBoxList(w,"*ref"),xs,0);
    XmStringFree(xs);
  }
  SetComboBoxVisibleItemCount(w,"*ref",j);
  sgetobjfield(d->Obj,id,"reference",NULL,&valstr,FALSE,FALSE,FALSE);
  for (i=0;(valstr[i]!='\0') && (valstr[i]!=':');i++);
  if (valstr[i]==':') i++;
  XtVaSetValues(GetComboBoxText(w,"*ref"),XmNvalue,valstr+i,NULL);
  memfree(valstr);
}

void AxisDialogGauge(Widget w,XtPointer client_data,XtPointer call_data)
{
  struct AxisDialog *d;

  d=(struct AxisDialog *)client_data;
  GaugeDialog(&DlgGauge,d->Obj,d->Id);
  DialogExecute(d->widget,&DlgGauge);
}


void AxisDialogBase(Widget w,XtPointer client_data,XtPointer call_data)
{
  struct AxisDialog *d;

  d=(struct AxisDialog *)client_data;
  AxisBaseDialog(&DlgAxisBase,d->Obj,d->Id);
  DialogExecute(d->widget,&DlgAxisBase);
}

void AxisDialogPos(Widget w,XtPointer client_data,XtPointer call_data)
{
  struct AxisDialog *d;

  d=(struct AxisDialog *)client_data;
  AxisPosDialog(&DlgAxisPos,d->Obj,d->Id);
  DialogExecute(d->widget,&DlgAxisPos);
}

void AxisDialogFont(Widget w,XtPointer client_data,XtPointer call_data)
{
  struct AxisDialog *d;

  d=(struct AxisDialog *)client_data;
  AxisFontDialog(&DlgAxisFont,d->Obj,d->Id);
  DialogExecute(d->widget,&DlgAxisFont);
}

void AxisDialogNum(Widget w,XtPointer client_data,XtPointer call_data)
{
  struct AxisDialog *d;

  d=(struct AxisDialog *)client_data;
  NumDialog(&DlgNum,d->Obj,d->Id);
  DialogExecute(d->widget,&DlgNum);
}

void AxisDialogClear(Widget w,XtPointer client_data,XtPointer call_data)
{
  struct AxisDialog *d;

  d=(struct AxisDialog *)client_data;
  XtVaSetValues(GetComboBoxText(d->widget,"*min"),XmNvalue,"0",NULL);
  XtVaSetValues(GetComboBoxText(d->widget,"*max"),XmNvalue,"0",NULL);
  XtVaSetValues(GetComboBoxText(d->widget,"*inc"),XmNvalue,"0",NULL);
}

void AxisDialogFile(Widget w,XtPointer client_data,XtPointer call_data)
{
  struct AxisDialog *d;
  int anum,room,type;
  char *buf,s[30];
  char *argv2[3];
  struct objlist *fobj;
  struct narray farray;
  int *selected,count,a,i,j,num,*array;
  struct narray *result;

  d=(struct AxisDialog *)client_data;
  if ((fobj=chkobject("file"))==NULL) return;
  if (chkobjlastinst(fobj)==-1) return;
  SelectDialog(&DlgSelect,fobj,FileCB,(struct narray *)&farray,NULL);
  if (DialogExecute(TopLevel,&DlgSelect)==IDOK) {
    num=arraynum(&farray);
    array=(int *)arraydata(&farray);
    anum=chkobjlastinst(d->Obj);
    if ((num>0) && (anum!=0)) {
      if ((buf=(char *)memalloc(6*num+6))!=NULL) {
        j=0;
        j+=sprintf(buf+j,"file:");
        for (i=0;i<num;i++)
          if (i==num-1) j+=sprintf(buf+j,"%d",array[i]);
          else j+=sprintf(buf+j,"%d,",array[i]);
        room=0;
        argv2[0]=(char *)buf;
        argv2[1]=(char *)&room;
        argv2[2]=NULL;
        XmListGetSelectedPos(GetComboBoxList(d->widget,"*scale"),
                             &selected,&count);
        if (count!=0) {
          a=selected[0]-1;
          XtFree((char *)selected);
          if ((getobj(d->Obj,"type",d->Id,0,NULL,&type)==-1)
          || (putobj(d->Obj,"type",d->Id,&a)==-1)) {
            arraydel(&farray);
            return;
          }
        }
        getobj(d->Obj,"get_auto_scale",d->Id,2,argv2,&result);
        memfree(buf);
        if (arraynum(result)==3) {
          sprintf(s,"%.15g",*(double *)arraynget(result,0));
          XtVaSetValues(GetComboBoxText(d->widget,"*min"),XmNvalue,s,NULL);
          sprintf(s,"%.15g",*(double *)arraynget(result,1));
          XtVaSetValues(GetComboBoxText(d->widget,"*max"),XmNvalue,s,NULL);
          sprintf(s,"%.15g",*(double *)arraynget(result,2));
          XtVaSetValues(GetComboBoxText(d->widget,"*inc"),XmNvalue,s,NULL);
        }
        putobj(d->Obj,"type",d->Id,&type);
      }
    }
  }
  arraydel(&farray);
}

void AxisDialogRef(Widget w,XtPointer client_data,XtPointer call_data)
{
  struct AxisDialog *d;
  XmComboBoxCallbackStruct *dd;
  char buf[10];
  int a,oid;

  d=(struct AxisDialog *)client_data;
  dd=(XmComboBoxCallbackStruct *)call_data;
#ifdef ZEROBASECOMBOBOX
  a=dd->item_position;
#else
  a=dd->item_position-1;
#endif
  if (a<0) return;
  getobj(d->Obj,"oid",a,0,NULL,&oid);
  sprintf(buf,"^%d",oid); 
  XtVaSetValues(GetComboBoxText(d->widget,"*ref"),XmNvalue,buf,NULL);
}

void AxisDialogDelete(Widget w,XtPointer client_data,XtPointer call_data)
{
  struct AxisDialog *d;

  d=(struct AxisDialog *)client_data;
  d->ret=IDDELETE;
}

void AxisDialogCopy(Widget w,XtPointer client_data,XtPointer call_data)
{
  struct AxisDialog *d;
  int sel;

  d=(struct AxisDialog *)client_data;
  if ((sel=CopyClick(d->widget,d->Obj,d->Id,AxisCB))!=-1) 
    AxisDialogSetupItem(d->widget,d,sel);
}

void AxisDialogSetup(Widget w,void *data,int makewidget)
{
  Arg al[20];
  Cardinal ac;
  Widget rc,rc2,rc3,rc4,button,frame,combo;
  struct AxisDialog *d;
  char *group;
  char title[25];
  XmString xs;

  d=(struct AxisDialog *)data;
  getobj(d->Obj,"group",d->Id,0,NULL,&group);
  if (group==NULL) group="";
  sprintf(title,"Axis %d %s",d->Id,group);
  xs=XmStringCreateLocalized(title);
  XtVaSetValues(w,XmNdialogTitle,xs,NULL);
  XmStringFree(xs);

  if (makewidget) {
  ac=0;
  XtManageChild(button=XmCreatePushButton(w,"Delete",al,ac));
  XtAddCallback(button,XmNdisarmCallback,AxisDialogDelete,d);
  ac=0;
  XtManageChild(button=XmCreatePushButton(w,"Copy",al,ac));
  XtAddCallback(button,XmNdisarmCallback,AxisDialogCopy,d); 

  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc=XmCreateRowColumn(w,"rc",al,ac));

  ac=0;
  XtManageChild(frame=XmCreateFrame(rc,"frame",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc2=XmCreateRowColumn(frame,"rc2",al,ac));

  ac=0;
  XtSetArg(al[ac],XmNorientation,XmVERTICAL); ac++;
  XtManageChild(rc3=XmCreateRowColumn(rc2,"rc3",al,ac));

  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc4=XmCreateRowColumn(rc3,"minrc",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc4,"Min",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNcomboBoxType,XmDROP_DOWN_COMBO_BOX); ac++;
  XtManageChild(XmCreateComboBox(rc4,"min",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc4=XmCreateRowColumn(rc3,"maxrc",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc4,"Max",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNcomboBoxType,XmDROP_DOWN_COMBO_BOX); ac++;
  XtManageChild(XmCreateComboBox(rc4,"max",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc4=XmCreateRowColumn(rc3,"incrc",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc4,"Inc",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNcomboBoxType,XmDROP_DOWN_COMBO_BOX); ac++;
  XtManageChild(XmCreateComboBox(rc4,"inc",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc4=XmCreateRowColumn(rc3,"scalerc",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc4,"Scale",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNcomboBoxType,XmDROP_DOWN_LIST); ac++;
  XtManageChild(XmCreateComboBox(rc4,"scale",al,ac));

  ac=0;
  XtSetArg(al[ac],XmNorientation,XmVERTICAL); ac++;
  XtManageChild(rc3=XmCreateRowColumn(rc2,"rc4",al,ac));
  ac=0;
  XtManageChild(button=XmCreatePushButton(rc3,"Clear",al,ac));
  XtAddCallback(button,XmNdisarmCallback,AxisDialogClear,d);
  ac=0;
  XtManageChild(button=XmCreatePushButton(rc3,"File",al,ac));
  XtAddCallback(button,XmNdisarmCallback,AxisDialogFile,d);
  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc4=XmCreateRowColumn(rc3,"divrc",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc4,"Div",al,ac));
  ac=0;
  XtManageChild(XmCreateTextField(rc4,"div",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc4=XmCreateRowColumn(rc3,"refrc",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc4,"Ref",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNcomboBoxType,XmDROP_DOWN_COMBO_BOX); ac++;
  XtManageChild(combo=XmCreateComboBox(rc4,"ref",al,ac));
  XtAddCallback(combo,XmNselectionCallback,AxisDialogRef,d);

  ac=0;
  XtSetArg(al[ac],XmNorientation,XmVERTICAL); ac++;
  XtManageChild(rc2=XmCreateRowColumn(rc,"buttonrc",al,ac));
  ac=0;
  XtManageChild(button=XmCreatePushButton(rc2,"Baseline",al,ac));
  XtAddCallback(button,XmNdisarmCallback,AxisDialogBase,d);
  ac=0;
  XtManageChild(button=XmCreatePushButton(rc2,"Gauge",al,ac));
  XtAddCallback(button,XmNdisarmCallback,AxisDialogGauge,d);
  ac=0;
  XtManageChild(button=XmCreatePushButton(rc2,"Numbering",al,ac));
  XtAddCallback(button,XmNdisarmCallback,AxisDialogNum,d);
  ac=0;
  XtManageChild(button=XmCreatePushButton(rc2,"Font",al,ac));
  XtAddCallback(button,XmNdisarmCallback,AxisDialogFont,d);
  ac=0;
  XtManageChild(button=XmCreatePushButton(rc2,"Position",al,ac));
  XtAddCallback(button,XmNdisarmCallback,AxisDialogPos,d);
  }
  if (d->CanDel) XtManageChild(XtNameToWidget(w,"*Delete"));
  else XtUnmanageChild(XtNameToWidget(w,"*Delete"));

  AxisDialogSetupItem(w,d,d->Id);

}

void AxisDialogClose(Widget w,void *data)
{
  struct AxisDialog *d;
  int ret;
  char *s,*buf;
  int len;
  
  d=(struct AxisDialog *)data;
  if (d->ret!=IDOK) return;
  ret=d->ret;
  d->ret=IDLOOP;
  exeobj(d->Obj,"scale_push",d->Id,0,NULL);
  if (SetObjFieldFromText(GetComboBoxText(w,"*min"),NULL,
                          d->Obj,d->Id,"min")) return;
  if (SetObjFieldFromText(GetComboBoxText(w,"*max"),NULL,
                          d->Obj,d->Id,"max")) return;
  if (SetObjFieldFromText(GetComboBoxText(w,"*inc"),NULL,
                          d->Obj,d->Id,"inc")) return;
  if (SetObjFieldFromText(w,"*div",d->Obj,d->Id,"div")) return;
  if (SetObjFieldFromList(w,"*scale",d->Obj,d->Id,"type")) return;
  XtVaGetValues(GetComboBoxText(w,"*ref"),XmNvalue,&s,NULL);
  if ((s==NULL) || (strlen(s)==0)) {
    if (sputobjfield(d->Obj,d->Id,"reference",NULL)!=0) return;
  } else {
    len=strlen(s);
    if ((buf=(char *)memalloc(len+6))!=NULL) {
      strcpy(buf,"axis:");
      if (s!=NULL) strcat(buf,s);
      if (sputobjfield(d->Obj,d->Id,"reference",buf)!=0) {
        memfree(buf);
        return;
      }
      memfree(buf);
    }
  }
  XtFree(s);
  d->ret=ret;
}

void AxisDialog(struct AxisDialog *data,struct objlist *obj,int id,int candel)
{
  data->SetupWindow=AxisDialogSetup;
  data->CloseWindow=AxisDialogClose;
  data->Obj=obj;
  data->Id=id;
  data->CanDel=candel;
}

void CmAxisNewFrame()
{
  struct objlist *obj,*obj2;
  int idx,idy,idu,idr,idg,ret;
  int type,x,y,lenx,leny;
  struct narray group;
  char *argv[2];

  if (menulock || globallock) return;
  if ((obj=chkobject("axis"))==NULL) return;
  if ((obj2=getobject("axisgrid"))==NULL) return;
  idx=newobj(obj);
  idy=newobj(obj);
  idu=newobj(obj);
  idr=newobj(obj);
  idg=-1;
  arrayinit(&group,sizeof(int));
  type=1;
  x=3500;
  y=22000;
  lenx=14000;
  leny=14000;
  arrayadd(&group,&type);
  arrayadd(&group,&idx);
  arrayadd(&group,&idy);
  arrayadd(&group,&idu);
  arrayadd(&group,&idr);
  arrayadd(&group,&x);
  arrayadd(&group,&y);
  arrayadd(&group,&lenx);
  arrayadd(&group,&leny);
  argv[0]=(char *)&group;
  argv[1]=NULL;
  exeobj(obj,"default_grouping",idr,1,argv);
  arraydel(&group);
  SectionDialog(&DlgSection,x,y,lenx,leny,obj,idx,idy,idu,idr,obj2,&idg,FALSE);
  ret=DialogExecute(TopLevel,&DlgSection);
  if ((ret==IDDELETE) || (ret==IDCANCEL)) {
    if (idg!=-1) delobj(obj2,idg);
    delobj(obj,idr);
    delobj(obj,idu);
    delobj(obj,idy);
    delobj(obj,idx);
  } else  NgraphApp.Changed=TRUE;
  AxisWinUpdate(TRUE);
}

void CmAxisNewSection()
{
  struct objlist *obj,*obj2;
  int idx,idy,idu,idr,idg,ret,oidx,oidy;
  int type,x,y,lenx,leny;
  struct narray group;
  char *argv[2];
  char *ref;

  if (menulock || globallock) return;
  if ((obj=getobject("axis"))==NULL) return;
  if ((obj2=getobject("axisgrid"))==NULL) return;
  idx=newobj(obj);
  idy=newobj(obj);
  idu=newobj(obj);
  idr=newobj(obj);
  idg=newobj(obj2);
  arrayinit(&group,sizeof(int));
  type=2;
  x=3500;
  y=22000;
  lenx=14000;
  leny=14000;
  arrayadd(&group,&type);
  arrayadd(&group,&idx);
  arrayadd(&group,&idy);
  arrayadd(&group,&idu);
  arrayadd(&group,&idr);
  arrayadd(&group,&x);
  arrayadd(&group,&y);
  arrayadd(&group,&lenx);
  arrayadd(&group,&leny);
  argv[0]=(char *)&group;
  argv[1]=NULL;
  exeobj(obj,"default_grouping",idr,1,argv);
  arraydel(&group);
  if (idg>=0) {
    getobj(obj,"oid",idx,0,NULL,&oidx);
    if ((ref=(char *)memalloc(15))!=NULL) {
      sprintf(ref,"axis:^%d",oidx);
      putobj(obj2,"axis_x",idg,ref);
    }
    getobj(obj,"oid",idy,0,NULL,&oidy);
    if ((ref=(char *)memalloc(15))!=NULL) {
      sprintf(ref,"axis:^%d",oidy);
      putobj(obj2,"axis_y",idg,ref);
    }
  }
  SectionDialog(&DlgSection,x,y,lenx,leny,obj,idx,idy,idu,idr,obj2,&idg,TRUE);
  ret=DialogExecute(TopLevel,&DlgSection);
  if ((ret==IDDELETE) || (ret==IDCANCEL)) {
    delobj(obj2,idg);
    delobj(obj,idr);
    delobj(obj,idu);
    delobj(obj,idy);
    delobj(obj,idx);
  } else NgraphApp.Changed=TRUE;
  AxisWinUpdate(TRUE);
}

void CmAxisNewCross()
{
  struct objlist *obj;
  int idx,idy,ret;
  int type,x,y,lenx,leny;
  struct narray group;
  char *argv[2];

  if (menulock || globallock) return;
  if ((obj=chkobject("axis"))==NULL) return;
  idx=newobj(obj);
  idy=newobj(obj);
  arrayinit(&group,sizeof(int));
  type=3;
  x=3500;
  y=22000;
  lenx=14000;
  leny=14000;
  arrayadd(&group,&type);
  arrayadd(&group,&idx);
  arrayadd(&group,&idy);
  arrayadd(&group,&x);
  arrayadd(&group,&y);
  arrayadd(&group,&lenx);
  arrayadd(&group,&leny);
  argv[0]=(char *)&group;
  argv[1]=NULL;
  exeobj(obj,"default_grouping",idy,1,argv);
  arraydel(&group);
  CrossDialog(&DlgCross,x,y,lenx,leny,obj,idx,idy);
  ret=DialogExecute(TopLevel,&DlgCross);
  if ((ret==IDDELETE) || (ret==IDCANCEL)) {
    delobj(obj,idy);
    delobj(obj,idx);
  } else NgraphApp.Changed=TRUE;
  AxisWinUpdate(TRUE);
}

void CmAxisNewSingle()
{
  struct objlist *obj;
  int id,ret;

  if (menulock || globallock) return;
  if ((obj=chkobject("axis"))==NULL) return;
  if ((id=newobj(obj))>=0) {
    AxisDialog(&DlgAxis,obj,id,TRUE);
    ret=DialogExecute(TopLevel,&DlgAxis);
    if ((ret==IDDELETE) || (ret==IDCANCEL)) {
      delobj(obj,id);
    } else NgraphApp.Changed=TRUE;
    AxisWinUpdate(TRUE);
  }
}

void CmAxisAddMenu(Widget w,XtPointer client_data,XtPointer call_data)
{
  switch ((int )client_data) {
  case 0:
    CmAxisNewFrame();
    break;
  case 1: 
    CmAxisNewSection();
    break;
  case 2: 
    CmAxisNewCross();
    break;
  case 3: 
    CmAxisNewSingle();
    break;
  }
}

void CmAxisDel()
{
  struct objlist *obj;
  int i;

  if (menulock || globallock) return;
  if ((obj=chkobject("axis"))==NULL) return;
  if (chkobjlastinst(obj)==-1) return;
  CopyDialog(&DlgCopy,obj,-1,AxisCB);
  if (DialogExecute(TopLevel,&DlgCopy)==IDOK) {
    i=DlgCopy.sel;
  } else {
    return;
  }
  AxisDel(i);
  NgraphApp.Changed=TRUE;
  AxisWinUpdate(TRUE);
  FileWinUpdate(TRUE);
}

void CmAxisUpdate()
{
  struct objlist *obj;
  int i,ret;

  if (menulock || globallock) return;
  if ((obj=chkobject("axis"))==NULL) return;
  if (chkobjlastinst(obj)==-1) return;
  CopyDialog(&DlgCopy,obj,-1,AxisCB);
  if (DialogExecute(TopLevel,&DlgCopy)==IDOK) {
    i=DlgCopy.sel;
    if (i<0) return;
  } else return;
  AxisDialog(&DlgAxis,obj,i,TRUE);
  if ((ret=DialogExecute(TopLevel,&DlgAxis))==IDDELETE) {
    AxisDel(i);
  }
  if (ret!=IDCANCEL) NgraphApp.Changed=TRUE;
  AxisWinUpdate(TRUE);
  FileWinUpdate(TRUE);
}

void CmAxisZoom()
{
  struct narray farray;
  struct objlist *obj;
  int i;
  int *array,num,room;
  double zoom,min,max,mid,wd;
  char *argv[4];

  if (menulock || globallock) return;
  if ((obj=chkobject("axis"))==NULL) return;
  if (chkobjlastinst(obj)==-1) return;
  ZoomDialog(&DlgZoom);
  if ((DialogExecute(TopLevel,&DlgZoom)==IDOK) && (DlgZoom.zoom>0)) {
    zoom=DlgZoom.zoom/10000.0;
    SelectDialog(&DlgSelect,obj,AxisCB,(struct narray *)&farray,NULL);
    if (DialogExecute(TopLevel,&DlgSelect)==IDOK) {
      num=arraynum(&farray);
      array=(int *)arraydata(&farray);
      for (i=0;i<num;i++) {
        getobj(obj,"min",array[i],0,NULL,&min);
        getobj(obj,"max",array[i],0,NULL,&max);
        wd=(max-min)/2;
        if (wd!=0) {
          mid=(min+max)/2;
          min=mid-wd*zoom;
          max=mid+wd*zoom;
          room=1;
          argv[0]=(char *)&min;
          argv[1]=(char *)&max;
          argv[2]=(char *)&room;
          argv[3]=NULL;
          exeobj(obj,"scale",array[i],3,argv);
          NgraphApp.Changed=TRUE;
        }
      }
      AxisWinUpdate(TRUE);
    }
    arraydel(&farray);
  }
}

void CmAxisClear()
{
  struct narray farray;
  struct objlist *obj;
  int i;
  int *array,num;

  if (menulock || globallock) return;
  if ((obj=chkobject("axis"))==NULL) return;
  if (chkobjlastinst(obj)==-1) return;
  SelectDialog(&DlgSelect,obj,AxisCB,(struct narray *)&farray,NULL);
  if (DialogExecute(TopLevel,&DlgSelect)==IDOK) {
    num=arraynum(&farray);
    array=(int *)arraydata(&farray);
    for (i=0;i<num;i++) {
      exeobj(obj,"scale_push",array[i],0,NULL);
      exeobj(obj,"clear",array[i],0,NULL);
      NgraphApp.Changed=TRUE;
    }
    AxisWinUpdate(TRUE);
  }
  arraydel(&farray);
}

void CmAxisMenu(Widget w,XtPointer client_data,XtPointer call_data)
{
  switch ((int )client_data) {
  case 0: 
    break;
  case 1: 
    CmAxisUpdate();
    break;
  case 2: 
    CmAxisDel();
    break;
  case 3: 
    CmAxisZoom();
    break;
  case 4: 
    CmAxisClear();
    break;
  }
}

void CmAxisGridNew()
{
  struct objlist *obj;
  int id,ret;

  if (menulock || globallock) return;
  if ((obj=chkobject("axisgrid"))==NULL) return;
  if ((id=newobj(obj))>=0) {
    GridDialog(&DlgGrid,obj,id);
    ret=DialogExecute(TopLevel,&DlgGrid);
    if ((ret==IDDELETE) || (ret==IDCANCEL)) {
      delobj(obj,id);
    } else NgraphApp.Changed=TRUE;
  }
}

void CmAxisGridDel()
{
  struct narray farray;
  struct objlist *obj;
  int i;
  int num,*array;

  if (menulock || globallock) return;
  if ((obj=chkobject("axisgrid"))==NULL) return;
  if (chkobjlastinst(obj)==-1) return;
  SelectDialog(&DlgSelect,obj,GridCB,(struct narray *)&farray,NULL);
  if (DialogExecute(TopLevel,&DlgSelect)==IDOK) {
    num=arraynum(&farray);
    array=(int *)arraydata(&farray);
    for (i=num-1;i>=0;i--) {
      delobj(obj,array[i]);
      NgraphApp.Changed=TRUE;
    }
  }
  arraydel(&farray);
}


void CmAxisGridUpdate()
{
  struct narray farray;
  struct objlist *obj;
  int i,j,ret;
  int *array,num;

  if (menulock || globallock) return;
  if ((obj=chkobject("axisgrid"))==NULL) return;
  if (chkobjlastinst(obj)==-1) return;
  SelectDialog(&DlgSelect,obj,GridCB,(struct narray *)&farray,NULL);
  if (DialogExecute(TopLevel,&DlgSelect)==IDOK) {
    num=arraynum(&farray);
    array=(int *)arraydata(&farray);
    for (i=0;i<num;i++) {
      GridDialog(&DlgGrid,obj,array[i]);
      if ((ret=DialogExecute(TopLevel,&DlgGrid))==IDDELETE) {
        delobj(obj,array[i]);
        for (j=i+1;j<num;j++) array[j]--;
      }
      if (ret!=IDCANCEL) NgraphApp.Changed=TRUE;
    }
  }
  arraydel(&farray);
}


void CmGridMenu(Widget w,XtPointer client_data,XtPointer call_data)
{
  switch ((int )client_data) {
  case 0: 
    CmAxisGridNew();
    break;
  case 1: 
    CmAxisGridUpdate();
    break;
  case 2: 
    CmAxisGridDel();
    break;
  }
}

void AxisWinAxisDelete()
{
  int sel;
  struct AxisWin *d;

  d=&(NgraphApp.AxisWin);
  if (menulock || globallock) return;
  UnFocus();
  sel=d->select;
  if ((sel>=0) && (sel<=d->axisnum)) {
    AxisDel(sel);
    AxisWinUpdate(TRUE);
    FileWinUpdate(TRUE);
    NgraphApp.Changed=TRUE;
  }
}

void AxisWinAxisCopy()
{
  int sel;
  int j,id,perm,type;
  char *field;
  struct AxisWin *d;

  d=&(NgraphApp.AxisWin);
  if (menulock || globallock) return;
  sel=d->select;
  if ((sel>=0) && (sel<=d->axisnum)) {
    if ((id=newobj(d->obj))>=0) {
      for (j=0;j<chkobjfieldnum(d->obj);j++) {
        field=chkobjfieldname(d->obj,j);
        perm=chkobjperm(d->obj,field);
        type=chkobjfieldtype(d->obj,field);
        if (((perm&NREAD)!=0) && ((perm&NWRITE)!=0) && (type<NVFUNC))
          copyobj(d->obj,field,id,sel);
      }
      d->axisnum++;
      NgraphApp.Changed=TRUE;
    }
    d->select=sel;
    AxisWinUpdate(FALSE);
  }
}

void AxisWinAxisTop()
{
  int sel;
  struct AxisWin *d;

  d=&(NgraphApp.AxisWin);
  if (menulock || globallock) return;
  UnFocus();
  sel=d->select;
  if ((sel>=0) && (sel<=d->axisnum)) {
    movetopobj(d->obj,sel);
    d->select=0;
    AxisMove(sel,0);
    AxisWinUpdate(FALSE);
    FileWinUpdate(FALSE);
    NgraphApp.Changed=TRUE;
  }
}

void AxisWinAxisLast()
{
  int sel;
  struct AxisWin *d;

  d=&(NgraphApp.AxisWin);
  if (menulock || globallock) return;
  UnFocus();
  sel=d->select;
  if ((sel>=0) && (sel<=d->axisnum)) {
    movelastobj(d->obj,sel);
    d->select=d->axisnum;
    AxisMove(sel,d->axisnum);
    AxisWinUpdate(FALSE);
    FileWinUpdate(FALSE);
    NgraphApp.Changed=TRUE;
  }
}

void AxisWinAxisUp()
{
  int sel;
  struct AxisWin *d;

  d=&(NgraphApp.AxisWin);
  if (menulock || globallock) return;
  UnFocus();
  sel=d->select;
  if ((sel>=1) && (sel<=d->axisnum)) {
    moveupobj(d->obj,sel);
    d->select=sel-1;
    AxisMove(sel,sel-1);
    AxisWinUpdate(FALSE);
    FileWinUpdate(FALSE);
    NgraphApp.Changed=TRUE;
  }
}

void AxisWinAxisDown()
{
  int sel;
  struct AxisWin *d;

  d=&(NgraphApp.AxisWin);
  if (menulock || globallock) return;
  UnFocus();
  sel=d->select;
  if ((sel>=0) && (sel<=d->axisnum-1)) {
    movedownobj(d->obj,sel);
    d->select=sel+1;
    AxisMove(sel,sel+1);
    AxisWinUpdate(FALSE);
    FileWinUpdate(FALSE);
    NgraphApp.Changed=TRUE;
  }
}

void AxisWinAxisUpdate()
{
  int sel,ret;
  int update;
  struct AxisWin *d;

  d=&(NgraphApp.AxisWin);
  if (menulock || globallock) return;
  UnFocus();
  sel=d->select;
  update=FALSE;
  if ((sel>=0) && (sel<=d->axisnum)) {
    AxisDialog(&DlgAxis,d->obj,sel,TRUE);
    if ((ret=DialogExecute(TopLevel,&DlgAxis))==IDDELETE) {
      AxisDel(sel);
      update=TRUE;
      d->select=-1;
    } else if (ret==IDOK) update=TRUE;
    if (ret!=IDCANCEL) NgraphApp.Changed=TRUE;
  }
  if (update) AxisWinUpdate(FALSE);
}

void AxisWinAxisSelect()
{
  int sel;
  struct AxisWin *d;

  d=&(NgraphApp.AxisWin);
  if (menulock || globallock) return;
  sel=d->select;
  if ((sel>=0) && (sel<=d->axisnum)) Focus(d->obj,sel);
}

void AxisWinAxisHidden()
{
  int sel;
  int hidden;
  struct AxisWin *d;

  d=&(NgraphApp.AxisWin);
  if (menulock || globallock) return;
  sel=d->select;
  if ((sel>=0) && (sel<=d->axisnum)) {
    getobj(d->obj,"hidden",sel,0,NULL,&hidden);
    hidden=hidden?FALSE:TRUE;
    putobj(d->obj,"hidden",sel,&hidden);
    AxisWinUpdate(FALSE);
    NgraphApp.Changed=TRUE;
  }
}

void AxisWinChangeAxisNum()
{
  struct AxisWin *d;

  d=&(NgraphApp.AxisWin);
  if (d->text==NULL) return;
  XtVaSetValues(d->text,XmNheight,(d->axisnum+2)*FHeight,NULL);
}

void AxisWinUpdate(int clear)
{
  struct AxisWin *d;

  d=&(NgraphApp.AxisWin);
  d->axisnum=chkobjlastinst(d->obj);
  AxisWinChangeAxisNum();
  if (d->text==NULL) return;
  XClearArea(XtDisplay(d->text),XtWindow(d->text),0,0,0,0,TRUE);
}

void AxisWinExpose(Widget wi,XtPointer client_data,XtPointer call_data)
{
  XmDrawingAreaCallbackStruct *dd;
  XExposeEvent *e;
  Display *disp;
  Window win;
  GC gc;
  int i;
  char buf[256];
  XRectangle rect;
  int h,w,x,y,len,cx;
  double min,max,inc;
  char *valstr;
  int hidden;
  char *name;
  struct AxisWin *d;

  d=&(NgraphApp.AxisWin);
  if (d->text==NULL) return;
  dd=(XmDrawingAreaCallbackStruct *)call_data;
  e=(XExposeEvent *)(dd->event);
  disp=e->display;
  win=e->window;
  gc=XCreateGC(disp,win,0,0);
  if (globallock) return;
  d->axisnum=chkobjlastinst(d->obj);
  h=FHeight;
  w=FWidth;
  XSetForeground(disp,gc,gray);
  XFillRectangle(disp,win,gc,0,0,72*w+2*w,h);
  x=FWidth;
  y=FAscent;
  XSetForeground(disp,gc,black);
  rect.y=y-FAscent;
  rect.height=h;
  rect.x=x;
  rect.width=6*w;
  len=sprintf(buf,"#");
  ExtTextOut(disp,win,gc,x,y,&rect,buf,len);
  x+=6*w;
  rect.x=x;
  rect.width=5*w;
  len=sprintf(buf,"name");
  ExtTextOut(disp,win,gc,x,y,&rect,buf,len);
  x+=5*w;
  rect.x=x;
  rect.width=10*w;
  len=sprintf(buf,"    min");
  ExtTextOut(disp,win,gc,x,y,&rect,buf,len);
  x+=10*w;
  rect.x=x;
  rect.width=10*w;
  len=sprintf(buf,"    max");
  ExtTextOut(disp,win,gc,x,y,&rect,buf,len);
  x+=10*w;
  rect.x=x;
  rect.width=10*w;
  len=sprintf(buf,"    inc");
  ExtTextOut(disp,win,gc,x,y,&rect,buf,len);
  x+=10*w;
  rect.x=x;
  rect.width=7*w;
  len=sprintf(buf," type  ");
  ExtTextOut(disp,win,gc,x,y,&rect,buf,len);
  x+=7*w;
  rect.x=x;
  rect.width=6*w;
  len=sprintf(buf,"     x");
  ExtTextOut(disp,win,gc,x,y,&rect,buf,len);
  x+=6*w;
  rect.x=x;
  rect.width=6*w;
  len=sprintf(buf,"     y");
  ExtTextOut(disp,win,gc,x,y,&rect,buf,len);
  x+=6*w;
  rect.x=x;
  rect.width=6*w;
  len=sprintf(buf,"   dir");
  ExtTextOut(disp,win,gc,x,y,&rect,buf,len);
  x+=6*w;
  rect.x=x;
  rect.width=x+6*w;
  len=sprintf(buf,"   len");
  ExtTextOut(disp,win,gc,x,y,&rect,buf,len);
  x+=6*w;
  rect.x=x+w;
  rect.width=x+8*w;
  len=sprintf(buf,"^#");
  ExtTextOut(disp,win,gc,x+w,y,&rect,buf,len);

  for (i=0;i<=d->axisnum;i++) {
      x=w;
      y=(i+1)*h+FAscent;
      rect.y=y-FAscent;
      rect.height=h;

      getobj(d->obj,"hidden",i,0,NULL,&hidden);
      if (hidden) XSetForeground(disp,gc,gray);
      else XSetForeground(disp,gc,black);
      if (i==d->select) {
        XSetForeground(disp,gc,black);
        XFillRectangle(disp,win,gc,0,rect.y,74*w+h+w,rect.height);
        XSetForeground(disp,gc,white);
      }

      getobj(d->obj,"id",i,0,NULL,&cx);
      rect.x=x;
      rect.width=6*w;
      len=sprintf(buf,"%d",cx);
      ExtTextOut(disp,win,gc,x,y,&rect,buf,len);
      x+=6*w;

      getobj(d->obj,"group",i,0,NULL,&name);
      rect.x=x;
      rect.width=5*w;
      if (name!=NULL) {
        ExtTextOut(disp,win,gc,x,y,&rect,name,strlen(name));
      } else {
        ExtTextOut(disp,win,gc,x,y,&rect,"....................",20);
      }
      x+=5*w;

      getobj(d->obj,"min",i,0,NULL,&min);
      getobj(d->obj,"max",i,0,NULL,&max);
      getobj(d->obj,"inc",i,0,NULL,&inc);

      rect.x=x;
      rect.width=10*w;
      if ((min==0) && (max==0)) len=sprintf(buf,"---------");
      else len=sprintf(buf,"%+.2e",min);
      ExtTextOut(disp,win,gc,x,y,&rect,buf,len);
      x+=10*w;

      rect.x=x;
      rect.width=10*w;
      if ((min==0) && (max==0)) len=sprintf(buf,"---------");
      else len=sprintf(buf,"%+.2e",max);
      ExtTextOut(disp,win,gc,x,y,&rect,buf,len);
      x+=10*w;

      rect.x=x;
      rect.width=10*w;
      if (inc==0) len=sprintf(buf,"---------");
      else len=sprintf(buf,"%+.2e",inc);
      ExtTextOut(disp,win,gc,x,y,&rect,buf,len);
      x+=10*w;

      sgetobjfield(d->obj,i,"type",NULL,&valstr,FALSE,FALSE,FALSE);
      rect.x=x+w;
      rect.width=7*w;
      ExtTextOut(disp,win,gc,x+w,y,&rect,valstr,strlen(valstr));
      memfree(valstr);
      x+=7*w;

      getobj(d->obj,"x",i,0,NULL,&cx);
      rect.x=x;
      rect.width=6*w;
      len=sprintf(buf,"%6d",cx);
      ExtTextOut(disp,win,gc,x,y,&rect,buf,len);
      x+=6*w;

      getobj(d->obj,"y",i,0,NULL,&cx);
      rect.x=x;
      rect.width=6*w;
      len=sprintf(buf,"%6d",cx);
      ExtTextOut(disp,win,gc,x,y,&rect,buf,len);
      x+=6*w;

      getobj(d->obj,"direction",i,0,NULL,&cx);
      rect.x=x;
      rect.width=6*w;
      len=sprintf(buf,"%6d",cx);
      ExtTextOut(disp,win,gc,x,y,&rect,buf,len);
      x+=6*w;

      getobj(d->obj,"oid",i,0,NULL,&cx);
      rect.x=x+w;
      rect.width=7*w;
      len=sprintf(buf,"^%d",cx);
      ExtTextOut(disp,win,gc,x+w,y,&rect,buf,len);
      x+=8*w;
    }
  XFreeGC(disp,gc);
}

void AxisWinEvLButtonDown(unsigned int state,TPoint point,struct AxisWin *d)
{
  int sel;

  if (menulock || globallock) return;
  sel=point.y/FHeight-1;
  if (sel!=d->select) {
    AxisWinUpdate(FALSE);
    d->select=sel;
  }
}

void AxisWinEvLButtonDblClk(unsigned int state,TPoint point,struct AxisWin *d)
{
  if (menulock || globallock) return;
  AxisWinAxisUpdate();
}

void AxisWinEvRButtonDown(unsigned int state,TPoint point,struct AxisWin *d,
                          XButtonPressedEvent *event)
{
  int sel;

  if (menulock || globallock) return;
  sel=point.y/FHeight-1;
  if (sel!=d->select) {
    AxisWinUpdate(TRUE);
    d->select=sel;
  }
  sel=d->select;
  if ((sel>=0) && (sel<=d->axisnum)) {
    XtSetSensitive(XtNameToWidget(d->popup,"button_0"),True);
    XtSetSensitive(XtNameToWidget(d->popup,"button_1"),True);
    XtSetSensitive(XtNameToWidget(d->popup,"button_2"),True);
    XtSetSensitive(XtNameToWidget(d->popup,"button_3"),True);
    XtSetSensitive(XtNameToWidget(d->popup,"button_4"),True);
    XtSetSensitive(XtNameToWidget(d->popup,"button_5"),True);
    XtSetSensitive(XtNameToWidget(d->popup,"button_6"),True);
    XtSetSensitive(XtNameToWidget(d->popup,"button_7"),True);
    XtSetSensitive(XtNameToWidget(d->popup,"button_8"),True);
  } else {
    XtSetSensitive(XtNameToWidget(d->popup,"button_0"),False);
    XtSetSensitive(XtNameToWidget(d->popup,"button_1"),False);
    XtSetSensitive(XtNameToWidget(d->popup,"button_2"),False);
    XtSetSensitive(XtNameToWidget(d->popup,"button_3"),False);
    XtSetSensitive(XtNameToWidget(d->popup,"button_4"),False);
    XtSetSensitive(XtNameToWidget(d->popup,"button_5"),False);
    XtSetSensitive(XtNameToWidget(d->popup,"button_6"),False);
    XtSetSensitive(XtNameToWidget(d->popup,"button_7"),False);
    XtSetSensitive(XtNameToWidget(d->popup,"button_8"),False);
  }
  XmMenuPosition(d->popup,event);
  XtManageChild(d->popup);
}

Time AxisWinTime=0;
TPoint AxisWinPoint;

void AxisWinEvButtonDown(Widget w,XtPointer client_data,XEvent *event,
                         Boolean *dispatch)
{
  struct AxisWin *d;
  XButtonEvent *e;
  TPoint point;
  int dbl;

  d=(struct AxisWin *)client_data;
  e=(XButtonEvent *)event;
  point.x=e->x;
  point.y=e->y;
  if (((e->time-AxisWinTime)<menulocal.mouseclick)
  && (AxisWinPoint.x==point.x) && (AxisWinPoint.y==point.y)) dbl=TRUE;
  else dbl=FALSE;
  AxisWinTime=e->time;
  AxisWinPoint.x=point.x;
  AxisWinPoint.y=point.y;
  if (e->button==Button1) {
    if (dbl) AxisWinEvLButtonDblClk(e->state,point,d);
    else AxisWinEvLButtonDown(e->state,point,d);
  } else if (e->button==Button2) {
    AxisWinEvLButtonDown(e->state,point,d);
    AxisWinEvLButtonDblClk(e->state,point,d);
  } else if (e->button==Button3) AxisWinEvRButtonDown(e->state,point,d,e);
}

void AxisWinPopupMenu(Widget w,XtPointer client_data,XtPointer call_data)
{
  switch ((int )client_data) {
  case 0: 
    AxisWinAxisSelect();
    break;
  case 1: 
    AxisWinAxisUpdate();
    break;
  case 2: 
    AxisWinAxisDelete();
    break;
  case 3: 
    AxisWinAxisTop();
    break;
  case 4: 
    AxisWinAxisUp();
    break;
  case 5: 
    AxisWinAxisDown();
    break;
  case 6: 
    AxisWinAxisLast();
    break;
  case 7: 
    AxisWinAxisCopy();
    break;
  case 8: 
    AxisWinAxisHidden();
    break;
  }
}

void AxisWinEvKeyDown(Widget w,XtPointer client_data,XEvent *event,
                     Boolean *dispatch)
{
  struct AxisWin *d;
  XKeyEvent *e;
  KeySym sym;
  int sel;

  if (menulock || globallock) return;
  d=(struct AxisWin *)client_data;
  e=(XKeyEvent *)event;
  sym=XKeycodeToKeysym(e->display,e->keycode,0);
  sel=d->select;
  switch (sym) {
  case XK_Down:
    if (e->state & ShiftMask) AxisWinAxisDown();
    else {
      if ((sel==-1) && (d->axisnum>=0)) sel=0;
      else if (sel<d->axisnum) sel++;
      if (sel!=d->select) {
        d->select=sel;
        AxisWinUpdate(TRUE);
      }
    }
    break;
  case XK_Up:
    if (e->state & ShiftMask) AxisWinAxisUp();
    else {
      if ((sel==-1) && (d->axisnum>=0)) sel=d->axisnum;
      else if (sel>0) sel--;
      if (sel!=d->select) {
        d->select=sel;
        AxisWinUpdate(TRUE);
      }
    }
    break;
  case XK_Delete:
    AxisWinAxisDelete();
    break;
  case XK_Insert:
    AxisWinAxisCopy();
    break;
  case XK_Home:
    if (e->state & ShiftMask) AxisWinAxisTop();
    break;
  case XK_End:
    if (e->state & ShiftMask) AxisWinAxisLast();
    break;
  case XK_Return:
    AxisWinAxisUpdate();
    break;
  case XK_space:
    AxisWinAxisSelect();
    break;
  case XK_BackSpace:
    AxisWinAxisHidden();
    break;
  }
}

void AxisWindowUnmap(Widget w,XtPointer client_data,XtPointer call_data)
{
  struct AxisWin *d;
  Position x,y,x0,y0;
  Dimension w0,h0;

  d=&(NgraphApp.AxisWin);
  if (d->Win!=NULL) {
    XtVaGetValues(d->Win,XmNx,&x,XmNy,&y,
                         XmNwidth,&w0,XmNheight,&h0,NULL);
    menulocal.axiswidth=w0;
    menulocal.axisheight=h0;
    XtTranslateCoords(TopLevel,0,0,&x0,&y0);
    menulocal.axisx=x-x0;
    menulocal.axisy=y-y0;
    XtDestroyWidget(d->Win);
    d->Win=NULL;
    d->text=NULL;
    XmToggleButtonSetState(XtNameToWidget(TopLevel,"*windowmenu.button_1"),
                           False,False);
  }
}

void CmAxisWinScaleUndo(Widget w,XtPointer client_data,XtPointer call_data)
{
  struct AxisWin *d;
  char *argv[1];
  struct objlist *obj;
  struct narray farray;
  int i,num,*array;

  if (menulock || globallock) return;
  d=&(NgraphApp.AxisWin);
  if ((obj=chkobject("axis"))==NULL) return;
  if (chkobjlastinst(obj)==-1) return;
  SelectDialog(&DlgSelect,obj,AxisCB,(struct narray *)&farray,NULL);
  if (DialogExecute(TopLevel,&DlgSelect)==IDOK) {
    num=arraynum(&farray);
    array=(int *)arraydata(&farray);
    for (i=num-1;i>=0;i--) {
      argv[0]=NULL;
      exeobj(obj,"scale_pop",array[i],0,argv);
      NgraphApp.Changed=TRUE;
    }
    AxisWinUpdate(TRUE);
  }
  arraydel(&farray);
}

void CmAxisWindow(Widget w,XtPointer client_data,XtPointer call_data)
{
  Arg al[20];
  Cardinal ac;
  Widget dlg,scw,clip;
  int width,height;
  Position x,y;
  struct AxisWin *d;

  d=&(NgraphApp.AxisWin);
  if (d->Win!=NULL) {
    XtUnmanageChild(d->Win);
  } else {
    if (menulocal.axiswidth==CW_USEDEFAULT) width=FWidth*72+2*FWidth;
    else width=menulocal.axiswidth;
    if (menulocal.axisheight==CW_USEDEFAULT) height=FHeight*10;
    else height=menulocal.axisheight;
    ac=0;
    XtSetArg(al[ac],XmNborderWidth,1);ac++;
    XtSetArg(al[ac],XmNdialogStyle,XmDIALOG_MODELESS); ac++;
    XtSetArg(al[ac],XmNautoUnmanage,FALSE); ac++;
    XtSetArg(al[ac],XmNwidth,width); ac++;
    XtSetArg(al[ac],XmNheight,height); ac++;
    if ((menulocal.axisx!=CW_USEDEFAULT)
    && (menulocal.axisy!=CW_USEDEFAULT)) {
      XtTranslateCoords(TopLevel,menulocal.axisx,menulocal.axisy,&x,&y);
      x-=menulocal.framex;
      y-=menulocal.framey;
      if (x<0) x=0;
      if (y<0) y=0;
      XtSetArg(al[ac],XmNdefaultPosition,False); ac++;
      XtSetArg(al[ac],XmNx,x); ac++;
      XtSetArg(al[ac],XmNy,y); ac++;
    } else {
      XtSetArg(al[ac],XmNdefaultPosition,True); ac++;
    }
    XtManageChild(dlg=XmCreateFormDialog(TopLevel,"axiswindow",al,ac));
    d->Win=dlg;
    XtAddCallback(dlg,XmNunmapCallback,AxisWindowUnmap,NULL);
    ac=0;
    XtSetArg(al[ac],XmNtopAttachment,XmATTACH_FORM); ac++;
    XtSetArg(al[ac],XmNbottomAttachment,XmATTACH_FORM); ac++;
    XtSetArg(al[ac],XmNleftAttachment,XmATTACH_FORM); ac++;
    XtSetArg(al[ac],XmNrightAttachment,XmATTACH_FORM); ac++;
    XtSetArg(al[ac],XmNalignment,XmALIGNMENT_BEGINNING); ac++; 
    XtSetArg(al[ac],XmNscrollingPolicy,XmAUTOMATIC); ac++;
    XtSetArg(al[ac],XmNscrollBarDisplayPolicy,XmSTATIC); ac++;
    XtSetArg(al[ac],XmNwidth,width); ac++;
    XtSetArg(al[ac],XmNheight,height); ac++;
    XtSetArg(al[ac],XmNborderWidth,0);ac++;
    XtManageChild(scw=XmCreateScrolledWindow(dlg,NULL,al,ac));
    ac=0;
    XtSetArg(al[ac],XmNwidth,FWidth*72+2*FWidth); ac++;
    XtSetArg(al[ac],XmNheight,height); ac++;
    XtSetArg(al[ac],XmNbackground,WhitePixel(XtDisplay(TopLevel),0)); ac++;
    XtManageChild(d->text=XmCreateDrawingArea(scw,NULL,al,ac));
    XtVaGetValues(scw,XmNclipWindow,&clip,NULL);
    XtVaSetValues(clip,XmNbackground,WhitePixel(XtDisplay(TopLevel),0),NULL);
    XtAddCallback(d->text,XmNexposeCallback,AxisWinExpose,NULL); 
    XtAddEventHandler(d->text,ButtonPressMask,False,AxisWinEvButtonDown,d);
    d->obj=chkobject("axis");
    d->axisnum=chkobjlastinst(d->obj);
    AxisWinChangeAxisNum();
    d->select=-1;
    d->popup=XmVaCreateSimplePopupMenu(d->text,"axispopup",AxisWinPopupMenu,
    XmVaPUSHBUTTON,NULL,NULL,NULL,NULL,
    XmVaPUSHBUTTON,NULL,NULL,NULL,NULL,
    XmVaPUSHBUTTON,NULL,NULL,NULL,NULL,
    XmVaPUSHBUTTON,NULL,NULL,NULL,NULL,
    XmVaPUSHBUTTON,NULL,NULL,NULL,NULL,
    XmVaPUSHBUTTON,NULL,NULL,NULL,NULL,
    XmVaPUSHBUTTON,NULL,NULL,NULL,NULL,
    XmVaPUSHBUTTON,NULL,NULL,NULL,NULL,
    XmVaPUSHBUTTON,NULL,NULL,NULL,NULL,
    NULL);
    XtAddEventHandler(d->text,KeyPressMask,False,AxisWinEvKeyDown,d);
    XmToggleButtonSetState(XtNameToWidget(TopLevel,"*windowmenu.button_1"),
                           True,False);
  }
}
