/* 
 * $Id: x11opt.c,v 1.8 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: x11opt.c,v $
 * Revision 1.8  2003/02/16 12:43:37  isizaka
 * for release 6.13.18
 *
 * Revision 1.7  2002/07/06 08:57:25  isizaka
 * change to GPL.
 *
 * Revision 1.6  2001/07/14 17:44:50  isizaka
 * for 6.03.14
 *
 * Revision 1.5  2001/03/23 12:17:43  isizaka
 * for 6.3.13
 *
 * Revision 1.4  1999/04/11 06:09:20  isizaka
 * *** empty log message ***
 *
 * Revision 1.3  1999/03/21 12:51:43  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 <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>

#include "motif12.h"

#include "ngraph.h"
#include "object.h"
#include "ioutil.h"
#include "nstring.h"
#include "config.h"
#include "odraw.h"

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

void DefaultDialogSetup(Widget w,void *data,int makewidget)
{
  Arg al[20];
  Cardinal ac;
  Widget rc;
  struct DefalutDialog *d;

  d=(struct DefalutDialog *)data;
  if (makewidget) {
    ac=0;
    XtSetArg(al[ac],XmNorientation,XmVERTICAL); ac++;
    XtManageChild(rc=XmCreateRowColumn(w,"rc",al,ac));
    ac=0;
    XtManageChild(XmCreateToggleButton(rc,"Geometry",al,ac));
    XtManageChild(XmCreateToggleButton(rc,"ChildGeometry",al,ac));
    XtManageChild(XmCreateToggleButton(rc,"Viewer",al,ac));
    XtManageChild(XmCreateToggleButton(rc,"ExternalViewer",al,ac));
    XtManageChild(XmCreateToggleButton(rc,"ExternalDriver",al,ac));
    XtManageChild(XmCreateToggleButton(rc,"AddinScript",al,ac));
    XtManageChild(XmCreateToggleButton(rc,"Miscellaneous",al,ac));
  }
  XmToggleButtonSetState(XtNameToWidget(w,"*Geometry"),FALSE,TRUE);
  XmToggleButtonSetState(XtNameToWidget(w,"*ChildGeometry"),FALSE,TRUE);
  XmToggleButtonSetState(XtNameToWidget(w,"*Viewer"),FALSE,TRUE);
  XmToggleButtonSetState(XtNameToWidget(w,"*ExternalViewer"),FALSE,TRUE);
  XmToggleButtonSetState(XtNameToWidget(w,"*ExternalDriver"),FALSE,TRUE);
  XmToggleButtonSetState(XtNameToWidget(w,"*AddinScript"),FALSE,TRUE);
  XmToggleButtonSetState(XtNameToWidget(w,"*Miscellaneous"),FALSE,TRUE);
}

void DefaultDialogClose(Widget w,void *data)
{
  struct DefaultDialog *d;
  int ret;
  struct narray conf;
  char *buf;
  struct extprinter *pcur;
  struct script *scur;
  char *driver,*ext,*option,*script;
  Position x,y,x0,y0;
  Dimension w0,h0;

  d=(struct DefaultDialog *)data;
  if (d->ret!=IDOK) return;
  ret=d->ret;
  d->ret=IDLOOP;
  if (!CheckIniFile()) {
    d->ret=ret;
    return;
  }
  arrayinit(&conf,sizeof(char *));
  if (XmToggleButtonGetState(XtNameToWidget(w,"*Geometry"))) {
    XtVaGetValues(MainWin,
                  XmNx,&x,XmNy,&y,
                  XmNwidth,&w0,XmNheight,&h0,NULL);
    menulocal.menux=x;
    menulocal.menuy=y;
    menulocal.menuwidth=w0;
    menulocal.menuheight=h0;
    if ((buf=(char *)memalloc(64))!=NULL) {
      sprintf(buf,"menu_win=%d,%d,%d,%d",
        menulocal.menux,menulocal.menuy,
        menulocal.menuwidth,menulocal.menuheight);
      arrayadd(&conf,&buf);
    } 
    if ((buf=(char *)memalloc(30))!=NULL) {
      sprintf(buf,"status_bar=%d",menulocal.statusb);
      arrayadd(&conf,&buf);
    }
    if ((buf=(char *)memalloc(30))!=NULL) {
      sprintf(buf,"move_child_window=%d",menulocal.movechild);
      arrayadd(&conf,&buf);
    }
  }
  if (XmToggleButtonGetState(XtNameToWidget(w,"*ChildGeometry"))) {
    if (NgraphApp.FileWin.Win!=NULL) {
      XtVaGetValues(NgraphApp.FileWin.Win,XmNx,&x,XmNy,&y,
                         XmNwidth,&w0,XmNheight,&h0,NULL);
      menulocal.filewidth=w0;
      menulocal.fileheight=h0;
      XtTranslateCoords(TopLevel,0,0,&x0,&y0);
      menulocal.filex=x-x0;
      menulocal.filey=y-y0;
      menulocal.fileopen=1;
    } else menulocal.fileopen=0;
    if ((buf=(char *)memalloc(64))!=NULL) {
      sprintf(buf,"file_win=%d,%d,%d,%d,%d",
        menulocal.filex,menulocal.filey,
        menulocal.filewidth,menulocal.fileheight,menulocal.fileopen);
      arrayadd(&conf,&buf);
    }
    if (NgraphApp.AxisWin.Win!=NULL) {
      XtVaGetValues(NgraphApp.AxisWin.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;
      menulocal.axisopen=1;
    } else menulocal.axisopen=0;
    if ((buf=(char *)memalloc(64))!=NULL) {
      sprintf(buf,"axis_win=%d,%d,%d,%d,%d",
        menulocal.axisx,menulocal.axisy,
        menulocal.axiswidth,menulocal.axisheight,menulocal.axisopen);
      arrayadd(&conf,&buf);
    }
    if (NgraphApp.LegendWin.Win!=NULL) {
      XtVaGetValues(NgraphApp.LegendWin.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;
      menulocal.legendopen=1;
    } else menulocal.legendopen=0;
    if ((buf=(char *)memalloc(64))!=NULL) {
      sprintf(buf,"legend_win=%d,%d,%d,%d,%d",
        menulocal.legendx,menulocal.legendy,
        menulocal.legendwidth,menulocal.legendheight,menulocal.legendopen);
      arrayadd(&conf,&buf);
    }
    if (NgraphApp.MergeWin.Win!=NULL) {
      XtVaGetValues(NgraphApp.MergeWin.Win,XmNx,&x,XmNy,&y,
                         XmNwidth,&w0,XmNheight,&h0,NULL);
      menulocal.mergewidth=w0;
      menulocal.mergeheight=h0;
      XtTranslateCoords(TopLevel,0,0,&x0,&y0);
      menulocal.mergex=x-x0;
      menulocal.mergey=y-y0;
      menulocal.mergeopen=1;
    } else menulocal.mergeopen=0;
    if ((buf=(char *)memalloc(64))!=NULL) {
      sprintf(buf,"merge_win=%d,%d,%d,%d,%d",
        menulocal.mergex,menulocal.mergey,
        menulocal.mergewidth,menulocal.mergeheight,menulocal.mergeopen);
      arrayadd(&conf,&buf);
    }
    if (NgraphApp.InfoWin.Win!=NULL) {
      XtVaGetValues(NgraphApp.InfoWin.Win,XmNx,&x,XmNy,&y,
                         XmNwidth,&w0,XmNheight,&h0,NULL);
      menulocal.dialogwidth=w0;
      menulocal.dialogheight=h0;
      XtTranslateCoords(TopLevel,0,0,&x0,&y0);
      menulocal.dialogx=x-x0;
      menulocal.dialogy=y-y0;
      menulocal.dialogopen=1;
    } else menulocal.dialogopen=0;
    if ((buf=(char *)memalloc(64))!=NULL) {
      sprintf(buf,"information_win=%d,%d,%d,%d,%d",
        menulocal.dialogx,menulocal.dialogy,
        menulocal.dialogwidth,menulocal.dialogheight,menulocal.dialogopen);
      arrayadd(&conf,&buf);
    }
    if (NgraphApp.CoordWin.Win!=NULL) {
      XtVaGetValues(NgraphApp.CoordWin.Win,XmNx,&x,XmNy,&y,
                         XmNwidth,&w0,XmNheight,&h0,NULL);
      menulocal.coordwidth=w0;
      menulocal.coordheight=h0;
      XtTranslateCoords(TopLevel,0,0,&x0,&y0);
      menulocal.coordx=x-x0;
      menulocal.coordy=y-y0;
      menulocal.coordopen=1;
    } else menulocal.coordopen=0;
    if ((buf=(char *)memalloc(64))!=NULL) {
      sprintf(buf,"coordinate_win=%d,%d,%d,%d,%d",
        menulocal.coordx,menulocal.coordy,
        menulocal.coordwidth,menulocal.coordheight,menulocal.coordopen);
      arrayadd(&conf,&buf);
    }
  }
  if (XmToggleButtonGetState(XtNameToWidget(w,"*Viewer"))) {
    if ((buf=(char *)memalloc(20))!=NULL) {
      sprintf(buf,"viewer_dpi=%d",mxlocal->windpi);
      arrayadd(&conf,&buf);
    }
    if ((buf=(char *)memalloc(30))!=NULL) {
      sprintf(buf,"viewer_auto_redraw=%d",mxlocal->autoredraw);
      arrayadd(&conf,&buf);
    }
    if ((buf=(char *)memalloc(40))!=NULL) {
      sprintf(buf,"viewer_load_file_on_redraw=%d",mxlocal->redrawf);
      arrayadd(&conf,&buf);
    }
    if ((buf=(char *)memalloc(30))!=NULL) {
      sprintf(buf,"viewer_show_ruler=%d",mxlocal->ruler);
      arrayadd(&conf,&buf);
    }
    if ((buf=(char *)memalloc(20))!=NULL) {
      sprintf(buf,"viewer_grid=%d",mxlocal->grid);
      arrayadd(&conf,&buf);
    }
    if ((buf=(char *)memalloc(30))!=NULL) {
      sprintf(buf,"backing_store=%d",mxlocal->backingstore);
      arrayadd(&conf,&buf);
    }
  }
  if (XmToggleButtonGetState(XtNameToWidget(w,"*ExternalDriver"))) {
    pcur=menulocal.extprinterroot;
    while (pcur!=NULL) {
      if (pcur->driver==NULL) driver="";
      else driver=pcur->driver;
      if (pcur->ext==NULL) ext="";
      else ext=pcur->ext;
      if (pcur->option==NULL) option="";
      else option=pcur->option;
      if ((buf=(char *)memalloc(strlen(pcur->name)+strlen(driver)+strlen(ext)
                                +strlen(option)+20))!=NULL) {
        sprintf(buf,"ext_driver=%s,%s,%s,%s",pcur->name,driver,ext,option);
        arrayadd(&conf,&buf);
      }
      pcur=pcur->next;
    }
  }
  if (XmToggleButtonGetState(XtNameToWidget(w,"*AddinScript"))) {
    scur=menulocal.scriptroot;
    while (scur!=NULL) {
      if (scur->script==NULL) script="";
      else script=scur->script;
      if (scur->option==NULL) option="";
      else option=scur->option;
      if ((buf=(char *)memalloc(strlen(scur->name)+strlen(script)
                                +strlen(option)+20))!=NULL) {
        sprintf(buf,"script=%s,%s,%s",scur->name,script,option);
        arrayadd(&conf,&buf);
      }
      scur=scur->next;
    }
  }
  if (XmToggleButtonGetState(XtNameToWidget(w,"*Miscellaneous"))) {
    if (menulocal.editor!=NULL) {
      if ((buf=(char *)memalloc(strlen(menulocal.editor)+10))!=NULL) {
        sprintf(buf,"editor=%s",menulocal.editor);
        arrayadd(&conf,&buf);
      }
    }
    if ((buf=(char *)memalloc(30))!=NULL) {
      sprintf(buf,"change_directory=%d",menulocal.changedirectory);
      arrayadd(&conf,&buf);
    }
    if ((buf=(char *)memalloc(30))!=NULL) {
      sprintf(buf,"save_history=%d",menulocal.savehistory);
      arrayadd(&conf,&buf);
    }
    if ((buf=(char *)memalloc(20))!=NULL) {
      sprintf(buf,"save_path=%d",menulocal.savepath);
      arrayadd(&conf,&buf);
    }
    if ((buf=(char *)memalloc(30))!=NULL) {
      sprintf(buf,"save_with_data=%d",menulocal.savewithdata);
      arrayadd(&conf,&buf);
    }
    if ((buf=(char *)memalloc(30))!=NULL) {
      sprintf(buf,"save_with_merge=%d",menulocal.savewithmerge);
      arrayadd(&conf,&buf);
    }
    if ((buf=(char *)memalloc(strlen(menulocal.expanddir)+20))!=NULL) {
      sprintf(buf,"expand_dir=%s",menulocal.expanddir);
      arrayadd(&conf,&buf);
    }
    if ((buf=(char *)memalloc(20))!=NULL) {
      sprintf(buf,"expand=%d",menulocal.expand);
      arrayadd(&conf,&buf);
    }
    if ((buf=(char *)memalloc(20))!=NULL) {
      sprintf(buf,"ignore_path=%d",menulocal.ignorepath);
      arrayadd(&conf,&buf);
    }
  }
  replaceconfig("[x11menu]",&conf);
  arraydel2(&conf);
  arrayinit(&conf,sizeof(char *));
  if (XmToggleButtonGetState(XtNameToWidget(w,"*ExternalViewer"))) {
    if ((buf=(char *)memalloc(20))!=NULL) {
      sprintf(buf,"win_dpi=%d",menulocal.exwindpi);
      arrayadd(&conf,&buf);
    }
    if ((buf=(char *)memalloc(20))!=NULL) {
      sprintf(buf,"win_width=%d",menulocal.exwinwidth);
      arrayadd(&conf,&buf);
    }
    if ((buf=(char *)memalloc(20))!=NULL) {
      sprintf(buf,"win_height=%d",menulocal.exwinheight);
      arrayadd(&conf,&buf);
    }
    if ((buf=(char *)memalloc(30))!=NULL) {
      sprintf(buf,"store_in_memory=%d",menulocal.exwinbackingstore);
      arrayadd(&conf,&buf);
    }
  }
  replaceconfig("[gra2x11]",&conf);
  arraydel2(&conf);

  arrayinit(&conf,sizeof(char *));
  if (XmToggleButtonGetState(XtNameToWidget(w,"*ExternalDriver"))) {
    if (menulocal.extprinterroot==NULL) {
      if ((buf=(char *)memalloc(20))!=NULL) {
        sprintf(buf,"ext_driver");
        arrayadd(&conf,&buf);
      }
    }
  }
  if (XmToggleButtonGetState(XtNameToWidget(w,"*AddinScript"))) {
    if (menulocal.scriptroot==NULL) {
      if ((buf=(char *)memalloc(20))!=NULL) {
        sprintf(buf,"script");
        arrayadd(&conf,&buf);
      }
    }
  }
  if (XmToggleButtonGetState(XtNameToWidget(w,"*Miscellaneous"))) {
    if (menulocal.editor==NULL) {
      if ((buf=(char *)memalloc(20))!=NULL) {
        sprintf(buf,"editor");
        arrayadd(&conf,&buf);
      }
    }
  }
  removeconfig("[x11menu]",&conf);
  arraydel2(&conf);
  d->ret=ret;
}

void DefaultDialog(struct DefaultDialog *data)
{
  data->SetupWindow=DefaultDialogSetup;
  data->CloseWindow=DefaultDialogClose;
}

void SetScriptDialogSetupItem(Widget w,struct SetScriptDialog *d)
{
  if (d->Script->name==NULL) 
    XtVaSetValues(XtNameToWidget(w,"*name"),XmNvalue,"",NULL);
  else
    XtVaSetValues(XtNameToWidget(w,"*name"),XmNvalue,d->Script->name,NULL);
  if (d->Script->script==NULL) 
    XtVaSetValues(XtNameToWidget(w,"*script"),XmNvalue,"",NULL);
  else
    XtVaSetValues(XtNameToWidget(w,"*script"),XmNvalue,d->Script->script,NULL);
  if (d->Script->option==NULL) 
    XtVaSetValues(XtNameToWidget(w,"*option"),XmNvalue,"",NULL);
  else
    XtVaSetValues(XtNameToWidget(w,"*option"),XmNvalue,d->Script->option,NULL);
}

void SetScriptDialogBrowse(Widget w,XtPointer client_data,XtPointer call_data)
{
  char *file;
  struct SetScriptDialog *d;
  
  d=(struct SetScriptDialog *)client_data;
  if (nGetOpenFileName(TopLevel,"Add-in Script","nsc",NULL,
      NULL,&file,"*.nsc",TRUE,FALSE)==IDOK) {
    XtVaSetValues(XtNameToWidget(d->widget,"*script"),XmNvalue,file,NULL);
  }
  free(file);
}

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

  d=(struct SetScriptDialog *)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,"namerc",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc2,"Name",al,ac));
  ac=0;
  XtManageChild(XmCreateTextField(rc2,"name",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc2=XmCreateRowColumn(rc,"scriptrc",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc2,"Script",al,ac));
  ac=0;
  XtManageChild(XmCreateTextField(rc2,"script",al,ac));
  ac=0;
  XtManageChild(button=XmCreatePushButton(rc2,"Browse",al,ac));
  XtAddCallback(button,XmNdisarmCallback,SetScriptDialogBrowse,d); 
  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc2=XmCreateRowColumn(rc,"optionrc",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc2,"Option",al,ac));
  ac=0;
  XtManageChild(XmCreateTextField(rc2,"option",al,ac));
  }
  SetScriptDialogSetupItem(w,d); 
}

void SetScriptDialogClose(Widget w,void *data)
{
  char *buf,*buf2;
  int len,ret;
  struct SetScriptDialog *d;

  d=(struct SetScriptDialog *)data;
  if (d->ret!=IDOK) return;
  ret=d->ret;
  d->ret=IDLOOP;
  XtVaGetValues(XtNameToWidget(w,"*name"),XmNvalue,&buf,NULL);
  len=strlen(buf);
  if (strlen(buf)==0) {
    MessageBox(TopLevel,"Please specify script name.",NULL,MB_OK);
    return;
  }
  if ((buf2=(char *)memalloc(len+1))!=NULL) {
    strcpy(buf2,buf);
    memfree(d->Script->name);
    d->Script->name=buf2;
  }
  XtFree(buf);
  XtVaGetValues(XtNameToWidget(w,"*script"),XmNvalue,&buf,NULL);
  len=strlen(buf);
  if ((buf2=(char *)memalloc(len+1))!=NULL) {
    strcpy(buf2,buf);
    memfree(d->Script->script);
    d->Script->script=buf2;
  }
  XtFree(buf);
  XtVaGetValues(XtNameToWidget(w,"*option"),XmNvalue,&buf,NULL);
  len=strlen(buf);
  if ((buf2=(char *)memalloc(len+1))!=NULL) {
    strcpy(buf2,buf);
    memfree(d->Script->option);
    d->Script->option=buf2;
  }
  XtFree(buf);
  d->ret=ret;
}

void SetScriptDialog(struct SetScriptDialog *data,struct script *sc)
{
  data->SetupWindow=SetScriptDialogSetup;
  data->CloseWindow=SetScriptDialogClose;
  data->Script=sc;
}

void PrefScriptDialogSetupItem(Widget w,struct PrefScriptDialog *d)
{
  struct script *fcur;
  XmString xs;

  XmListDeleteAllItems(XtNameToWidget(w,"*list"));
  fcur=menulocal.scriptroot;
  while (fcur!=NULL) {
    xs=XmStringCreateLocalized(fcur->name);
    XmListAddItem(XtNameToWidget(w,"*list"),xs,0);
    XmStringFree(xs);
    fcur=fcur->next;
  }
}

void PrefScriptDialogUpdate(Widget w,XtPointer client_data,XtPointer call_data)
{
  struct PrefScriptDialog *d;
  int a,j;
  struct script *fcur;
  int *selected,num;

  d=(struct PrefScriptDialog *)client_data;
  XmListGetSelectedPos(XtNameToWidget(d->widget,"*list"),&selected,&num);
  if (num==0) return;
  a=selected[0]-1;
  XtFree((char *)selected);
  j=0;
  fcur=menulocal.scriptroot;
  while (fcur!=NULL) {
    if (j==a) break;
    fcur=fcur->next;
    j++;
  }
  if (fcur!=NULL) {
    SetScriptDialog(&DlgSetScript,fcur);
    DialogExecute(d->widget,&DlgSetScript);
    PrefScriptDialogSetupItem(d->widget,d);
  }
}

void PrefScriptDialogRemove(Widget w,XtPointer client_data,XtPointer call_data)
{
  int j;
  struct script *fcur,*fprev,*fdel;
  int *selected,num,a;
  struct PrefScriptDialog *d;

  d=(struct PrefScriptDialog *)client_data;
  XmListGetSelectedPos(XtNameToWidget(d->widget,"*list"),&selected,&num);
  if (num==0) return;
  a=selected[0]-1;
  XtFree((char *)selected);
  j=0;
  fprev=NULL;
  fcur=menulocal.scriptroot;
  while (fcur!=NULL) {
    if (j==a) {
      fdel=fcur;
      if (fprev==NULL) menulocal.scriptroot=fcur->next;
      else fprev->next=fcur->next;
      fcur=fcur->next;
      memfree(fdel->name);
      memfree(fdel->script);
      memfree(fdel->option);
      memfree(fdel);
      PrefScriptDialogSetupItem(d->widget,d);
      break;
    } else {
      fprev=fcur;
      fcur=fcur->next;
    }
    j++;
  }
}

void PrefScriptDialogAdd(Widget w,XtPointer client_data,XtPointer call_data)
{
  struct PrefScriptDialog *d;
  struct script *fcur,*fprev,*fnew;

  d=(struct PrefScriptDialog *)client_data;
  fprev=NULL;
  fcur=menulocal.scriptroot;
  while (fcur!=NULL) {
    fprev=fcur;
    fcur=fcur->next;
  }
  if ((fnew=(struct script *)memalloc(sizeof(struct script)))!=NULL) {
    fnew->next=NULL;
    fnew->name=NULL;
    fnew->script=NULL;
    fnew->option=NULL;
    if (fprev==NULL) menulocal.scriptroot=fnew;
    else fprev->next=fnew;
    SetScriptDialog(&DlgSetScript,fnew);
    if (DialogExecute(d->widget,&DlgSetScript)!=IDOK) {
      if (fprev==NULL) menulocal.scriptroot=NULL;
      else fprev->next=NULL;
      memfree(fnew);
    }
    PrefScriptDialogSetupItem(d->widget,d);
  } else {
    memfree(fnew);
  }
}

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

  d=(struct PrefScriptDialog *)data;
  if (makewidget) {
  XtUnmanageChild(XmMessageBoxGetChild(w,XmDIALOG_CANCEL_BUTTON));

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

  ac=0;
  XtSetArg(al[ac],XmNlistSizePolicy,XmCONSTANT); ac++;
  XtSetArg(al[ac],XmNscrollBarDisplayPolicy,XmSTATIC); ac++;
  XtSetArg(al[ac],XmNselectionPolicy,XmBROWSE_SELECT); ac++;
  XtManageChild(XmCreateScrolledList(rc,"list",al,ac));

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

  ac=0;
  XtManageChild(button=XmCreatePushButton(rc2,"Add",al,ac));
  XtAddCallback(button,XmNdisarmCallback,PrefScriptDialogAdd,d);  
  ac=0;
  XtManageChild(button=XmCreatePushButton(rc2,"Setup",al,ac));
  XtAddCallback(button,XmNdisarmCallback,PrefScriptDialogUpdate,d); 
  ac=0;
  XtManageChild(button=XmCreatePushButton(rc2,"Remove",al,ac));
  XtAddCallback(button,XmNdisarmCallback,PrefScriptDialogRemove,d); 
  }
  PrefScriptDialogSetupItem(w,d); 
}

void PrefScriptDialogClose(Widget w,void *data)
{
}

void PrefScriptDialog(struct PrefScriptDialog *data)
{
  data->SetupWindow=PrefScriptDialogSetup;
  data->CloseWindow=PrefScriptDialogClose;
}


void SetDriverDialogSetupItem(Widget w,struct SetDriverDialog *d)
{
  if (d->Driver->name==NULL)
    XtVaSetValues(XtNameToWidget(w,"*name"),XmNvalue,"",NULL);
  else
    XtVaSetValues(XtNameToWidget(w,"*name"),XmNvalue,d->Driver->name,NULL);
  if (d->Driver->driver==NULL)
    XtVaSetValues(XtNameToWidget(w,"*driver"),XmNvalue,"",NULL);
  else
    XtVaSetValues(XtNameToWidget(w,"*driver"),XmNvalue,d->Driver->driver,NULL);
  if (d->Driver->option==NULL)
    XtVaSetValues(XtNameToWidget(w,"*option"),XmNvalue,"",NULL);
  else
    XtVaSetValues(XtNameToWidget(w,"*option"),XmNvalue,d->Driver->option,NULL);
  if (d->Driver->ext==NULL)
    XtVaSetValues(XtNameToWidget(w,"*ext"),XmNvalue,"",NULL);
  else
    XtVaSetValues(XtNameToWidget(w,"*ext"),XmNvalue,d->Driver->ext,NULL);
}

void SetDriverDialogBrowse(Widget w,XtPointer client_data,XtPointer call_data)
{
  char *file;
  struct SetDriverDialog *d;
  
  d=(struct SetDriverDialog *)client_data;
  if (nGetOpenFileName(TopLevel,"External Driver",NULL,NULL,
      NULL,&file,"*",TRUE,FALSE)==IDOK) {
    XtVaSetValues(XtNameToWidget(d->widget,"*driver"),XmNvalue,file,NULL);
  }
  free(file);
}

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

  d=(struct SetDriverDialog *)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,"namerc",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc2,"Name",al,ac));
  ac=0;
  XtManageChild(XmCreateTextField(rc2,"name",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc2=XmCreateRowColumn(rc,"driverrc",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc2,"Driver",al,ac));
  ac=0;
  XtManageChild(XmCreateTextField(rc2,"driver",al,ac));
  ac=0;
  XtManageChild(button=XmCreatePushButton(rc2,"Browse",al,ac));
  XtAddCallback(button,XmNdisarmCallback,SetDriverDialogBrowse,d); 
  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc2=XmCreateRowColumn(rc,"optionrc",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc2,"Option",al,ac));
  ac=0;
  XtManageChild(XmCreateTextField(rc2,"option",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc2=XmCreateRowColumn(rc,"extrc",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc2,"Extension",al,ac));
  ac=0;
  XtManageChild(XmCreateTextField(rc2,"ext",al,ac));
  }
  SetDriverDialogSetupItem(w,d); 
}

void SetDriverDialogClose(Widget w,void *data)
{
  char *buf,*buf2;
  int len,ret;
  struct SetDriverDialog *d;

  d=(struct SetDriverDialog *)data;
  if (d->ret!=IDOK) return;
  ret=d->ret;
  d->ret=IDLOOP;
  XtVaGetValues(XtNameToWidget(w,"*name"),XmNvalue,&buf,NULL);
  len=strlen(buf);
  if (strlen(buf)==0) {
    MessageBox(TopLevel,"Please specify driver name.",NULL,MB_OK);
    return;
  }
  if ((buf2=(char *)memalloc(len+1))!=NULL) {
    strcpy(buf2,buf);
    memfree(d->Driver->name);
    d->Driver->name=buf2;
  }
  XtFree(buf);
  XtVaGetValues(XtNameToWidget(w,"*driver"),XmNvalue,&buf,NULL);
  len=strlen(buf);
  if ((buf2=(char *)memalloc(len+1))!=NULL) {
    strcpy(buf2,buf);
    memfree(d->Driver->driver);
    d->Driver->driver=buf2;
  }
  XtFree(buf);
  XtVaGetValues(XtNameToWidget(w,"*ext"),XmNvalue,&buf,NULL);
  len=strlen(buf);
  if ((buf2=(char *)memalloc(len+1))!=NULL) {
    strcpy(buf2,buf);
    memfree(d->Driver->ext);
    d->Driver->ext=buf2;
  }
  XtFree(buf);
  XtVaGetValues(XtNameToWidget(w,"*option"),XmNvalue,&buf,NULL);
  len=strlen(buf);
  if ((buf2=(char *)memalloc(len+1))!=NULL) {
    strcpy(buf2,buf);
    memfree(d->Driver->option);
    d->Driver->option=buf2;
  }
  XtFree(buf);
  d->ret=ret;
}

void SetDriverDialog(struct SetDriverDialog *data,struct extprinter *prn)
{
  data->SetupWindow=SetDriverDialogSetup;
  data->CloseWindow=SetDriverDialogClose;
  data->Driver=prn;
}

void PrefDriverDialogSetupItem(Widget w,struct PrefDriverDialog *d)
{
  struct extprinter *fcur;
  XmString xs;

  XmListDeleteAllItems(XtNameToWidget(w,"*list"));
  fcur=menulocal.extprinterroot;
  while (fcur!=NULL) {
    xs=XmStringCreateLocalized(fcur->name);
    XmListAddItem(XtNameToWidget(w,"*list"),xs,0);
    XmStringFree(xs);
    fcur=fcur->next;
  }
}

void PrefDriverDialogUpdate(Widget w,XtPointer client_data,XtPointer call_data)
{
  struct PrefDriverDialog *d;
  int j;
  struct extprinter *fcur;
  int *selected,num,a;

  d=(struct PrefDriverDialog *)client_data;
  XmListGetSelectedPos(XtNameToWidget(d->widget,"*list"),&selected,&num);
  if (num==0) return;
  a=selected[0]-1;
  XtFree((char *)selected);
  j=0;
  fcur=menulocal.extprinterroot;
  while (fcur!=NULL) {
    if (j==a) break;
    fcur=fcur->next;
    j++;
  }
  if (fcur!=NULL) {
    SetDriverDialog(&DlgSetDriver,fcur);
    DialogExecute(d->widget,&DlgSetDriver);
    PrefDriverDialogSetupItem(d->widget,d);
  }
}

void PrefDriverDialogRemove(Widget w,XtPointer client_data,XtPointer call_data)
{
  int j;
  struct extprinter *fcur,*fprev,*fdel;
  int *selected,num,a;
  struct PrefDriverDialog *d;

  d=(struct PrefDriverDialog *)client_data;
  XmListGetSelectedPos(XtNameToWidget(d->widget,"*list"),&selected,&num);
  if (num==0) return;
  a=selected[0]-1;
  XtFree((char *)selected);
  j=0;
  fprev=NULL;
  fcur=menulocal.extprinterroot;
  while (fcur!=NULL) {
    if (j==a) {
      fdel=fcur;
      if (fprev==NULL) menulocal.extprinterroot=fcur->next;
      else fprev->next=fcur->next;
      fcur=fcur->next;
      memfree(fdel->name);
      memfree(fdel->driver);
      memfree(fdel->option);
      memfree(fdel);
      PrefDriverDialogSetupItem(d->widget,d);
      break;
    } else {
      fprev=fcur;
      fcur=fcur->next;
    }
    j++;
  }
}

void PrefDriverDialogAdd(Widget w,XtPointer client_data,XtPointer call_data)
{
  struct extprinter *fcur,*fprev,*fnew;
  struct PrefDriverDialog *d;

  d=(struct PrefDriverDialog *)client_data;
  fprev=NULL;
  fcur=menulocal.extprinterroot;
  while (fcur!=NULL) {
    fprev=fcur;
    fcur=fcur->next;
  }
  if ((fnew=(struct extprinter *)memalloc(sizeof(struct extprinter)))!=NULL) {
    fnew->next=NULL;
    fnew->name=NULL;
    fnew->driver=NULL;
    fnew->option=NULL;
    fnew->ext=NULL;
    if (fprev==NULL) menulocal.extprinterroot=fnew;
    else fprev->next=fnew;
    SetDriverDialog(&DlgSetDriver,fnew);
    if (DialogExecute(d->widget,&DlgSetDriver)!=IDOK) {
      if (fprev==NULL) menulocal.extprinterroot=NULL;
      else fprev->next=NULL;
      memfree(fnew);
    }
    PrefDriverDialogSetupItem(d->widget,d);
  } else {
    memfree(fnew);
  }
}

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

  d=(struct PrefDriverDialog *)data;
  if (makewidget) {
  XtUnmanageChild(XmMessageBoxGetChild(w,XmDIALOG_CANCEL_BUTTON));

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

  ac=0;
  XtSetArg(al[ac],XmNlistSizePolicy,XmCONSTANT); ac++;
  XtSetArg(al[ac],XmNscrollBarDisplayPolicy,XmSTATIC); ac++;
  XtSetArg(al[ac],XmNselectionPolicy,XmBROWSE_SELECT); ac++;
  XtManageChild(XmCreateScrolledList(rc,"list",al,ac));

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

  ac=0;
  XtManageChild(button=XmCreatePushButton(rc2,"Add",al,ac));
  XtAddCallback(button,XmNdisarmCallback,PrefDriverDialogAdd,d);  
  ac=0;
  XtManageChild(button=XmCreatePushButton(rc2,"Setup",al,ac));
  XtAddCallback(button,XmNdisarmCallback,PrefDriverDialogUpdate,d); 
  ac=0;
  XtManageChild(button=XmCreatePushButton(rc2,"Remove",al,ac));
  XtAddCallback(button,XmNdisarmCallback,PrefDriverDialogRemove,d); 
  }
  PrefDriverDialogSetupItem(w,d); 
}

void PrefDriverDialogClose(Widget w,void *data)
{
}

void PrefDriverDialog(struct PrefDriverDialog *data)
{
  data->SetupWindow=PrefDriverDialogSetup;
  data->CloseWindow=PrefDriverDialogClose;
}

void MiscDialogSetupItem(Widget w,struct MiscDialog *d)
{
  if (menulocal.editor!=NULL) 
    XtVaSetValues(XtNameToWidget(w,"*editor"),XmNvalue,menulocal.editor,NULL);
  XmToggleButtonSetState(XtNameToWidget(w,"*directory"),
                         menulocal.changedirectory,TRUE);
  XmToggleButtonSetState(XtNameToWidget(w,"*history"),
                         menulocal.savehistory,TRUE);
  XmListDeselectAllItems(GetComboBoxList(w,"*path"));
  XmListSelectPos(GetComboBoxList(w,"*path"),menulocal.savepath+1,TRUE);
  XtVaSetValues(XtNameToWidget(w,"*datafile"),XmNset,
                menulocal.savewithdata,NULL);
  XtVaSetValues(XtNameToWidget(w,"*mergefile"),XmNset,
                menulocal.savewithmerge,NULL);
  XmToggleButtonSetState(XtNameToWidget(w,"*expand"),menulocal.expand,TRUE);
  if (menulocal.expanddir!=NULL) 
    XtVaSetValues(XtNameToWidget(w,"*expanddir"),XmNvalue,
                  menulocal.expanddir,NULL);
  XmToggleButtonSetState(XtNameToWidget(w,"*ignorepath"),
                         menulocal.ignorepath,TRUE);
}

void MiscDialogSetup(Widget w,void *data,int makewidget)
{
  Arg al[20];
  Cardinal ac;
  Widget rc,rc2,rc3,frame;
  struct MiscDialog *d;
  int j;

  d=(struct MiscDialog *)data;
  if (makewidget) {
  ac=0;
  XtSetArg(al[ac],XmNorientation,XmVERTICAL); ac++;
  XtManageChild(rc=XmCreateRowColumn(w,"rc",al,ac));

  ac=0;
  XtManageChild(frame=XmCreateFrame(rc,"eframe",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNorientation,XmVERTICAL); ac++;
  XtManageChild(rc3=XmCreateRowColumn(frame,"erc",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc2=XmCreateRowColumn(rc3,"editorrc",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc2,"Editor",al,ac));
  ac=0;
  XtManageChild(XmCreateTextField(rc2,"editor",al,ac));

  ac=0;
  XtManageChild(frame=XmCreateFrame(rc,"dframe",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNorientation,XmVERTICAL); ac++;
  XtManageChild(rc3=XmCreateRowColumn(frame,"drc",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc2=XmCreateRowColumn(rc3,"dirrc",al,ac));
  ac=0;
  XtManageChild(XmCreateToggleButton(rc2,"directory",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc2=XmCreateRowColumn(rc3,"historyrc",al,ac));
  ac=0;
  XtManageChild(XmCreateToggleButton(rc2,"history",al,ac));

  ac=0;
  XtManageChild(frame=XmCreateFrame(rc,"pframe",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNorientation,XmVERTICAL); ac++;
  XtManageChild(rc3=XmCreateRowColumn(frame,"prc",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc2=XmCreateRowColumn(rc3,"pathrc",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc2,"Path",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNcomboBoxType,XmDROP_DOWN_LIST); ac++;
  XtManageChild(XmCreateComboBox(rc2,"path",al,ac));
  ac=0;
  XtManageChild(XmCreateToggleButton(rc3,"datafile",al,ac));
  ac=0;
  XtManageChild(XmCreateToggleButton(rc3,"mergefile",al,ac));

  ac=0;
  XtManageChild(frame=XmCreateFrame(rc,"lframe",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNorientation,XmVERTICAL); ac++;
  XtManageChild(rc3=XmCreateRowColumn(frame,"lrc",al,ac));
  ac=0;
  XtManageChild(XmCreateToggleButton(rc3,"expand",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc2=XmCreateRowColumn(rc3,"expandrc",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc2,"Expanddir",al,ac));
  ac=0;
  XtManageChild(XmCreateTextField(rc2,"expanddir",al,ac));
  ac=0;
  XtManageChild(XmCreateToggleButton(rc3,"ignorepath",al,ac));

  for (j=0;pathchar[j]!=NULL;j++);
  SetComboList(w,"*path",pathchar,j);

  }
  MiscDialogSetupItem(w,d); 
}

void MiscDialogClose(Widget w,void *data)
{
  struct MiscDialog *d;
  int ret;
  char *buf,*buf2;
  int a;
  int *selected,num;

  d=(struct MiscDialog *)data;
  if (d->ret!=IDOK) return;
  ret=d->ret;
  d->ret=IDLOOP;
  XtVaGetValues(XtNameToWidget(w,"*editor"),XmNvalue,&buf,NULL);
  if (buf==NULL) {
    memfree(menulocal.editor);
    menulocal.editor=NULL;
  } else if ((buf2=(char *)memalloc(strlen(buf)+1))!=NULL) {
    strcpy(buf2,buf);
    changefilename(buf2);
    memfree(menulocal.editor);
    menulocal.editor=buf2;
  }
  XtFree(buf);
  menulocal.changedirectory=
    XmToggleButtonGetState(XtNameToWidget(w,"*directory"));
  menulocal.savehistory=
    XmToggleButtonGetState(XtNameToWidget(w,"*history"));
  XmListGetSelectedPos(GetComboBoxList(w,"*path"),&selected,&num);
  if (num!=0) {
    a=selected[0]-1;
    XtFree((char *)selected);
    menulocal.savepath=a;
  }
  menulocal.savewithdata=
    XmToggleButtonGetState(XtNameToWidget(w,"*datafile"));
  menulocal.savewithmerge=
    XmToggleButtonGetState(XtNameToWidget(w,"*mergefile"));
  menulocal.expand=
    XmToggleButtonGetState(XtNameToWidget(w,"*expand"));
  XtVaGetValues(XtNameToWidget(w,"*expanddir"),XmNvalue,&buf,NULL);
  if (buf!=NULL) {
    buf2=(char *)memalloc(strlen(buf)+1);
    strcpy(buf2,buf);
    memfree(menulocal.expanddir);
    menulocal.expanddir=buf2;
  }
  XtFree(buf);
  menulocal.ignorepath=
    XmToggleButtonGetState(XtNameToWidget(w,"*ignorepath"));
  d->ret=ret;
}

void MiscDialog(struct MiscDialog *data)
{
  data->SetupWindow=MiscDialogSetup;
  data->CloseWindow=MiscDialogClose;
}

void ExViewerDialogSetupItem(Widget w,struct ExViewerDialog *d)
{
  int dpi;
  char buf[64];

  dpi=menulocal.exwindpi;
  XmScaleSetValue(XtNameToWidget(w,"*dpi"),dpi);
  sprintf(buf,"%d",menulocal.exwinwidth);
  XtVaSetValues(XtNameToWidget(w,"*width"),XmNvalue,buf,NULL);
  sprintf(buf,"%d",menulocal.exwinheight);
  XtVaSetValues(XtNameToWidget(w,"*height"),XmNvalue,buf,NULL);
  XmToggleButtonSetState(XtNameToWidget(w,"*memory"),
                         menulocal.exwinbackingstore,TRUE);
}

void ExViewerDialogSetup(Widget w,void *data,int makewidget)
{
  Arg al[20];
  Cardinal ac;
  Widget rc,rc2;
  struct ExViewerDialog *d;

  d=(struct ExViewerDialog *)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,"dpirc",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc2,"DPI",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNminimum,20); ac++;
  XtSetArg(al[ac],XmNmaximum,620); ac++;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtSetArg(al[ac],XmNshowValue,XmNEAR_SLIDER); ac++;
  XtManageChild(XmCreateScale(rc2,"dpi",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;
  XtManageChild(XmCreateTextField(rc2,"width",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc2=XmCreateRowColumn(rc,"heightrc",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,"memoryrc",al,ac));
  ac=0;
  XtManageChild(XmCreateToggleButton(rc2,"memory",al,ac));
  }
  ExViewerDialogSetupItem(w,d); 
}

void ExViewerDialogClose(Widget w,void *data)
{
  struct ExViewerDialog *d;
  int ret;
  int dpi;
  char *buf,*endptr;
  int a;

  d=(struct ExViewerDialog *)data;
  if (d->ret!=IDOK) return;
  ret=d->ret;
  d->ret=IDLOOP;
  XmScaleGetValue(XtNameToWidget(w,"*dpi"),&dpi);
  menulocal.exwindpi=dpi;
  XtVaGetValues(XtNameToWidget(w,"*width"),XmNvalue,&buf,NULL);
  a=strtol(buf,&endptr,10);
  if (endptr[0]=='\0') menulocal.exwinwidth=a;
  XtFree(buf);
  XtVaGetValues(XtNameToWidget(w,"*height"),XmNvalue,&buf,NULL);
  a=strtol(buf,&endptr,10);
  if (endptr[0]=='\0') menulocal.exwinheight=a;
  XtFree(buf);
  menulocal.exwinbackingstore=
    XmToggleButtonGetState(XtNameToWidget(w,"*memory"));;
  d->ret=ret;
}


void ExViewerDialog(struct ExViewerDialog *data)
{
  data->SetupWindow=ExViewerDialogSetup;
  data->CloseWindow=ExViewerDialogClose;
}

void ViewerDialogSetupItem(Widget w,struct ViewerDialog *d)
{
  int a;
  char buf[64];

  getobj(d->Obj,"dpi",d->Id,0,NULL,&(d->dpis));
  XmScaleSetValue(XtNameToWidget(w,"*dpi"),d->dpis);
  XmToggleButtonSetState(XtNameToWidget(w,"*ruler"),mxlocal->ruler,TRUE);
  getobj(d->Obj,"auto_redraw",d->Id,0,NULL,&a);
  XmToggleButtonSetState(XtNameToWidget(w,"*redraw"),a,TRUE);
  getobj(d->Obj,"redraw_flag",d->Id,0,NULL,&a);
  XmToggleButtonSetState(XtNameToWidget(w,"*loadfile"),a,TRUE);
  sprintf(buf,"%d",mxlocal->grid);
  XtVaSetValues(XtNameToWidget(w,"*grid"),XmNvalue,buf,NULL);
  XmToggleButtonSetState(XtNameToWidget(w,"*memory"),
                         mxlocal->backingstore,TRUE);
}

void ViewerDialogSetup(Widget w,void *data,int makewidget)
{
  Arg al[20];
  Cardinal ac;
  Widget rc,rc2;
  struct ViewerDialog *d;

  d=(struct ViewerDialog *)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,"dpirc",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc2,"DPI",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNminimum,20); ac++;
  XtSetArg(al[ac],XmNmaximum,620); ac++;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtSetArg(al[ac],XmNshowValue,XmNEAR_SLIDER); ac++;
  XtManageChild(XmCreateScale(rc2,"dpi",al,ac));

  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc2=XmCreateRowColumn(rc,"gridrc",al,ac));
  ac=0;
  XtManageChild(XmCreateLabel(rc2,"Grid",al,ac));
  ac=0;
  XtManageChild(XmCreateTextField(rc2,"grid",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc2=XmCreateRowColumn(rc,"rulerrc",al,ac));
  ac=0;
  XtManageChild(XmCreateToggleButton(rc2,"ruler",al,ac));

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

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

  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  XtManageChild(rc2=XmCreateRowColumn(rc,"memoryrc",al,ac));
  ac=0;
  XtManageChild(XmCreateToggleButton(rc2,"memory",al,ac));
  }
  ViewerDialogSetupItem(w,d); 
}

void ViewerDialogClose(Widget w,void *data)
{
  struct ViewerDialog *d;
  int ret;
  int dpi;
  char *buf,*endptr;
  int a;
  XSetWindowAttributes attr;

  d=(struct ViewerDialog *)data;
  if (d->ret!=IDOK) return;
  ret=d->ret;
  d->ret=IDLOOP;
  XmScaleGetValue(XtNameToWidget(w,"*dpi"),&dpi);
  if (d->dpis!=dpi) {
    if (putobj(d->Obj,"dpi",d->Id,&dpi)==-1) return;
    d->Clear=TRUE;
  }
  a=XmToggleButtonGetState(XtNameToWidget(w,"*ruler"));
  a=a?TRUE:FALSE;
  if (mxlocal->ruler!=a) d->Clear=TRUE;
  mxlocal->ruler=a;
  a=XmToggleButtonGetState(XtNameToWidget(w,"*redraw"));
  a=a?TRUE:FALSE;
  if (putobj(d->Obj,"auto_redraw",d->Id,&a)==-1) return;
  mxlocal->autoredraw=a;
  a=XmToggleButtonGetState(XtNameToWidget(w,"*loadfile"));
  a=a?TRUE:FALSE;
  if (putobj(d->Obj,"redraw_flag",d->Id,&a)==-1) return;
  mxlocal->redrawf=a;
  XtVaGetValues(XtNameToWidget(w,"*grid"),XmNvalue,&buf,NULL);
  a=strtol(buf,&endptr,10);
  if (a<1) a=1;
  else if (a>1000) a=1000;
  if (endptr[0]=='\0') mxlocal->grid=a;
  XtFree(buf);
  a=XmToggleButtonGetState(XtNameToWidget(w,"*memory"));
  a=a?TRUE:FALSE;
  if (a!=mxlocal->backingstore) {
    mxlocal->backingstore=a;
    if (mxlocal->backingstore) attr.backing_store=Always;
    else attr.backing_store=NotUseful;
    XChangeWindowAttributes(XtDisplay(NgraphApp.Viewer.Win),
                            XtWindow(NgraphApp.Viewer.Win),
                            CWBackingStore,&attr);
  }
  d->ret=ret;
}


void ViewerDialog(struct ViewerDialog *data,struct objlist *obj,int id)
{
  data->SetupWindow=ViewerDialogSetup;
  data->CloseWindow=ViewerDialogClose;
  data->Obj=obj;
  data->Id=id;
  data->Clear=FALSE;
}

void CmOptionSaveNgp()
{
  char *ngpfile;
  char mes[256],*buf;
  int i,path;
  struct objlist *obj;

  if ((ngpfile=getscriptname("Ngraph.ngp"))==NULL) return;
  path=1;
  if ((obj=chkobject("file"))!=NULL) {
    for (i=0;i<=chkobjlastinst(obj);i++)
      putobj(obj,"save_path",i,&path);
  }
  if ((obj=chkobject("merge"))!=NULL) {
    for (i=0;i<=chkobjlastinst(obj);i++)
      putobj(obj,"save_path",i,&path);
  }
  if (access(ngpfile,04)==0) {
    buf=(char *)memalloc(strlen(ngpfile)+60);
    if (buf!=NULL) {
      sprintf(buf,
               "`%s'\n\nOverwrite existing file?",
               ngpfile);
      if (MessageBox(TopLevel,buf,"Save as .Ngraph.ngp",MB_YESNO)!=IDYES) {
        memfree(buf);
        memfree(ngpfile);
        return;
      }
      memfree(buf);
    } else {
      if (MessageBox(TopLevel,"Overwrite existing file?",
       "Save as .Ngraph.ngp",MB_YESNO)!=IDYES) {
        memfree(ngpfile);
        return;
      }
    }
  }
  sprintf(mes,"Saving `%.128s'.",ngpfile);
  SetStatusBar(mes);
  SaveDrawrable(ngpfile,FALSE,FALSE);
  ResetStatusBar();
  memfree(ngpfile);
  return;
}

void CmOptionViewer()
{
  if (menulock || globallock) return;
  ViewerDialog(&DlgViewer,menulocal.obj,0);
  if (DialogExecute(TopLevel,&DlgViewer)==IDOK) {
    if (DlgViewer.Clear) ChangeDPI(TRUE);
  }
}

void CmOptionExtViewer()
{
  if (menulock || globallock) return;
  ExViewerDialog(&DlgExViewer);
  DialogExecute(TopLevel,&DlgExViewer);
}

void CmOptionPrefDriver()
{
  if (menulock || globallock) return;
  PrefDriverDialog(&DlgPrefDriver);
  DialogExecute(TopLevel,&DlgPrefDriver);
}

void CmOptionScript()
{
  if (menulock || globallock) return;
  PrefScriptDialog(&DlgPrefScript);
  DialogExecute(TopLevel,&DlgPrefScript);
}

void CmOptionMisc()
{
  if (menulock || globallock) return;
  MiscDialog(&DlgMisc);
  DialogExecute(TopLevel,&DlgMisc);
}

void CmOptionSaveDefault()
{
  if (menulock || globallock) return;
  DefaultDialog(&DlgDefault);
  DialogExecute(TopLevel,&DlgDefault);
}

void CmOptionMenu(Widget w,XtPointer client_data,XtPointer call_data)
{
  switch ((int )client_data) {
  case 0: 
    CmOptionViewer();
    break;
  case 1: 
    CmOptionExtViewer();
    break;
  case 2: 
    CmOptionPrefDriver();
    break;
  case 3: 
    CmOptionScript();
    break;
  case 4: 
    CmOptionMisc();
    break;
  case 5: 
    CmOptionSaveDefault();
    break;
  case 6: 
    CmOptionSaveNgp();
    break;
  case 7: 
    CmOptionFileDef();
    break;
  case 8: 
    CmOptionTextDef();
    break;
  }
}
