/* 
 * $Id: x11lgnd.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: x11lgnd.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/07/14 17:44:50  isizaka
 * for 6.03.14
 *
 * Revision 1.7  2001/03/23 12:17:43  isizaka
 * for 6.3.13
 *
 * Revision 1.6  1999/07/25 11:28:13  isizaka
 * for release 6.03.04
 *
 * Revision 1.5  1999/05/08 13:31:30  isizaka
 * for release 6.03.02
 *
 * Revision 1.4  1999/04/15 12:14:26  isizaka
 * for release 6.03.01
 *
 * Revision 1.3  1999/04/11 06:09:20  isizaka
 * *** empty log message ***
 *
 * Revision 1.2  1999/03/20 12:32:54  isizaka
 * minor change
 *
 * Revision 1.1  1999/03/17 13:29:01  isizaka
 * Initial revision
 *
 *
 **/

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

#include "motif12.h"

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

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

char *legendlist[LEGENDNUM]=
{"line","curve","polygon","rectangle","arc","mark","text"};

char *LegendLineCB(struct objlist *obj,int id)
{
  struct narray *array;
  int num,*data;
  char *s;

  if ((s=(char *)memalloc(128))==NULL) return NULL;
  getobj(obj,"points",id,0,NULL,&array);
  num=arraynum(array);
  data=(int *)arraydata(array);
  if (num<2) sprintf(s,"%-5d",id);
  else sprintf(s,"%-5d (%d,%d)-",id,data[0],data[1]);
  return s;
}

char *LegendRectCB(struct objlist *obj,int id)
{
  int x1,y1;
  char *s;

  if ((s=(char *)memalloc(128))==NULL) return NULL;
  getobj(obj,"x1",id,0,NULL,&x1);
  getobj(obj,"y1",id,0,NULL,&y1);
  sprintf(s,"%-5d x1:%d y1:%d",id,x1,y1);
  return s;
}

char *LegendArcCB(struct objlist *obj,int id)
{
  int x1,y1;
  char *s;

  if ((s=(char *)memalloc(128))==NULL) return NULL;
  getobj(obj,"x",id,0,NULL,&x1);
  getobj(obj,"y",id,0,NULL,&y1);
  sprintf(s,"%-5d x:%d y:%d",id,x1,y1);
  return s;
}

char *LegendTextCB(struct objlist *obj,int id)
{
  char *text;
  char *s;

  if ((s=(char *)memalloc(128))==NULL) return NULL;
  getobj(obj,"text",id,0,NULL,&text);
  sprintf(s,"%-5d",id);
  if (text!=NULL) {
    strncat(s, text, 64);
#ifdef JAPANESE
/* SJIS ---> EUC */
    njms2euc(s);
#endif
  }
  return s;
}

void LegendCurveDialogSetupItem(Widget w,struct LegendCurveDialog *d,int id)
{
  SetTextFromObjField(w,"*points",d->Obj,id,"points");
  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");
  SetListFromObjField(w,"*join",d->Obj,id,"join");
  SetTextFromObjField(w,"*miter",d->Obj,id,"miter_limit");
  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);
  SetListFromObjField(w,"*interpolation",d->Obj,id,"interpolation"); 
}

void LegendCurveDialogDelete(Widget w,XtPointer client_data,XtPointer call_data)
{
  struct LegendCurveDialog *d;

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

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

  d=(struct LegendCurveDialog *)client_data;
  if ((sel=CopyClick(d->widget,d->Obj,d->Id,LegendLineCB))!=-1) 
    LegendCurveDialogSetupItem(d->widget,d,sel);
}

void LegendCurveDialogColor(Widget w,XtPointer client_data,XtPointer call_data)
{
  struct LegendCurveDialog *d;

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

void LegendCurveDialogSetup(Widget w,void *data,int makewidget)
{
  Arg al[20];
  Cardinal ac;
  Widget rc,rc2,button;
  struct LegendCurveDialog *d;
  char title[30];
  XmString xs;

  d=(struct LegendCurveDialog *)data;
  sprintf(title,"Legend curve %d",d->Id);
  xs=XmStringCreateLocalized(title);
  XtVaSetValues(w,XmNdialogTitle,xs,NULL);
  XmStringFree(xs);
  if (makewidget) {
  ac=0;
  XtManageChild(button=XmCreatePushButton(w,"Delete",al,ac));
  XtAddCallback(button,XmNdisarmCallback,LegendCurveDialogDelete,d);
  ac=0;
  XtManageChild(button=XmCreatePushButton(w,"Copy",al,ac));
  XtAddCallback(button,XmNdisarmCallback,LegendCurveDialogCopy,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,"pointsrc",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc2,"Points",al,ac));
  ac=0;
  XtManageChild(XmCreateTextField(rc2,"points",al,ac));

  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc2=XmCreateRowColumn(rc,"stylerc",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,"Interpolation",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNcomboBoxType,XmDROP_DOWN_LIST); ac++;
  XtManageChild(XmCreateComboBox(rc2,"interpolation",al,ac));

  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc2=XmCreateRowColumn(rc,"widthrc",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,"Miter",al,ac));
  ac=0;
  XtManageChild(XmCreateTextField(rc2,"miter",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc2,"Join",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNcomboBoxType,XmDROP_DOWN_LIST); ac++;
  XtManageChild(XmCreateComboBox(rc2,"join",al,ac));

  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,LegendCurveDialogColor,d);
  }
  LegendCurveDialogSetupItem(w,d,d->Id);
}

void LegendCurveDialogClose(Widget w,void *data)
{
  struct LegendCurveDialog *d;
  int ret;

  d=(struct LegendCurveDialog *)data;
  if (d->ret!=IDOK) return;
  ret=d->ret;
  d->ret=IDLOOP;
  if (SetObjFieldFromText(w,"*points",d->Obj,d->Id,"points")) return;
  if (SetObjFieldFromStyle(w,"*style",d->Obj,d->Id,"style")) return;
  if (SetObjFieldFromText(GetComboBoxText(w,"*width"),NULL,
      d->Obj,d->Id,"width")) return;
  if (SetObjFieldFromList(w,"*join",d->Obj,d->Id,"join")) return;
  if (SetObjFieldFromText(w,"*miter",d->Obj,d->Id,"miter_limit")) 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 (SetObjFieldFromList(w,"*interpolation",
      d->Obj,d->Id,"interpolation")) return;
  d->ret=ret;
}

void LegendCurveDialog(struct LegendCurveDialog *data,
                       struct objlist *obj,int id)
{
  data->SetupWindow=LegendCurveDialogSetup;
  data->CloseWindow=LegendCurveDialogClose;
  data->Obj=obj;
  data->Id=id;
}

void LegendPolyDialogSetupItem(Widget w,struct LegendPolyDialog *d,int id)
{
  SetTextFromObjField(w,"*points",d->Obj,id,"points");
  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");
  SetListFromObjField(w,"*join",d->Obj,id,"join");
  SetTextFromObjField(w,"*miter",d->Obj,id,"miter_limit");
  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);
  SetListFromObjField(w,"*fill",d->Obj,id,"fill"); 
}

void LegendPolyDialogDelete(Widget w,XtPointer client_data,XtPointer call_data)
{
  struct LegendPolyDialog *d;

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

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

  d=(struct LegendPolyDialog *)client_data;
  if ((sel=CopyClick(d->widget,d->Obj,d->Id,LegendLineCB))!=-1) 
    LegendPolyDialogSetupItem(d->widget,d,sel);
}

void LegendPolyDialogColor(Widget w,XtPointer client_data,XtPointer call_data)
{
  struct LegendPolyDialog *d;

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

void LegendPolyDialogSetup(Widget w,void *data,int makewidget)
{
  Arg al[20];
  Cardinal ac;
  Widget rc,rc2,button;
  struct LegendPolyDialog *d;
  char title[30];
  XmString xs;

  d=(struct LegendPolyDialog *)data;
  sprintf(title,"Legend polygon %d",d->Id);
  xs=XmStringCreateLocalized(title);
  XtVaSetValues(w,XmNdialogTitle,xs,NULL);
  XmStringFree(xs);
  if (makewidget) {
  ac=0;
  XtManageChild(button=XmCreatePushButton(w,"Delete",al,ac));
  XtAddCallback(button,XmNdisarmCallback,LegendPolyDialogDelete,d);
  ac=0;
  XtManageChild(button=XmCreatePushButton(w,"Copy",al,ac));
  XtAddCallback(button,XmNdisarmCallback,LegendPolyDialogCopy,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,"pointsrc",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc2,"Points",al,ac));
  ac=0;
  XtManageChild(XmCreateTextField(rc2,"points",al,ac));

  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc2=XmCreateRowColumn(rc,"stylerc",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;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc2=XmCreateRowColumn(rc,"widthrc",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,"Miter",al,ac));
  ac=0;
  XtManageChild(XmCreateTextField(rc2,"miter",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc2,"Join",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNcomboBoxType,XmDROP_DOWN_LIST); ac++;
  XtManageChild(XmCreateComboBox(rc2,"join",al,ac));
  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,LegendPolyDialogColor,d);
  ac=0;
  XtManageChild(XmCreateLabel(rc2,"Fill",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNcomboBoxType,XmDROP_DOWN_LIST); ac++;
  XtManageChild(XmCreateComboBox(rc2,"fill",al,ac));
  }
  LegendPolyDialogSetupItem(w,d,d->Id);
}

void LegendPolyDialogClose(Widget w,void *data)
{
  struct LegendPolyDialog *d;
  int ret;

  d=(struct LegendPolyDialog *)data;
  if (d->ret!=IDOK) return;
  ret=d->ret;
  d->ret=IDLOOP;
  if (SetObjFieldFromText(w,"*points",d->Obj,d->Id,"points")) return;
  if (SetObjFieldFromStyle(w,"*style",d->Obj,d->Id,"style")) return;
  if (SetObjFieldFromText(GetComboBoxText(w,"*width"),NULL,
      d->Obj,d->Id,"width")) return;
  if (SetObjFieldFromList(w,"*join",d->Obj,d->Id,"join")) return;
  if (SetObjFieldFromText(w,"*miter",d->Obj,d->Id,"miter_limit")) 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 (SetObjFieldFromList(w,"*fill",d->Obj,d->Id,"fill")) return;
  d->ret=ret;
}

void LegendPolyDialog(struct LegendPolyDialog *data,struct objlist *obj,int id)
{
  data->SetupWindow=LegendPolyDialogSetup;
  data->CloseWindow=LegendPolyDialogClose;
  data->Obj=obj;
  data->Id=id;
}


void LegendArrowDialogSetupItem(Widget w,struct LegendArrowDialog *d,int id)
{
  int len;

  SetTextFromObjField(w,"*points",d->Obj,id,"points");
  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");
  SetListFromObjField(w,"*join",d->Obj,id,"join");
  SetTextFromObjField(w,"*miter",d->Obj,id,"miter_limit");
  SetListFromObjField(w,"*arrow",d->Obj,id,"arrow");
  getobj(d->Obj,"arrow_length",id,0,NULL,&len);
  getobj(d->Obj,"arrow_width",id,0,NULL,&(d->wid));
  d->wid=(d->wid/100)*100;
  d->ang=atan(0.5*d->wid/len)*2*180/MPI;
  if (d->ang<10) d->ang=10;
  else if (d->ang>170) d->ang=170;
  XtVaSetValues(XtNameToWidget(w,"*sca"),XmNvalue,d->ang,NULL);
  XtVaSetValues(XtNameToWidget(w,"*scw"),XmNvalue,d->wid/100,NULL);
  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 LegendArrowDialogPaint(Widget w,XtPointer client_data,XtPointer call_data)
{
  struct LegendArrowDialog *d;
  XmDrawingAreaCallbackStruct *dd;
  Window root,win;
  Display *disp;
  int x,y,lw,len;
  unsigned int ww,hh,border,depth;
  GC gc;
  XPoint points[3];

  d=(struct LegendArrowDialog *)client_data;
  dd=(XmDrawingAreaCallbackStruct *)call_data;
  disp=XtDisplay(w);
  win=XtWindow(w);
  gc=XCreateGC(disp,win,0,0);
  XGetGeometry(disp,win,&root,&x,&y,&ww,&hh,&border,&depth);
  XSetForeground(disp,gc,WhitePixel(XtDisplay(TopLevel),0));
  x=y=0;
  XFillRectangle(disp,win,gc,x,y,ww,hh);
  XSetForeground(disp,gc,BlackPixel(XtDisplay(TopLevel),0));
  if (ww/20<hh/20) lw=ww/20;
  else lw=hh/20;
  len=d->wid*0.5/tan(d->ang*0.5*MPI/180);
  XFillRectangle(disp,win,gc,x+nround(lw*(len/10000.0)),y+(hh-lw)/2,ww,lw);
  points[0].x=x;
  points[0].y=y+hh/2;
  points[1].x=x+nround(lw*(len/10000.0));
  points[1].y=y+hh/2-nround(lw*(d->wid/20000.0));
  points[2].x=x+nround(lw*(len/10000.0));
  points[2].y=y+hh/2+nround(lw*(d->wid/20000.0));
  XFillPolygon(disp,win,gc,points,3,Complex,CoordModeOrigin);
  XFreeGC(disp,gc);
}

void LegendArrowDialogScaleW(Widget w,XtPointer client_data,XtPointer call_data)
{
  struct LegendArrowDialog *d;
  XmScaleCallbackStruct *dd;
  Widget win;

  d=(struct LegendArrowDialog *)client_data;
  dd=(XmScaleCallbackStruct *)call_data;
  d->wid=dd->value*100;
  win=XtNameToWidget(d->widget,"*win");
  XClearArea(XtDisplay(win),XtWindow(win),0,0,0,0,TRUE); 
}

void LegendArrowDialogScaleL(Widget w,XtPointer client_data,XtPointer call_data)
{
  struct LegendArrowDialog *d;
  XmScaleCallbackStruct *dd;
  Widget win;
  char buf[30];
  XmString xs;

  d=(struct LegendArrowDialog *)client_data;
  dd=(XmScaleCallbackStruct *)call_data;
  d->ang=dd->value;
  win=XtNameToWidget(d->widget,"*win");
  XClearArea(XtDisplay(win),XtWindow(win),0,0,0,0,TRUE); 
}

void LegendArrowDialogDelete(Widget w,XtPointer client_data,XtPointer call_data)
{
  struct LegendArrowDialog *d;

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

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

  d=(struct LegendArrowDialog *)client_data;
  if ((sel=CopyClick(d->widget,d->Obj,d->Id,LegendLineCB))!=-1) 
    LegendArrowDialogSetupItem(d->widget,d,sel);
}

void LegendArrowDialogColor(Widget w,XtPointer client_data,XtPointer call_data)
{
  struct LegendArrowDialog *d;

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

void LegendArrowDialogSetup(Widget w,void *data,int makewidget)
{
  Arg al[20];
  Cardinal ac;
  Widget rc0,rc,rc2,button,da,sc;
  struct LegendArrowDialog *d;
  char title[30];
  XmString xs;

  d=(struct LegendArrowDialog *)data;
  sprintf(title,"Legend line %d",d->Id);
  xs=XmStringCreateLocalized(title);
  XtVaSetValues(w,XmNdialogTitle,xs,NULL);
  XmStringFree(xs);
  if (makewidget) {
  ac=0;
  XtManageChild(button=XmCreatePushButton(w,"Delete",al,ac));
  XtAddCallback(button,XmNdisarmCallback,LegendArrowDialogDelete,d);
  ac=0;
  XtManageChild(button=XmCreatePushButton(w,"Copy",al,ac));
  XtAddCallback(button,XmNdisarmCallback,LegendArrowDialogCopy,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,"pointsrc",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc2,"Points",al,ac));
  ac=0;
  XtManageChild(XmCreateTextField(rc2,"points",al,ac));

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

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

  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc2=XmCreateRowColumn(rc,"stylerc",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;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc2=XmCreateRowColumn(rc,"widthrc",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;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc2=XmCreateRowColumn(rc,"miterrc",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc2,"Miter",al,ac));
  ac=0;
  XtManageChild(XmCreateTextField(rc2,"miter",al,ac));

  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc2=XmCreateRowColumn(rc,"joinrc",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc2,"Join",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNcomboBoxType,XmDROP_DOWN_LIST); ac++;
  XtManageChild(XmCreateComboBox(rc2,"join",al,ac));

  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,LegendArrowDialogColor,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_COMBO_BOX); ac++;
  XtManageChild(XmCreateComboBox(rc2,"arrow",al,ac));

  ac=0;
  XtSetArg(al[ac],XmNorientation,XmVERTICAL); ac++;
  XtManageChild(rc=XmCreateRowColumn(rc0,"winrc",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNminimum,10); ac++;
  XtSetArg(al[ac],XmNmaximum,170); ac++;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtSetArg(al[ac],XmNshowValue,XmNEAR_SLIDER); ac++;
  XtManageChild(sc=XmCreateScale(rc,"sca",al,ac));
  XtAddCallback(sc,XmNvalueChangedCallback,LegendArrowDialogScaleL,d);
  XtAddCallback(sc,XmNdragCallback,LegendArrowDialogScaleL,d);
  ac=0;
  XtSetArg(al[ac],XmNresizeWidth,FALSE); ac++;
  XtSetArg(al[ac],XmNresizeHeight,FALSE); ac++;
  XtManageChild(da=XmCreateDrawnButton(rc,"win",al,ac));
  XtAddCallback(da,XmNexposeCallback,LegendArrowDialogPaint,d);
  ac=0;
  XtSetArg(al[ac],XmNminimum,100); ac++;
  XtSetArg(al[ac],XmNmaximum,2000); ac++;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtSetArg(al[ac],XmNshowValue,XmNEAR_SLIDER); ac++;
  XtManageChild(sc=XmCreateScale(rc,"scw",al,ac));
  XtAddCallback(sc,XmNvalueChangedCallback,LegendArrowDialogScaleW,d);
  XtAddCallback(sc,XmNdragCallback,LegendArrowDialogScaleW,d);
  }
  LegendArrowDialogSetupItem(w,d,d->Id);
}

void LegendArrowDialogClose(Widget w,void *data)
{
  struct LegendArrowDialog *d;
  int ret,len;

  d=(struct LegendArrowDialog *)data;
  if (d->ret!=IDOK) return;
  ret=d->ret;
  d->ret=IDLOOP;
  if (SetObjFieldFromText(w,"*points",d->Obj,d->Id,"points")) return;
  if (SetObjFieldFromStyle(w,"*style",d->Obj,d->Id,"style")) return;
  if (SetObjFieldFromText(GetComboBoxText(w,"*width"),NULL,
                          d->Obj,d->Id,"width")) return;
  if (SetObjFieldFromList(w,"*join",d->Obj,d->Id,"join")) return;
  if (SetObjFieldFromText(w,"*miter",d->Obj,d->Id,"miter_limit")) return;
  if (SetObjFieldFromList(w,"*arrow",d->Obj,d->Id,"arrow")) return;
  len=d->wid*0.5/tan(d->ang*0.5*MPI/180);
  if (putobj(d->Obj,"arrow_length",d->Id,&len)==-1) return;
  if (putobj(d->Obj,"arrow_width",d->Id,&(d->wid))==-1) 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 LegendArrowDialog(struct LegendArrowDialog *data,
                       struct objlist *obj,int id)
{
  data->SetupWindow=LegendArrowDialogSetup;
  data->CloseWindow=LegendArrowDialogClose;
  data->Obj=obj;
  data->Id=id;
}

void LegendRectDialogSetupItem(Widget w,struct LegendRectDialog *d,int id)
{
  SetTextFromObjField(w,"*x1",d->Obj,id,"x1");
  SetTextFromObjField(w,"*y1",d->Obj,id,"y1");
  SetTextFromObjField(w,"*x2",d->Obj,id,"x2");
  SetTextFromObjField(w,"*y2",d->Obj,id,"y2");
  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");
  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);
  SetToggleFromObjField(w,"*Fill",d->Obj,id,"fill");
  getobj(d->Obj,"R2",id,0,NULL,&d->R2);
  getobj(d->Obj,"G2",id,0,NULL,&d->G2);
  getobj(d->Obj,"B2",id,0,NULL,&d->B2);
  XtVaSetValues(XtNameToWidget(w,"*col2"),XmNbackground,RGB(d->R2,d->G2,d->B2),NULL);
  SetToggleFromObjField(w,"*Frame",d->Obj,id,"frame");
}

void LegendRectDialogDelete(Widget w,XtPointer client_data,XtPointer call_data)
{
  struct LegendRectDialog *d;

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

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

  d=(struct LegendRectDialog *)client_data;
  if ((sel=CopyClick(d->widget,d->Obj,d->Id,LegendRectCB))!=-1) 
    LegendRectDialogSetupItem(d->widget,d,sel);
}

void LegendRectDialogColor(Widget w,XtPointer client_data,XtPointer call_data)
{
  struct LegendRectDialog *d;

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

void LegendRectDialogColor2(Widget w,XtPointer client_data,XtPointer call_data)
{
  struct LegendRectDialog *d;

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

void LegendRectDialogSetup(Widget w,void *data,int makewidget)
{
  Arg al[20];
  Cardinal ac;
  Widget rc,rc2,button;
  struct LegendRectDialog *d;
  char title[30];
  XmString xs;
  
  d=(struct LegendRectDialog *)data;
  sprintf(title,"Legend rectangle %d",d->Id);
  xs=XmStringCreateLocalized(title);
  XtVaSetValues(w,XmNdialogTitle,xs,NULL);
  XmStringFree(xs);
  if (makewidget) {
  ac=0;
  XtManageChild(button=XmCreatePushButton(w,"Delete",al,ac));
  XtAddCallback(button,XmNdisarmCallback,LegendRectDialogDelete,d);
  ac=0;
  XtManageChild(button=XmCreatePushButton(w,"Copy",al,ac));
  XtAddCallback(button,XmNdisarmCallback,LegendRectDialogCopy,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,"pointsrc",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc2,"X1",al,ac));
  ac=0;
  XtManageChild(XmCreateTextField(rc2,"x1",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc2,"Y1",al,ac));
  ac=0;
  XtManageChild(XmCreateTextField(rc2,"y1",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc2,"X2",al,ac));
  ac=0;
  XtManageChild(XmCreateTextField(rc2,"x2",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc2,"Y2",al,ac));
  ac=0;
  XtManageChild(XmCreateTextField(rc2,"y2",al,ac));

  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc2=XmCreateRowColumn(rc,"stylerc",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;
  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,LegendRectDialogColor,d);
  ac=0;
  XtManageChild(XmCreateToggleButton(rc2,"Fill",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc2,"Color2",al,ac));
  ac=0;
  XtManageChild(button=XmCreateDrawnButton(rc2,"col2",al,ac));
  XtAddCallback(button,XmNdisarmCallback,LegendRectDialogColor2,d);
  ac=0;
  XtManageChild(XmCreateToggleButton(rc2,"Frame",al,ac));
  }
  LegendRectDialogSetupItem(w,d,d->Id);
}

void LegendRectDialogClose(Widget w,void *data)
{
  struct LegendRectDialog *d;
  int ret;

  d=(struct LegendRectDialog *)data;
  if (d->ret!=IDOK) return;
  ret=d->ret;
  d->ret=IDLOOP;
  if (SetObjFieldFromText(w,"*x1",d->Obj,d->Id,"x1")) return;
  if (SetObjFieldFromText(w,"*y1",d->Obj,d->Id,"y1")) return;
  if (SetObjFieldFromText(w,"*x2",d->Obj,d->Id,"x2")) return;
  if (SetObjFieldFromText(w,"*y2",d->Obj,d->Id,"y2")) return;
  if (SetObjFieldFromStyle(w,"*style",d->Obj,d->Id,"style")) return;
  if (SetObjFieldFromText(GetComboBoxText(w,"*width"),NULL,
      d->Obj,d->Id,"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;
  if (SetObjFieldFromToggle(w,"*Fill",d->Obj,d->Id,"fill")) return;
  if (putobj(d->Obj,"R2",d->Id,&(d->R2))==-1) return;
  if (putobj(d->Obj,"G2",d->Id,&(d->G2))==-1) return;
  if (putobj(d->Obj,"B2",d->Id,&(d->B2))==-1) return;
  if (SetObjFieldFromToggle(w,"*Frame",d->Obj,d->Id,"frame")) return;
  d->ret=ret;
}

void LegendRectDialog(struct LegendRectDialog *data,
                       struct objlist *obj,int id)
{
  data->SetupWindow=LegendRectDialogSetup;
  data->CloseWindow=LegendRectDialogClose;
  data->Obj=obj;
  data->Id=id;
}

void LegendArcDialogSetupItem(Widget w,struct LegendArcDialog *d,int id)
{
  SetTextFromObjField(w,"*x",d->Obj,id,"x");
  SetTextFromObjField(w,"*y",d->Obj,id,"y");
  SetTextFromObjField(w,"*rx",d->Obj,id,"rx");
  SetTextFromObjField(w,"*ry",d->Obj,id,"ry");
  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");
  SetTextFromObjField(w,"*angle1",d->Obj,id,"angle1");
  SetTextFromObjField(w,"*angle2",d->Obj,id,"angle2");
  SetToggleFromObjField(w,"*Pieslice",d->Obj,id,"pieslice");
  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);
  SetToggleFromObjField(w,"*Fill",d->Obj,id,"fill");
}


void LegendArcDialogDelete(Widget w,XtPointer client_data,XtPointer call_data)
{
  struct LegendArcDialog *d;

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

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

  d=(struct LegendArcDialog *)client_data;
  if ((sel=CopyClick(d->widget,d->Obj,d->Id,LegendArcCB))!=-1) 
    LegendArcDialogSetupItem(d->widget,d,sel);
}

void LegendArcDialogColor(Widget w,XtPointer client_data,XtPointer call_data)
{
  struct LegendArcDialog *d;

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

void LegendArcDialogSetup(Widget w,void *data,int makewidget)
{
  Arg al[20];
  Cardinal ac;
  Widget rc,rc2,button;
  struct LegendArcDialog *d;
  char title[30];
  XmString xs;
  
  d=(struct LegendArcDialog *)data;
  sprintf(title,"Legend arc %d",d->Id);
  xs=XmStringCreateLocalized(title);
  XtVaSetValues(w,XmNdialogTitle,xs,NULL);
  XmStringFree(xs);
  if (makewidget) {
  ac=0;
  XtManageChild(button=XmCreatePushButton(w,"Delete",al,ac));
  XtAddCallback(button,XmNdisarmCallback,LegendArcDialogDelete,d);
  ac=0;
  XtManageChild(button=XmCreatePushButton(w,"Copy",al,ac));
  XtAddCallback(button,XmNdisarmCallback,LegendArcDialogCopy,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,"pointsrc",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,"RX",al,ac));
  ac=0;
  XtManageChild(XmCreateTextField(rc2,"rx",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc2,"RY",al,ac));
  ac=0;
  XtManageChild(XmCreateTextField(rc2,"ry",al,ac));

  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc2=XmCreateRowColumn(rc,"anglerc",al,ac));
  ac=0;
  XtManageChild(XmCreateToggleButton(rc2,"Pieslice",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc2,"Angle1",al,ac));
  ac=0;
  XtManageChild(XmCreateTextField(rc2,"angle1",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc2,"Angle2",al,ac));
  ac=0;
  XtManageChild(XmCreateTextField(rc2,"angle2",al,ac));

  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc2=XmCreateRowColumn(rc,"stylerc",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;
  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,LegendArcDialogColor,d);
  ac=0;
  XtManageChild(XmCreateToggleButton(rc2,"Fill",al,ac));
  }
  LegendArcDialogSetupItem(w,d,d->Id);
}

void LegendArcDialogClose(Widget w,void *data)
{
  struct LegendArcDialog *d;
  int ret;

  d=(struct LegendArcDialog *)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,"*rx",d->Obj,d->Id,"rx")) return;
  if (SetObjFieldFromText(w,"*ry",d->Obj,d->Id,"ry")) return;
  if (SetObjFieldFromStyle(w,"*style",d->Obj,d->Id,"style")) return;
  if (SetObjFieldFromText(GetComboBoxText(w,"*width"),NULL,
      d->Obj,d->Id,"width")) return;
  if (SetObjFieldFromText(w,"*angle1",d->Obj,d->Id,"angle1")) return;
  if (SetObjFieldFromText(w,"*angle2",d->Obj,d->Id,"angle2")) return;
  if (SetObjFieldFromToggle(w,"*Pieslice",d->Obj,d->Id,"pieslice")) 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 (SetObjFieldFromToggle(w,"*Fill",d->Obj,d->Id,"fill")) return;
  d->ret=ret;
}

void LegendArcDialog(struct LegendArcDialog *data,
                       struct objlist *obj,int id)
{
  data->SetupWindow=LegendArcDialogSetup;
  data->CloseWindow=LegendArcDialogClose;
  data->Obj=obj;
  data->Id=id;
}

void LegendMarkDialogSetupItem(Widget w,struct LegendMarkDialog *d,int id)
{
  int a;

  SetTextFromObjField(w,"*x",d->Obj,id,"x");
  SetTextFromObjField(w,"*y",d->Obj,id,"y");
  getobj(d->Obj,"type",id,0,NULL,&a);
  if (a<0) a=89;
  if (a>89) a=89;
  XtVaSetValues(XtNameToWidget(w,"*mark"),XmNlabelPixmap,
                NgraphApp.markpix[a],NULL);
  MarkDialog(&d->mark,a);
  SetComboList(w,"*size",cbmarksize,CBMARKSIZE);
  SetTextFromObjField(GetComboBoxText(w,"*size"),NULL,d->Obj,id,"size");
  SetComboListFromObjField(GetComboBoxList(w,"*size"),NULL,d->Obj,id,"size");
  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");
  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,"R2",id,0,NULL,&d->R2);
  getobj(d->Obj,"G2",id,0,NULL,&d->G2);
  getobj(d->Obj,"B2",id,0,NULL,&d->B2);
  XtVaSetValues(XtNameToWidget(w,"*col2"),XmNbackground,RGB(d->R2,d->G2,d->B2),NULL);
}

void LegendMarkDialogDelete(Widget w,XtPointer client_data,XtPointer call_data)
{
  struct LegendMarkDialog *d;

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

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

  d=(struct LegendMarkDialog *)client_data;
  if ((sel=CopyClick(d->widget,d->Obj,d->Id,LegendArcCB))!=-1) 
    LegendMarkDialogSetupItem(d->widget,d,sel);
}

void LegendMarkDialogColor(Widget w,XtPointer client_data,XtPointer call_data)
{
  struct LegendMarkDialog *d;

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

void LegendMarkDialogColor2(Widget w,XtPointer client_data,XtPointer call_data)
{
  struct LegendMarkDialog *d;

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

void LegendMarkDialogMark(Widget w,XtPointer client_data,XtPointer call_data)
{
  struct LegendMarkDialog *d;

  d=(struct LegendMarkDialog *)client_data;
  DialogExecute(d->widget,&d->mark);
  XtVaSetValues(w,XmNlabelPixmap,NgraphApp.markpix[d->mark.Type],NULL);
}

void LegendMarkDialogSetup(Widget w,void *data,int makewidget)
{
  Arg al[20];
  Cardinal ac;
  Widget rc,rc2,button;
  struct LegendMarkDialog *d;
  char title[30];
  XmString xs;
  
  d=(struct LegendMarkDialog *)data;
  sprintf(title,"Legend mark %d",d->Id);
  xs=XmStringCreateLocalized(title);
  XtVaSetValues(w,XmNdialogTitle,xs,NULL);
  XmStringFree(xs);
  if (makewidget) {
  ac=0;
  XtManageChild(button=XmCreatePushButton(w,"Delete",al,ac));
  XtAddCallback(button,XmNdisarmCallback,LegendMarkDialogDelete,d);
  ac=0;
  XtManageChild(button=XmCreatePushButton(w,"Copy",al,ac));
  XtAddCallback(button,XmNdisarmCallback,LegendMarkDialogCopy,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,"pointsrc",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;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc2=XmCreateRowColumn(rc,"stylerc",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;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc2=XmCreateRowColumn(rc,"markrc",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc2,"Mark",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNlabelType,XmPIXMAP); ac++;
  XtSetArg(al[ac],XmNlabelPixmap,NgraphApp.markpix[0]); ac++;
  XtManageChild(button=XmCreateDrawnButton(rc2,"mark",al,ac));
  XtAddCallback(button,XmNdisarmCallback,LegendMarkDialogMark,d);
  ac=0;
  XtManageChild(XmCreateLabel(rc2," Size",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNcomboBoxType,XmDROP_DOWN_COMBO_BOX); ac++;
  XtManageChild(XmCreateComboBox(rc2,"size",al,ac));

  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc2=XmCreateRowColumn(rc,"colorrc",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc2,"Color1",al,ac));
  ac=0;
  XtManageChild(button=XmCreateDrawnButton(rc2,"col",al,ac));
  XtAddCallback(button,XmNdisarmCallback,LegendMarkDialogColor,d);
  ac=0;
  XtManageChild(XmCreateLabel(rc2,"Color2",al,ac));
  ac=0;
  XtManageChild(button=XmCreateDrawnButton(rc2,"col2",al,ac));
  XtAddCallback(button,XmNdisarmCallback,LegendMarkDialogColor2,d);

  XtManageChild(d->widget);
  XtVaSetValues(rc,XmNresizeWidth,FALSE,
                   XmNresizeHeight,FALSE,NULL);
  }
  LegendMarkDialogSetupItem(w,d,d->Id);
  if (makewidget) d->widget=NULL;
}

void LegendMarkDialogClose(Widget w,void *data)
{
  struct LegendMarkDialog *d;
  int ret;

  d=(struct LegendMarkDialog *)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 (putobj(d->Obj,"type",d->Id,&(d->mark.Type))==-1) return; 
  if (SetObjFieldFromText(GetComboBoxText(w,"*size"),NULL,
      d->Obj,d->Id,"size")) return;
  if (SetObjFieldFromStyle(w,"*style",d->Obj,d->Id,"style")) return;
  if (SetObjFieldFromText(GetComboBoxText(w,"*width"),NULL,
      d->Obj,d->Id,"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;
  if (putobj(d->Obj,"R2",d->Id,&(d->R2))==-1) return;
  if (putobj(d->Obj,"G2",d->Id,&(d->G2))==-1) return;
  if (putobj(d->Obj,"B2",d->Id,&(d->B2))==-1) return;
  d->ret=ret;
}

void LegendMarkDialog(struct LegendMarkDialog *data,
                       struct objlist *obj,int id)
{
  data->SetupWindow=LegendMarkDialogSetup;
  data->CloseWindow=LegendMarkDialogClose;
  data->Obj=obj;
  data->Id=id;
}

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

  SetTextFromObjField(w,"*x",d->Obj,id,"x");
  SetTextFromObjField(w,"*y",d->Obj,id,"y");

  sgetobjfield(d->Obj,id,"text",NULL,&buf,FALSE,FALSE,FALSE);
#ifdef JAPANESE
/* SJIS ---> EUC */
  njms2euc(buf);
#endif
  XtVaSetValues(XtNameToWidget(w,"*text"),XmNvalue,buf,NULL);
  memfree(buf);
  SetComboList(w,"*direction",cbdirection,CBDIRECTION);
  SetTextFromObjField(GetComboBoxText(w,"*direction"),NULL,
                      d->Obj,id,"direction");
  SetComboListFromObjField(GetComboBoxList(w,"*direction"),NULL,
                      d->Obj,id,"direction");
  SetTextFromObjField(w,"*space",d->Obj,id,"space");
  SetComboList(w,"*pt",cbtextpt,CBTEXTPT);
  SetTextFromObjField(GetComboBoxText(w,"*pt"),NULL,
                      d->Obj,id,"pt");
  SetComboListFromObjField(GetComboBoxList(w,"*pt"),NULL,
                      d->Obj,id,"pt");
  SetTextFromObjField(w,"*script",d->Obj,id,"script_size");
  getobj(d->Obj,"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,"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,"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); 
  SetToggleFromObjField(w,"*Raw",d->Obj,id,"raw");
}

void LegendTextDialogDelete(Widget w,XtPointer client_data,XtPointer call_data)
{
  struct LegendTextDialog *d;

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

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

  d=(struct LegendTextDialog *)client_data;
  if ((sel=CopyClick(d->widget,d->Obj,d->Id,LegendTextCB))!=-1) 
    LegendTextDialogSetupItem(d->widget,d,sel);
}

void LegendTextDialogColor(Widget w,XtPointer client_data,XtPointer call_data)
{
  struct LegendTextDialog *d;

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

void LegendTextDialogSetup(Widget w,void *data,int makewidget)
{
  Arg al[20];
  Cardinal ac;
  Widget rc,rc2,button;
  struct LegendTextDialog *d;
  char title[30];
  XmString xs;
  
  d=(struct LegendTextDialog *)data;
  sprintf(title,"Legend text %d",d->Id);
  xs=XmStringCreateLocalized(title);
  XtVaSetValues(w,XmNdialogTitle,xs,NULL);
  XmStringFree(xs);
  if (makewidget) {
  ac=0;
  XtManageChild(button=XmCreatePushButton(w,"Delete",al,ac));
  XtAddCallback(button,XmNdisarmCallback,LegendTextDialogDelete,d);
  ac=0;
  XtManageChild(button=XmCreatePushButton(w,"Copy",al,ac));
  XtAddCallback(button,XmNdisarmCallback,LegendTextDialogCopy,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,"pointsrc",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;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc2=XmCreateRowColumn(rc,"textrc",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc2,"Text",al,ac));
  ac=0;
  XtManageChild(XmCreateTextField(rc2,"text",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,LegendTextDialogColor,d);
  ac=0;
  XtManageChild(XmCreateLabel(rc2,"Direction",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNcomboBoxType,XmDROP_DOWN_COMBO_BOX); ac++;
  XtManageChild(XmCreateComboBox(rc2,"direction",al,ac));
  ac=0;
  XtManageChild(XmCreateToggleButton(rc2,"Raw",al,ac));
  }
  LegendTextDialogSetupItem(w,d,d->Id);
}

void LegendTextDialogClose(Widget w,void *data)
{
  struct LegendTextDialog *d;
  int ret;
  char *buf;
  struct fontmap *fcur;
  int *selected,num,a,j;

  d=(struct LegendTextDialog *)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;

  XtVaGetValues(XtNameToWidget(w,"*text"),XmNvalue,&buf,NULL);
#ifdef JAPANESE
/* EUC ---> SJIS */
  neuc2jms(buf);
#endif
  if (sputobjfield(d->Obj,d->Id,"text",buf)!=0) {
    XtFree(buf);
    return;
  }
  XtFree(buf);

  if (SetObjFieldFromText(GetComboBoxText(w,"*direction"),NULL,
                          d->Obj,d->Id,"direction")) return;
  if (SetObjFieldFromText(w,"*space",d->Obj,d->Id,"space")) return;
  if (SetObjFieldFromText(GetComboBoxText(w,"*pt"),NULL,
                          d->Obj,d->Id,"pt")) return;
  if (SetObjFieldFromText(w,"*script",d->Obj,d->Id,"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,"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,"jfont",fcur->fontalias);
          break;
        }
      }
      fcur=fcur->next;
    }
    XtFree((char *)selected);
  }
#endif
  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 (SetObjFieldFromToggle(w,"*Raw",d->Obj,d->Id,"raw")) return;
  d->ret=ret;
}

void LegendTextDialog(struct LegendTextDialog *data,
                       struct objlist *obj,int id)
{
  data->SetupWindow=LegendTextDialogSetup;
  data->CloseWindow=LegendTextDialogClose;
  data->Obj=obj;
  data->Id=id;
}

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

  SetComboList(w,"*direction",cbdirection,CBDIRECTION);
  SetTextFromObjField(GetComboBoxText(w,"*direction"),NULL,
                      d->Obj,id,"direction");
  SetComboListFromObjField(GetComboBoxList(w,"*direction"),NULL,
                      d->Obj,id,"direction");
  SetTextFromObjField(w,"*space",d->Obj,id,"space");
  SetComboList(w,"*pt",cbtextpt,CBTEXTPT);
  SetTextFromObjField(GetComboBoxText(w,"*pt"),NULL,
                      d->Obj,id,"pt");
  SetComboListFromObjField(GetComboBoxList(w,"*pt"),NULL,
                      d->Obj,id,"pt");
  SetTextFromObjField(w,"*script",d->Obj,id,"script_size");
  getobj(d->Obj,"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,"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,"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); 
  SetToggleFromObjField(w,"*Raw",d->Obj,id,"raw");
}

void LegendTextDefDialogSetup(Widget w,void *data,int makewidget)
{
  Arg al[20];
  Cardinal ac;
  Widget rc,rc2,button;
  struct LegendTextDialog *d;
  
  d=(struct LegendTextDialog *)data;
  if (makewidget) {
  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,LegendTextDialogColor,d);
  ac=0;
  XtManageChild(XmCreateLabel(rc2,"Direction",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNcomboBoxType,XmDROP_DOWN_COMBO_BOX); ac++;
  XtManageChild(XmCreateComboBox(rc2,"direction",al,ac));
  ac=0;
  XtManageChild(XmCreateToggleButton(rc2,"Raw",al,ac));
  }
  LegendTextDefDialogSetupItem(w,d,d->Id);
}

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

  d=(struct LegendTextDialog *)data;
  if (d->ret!=IDOK) return;
  ret=d->ret;
  d->ret=IDLOOP;
  if (SetObjFieldFromText(GetComboBoxText(w,"*direction"),NULL,
                          d->Obj,d->Id,"direction")) return;
  if (SetObjFieldFromText(w,"*space",d->Obj,d->Id,"space")) return;
  if (SetObjFieldFromText(GetComboBoxText(w,"*pt"),NULL,
                          d->Obj,d->Id,"pt")) return;
  if (SetObjFieldFromText(w,"*script",d->Obj,d->Id,"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,"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,"jfont",fcur->fontalias);
          break;
        }
      }
      fcur=fcur->next;
    }
    XtFree((char *)selected);
  }
#endif
  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 (SetObjFieldFromToggle(w,"*Raw",d->Obj,d->Id,"raw")) return;
  d->ret=ret;
}

void LegendTextDefDialog(struct LegendTextDialog *data,
                         struct objlist *obj,int id)
{
  data->SetupWindow=LegendTextDefDialogSetup;
  data->CloseWindow=LegendTextDefDialogClose;
  data->Obj=obj;
  data->Id=id;
}


void CmLineDel()
{
  struct narray array;
  struct objlist *obj;
  int i;
  int num,*data;

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

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

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


void CmLineMenu(Widget w,XtPointer client_data,XtPointer call_data)
{
  switch ((int )client_data) {
  case 0: 
    CmLineUpdate();
    break;
  case 1: 
    CmLineDel();
    break;
  }
}

void CmCurveDel()
{
  struct narray array;
  struct objlist *obj;
  int i;
  int num,*data;

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

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

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

void CmCurveMenu(Widget w,XtPointer client_data,XtPointer call_data)
{
  switch ((int )client_data) {
  case 0: 
    CmCurveUpdate();
    break;
  case 1:
    CmCurveDel();
    break;
  }
}

void CmPolyDel()
{
  struct narray array;
  struct objlist *obj;
  int i;
  int num,*data;

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

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

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

void CmPolygonMenu(Widget w,XtPointer client_data,XtPointer call_data)
{
  switch ((int )client_data) {
  case 0: 
    CmPolyUpdate();
    break;
  case 1:
    CmPolyDel();
    break;
  }
}

void CmRectDel()
{
  struct narray array;
  struct objlist *obj;
  int i;
  int num,*data;

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

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

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

void CmRectangleMenu(Widget w,XtPointer client_data,XtPointer call_data)
{
  switch ((int )client_data) {
  case 0: 
    CmRectUpdate();
    break;
  case 1:
    CmRectDel();
    break;
  }
}

void CmArcDel()
{
  struct narray array;
  struct objlist *obj;
  int i;
  int num,*data;

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

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

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

void CmArcMenu(Widget w,XtPointer client_data,XtPointer call_data)
{
  switch ((int )client_data) {
  case 0: 
    CmArcUpdate();
    break;
  case 1:
    CmArcDel();
    break;
  }
}

void CmMarkDel()
{
  struct narray array;
  struct objlist *obj;
  int i;
  int num,*data;

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

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

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

void CmMarkMenu(Widget w,XtPointer client_data,XtPointer call_data)
{
  switch ((int )client_data) {
  case 0:
    CmMarkUpdate(); 
    break;
  case 1:
    CmMarkDel();
    break;
  }
}

void CmTextDel()
{
  struct narray array;
  struct objlist *obj;
  int i;
  int num,*data;

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

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

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

void CmTextMenu(Widget w,XtPointer client_data,XtPointer call_data)
{
  switch ((int )client_data) {
  case 0: 
    CmTextUpdate(); 
    break;
  case 1:
    CmTextDel();
    break;
  }
}

void CmOptionTextDef()
{
  struct objlist *obj;
  int id;

  if (menulock || globallock) return;
  if ((obj=chkobject("text"))==NULL) return;
  if ((id=newobj(obj))>=0) {
    LegendTextDefDialog(&DlgLegendTextDef,obj,id);
    if (DialogExecute(TopLevel,&DlgLegendTextDef)==IDOK) {
      if (CheckIniFile()) {
        exeobj(obj,"save_config",id,0,NULL);
      }
    }
    delobj(obj,id);
    UpdateAll2();
  }
}

void LegendWinLegendDelete()
{
  int sel,i,num;
  struct LegendWin *d;

  d=&(NgraphApp.LegendWin);
  if (menulock || globallock) return;
  UnFocus();
  sel=d->select;
  num=0;
  for (i=0;i<LEGENDNUM;i++) {
    if ((sel>=num) && (sel<=num+d->legend[i])) {
      delobj(d->obj[i],sel-num);
      LegendWinUpdate(TRUE);
      NgraphApp.Changed=TRUE;
      break;
    }
    num+=d->legend[i]+1;
  }
}

void LegendWinLegendCopy()
{
  int sel,i,num;
  int j,id,perm,type;
  char *field;
  struct LegendWin *d;

  d=&(NgraphApp.LegendWin);
  if (menulock || globallock) return;
  sel=d->select;
  num=0;
  for (i=0;i<LEGENDNUM;i++) {
    if ((sel>=num) && (sel<=num+d->legend[i])) {
      if ((id=newobj(d->obj[i]))>=0) {
        for (j=0;j<chkobjfieldnum(d->obj[i]);j++) {
          field=chkobjfieldname(d->obj[i],j);
          perm=chkobjperm(d->obj[i],field);
          type=chkobjfieldtype(d->obj[i],field);
          if ((strcmp2(field,"name")!=0)
            && ((perm&NREAD)!=0) && ((perm&NWRITE)!=0) && (type<NVFUNC))
            copyobj(d->obj[i],field,id,sel-num);
        }
        d->legend[i]++;
        NgraphApp.Changed=TRUE;
      }
      d->select=sel;
      LegendWinUpdate(FALSE);
      break;
    }
    num+=d->legend[i]+1;
  }
}

void LegendWinLegendCopy2()
{
  int sel,i,num;
  int j,id,perm,type;
  char *field;
  struct LegendWin *d;

  d=&(NgraphApp.LegendWin);
  if (menulock || globallock) return;
  sel=d->select;
  num=0;
  for (i=0;i<LEGENDNUM;i++) {
    if ((sel>=num) && (sel<=num+d->legend[i])) {
      if ((id=newobj(d->obj[i]))>=0) {
        for (j=0;j<chkobjfieldnum(d->obj[i]);j++) {
          field=chkobjfieldname(d->obj[i],j);
          perm=chkobjperm(d->obj[i],field);
          type=chkobjfieldtype(d->obj[i],field);
          if ((strcmp2(field,"name")!=0)
            && ((perm&NREAD)!=0) && ((perm&NWRITE)!=0) && (type<NVFUNC))
            copyobj(d->obj[i],field,id,sel-num);
        }
        d->legend[i]++;
        for (j=d->legend[i];j>sel-num+1;j--) moveupobj(d->obj[i],j);
        NgraphApp.Changed=TRUE;
      }
      d->select=sel;
      LegendWinUpdate(FALSE);
      break;
    }
    num+=d->legend[i]+1;
  }
}

void LegendWinLegendTop()
{
  int sel,i,num;
  struct LegendWin *d;

  d=&(NgraphApp.LegendWin);
  if (menulock || globallock) return;
  sel=d->select;
  num=0;
  for (i=0;i<LEGENDNUM;i++) {
    if ((sel>=num) && (sel<=num+d->legend[i])) {
      movetopobj(d->obj[i],sel-num);
      d->select=num;
      LegendWinUpdate(FALSE);
      NgraphApp.Changed=TRUE;
      break;
    }
    num+=d->legend[i]+1;
  }
}

void LegendWinLegendLast()
{
  int sel,i,num;
  struct LegendWin *d;

  d=&(NgraphApp.LegendWin);
  if (menulock || globallock) return;
  sel=d->select;
  num=0;
  for (i=0;i<LEGENDNUM;i++) {
    if ((sel>=num) && (sel<=num+d->legend[i])) {
      movelastobj(d->obj[i],sel-num);
      d->select=num+d->legend[i];
      LegendWinUpdate(FALSE);
      NgraphApp.Changed=TRUE;
      break;
    }
    num+=d->legend[i]+1;
  }
}

void LegendWinLegendUp()
{
  int sel,i,num;
  struct LegendWin *d;

  d=&(NgraphApp.LegendWin);
  if (menulock || globallock) return;
  sel=d->select;
  num=0;
  for (i=0;i<LEGENDNUM;i++) {
    if ((sel>=num+1) && (sel<=num+d->legend[i])) {
      moveupobj(d->obj[i],sel-num);
      d->select=sel-1;
      LegendWinUpdate(FALSE);
      NgraphApp.Changed=TRUE;
      break;
    }
    num+=d->legend[i]+1;
  }
}

void LegendWinLegendDown()
{
  int sel,i,num;
  struct LegendWin *d;

  d=&(NgraphApp.LegendWin);
  if (menulock || globallock) return;
  sel=d->select;
  num=0;
  for (i=0;i<LEGENDNUM;i++) {
    if ((sel>=num) && (sel<=num+d->legend[i]-1)) {
      movedownobj(d->obj[i],sel-num);
      d->select=sel+1;
      LegendWinUpdate(FALSE);
      NgraphApp.Changed=TRUE;
      break;
    }
    num+=d->legend[i]+1;
  }
}

void LegendWinLegendUpdate()
{
  int sel,i,num;
  int update,ret;
  struct LegendWin *d;

  d=&(NgraphApp.LegendWin);
  if (menulock || globallock) return;
  UnFocus();
  sel=d->select;
  num=0;
  update=FALSE;
  for (i=0;i<LEGENDNUM;i++) {
    if ((sel>=num) && (sel<=num+d->legend[i])) {
      ret=IDCANCEL;
      if (i==0) {
        LegendArrowDialog(&DlgLegendArrow,d->obj[i],sel-num);
        ret=DialogExecute(TopLevel,&DlgLegendArrow);
      } else if (i==1) {
        LegendCurveDialog(&DlgLegendCurve,d->obj[i],sel-num);
        ret=DialogExecute(TopLevel,&DlgLegendCurve);
      } else if (i==2) {
        LegendPolyDialog(&DlgLegendPoly,d->obj[i],sel-num);
        ret=DialogExecute(TopLevel,&DlgLegendPoly);
      } else if (i==3) {
        LegendRectDialog(&DlgLegendRect,d->obj[i],sel-num);
        ret=DialogExecute(TopLevel,&DlgLegendRect);
      } else if (i==4) {
        LegendArcDialog(&DlgLegendArc,d->obj[i],sel-num);
        ret=DialogExecute(TopLevel,&DlgLegendArc);
      } else if (i==5) {
        LegendMarkDialog(&DlgLegendMark,d->obj[i],sel-num);
        ret=DialogExecute(TopLevel,&DlgLegendMark);
      } else if (i==6) {
        LegendTextDialog(&DlgLegendText,d->obj[i],sel-num);
        ret=DialogExecute(TopLevel,&DlgLegendText);
      }
      if (ret==IDDELETE) {
        delobj(d->obj[i],sel-num);
        update=TRUE;
        d->select=-1;
      } else if (ret==IDOK) update=TRUE;
      if (ret!=IDCANCEL) NgraphApp.Changed=TRUE;
    }
    num+=d->legend[i]+1;
  }
  if (update) LegendWinUpdate(FALSE);
}

void LegendWinLegendSelect()
{
  int sel,i,num;
  struct LegendWin *d;

  d=&(NgraphApp.LegendWin);
  if (menulock || globallock) return;
  sel=d->select;
  num=0;
  for (i=0;i<LEGENDNUM;i++) {
    if ((sel>=num) && (sel<=num+d->legend[i])) {
      Focus(d->obj[i],sel-num);
      break;
    }
    num+=d->legend[i]+1;
  }
}

void LegendWinLegendHidden()
{
  int sel,i,num;
  int hidden;
  struct LegendWin *d;

  d=&(NgraphApp.LegendWin);
  if (menulock || globallock) return;
  sel=d->select;
  num=0;
  for (i=0;i<LEGENDNUM;i++) {
    if ((sel>=num) && (sel<=num+d->legend[i])) {
      getobj(d->obj[i],"hidden",sel-num,0,NULL,&hidden);
      hidden=hidden?FALSE:TRUE;
      putobj(d->obj[i],"hidden",sel-num,&hidden);
      LegendWinUpdate(FALSE);
      NgraphApp.Changed=TRUE;
      break;
    }
    num+=d->legend[i]+1;
  }
}

void LegendWinChangeLegendNum()
{
  int i,num;
  struct LegendWin *d;

  d=&(NgraphApp.LegendWin);
  if (d->text==NULL) return;
  num=0;
  for (i=0;i<LEGENDNUM;i++) num+=d->legend[i]+1;
  XtVaSetValues(d->text,XmNheight,(num+2)*FHeight,NULL);
}

void LegendWinUpdate(int clear)
{
  int i;
  struct LegendWin *d;

  d=&(NgraphApp.LegendWin);
  for (i=0;i<LEGENDNUM;i++) d->legend[i]=chkobjlastinst(d->obj[i]);
  LegendWinChangeLegendNum();
  if (d->text==NULL) return;
  XClearArea(XtDisplay(d->text),XtWindow(d->text),0,0,0,0,TRUE);
}

void LegendWinExpose(Widget wi,XtPointer client_data,XtPointer call_data)
{
  XmDrawingAreaCallbackStruct *dd;
  XExposeEvent *e;
  Display *disp;
  Window win;
  GC gc;
  int i,k,tot;
  char buf[256];
  XRectangle rect;
  int h,w,x,y,len,x1,y1,x2,y2,type,cx,x0=0,y0=0;
  struct narray *array;
  int *points;
  char *text;
  char *valstr;
  int hidden;
  struct LegendWin *d;

  d=&(NgraphApp.LegendWin);
  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;
  h=FHeight;
  w=FWidth;
  XSetForeground(disp,gc,gray);
  XFillRectangle(disp,win,gc,0,0,63*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=10*w;
  len=sprintf(buf,"object");
  ExtTextOut(disp,win,gc,x,y,&rect,buf,len);
  x+=10*w;
  rect.x=x;
  rect.width=25*w;
  len=sprintf(buf,"property");
  ExtTextOut(disp,win,gc,x,y,&rect,buf,len);
  x+=25*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+w;
  rect.width=8*w;
  len=sprintf(buf,"^#");
  ExtTextOut(disp,win,gc,x+w,y,&rect,buf,len);

  tot=0;
  for (k=0;k<LEGENDNUM;k++) {
    d->legend[k]=chkobjlastinst(d->obj[k]);
    for (i=0;i<=d->legend[k];i++) {

        x=w;
        y=(tot+i+1)*h+FAscent;
        rect.y=y-FAscent;
        rect.height=h;

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

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

        rect.x=x;
        rect.width=10*w;
        len=sprintf(buf,"%s",legendlist[k]);
        ExtTextOut(disp,win,gc,x,y,&rect,buf,len);
        x+=10*w;

        switch (k) {
        case 0:
          getobj(d->obj[k],"points",i,0,NULL,&array);
          points=(int *)arraydata(array);
          if (arraynum(array)<2) {
            x0=0;
            y0=0;
          } else {
            x0=points[0];
            y0=points[1];
          }
          sgetobjfield(d->obj[k],i,"arrow",NULL,&valstr,FALSE,FALSE,FALSE);
          rect.x=x;
          rect.width=25*w;
          len=sprintf(buf,"points:%-6d arrow:%s",arraynum(array)/2,valstr);
          memfree(valstr);
          ExtTextOut(disp,win,gc,x,y,&rect,buf,len);
          x+=25*w;
          break;
        case 1:
        case 2:
          getobj(d->obj[k],"points",i,0,NULL,&array);
          points=(int *)arraydata(array);
          if (arraynum(array)<2) {
            x0=0;
            y0=0;
          } else {
            x0=points[0];
            y0=points[1];
          }
          rect.x=x;
          rect.width=25*w;
          len=sprintf(buf,"points:%-6d",arraynum(array)/2);
          ExtTextOut(disp,win,gc,x,y,&rect,buf,len);
          x+=25*w;
          break;
        case 3:
          getobj(d->obj[k],"x1",i,0,NULL,&x1);
          getobj(d->obj[k],"y1",i,0,NULL,&y1);
          x0=x1;
          y0=y1;
          getobj(d->obj[k],"x2",i,0,NULL,&x2);
          getobj(d->obj[k],"y2",i,0,NULL,&y2);
          rect.x=x;
          rect.width=25*w;
          len=sprintf(buf,"w:%-6d h:%-6d",abs(x1-x2),abs(y1-y2));
          ExtTextOut(disp,win,gc,x,y,&rect,buf,len);
          x+=25*w;
          break;
        case 4:
          getobj(d->obj[k],"x",i,0,NULL,&x1);
          getobj(d->obj[k],"y",i,0,NULL,&y1);
          x0=x1;
          y0=y1;
          getobj(d->obj[k],"rx",i,0,NULL,&x2);
          getobj(d->obj[k],"ry",i,0,NULL,&y2);
          rect.x=x;
          rect.width=25*w;
          len=sprintf(buf,"rx:%-6d ry:%-6d",x2,y2);
          ExtTextOut(disp,win,gc,x,y,&rect,buf,len);
          x+=25*w;
          break;
        case 5:
          getobj(d->obj[k],"x",i,0,NULL,&x1);
          getobj(d->obj[k],"y",i,0,NULL,&y1);
          x0=x1;
          y0=y1;
          getobj(d->obj[k],"type",i,0,NULL,&type);
          rect.x=x;
          rect.width=25*w;
          len=sprintf(buf,"type:%-6d",type);
          ExtTextOut(disp,win,gc,x,y,&rect,buf,len);
          x+=25*w;
          break;
        case 6:
          getobj(d->obj[k],"x",i,0,NULL,&x1);
          getobj(d->obj[k],"y",i,0,NULL,&y1);
          x0=x1;
          y0=y1;
          getobj(d->obj[k],"text",i,0,NULL,&text);
          rect.x=x;
          rect.width=25*w;
          strncpy(buf, text, 25);
          buf[25] = '\0';
          len = strlen(buf);
#ifdef JAPANESE
/* SJIS ---> EUC */
          njms2euc(buf);
#endif
          ExtTextOut(disp,win,gc,x,y,&rect,buf,len);
          x+=25*w;
          break;
        }
        rect.x=x;
        rect.width=6*w;
        len=sprintf(buf,"%6d",x0);
        ExtTextOut(disp,win,gc,x,y,&rect,buf,len);
        x+=6*w;
        rect.x=x;
        rect.width=6*w;
        len=sprintf(buf,"%6d",y0);
        ExtTextOut(disp,win,gc,x,y,&rect,buf,len);
        x+=6*w;
        rect.x=x+w;
        rect.width=x+8*w;
        getobj(d->obj[k],"oid",i,0,NULL,&cx);
        len=sprintf(buf,"^%d",cx);
        ExtTextOut(disp,win,gc,x+w,y,&rect,buf,len);
        x+=8*w;
      }
      tot+=d->legend[k]+1;
    }
  XFreeGC(disp,gc);
}

void LegendWinEvLButtonDown(unsigned int state,TPoint point,struct LegendWin *d)
{
  int sel;

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

void LegendWinEvLButtonDblClk(unsigned int state,TPoint point,struct LegendWin *d)
{
  if (menulock || globallock) return;
  LegendWinLegendUpdate();
}

void LegendWinEvRButtonDown(unsigned int state,TPoint point,
                            struct LegendWin *d,XButtonPressedEvent *event)
{
  int i,sel,num;

  if (menulock || globallock) return;
  sel=point.y/FHeight-1;
  if (sel!=d->select) {
    LegendWinUpdate(TRUE);
    d->select=sel;
  }
  sel=d->select;
  num=0;
  for (i=0;i<LEGENDNUM;i++) num+=d->legend[i]+1;
  if ((sel>=0) && (sel<num)) {
    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);
    XtSetSensitive(XtNameToWidget(d->popup,"button_9"),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);
    XtSetSensitive(XtNameToWidget(d->popup,"button_9"),False);
  }
  XmMenuPosition(d->popup,event);
  XtManageChild(d->popup);
}

Time LegendWinTime=0;
TPoint LegendWinPoint;

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

  d=(struct LegendWin *)client_data;
  e=(XButtonEvent *)event;
  point.x=e->x;
  point.y=e->y;
  if (((e->time-LegendWinTime)<menulocal.mouseclick)
  && (LegendWinPoint.x==point.x) && (LegendWinPoint.y==point.y)) dbl=TRUE;
  else dbl=FALSE;
  LegendWinTime=e->time;
  LegendWinPoint.x=point.x;
  LegendWinPoint.y=point.y;
  if (e->button==Button1) {
    if (dbl) LegendWinEvLButtonDblClk(e->state,point,d);
    else LegendWinEvLButtonDown(e->state,point,d);
  } else if (e->button==Button2) {
    LegendWinEvLButtonDown(e->state,point,d);
    LegendWinEvLButtonDblClk(e->state,point,d);
  } else if (e->button==Button3) LegendWinEvRButtonDown(e->state,point,d,e);
}

void LegendWinPopupMenu(Widget w,XtPointer client_data,XtPointer call_data)
{
  switch ((int )client_data) {
  case 0: 
    LegendWinLegendSelect();
    break;
  case 1: 
    LegendWinLegendUpdate();
    break;
  case 2: 
    LegendWinLegendDelete();
    break;
  case 3: 
    LegendWinLegendTop();
    break;
  case 4: 
    LegendWinLegendUp();
    break;
  case 5: 
    LegendWinLegendDown();
    break;
  case 6: 
    LegendWinLegendLast();
    break;
  case 7: 
    LegendWinLegendCopy();
    break;
  case 8: 
    LegendWinLegendCopy2();
    break;
  case 9: 
    LegendWinLegendHidden();
    break;
  }
}

void LegendWinEvKeyDown(Widget w,XtPointer client_data,XEvent *event,
                     Boolean *dispatch)
{
  struct LegendWin *d;
  XKeyEvent *e;
  KeySym sym;
  int i,sel,num;

  if (menulock || globallock) return;
  d=(struct LegendWin *)client_data;
  e=(XKeyEvent *)event;
  sym=XKeycodeToKeysym(e->display,e->keycode,0);
  sel=d->select;
  num=0;
  for (i=0;i<LEGENDNUM;i++) num+=d->legend[i]+1;
  num--;
  switch (sym) {
  case XK_Down:
    if (e->state & ShiftMask) LegendWinLegendDown();
    else {
      if ((sel==-1) && (num>=0)) sel=0;
      else if (sel<num) sel++;
      if (sel!=d->select) {
        d->select=sel;
        LegendWinUpdate(TRUE);
      }
    }
    break;
  case XK_Up:
    if (e->state & ShiftMask) LegendWinLegendUp();
    else {
      if ((sel==-1) && (num>=0)) sel=num;
      else if (sel>0) sel--;
      if (sel!=d->select) {
        d->select=sel;
        LegendWinUpdate(TRUE);
      }
    }
    break;
  case XK_Delete:
    LegendWinLegendDelete();
    break;
  case XK_Insert:
    if (e->state & ShiftMask) LegendWinLegendCopy2();
    else LegendWinLegendCopy();
    break;
  case XK_Home:
    if (e->state & ShiftMask) LegendWinLegendTop();
    break;
  case XK_End:
    if (e->state & ShiftMask) LegendWinLegendLast();
    break;
  case XK_Return:
    LegendWinLegendUpdate();
    break;
  case XK_space:
    LegendWinLegendSelect();
    break;
  case XK_BackSpace:
    LegendWinLegendHidden();
    break;
  }
}

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

  d=&(NgraphApp.LegendWin);
  if (d->Win!=NULL) {
    XtVaGetValues(d->Win,XmNx,&x,XmNy,&y,
                         XmNwidth,&w0,XmNheight,&h0,NULL);
    menulocal.legendwidth=w0;
    menulocal.legendheight=h0;
    XtTranslateCoords(TopLevel,0,0,&x0,&y0);
    menulocal.legendx=x-x0;
    menulocal.legendy=y-y0;
    XtDestroyWidget(d->Win);
    d->Win=NULL;
    d->text=NULL;
    XmToggleButtonSetState(XtNameToWidget(TopLevel,"*windowmenu.button_2"),
                           False,False);
  }
}

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

  d=&(NgraphApp.LegendWin);
  if (d->Win!=NULL) {
    XtUnmanageChild(d->Win);
  } else {
    if (menulocal.legendwidth==CW_USEDEFAULT) width=FWidth*63+2*FWidth;
    else width=menulocal.legendwidth;
    if (menulocal.legendheight==CW_USEDEFAULT) height=FHeight*10;
    else height=menulocal.legendheight;
    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.legendx!=CW_USEDEFAULT)
    && (menulocal.legendy!=CW_USEDEFAULT)) {
      XtTranslateCoords(TopLevel,menulocal.legendx,menulocal.legendy,&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,"legendwindow",al,ac));
    d->Win=dlg;
    XtAddCallback(dlg,XmNunmapCallback,LegendWindowUnmap,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,LegendWinExpose,NULL); 
    XtAddEventHandler(d->text,ButtonPressMask,False,LegendWinEvButtonDown,d);
    for (i=0;i<LEGENDNUM;i++) {
      d->obj[i]=chkobject(legendlist[i]);
      d->legend[i]=chkobjlastinst(d->obj[i]);
    }
    LegendWinChangeLegendNum();
    d->select=-1;
    d->popup=XmVaCreateSimplePopupMenu(d->text,"legendpopup",
    LegendWinPopupMenu,
    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,
    XmVaPUSHBUTTON,NULL,NULL,NULL,NULL,
    NULL);
    XtAddEventHandler(d->text,KeyPressMask,False,LegendWinEvKeyDown,d);
    XmToggleButtonSetState(XtNameToWidget(TopLevel,"*windowmenu.button_2"),
                           True,False);
  }
}
