/* 
 * $Id: x11menu.c,v 1.9 2002/08/15 13:12:44 isizaka Exp $
 * 
 * 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: x11menu.c,v $
 * Revision 1.9  2002/08/15 13:12:44  isizaka
 * buf fix: XmNwidth and XmNheight (thanks to Mr tanaka, tt@flab.fujitsu.co.jp)
 *
 * Revision 1.8  2002/07/06 08:57:25  isizaka
 * change to GPL.
 *
 * Revision 1.7  2001/07/14 17:44:50  isizaka
 * for 6.03.14
 *
 * Revision 1.6  2001/03/23 12:17:43  isizaka
 * for 6.3.13
 *
 * 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 <Xm/XmP.h>
#include <X11/keysym.h>
#include <X11/cursorfont.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
#include <math.h>
#include <time.h>
#include <limits.h>

#include "motif12.h"

#include "ngraph.h"
#include "object.h"
#include "ioutil.h"
#include "shell.h"
#include "jstring.h"
#include "nstring.h"
#include "config.h"
#include "mathfn.h"
#include "gra.h"
#include "spline.h"

#include "x11dialg.h"
#include "ox11menu.h"
#include "x11menu.h"
#include "x11gui.h"
#include "x11view.h"
#include "x11file.h"
#include "x11axis.h"
#include "x11lgnd.h"
#include "x11merge.h"
#include "x11graph.h"
#include "x11scrip.h"
#include "x11opt.h"
#include "x11print.h"
#include "x11info.h"
#include "x11cood.h"
#include "x11commn.h"
#include "x11bitmp.h"

int menulock=FALSE;
struct NgraphApp NgraphApp;
Widget TopLevel=NULL,MainWin;
int FHeight,FAscent,FDescent,FWidth;
XFontSet FFont=NULL;

Atom NgraphClose;
Atom COMPOUND_TEXT;
char *CloseMessage="NgraphClose";
int RegisterWorkProc;
XtWorkProcId WorkProcId;

extern char *AppName,*AppClass;

typedef struct {
  String windowfont;
} CustomRec;

CustomRec resources;

static XtResource Res[]= {
  {"windowfont","Windowfont",XtRString,sizeof(String), 
   XtOffsetOf(CustomRec,windowfont),XtRString,"-adobe-courier-medium-r-normal--14-*-*-*-*-*-iso8859-1"}
};

typedef struct {
  XmString tipstring;
  XmString sbstring;
} CustomRecTip;

static XtResource TipRes[]= {
  {"tipString","TipString",XmRXmString,sizeof(XmString), 
   XtOffsetOf(CustomRecTip,tipstring),XtRString,"undefined"},
  {"sbString","SbString",XmRXmString,sizeof(XmString), 
   XtOffsetOf(CustomRecTip,sbstring),XtRString,""}
};

struct narray childlist;
int signaltrap=FALSE;

unsigned int black,white,gray,red,blue;

void childhandler(int sig)
{
  int i,num;
  pid_t *data;

  if (!signaltrap) return;
  signal(sig,SIG_IGN);
  data=arraydata(&childlist);
  num=arraynum(&childlist);
  for (i=num-1;i>=0;i--) {
    if (waitpid(-data[i],NULL,WNOHANG | WUNTRACED)>0) arrayndel(&childlist,i);
  }
  signal(sig,childhandler);
}

static Boolean WorkProc(XtPointer client_data)
{
  if (!menulock && !globallock) eventloop();
  return FALSE;
}

void AppMainLoop(XtAppContext app_context)
{
  XEvent event;
  XClientMessageEvent *e;
  Atom close;

  while (TRUE) {
    NgraphApp.Interrupt=FALSE;
    XtAppNextEvent(app_context,&event);
    if (event.type==ClientMessage) {
      e=(XClientMessageEvent *)&event;
      close=XInternAtom(Disp,CloseMessage,TRUE);
      if (e->message_type==close) break;
    }
    XtDispatchEvent(&event);
    if ((looproot!=NULL) && (!RegisterWorkProc)) {
      WorkProcId=XtAppAddWorkProc(Application,WorkProc,NULL);
      RegisterWorkProc=TRUE;
    }
    if ((looproot==NULL) && RegisterWorkProc) {
      XtRemoveWorkProc(WorkProcId);
      RegisterWorkProc=FALSE;
    }
  }
}

void ResetEvent()
{
  XEvent event;

  XSync(Disp,False);
  while (XtAppPending(Application)) {
    XtAppNextEvent(Application,&event);
    XtDispatchEvent(&event);
    XFlush(Disp);
  }
}


void EvStructure(Widget w,int *mapped,XEvent *e)
{
  if (e->type==MapNotify) *mapped = TRUE;
}

void WaitForMap(Widget w)
{
  XEvent event;
  int mapped;

  mapped=FALSE;
  XtAddEventHandler(w,StructureNotifyMask,False,(void *)EvStructure,
                    &mapped);
  XSync(Disp,False);
  while (!mapped || XtAppPending(Application)) {
    XtAppNextEvent(Application,&event);
    XtDispatchEvent(&event);
    XFlush(Disp);
  }
  XtRemoveEventHandler(w,StructureNotifyMask,False,(void *)EvStructure,
                       &mapped);
}

void GetWMFrame(Widget w)
{
  Position x,y,x2,y2;
  
  XtVaGetValues(w,XmNx,&x,XmNy,&y,NULL);
  WaitForMap(w);
  XtVaGetValues(w,XmNx,&x2,XmNy,&y2,NULL);
  menulocal.framex=x2-x;
  menulocal.framey=y2-y;
}

struct WmStateHint {
  unsigned long state;
  Window icon;
};

int IsIconicState(Widget w)
{
  Atom property,actual_type;
  int actual_format;
  unsigned long nitems,bytes_after;
  struct WmStateHint *prop;

  property=XmInternAtom(XtDisplay(w),"WM_STATE",False);
  if (XGetWindowProperty(XtDisplay(w),XtWindow(w),
                    property,0,2,False,property,
                    &actual_type,&actual_format,&nitems,&bytes_after,
                    (unsigned char **)&prop)==Success) {
    if ((actual_type==property) & (nitems==2)) {
      if (prop->state!=NormalState) return TRUE;
    }
  }
  return FALSE;
}

int iconic=FALSE;

void EvMove(Widget w,XtPointer client_data,XEvent *event,
                      Boolean *dispatch)
{
  XConfigureEvent *e;
  int dx,dy;
  Position x,y,framex,framey;
  Widget Win;

  e=(XConfigureEvent *)event;
  if (IsIconicState(w)) {
    iconic=TRUE;
    return;
  }
  if (iconic) {
    iconic=FALSE;
    return;
  }
  XtVaGetValues(MainWin,XmNx,&framex,XmNy,&framey,NULL);
  dx=framex-menulocal.menux+1;
  dy=framey-menulocal.menuy+1;
  if (menulocal.movechild) {
    Win=NgraphApp.FileWin.Win;
    if (Win!=NULL) {
      XtVaGetValues(Win,XmNx,&x,XmNy,&y,NULL);
      x+=dx-menulocal.framex;
      y+=dy-menulocal.framey;
      XtVaSetValues(Win,XmNx,x,XmNy,y,NULL);
    }
    Win=NgraphApp.AxisWin.Win;
    if (Win!=NULL) {
      XtVaGetValues(Win,XmNx,&x,XmNy,&y,NULL);
      x+=dx-menulocal.framex;
      y+=dy-menulocal.framey;
      XtVaSetValues(Win,XmNx,x,XmNy,y,NULL);
    }
    Win=NgraphApp.LegendWin.Win;
    if (Win!=NULL) {
      XtVaGetValues(Win,XmNx,&x,XmNy,&y,NULL);
      x+=dx-menulocal.framex;
      y+=dy-menulocal.framey;
      XtVaSetValues(Win,XmNx,x,XmNy,y,NULL);
    }
    Win=NgraphApp.MergeWin.Win;
    if (Win!=NULL) {
      XtVaGetValues(Win,XmNx,&x,XmNy,&y,NULL);
      x+=dx-menulocal.framex;
      y+=dy-menulocal.framey;
      XtVaSetValues(Win,XmNx,x,XmNy,y,NULL);
    }
    Win=NgraphApp.CoordWin.Win;
    if (Win!=NULL) {
      XtVaGetValues(Win,XmNx,&x,XmNy,&y,NULL);
      x+=dx-menulocal.framex;
      y+=dy-menulocal.framey;
      XtVaSetValues(Win,XmNx,x,XmNy,y,NULL);
    }
    Win=NgraphApp.InfoWin.Win;
    if (Win!=NULL) {
      XtVaGetValues(Win,XmNx,&x,XmNy,&y,NULL);
      x+=dx-menulocal.framex;
      y+=dy-menulocal.framey;
      XtVaSetValues(Win,XmNx,x,XmNy,y,NULL);
    }
  }
  menulocal.menux=framex;
  menulocal.menuy=framey;
}

void CloseCallback(Widget w,XtPointer client_data,XtPointer call_data)
{
  CmGraphQuit();
}

void CmWindowMenu(Widget w,XtPointer client_data,XtPointer call_data);

Widget TipWidget=NULL;
int TipDisplay=FALSE;
XtIntervalId TipId=0;

void TipDisplayCallback(XtPointer client_data,XtIntervalId *id)
{
  if (TipWidget!=NULL) {
    XtPopup(TipWidget,XtGrabNone);
    TipDisplay=TRUE;
  }
}

void TipCallback(Widget w,XtPointer client_data,XEvent *event,
                 Boolean *dispatch)
{
  Position x, y;
  CustomRecTip tipres;
  Widget label;

  if (!menulocal.showtip) return;
  if (event->type==EnterNotify) {
    TipWidget=XtVaCreatePopupShell("tip_shell",overrideShellWidgetClass,
                                   TopLevel,NULL);
    XtTranslateCoords(w,button_width/2+5,button_height+10,&x,&y);
    XtVaSetValues(TipWidget,XmNx,x,XmNy,y,NULL);
    label=XtVaCreateWidget("tip_label",xmLabelWidgetClass,TipWidget,NULL);
    XtGetApplicationResources(w,&tipres,TipRes,XtNumber(TipRes),NULL,0);
    XtVaSetValues(label,XmNlabelString,tipres.tipstring,NULL);
    SetStatusBarXm(tipres.sbstring);
    TipDisplay=FALSE;
    XtManageChild(label);
    TipId=XtAppAddTimeOut(XtWidgetToApplicationContext(w),700,
                          TipDisplayCallback,NULL);
  } else if (event->type==LeaveNotify) {
    if (TipWidget!=NULL) {
      XtDestroyWidget(TipWidget);
      if (TipDisplay) XtPopdown (TipWidget);
      else XtRemoveTimeOut(TipId);
      ResetStatusBar();
      TipWidget=NULL;
    }
  }
}

void DropTransfer(Widget w,XtPointer closure,Atom *seltype,
                  Atom *atype,XtPointer value,unsigned long *length,int format)
{
  char **list;
  int num;
  char *name,*ext;
  int i,len,id;
  struct objlist *obj;
  int id0,j,perm,type,ret;
  char *field;
  int load;
  XTextProperty ct;

  if (*atype!=COMPOUND_TEXT) return;
  ct.value=value;
  ct.encoding=COMPOUND_TEXT;
  ct.format=8;
  ct.nitems=*length;
  if (XmbTextPropertyToTextList(Disp,&ct,&list,&num)!=Success) return;
  if (num==1) {
    len=strlen(list[0]);
    if ((name=(char *)memalloc(len+1))!=NULL) {
      strcpy(name,list[0]);
      load=FALSE;
      if ((ext=getextention(name))!=NULL) {
        if ((strcmp0(ext,"PRM")==0) || (strcmp0(ext,"prm")==0)) {
          LoadPrmFile(name);
          load=TRUE;
        } else if ((strcmp0(ext,"NGP")==0) || (strcmp0(ext,"ngp")==0)) {
          LoadNgpFile(name,menulocal.ignorepath,menulocal.expand,
                      menulocal.expanddir,FALSE,NULL);
          load=TRUE;
        }
      }
      memfree(name);
      if (load) {
        XFreeStringList(list);
        CmViewerDrawB(NgraphApp.Viewer.Win,NULL,NULL);
        return;
      }
    }
  }
  if ((obj=chkobject("file"))==NULL) {
    XFreeStringList(list);
    return;
  }
  id0=-1;
  for (i=0;i<num;i++) {
    if ((id=newobj(obj))>=0) {
      len=strlen(list[i]);
      if ((name=(char *)memalloc(len+1))!=NULL) {
        strcpy(name,list[i]);
        AddDataFileList(name);
        putobj(obj,"file",id,name);
        if (id0!=-1) {
          for (j=0;j<chkobjfieldnum(obj);j++) {
            field=chkobjfieldname(obj,j);
            perm=chkobjperm(obj,field);
            type=chkobjfieldtype(obj,field);
            if ((strcmp2(field,"name")!=0) && (strcmp2(field,"file")!=0)
             && (strcmp2(field,"fit")!=0)
             && ((perm&NREAD)!=0) && ((perm&NWRITE)!=0) && (type<NVFUNC))
              copyobj(obj,field,id,id0);
          }
          FitCopy(obj,id,id0);
        } else {
          FileDialog(&DlgFile,obj,id);
          ret=DialogExecute(TopLevel,&DlgFile);
          if ((ret==IDDELETE) || (ret==IDCANCEL)) {
            FitDel(obj,id);
            delobj(obj,id);
          } else {
            if (ret==IDFAPPLY) id0=id;
            NgraphApp.Changed=TRUE;
          }
        }
      }
    }
  }
  XFreeStringList(list);
  FileWinUpdate(TRUE);
}

void DropHandle(Widget w,XtPointer client_data,XtPointer call_data)
{
  XmDropProcCallback DropData;
  XmDropTransferEntryRec transferEntries[1];
  XmDropTransferEntry transferList;
  Arg al[20];
  Cardinal ac;

  DropData=(XmDropProcCallback)call_data;
  ac=0;
  if ((DropData->dropAction != XmDROP)
   || (DropData->operation != XmDROP_COPY)) {
    XtSetArg(al[ac],XmNtransferStatus,XmTRANSFER_FAILURE);
    ac++;
  } else {
    transferEntries[0].target=COMPOUND_TEXT;
    transferEntries[0].client_data=(XtPointer)w;
    transferList=transferEntries;
    XtSetArg(al[ac],XmNdropTransfers,transferList); ac++;
    XtSetArg(al[ac],XmNnumDropTransfers,1); ac++;
    XtSetArg(al[ac],XmNtransferProc,DropTransfer); ac++;
  }
  XmDropTransferStart(DropData->dragContext,al,ac);
}


void createmenu(Widget parent)
{
  Widget graphmenu,filemenu,axismenu,legendmenu,mergemenu;
  Arg al[20];
  Cardinal ac;
  int i,num;
  char **data;
  XmString s;

  graphmenu=XmVaCreateSimplePulldownMenu(parent,"graphmenu",0,CmGraphMenu,
    XmVaCASCADEBUTTON,NULL,NULL,
    XmVaPUSHBUTTON,NULL,NULL,NULL,NULL,
    XmVaPUSHBUTTON,NULL,NULL,NULL,NULL,
    XmVaPUSHBUTTON,NULL,NULL,NULL,NULL,
    XmVaSEPARATOR,
    XmVaPUSHBUTTON,NULL,NULL,NULL,NULL,
    XmVaPUSHBUTTON,NULL,NULL,NULL,NULL,
    XmVaSEPARATOR,
    XmVaPUSHBUTTON,NULL,NULL,NULL,NULL,
    XmVaSEPARATOR,
    XmVaPUSHBUTTON,NULL,NULL,NULL,NULL,
    XmVaSEPARATOR,
    XmVaPUSHBUTTON,NULL,NULL,NULL,NULL,
    XmVaPUSHBUTTON,NULL,NULL,NULL,NULL,
    XmVaSEPARATOR,
    XmVaPUSHBUTTON,NULL,NULL,NULL,NULL,
    XmVaSEPARATOR,
    NULL);
  ac=0;
  for (i=0;i<10;i++) {
   NgraphApp.ghistory[i]=XmCreatePushButton(graphmenu,NULL,al,ac);
   XtAddCallback(NgraphApp.ghistory[i],XmNactivateCallback,
                 CmGraphHistory,NULL);
  }
  XmVaCreateSimplePulldownMenu(graphmenu,"graphnewmenu",0,CmGraphNewMenu,
    XmVaPUSHBUTTON,NULL,NULL,NULL,NULL,
    XmVaPUSHBUTTON,NULL,NULL,NULL,NULL,
    XmVaPUSHBUTTON,NULL,NULL,NULL,NULL,
    XmVaPUSHBUTTON,NULL,NULL,NULL,NULL,
    NULL);

  filemenu=XmVaCreateSimplePulldownMenu(parent,"datamenu",1,CmFileMenu,
    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,
    XmVaSEPARATOR,
    NULL);
  ac=0;
  for (i=0;i<10;i++) {
    NgraphApp.fhistory[i]=XmCreatePushButton(filemenu,NULL,al,ac);
    XtAddCallback(NgraphApp.fhistory[i],XmNactivateCallback,
                  CmFileHistory,NULL);
  }

  axismenu=XmVaCreateSimplePulldownMenu(parent,"axismenu",2,CmAxisMenu,
    XmVaCASCADEBUTTON,NULL,NULL,
    XmVaPUSHBUTTON,NULL,NULL,NULL,NULL,
    XmVaPUSHBUTTON,NULL,NULL,NULL,NULL,
    XmVaPUSHBUTTON,NULL,NULL,NULL,NULL,
    XmVaPUSHBUTTON,NULL,NULL,NULL,NULL,
    XmVaCASCADEBUTTON,NULL,NULL,
    NULL);

  XmVaCreateSimplePulldownMenu(axismenu,"axisaddmenu",0,CmAxisAddMenu,
    XmVaPUSHBUTTON,NULL,NULL,NULL,NULL,
    XmVaPUSHBUTTON,NULL,NULL,NULL,NULL,
    XmVaPUSHBUTTON,NULL,NULL,NULL,NULL,
    XmVaPUSHBUTTON,NULL,NULL,NULL,NULL,
    NULL);

  XmVaCreateSimplePulldownMenu(axismenu,"axisgridmenu",5,CmGridMenu,
    XmVaPUSHBUTTON,NULL,NULL,NULL,NULL,
    XmVaPUSHBUTTON,NULL,NULL,NULL,NULL,
    XmVaPUSHBUTTON,NULL,NULL,NULL,NULL,
    NULL);

  legendmenu=XmVaCreateSimplePulldownMenu(parent,"legendmenu",3,NULL,
    XmVaCASCADEBUTTON,NULL,NULL,
    XmVaCASCADEBUTTON,NULL,NULL,
    XmVaCASCADEBUTTON,NULL,NULL,
    XmVaCASCADEBUTTON,NULL,NULL,
    XmVaCASCADEBUTTON,NULL,NULL,
    XmVaCASCADEBUTTON,NULL,NULL,
    XmVaCASCADEBUTTON,NULL,NULL,
    NULL);

  XmVaCreateSimplePulldownMenu(legendmenu,"linemenu",0,CmLineMenu,
    XmVaPUSHBUTTON,NULL,NULL,NULL,NULL,
    XmVaPUSHBUTTON,NULL,NULL,NULL,NULL,
    NULL);

  XmVaCreateSimplePulldownMenu(legendmenu,"curvemenu",1,CmCurveMenu,
    XmVaPUSHBUTTON,NULL,NULL,NULL,NULL,
    XmVaPUSHBUTTON,NULL,NULL,NULL,NULL,
    NULL);

  XmVaCreateSimplePulldownMenu(legendmenu,"polygonmenu",2,CmPolygonMenu,
    XmVaPUSHBUTTON,NULL,NULL,NULL,NULL,
    XmVaPUSHBUTTON,NULL,NULL,NULL,NULL,
    NULL);

  XmVaCreateSimplePulldownMenu(legendmenu,"rectanglemenu",3,CmRectangleMenu,
    XmVaPUSHBUTTON,NULL,NULL,NULL,NULL,
    XmVaPUSHBUTTON,NULL,NULL,NULL,NULL,
    NULL);

  XmVaCreateSimplePulldownMenu(legendmenu,"arcmenu",4,CmArcMenu,
    XmVaPUSHBUTTON,NULL,NULL,NULL,NULL,
    XmVaPUSHBUTTON,NULL,NULL,NULL,NULL,
    NULL);

  XmVaCreateSimplePulldownMenu(legendmenu,"markmenu",5,CmMarkMenu,
    XmVaPUSHBUTTON,NULL,NULL,NULL,NULL,
    XmVaPUSHBUTTON,NULL,NULL,NULL,NULL,
    NULL);

  XmVaCreateSimplePulldownMenu(legendmenu,"textmenu",6,CmTextMenu,
    XmVaPUSHBUTTON,NULL,NULL,NULL,NULL,
    XmVaPUSHBUTTON,NULL,NULL,NULL,NULL,
    NULL);

  mergemenu=XmVaCreateSimplePulldownMenu(parent,"mergemenu",4,CmMergeMenu,
    XmVaPUSHBUTTON,NULL,NULL,NULL,NULL,
    XmVaPUSHBUTTON,NULL,NULL,NULL,NULL,
    XmVaPUSHBUTTON,NULL,NULL,NULL,NULL,
    NULL);

  XmVaCreateSimplePulldownMenu(parent,"outputmenu",5,CmOutputMenu,
    XmVaPUSHBUTTON,NULL,NULL,NULL,NULL,
    XmVaPUSHBUTTON,NULL,NULL,NULL,NULL,
    XmVaSEPARATOR,
    XmVaPUSHBUTTON,NULL,NULL,NULL,NULL,
    XmVaPUSHBUTTON,NULL,NULL,NULL,NULL,
    XmVaPUSHBUTTON,NULL,NULL,NULL,NULL,
    XmVaPUSHBUTTON,NULL,NULL,NULL,NULL,
    NULL);

  XmVaCreateSimplePulldownMenu(parent,"preferencemenu",6,CmOptionMenu,
    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,
    XmVaSEPARATOR,
    XmVaPUSHBUTTON,NULL,NULL,NULL,NULL,
    XmVaPUSHBUTTON,NULL,NULL,NULL,NULL,
    XmVaSEPARATOR,
    XmVaPUSHBUTTON,NULL,NULL,NULL,NULL,
    XmVaPUSHBUTTON,NULL,NULL,NULL,NULL,
    NULL);

  XmVaCreateSimplePulldownMenu(parent,"windowmenu",7,CmWindowMenu,
    XmVaCHECKBUTTON,NULL,NULL,NULL,NULL,
    XmVaCHECKBUTTON,NULL,NULL,NULL,NULL,
    XmVaCHECKBUTTON,NULL,NULL,NULL,NULL,
    XmVaCHECKBUTTON,NULL,NULL,NULL,NULL,
    XmVaCHECKBUTTON,NULL,NULL,NULL,NULL,
    XmVaCHECKBUTTON,NULL,NULL,NULL,NULL,
    XmVaSEPARATOR,
    XmVaPUSHBUTTON,NULL,NULL,NULL,NULL,
    XmVaCHECKBUTTON,NULL,NULL,NULL,NULL,
    XmVaCHECKBUTTON,NULL,NULL,NULL,NULL,
    NULL);
  XmVaCreateSimplePulldownMenu(parent,"helpmenu",8,CmHelpMenu,
    XmVaPUSHBUTTON,NULL,NULL,NULL,NULL,
    XmVaPUSHBUTTON,NULL,NULL,NULL,NULL,
    NULL);

  num=arraynum(menulocal.ngpfilelist);
  data=(char **)arraydata(menulocal.ngpfilelist);
  for (i=0;i<10;i++) {
    if (i<num) {
      s=XmStringCreate(data[i],XmFONTLIST_DEFAULT_TAG);
      XtVaSetValues(NgraphApp.ghistory[i],XmNlabelString,s,NULL);
      XtManageChild(NgraphApp.ghistory[i]);
      XmStringFree(s);
    } else XtUnmanageChild(NgraphApp.ghistory[i]);
  }
  num=arraynum(menulocal.datafilelist);
  data=(char **)arraydata(menulocal.datafilelist);
  for (i=0;i<10;i++) {
    if (i<num) {
      s=XmStringCreate(data[i],XmFONTLIST_DEFAULT_TAG);
      XtVaSetValues(NgraphApp.fhistory[i],XmNlabelString,s,NULL);
      XtManageChild(NgraphApp.fhistory[i]);
      XmStringFree(s);
    } else XtUnmanageChild(NgraphApp.fhistory[i]);
  }

}

int setwindowfont() 
{
  char **missing,*defstring;
  int missingcount;
  XRectangle ink,logical;

  FFont=XCreateFontSet(Disp,resources.windowfont,
                       &missing,&missingcount,&defstring);
  if (FFont==NULL) return FALSE;
  XFreeStringList(missing);
  XmbTextExtents(FFont,"H",1,&ink,&logical);
  FAscent=-logical.y;
  XmbTextExtents(FFont,"g",1,&ink,&logical);
  FDescent=logical.y+logical.height;
  FHeight=FAscent+FDescent;
  FWidth=XmbTextEscapement(FFont,"M",1);
  if (FHeight<1) FHeight=1;
  if (FWidth<1) FWidth=1;
  return TRUE;
}

void createpixmap1(Window win)
{
  XImage *image;

  _XmCreateImage(image,Disp,(char *)filewin_bits,
                            button_width,button_height,LSBFirst);
  XmInstallImage(image,"filewin");
  NgraphApp.com1pix[0]=XmGetPixmap(DefaultScreenOfDisplay(Disp),
                       "filewin",black,gray);
  _XmCreateImage(image,Disp,(char *)axiswin_bits,
                            button_width,button_height,LSBFirst);
  XmInstallImage(image,"axiswin");
  NgraphApp.com1pix[1]=XmGetPixmap(DefaultScreenOfDisplay(Disp),
                       "axiswin",black,gray);
  _XmCreateImage(image,Disp,(char *)legendwin_bits,
                            button_width,button_height,LSBFirst);
  XmInstallImage(image,"legendwin");
  NgraphApp.com1pix[2]=XmGetPixmap(DefaultScreenOfDisplay(Disp),
                       "legendwin",black,gray);
  _XmCreateImage(image,Disp,(char *)mergewin_bits,
                            button_width,button_height,LSBFirst);
  XmInstallImage(image,"mergewin");
  NgraphApp.com1pix[3]=XmGetPixmap(DefaultScreenOfDisplay(Disp),
                       "mergewin",black,gray);
  _XmCreateImage(image,Disp,(char *)coordwin_bits,
                            button_width,button_height,LSBFirst);
  XmInstallImage(image,"coordwin");
  NgraphApp.com1pix[4]=XmGetPixmap(DefaultScreenOfDisplay(Disp),
                       "coordwin",black,gray);
  _XmCreateImage(image,Disp,(char *)infowin_bits,
                            button_width,button_height,LSBFirst);
  XmInstallImage(image,"infowin");
  NgraphApp.com1pix[5]=XmGetPixmap(DefaultScreenOfDisplay(Disp),
                       "infowin",black,gray);
  _XmCreateImage(image,Disp,(char *)fileopen_bits,
                            button_width,button_height,LSBFirst);
  XmInstallImage(image,"fileopen");
  NgraphApp.com1pix[6]=XmGetPixmap(DefaultScreenOfDisplay(Disp),
                       "fileopen",black,gray);
  _XmCreateImage(image,Disp,(char *)load_bits,
                            button_width,button_height,LSBFirst);
  XmInstallImage(image,"load");
  NgraphApp.com1pix[7]=XmGetPixmap(DefaultScreenOfDisplay(Disp),
                       "load",black,gray);
  _XmCreateImage(image,Disp,(char *)save_bits,
                            button_width,button_height,LSBFirst);
  XmInstallImage(image,"save");
  NgraphApp.com1pix[8]=XmGetPixmap(DefaultScreenOfDisplay(Disp),
                       "save",black,gray);
  _XmCreateImage(image,Disp,(char *)scale_bits,
                            button_width,button_height,LSBFirst);
  XmInstallImage(image,"scale");
  NgraphApp.com1pix[9]=XmGetPixmap(DefaultScreenOfDisplay(Disp),
                       "scale",black,gray);
  _XmCreateImage(image,Disp,(char *)draw_bits,
                            draw_width,draw_height,LSBFirst);
  XmInstallImage(image,"draw");
  NgraphApp.com1pix[10]=XmGetPixmap(DefaultScreenOfDisplay(Disp),
                       "draw",black,gray);
  _XmCreateImage(image,Disp,(char *)clear_bits,
                            button_width,button_height,LSBFirst);
  XmInstallImage(image,"clear");
  NgraphApp.com1pix[11]=XmGetPixmap(DefaultScreenOfDisplay(Disp),
                       "clear",black,gray);
  _XmCreateImage(image,Disp,(char *)print_bits,
                            button_width,button_height,LSBFirst);
  XmInstallImage(image,"print");
  NgraphApp.com1pix[12]=XmGetPixmap(DefaultScreenOfDisplay(Disp),
                       "print",black,gray);
  _XmCreateImage(image,Disp,(char *)preview_bits,
                            button_width,button_height,LSBFirst);
  XmInstallImage(image,"preview");
  NgraphApp.com1pix[13]=XmGetPixmap(DefaultScreenOfDisplay(Disp),
                       "preview",black,gray);
  _XmCreateImage(image,Disp,(char *)math_bits,
                            button_width,button_height,LSBFirst);
  XmInstallImage(image,"math");
  NgraphApp.com1pix[14]=XmGetPixmap(DefaultScreenOfDisplay(Disp),
                       "math",black,gray);
  _XmCreateImage(image,Disp,(char *)scaleundo_bits,
                            button_width,button_height,LSBFirst);
  XmInstallImage(image,"scaleundo");
  NgraphApp.com1pix[15]=XmGetPixmap(DefaultScreenOfDisplay(Disp),
                       "scaleundo",black,gray);
  _XmCreateImage(image,Disp,(char *)interrupt_bits,
                            button_width,button_height,LSBFirst);
  XmInstallImage(image,"interrupt");
  NgraphApp.com1pix[16]=XmGetPixmap(DefaultScreenOfDisplay(Disp),
                       "interrupt",black,gray);
}

void createpixmap2(Window win)
{
  XImage *image;

  _XmCreateImage(image,Disp,(char *)point_bits,
                            button_width,button_height,LSBFirst);
  XmInstallImage(image,"point");
  NgraphApp.com2pix[0][1]=XmGetPixmap(DefaultScreenOfDisplay(Disp),
                       "point",black,white);
  NgraphApp.com2pix[0][0]=XmGetPixmap(DefaultScreenOfDisplay(Disp),
                       "point",white,black);
  _XmCreateImage(image,Disp,(char *)legendpoint_bits,
                            button_width,button_height,LSBFirst);
  XmInstallImage(image,"legendpoint");
  NgraphApp.com2pix[1][1]=XmGetPixmap(DefaultScreenOfDisplay(Disp),
                       "legendpoint",black,white);
  NgraphApp.com2pix[1][0]=XmGetPixmap(DefaultScreenOfDisplay(Disp),
                       "legendpoint",white,black);
  _XmCreateImage(image,Disp,(char *)line_bits,
                            button_width,button_height,LSBFirst);
  XmInstallImage(image,"line");
  NgraphApp.com2pix[2][1]=XmGetPixmap(DefaultScreenOfDisplay(Disp),
                       "line",black,white);
  NgraphApp.com2pix[2][0]=XmGetPixmap(DefaultScreenOfDisplay(Disp),
                       "line",white,black);
  _XmCreateImage(image,Disp,(char *)curve_bits,
                            button_width,button_height,LSBFirst);
  XmInstallImage(image,"curve");
  NgraphApp.com2pix[3][1]=XmGetPixmap(DefaultScreenOfDisplay(Disp),
                       "curve",black,white);
  NgraphApp.com2pix[3][0]=XmGetPixmap(DefaultScreenOfDisplay(Disp),
                       "curve",white,black);
  _XmCreateImage(image,Disp,(char *)polygon_bits,
                            button_width,button_height,LSBFirst);
  XmInstallImage(image,"polygon");
  NgraphApp.com2pix[4][1]=XmGetPixmap(DefaultScreenOfDisplay(Disp),
                       "polygon",black,white);
  NgraphApp.com2pix[4][0]=XmGetPixmap(DefaultScreenOfDisplay(Disp),
                       "polygon",white,black);
  _XmCreateImage(image,Disp,(char *)rect_bits,
                            button_width,button_height,LSBFirst);
  XmInstallImage(image,"rect");
  NgraphApp.com2pix[5][1]=XmGetPixmap(DefaultScreenOfDisplay(Disp),
                       "rect",black,white);
  NgraphApp.com2pix[5][0]=XmGetPixmap(DefaultScreenOfDisplay(Disp),
                       "rect",white,black);
  _XmCreateImage(image,Disp,(char *)arc_bits,
                            button_width,button_height,LSBFirst);
  XmInstallImage(image,"arc");
  NgraphApp.com2pix[6][1]=XmGetPixmap(DefaultScreenOfDisplay(Disp),
                       "arc",black,white);
  NgraphApp.com2pix[6][0]=XmGetPixmap(DefaultScreenOfDisplay(Disp),
                       "arc",white,black);
  _XmCreateImage(image,Disp,(char *)mark_bits,
                            button_width,button_height,LSBFirst);
  XmInstallImage(image,"mark");
  NgraphApp.com2pix[7][1]=XmGetPixmap(DefaultScreenOfDisplay(Disp),
                       "mark",black,white);
  NgraphApp.com2pix[7][0]=XmGetPixmap(DefaultScreenOfDisplay(Disp),
                       "mark",white,black);
  _XmCreateImage(image,Disp,(char *)text_bits,
                            button_width,button_height,LSBFirst);
  XmInstallImage(image,"text");
  NgraphApp.com2pix[8][1]=XmGetPixmap(DefaultScreenOfDisplay(Disp),
                       "text",black,white);
  NgraphApp.com2pix[8][0]=XmGetPixmap(DefaultScreenOfDisplay(Disp),
                       "text",white,black);
  _XmCreateImage(image,Disp,(char *)gauss_bits,
                            button_width,button_height,LSBFirst);
  XmInstallImage(image,"gauss");
  NgraphApp.com2pix[9][1]=XmGetPixmap(DefaultScreenOfDisplay(Disp),
                       "gauss",black,white);
  NgraphApp.com2pix[9][0]=XmGetPixmap(DefaultScreenOfDisplay(Disp),
                       "gauss",white,black);
  _XmCreateImage(image,Disp,(char *)axispoint_bits,
                            button_width,button_height,LSBFirst);
  XmInstallImage(image,"axispoint");
  NgraphApp.com2pix[10][1]=XmGetPixmap(DefaultScreenOfDisplay(Disp),
                       "axispoint",black,white);
  NgraphApp.com2pix[10][0]=XmGetPixmap(DefaultScreenOfDisplay(Disp),
                       "axispoint",white,black);
  _XmCreateImage(image,Disp,(char *)trimming_bits,
                            button_width,button_height,LSBFirst);
  XmInstallImage(image,"trimming");
  NgraphApp.com2pix[11][1]=XmGetPixmap(DefaultScreenOfDisplay(Disp),
                       "trimming",black,white);
  NgraphApp.com2pix[11][0]=XmGetPixmap(DefaultScreenOfDisplay(Disp),
                       "trimming",white,black);
  _XmCreateImage(image,Disp,(char *)frame_bits,
                            button_width,button_height,LSBFirst);
  XmInstallImage(image,"frame");
  NgraphApp.com2pix[12][1]=XmGetPixmap(DefaultScreenOfDisplay(Disp),
                       "frame",black,white);
  NgraphApp.com2pix[12][0]=XmGetPixmap(DefaultScreenOfDisplay(Disp),
                       "frame",white,black);
  _XmCreateImage(image,Disp,(char *)section_bits,
                            button_width,button_height,LSBFirst);
  XmInstallImage(image,"section");
  NgraphApp.com2pix[13][1]=XmGetPixmap(DefaultScreenOfDisplay(Disp),
                       "section",black,white);
  NgraphApp.com2pix[13][0]=XmGetPixmap(DefaultScreenOfDisplay(Disp),
                       "section",white,black);
  _XmCreateImage(image,Disp,(char *)cross_bits,
                            button_width,button_height,LSBFirst);
  XmInstallImage(image,"cross");
  NgraphApp.com2pix[14][1]=XmGetPixmap(DefaultScreenOfDisplay(Disp),
                       "cross",black,white);
  NgraphApp.com2pix[14][0]=XmGetPixmap(DefaultScreenOfDisplay(Disp),
                       "cross",white,black);
  _XmCreateImage(image,Disp,(char *)single_bits,
                            button_width,button_height,LSBFirst);
  XmInstallImage(image,"single");
  NgraphApp.com2pix[15][1]=XmGetPixmap(DefaultScreenOfDisplay(Disp),
                       "single",black,white);
  NgraphApp.com2pix[15][0]=XmGetPixmap(DefaultScreenOfDisplay(Disp),
                       "single",white,black);
  _XmCreateImage(image,Disp,(char *)datapoint_bits,
                            button_width,button_height,LSBFirst);
  XmInstallImage(image,"datapoint");
  NgraphApp.com2pix[16][1]=XmGetPixmap(DefaultScreenOfDisplay(Disp),
                       "datapoint",black,white);
  NgraphApp.com2pix[16][0]=XmGetPixmap(DefaultScreenOfDisplay(Disp),
                       "datapoint",white,black);
  _XmCreateImage(image,Disp,(char *)eval_bits,
                            button_width,button_height,LSBFirst);
  XmInstallImage(image,"eval");
  NgraphApp.com2pix[17][1]=XmGetPixmap(DefaultScreenOfDisplay(Disp),
                       "eval",black,white);
  NgraphApp.com2pix[17][0]=XmGetPixmap(DefaultScreenOfDisplay(Disp),
                       "eval",white,black);
  _XmCreateImage(image,Disp,(char *)zoom_bits,
                            button_width,button_height,LSBFirst);
  XmInstallImage(image,"zoom");
  NgraphApp.com2pix[18][1]=XmGetPixmap(DefaultScreenOfDisplay(Disp),
                       "zoom",black,white);
  NgraphApp.com2pix[18][0]=XmGetPixmap(DefaultScreenOfDisplay(Disp),
                       "zoom",white,black);
}

void createmarkpixmap(Window win)
{
  XWindowAttributes attr;
  int depth;
  Pixmap pix;
  int dpi,gc;
  GC XGC;
  struct mxlocal mxsave;
  int i,R,G,B,R2,G2,B2;

  XGetWindowAttributes(Disp,win,&attr);
  depth=attr.depth;
  R=G=B=0;
  R2=0;
  G2=B2=255;
  for (i=0;i<90;i++) {
    pix=NgraphApp.markpix[i]=XCreatePixmap(Disp,win,20,20,depth);
    dpi=nround(20*25.4);
    XGC=XCreateGC(Disp,pix,0,0);
    XSetForeground(Disp,XGC,RGB(255,255,255));
    XFillRectangle(Disp,pix,XGC,0,0,20,20);
    mxsaveGC(XGC,pix,0,0,&mxsave,dpi,NULL);
    gc=_GRAopen(chkobjectname(menulocal.obj),"_output",menulocal.outputobj,
             menulocal.inst,menulocal.output,-1,-1,-1,NULL,mxlocal);
    if (gc>=0) {
      GRAview(gc,0,0,100,100,0);
      GRAlinestyle(gc,0,NULL,1,0,0,1000);
      GRAmark(gc,i,49,49,80,R,G,B,R2,G2,B2);
    }
    _GRAclose(gc);
    mxrestoreGC(&mxsave);
    XFreeGC(Disp,XGC);
  }
}

void createicon(Window win)
{
  Pixmap pix;
  int x,y;
  unsigned int width,height,border,depth;
  Window root;
  GC gc;
  int h,w;
  char c;

  XGetGeometry(Disp,win,&root,&x,&y,&width,&height,&border,&depth);
  pix=XCreatePixmap(Disp,win,icon_width+2,icon_height+2,depth);
  gc=XCreateGC(Disp,pix,0,0);
  for (h=0;h<icon_height+2;h++) {
    for (w=0;w<icon_width+2;w++) {
      if ((h==0) || (h==icon_height+1) || (w==0) || (w==icon_width+1)) c='a';
      else c=icon_xpm[h-1][w-1];
      switch(c) {
      case '.': XSetForeground(Disp,gc,RGB(0,0,0)); break;
      case '#': XSetForeground(Disp,gc,RGB(0,0,255)); break;
      case 'a': XSetForeground(Disp,gc,RGB(0,127,127)); break;
      case 'b': XSetForeground(Disp,gc,RGB(0,255,255)); break;
      case 'c': XSetForeground(Disp,gc,RGB(127,127,0)); break;
      case 'd': XSetForeground(Disp,gc,RGB(127,127,127)); break;
      case 'e': XSetForeground(Disp,gc,RGB(191,191,191)); break;
      case 'f': XSetForeground(Disp,gc,RGB(255,0,0)); break;
      case 'g': XSetForeground(Disp,gc,RGB(255,255,0)); break;
      case 'h': XSetForeground(Disp,gc,RGB(255,255,255)); break;
      default: XSetForeground(Disp,gc,RGB(0,0,0)); break;
      }
      XDrawPoint(Disp,pix,gc,w,h);
    }
  }
  XFreeGC(Disp,gc);
  NgraphApp.iconpix=pix;
}

void createcursor()
{
  NgraphApp.cursor[0]=XCreateFontCursor(Disp,XC_left_ptr);
  NgraphApp.cursor[1]=XCreateFontCursor(Disp,XC_xterm);
  NgraphApp.cursor[2]=XCreateFontCursor(Disp,XC_crosshair);
  NgraphApp.cursor[3]=XCreateFontCursor(Disp,XC_top_left_corner);
  NgraphApp.cursor[4]=XCreateFontCursor(Disp,XC_top_right_corner);
  NgraphApp.cursor[5]=XCreateFontCursor(Disp,XC_bottom_right_corner);
  NgraphApp.cursor[6]=XCreateFontCursor(Disp,XC_bottom_left_corner);
  NgraphApp.cursor[7]=XCreateFontCursor(Disp,XC_centering);
  NgraphApp.cursor[8]=XCreateFontCursor(Disp,XC_zoomin);
  NgraphApp.cursor[9]=XCreateFontCursor(Disp,XC_zoomout);
  NgraphApp.cursor[10]=XCreateFontCursor(Disp,XC_watch);
}

void createcommand1(Widget parent)
{
  Arg al[20];
  Cardinal ac;
  Widget b;
  int i;
  char res[128];

  for (i=0;i<=5;i++) {
    ac=0;
    XtSetArg(al[ac],XmNlabelType,XmPIXMAP); ac++;
    XtSetArg(al[ac],XmNlabelPixmap,NgraphApp.com1pix[i]); ac++;
    XtSetArg(al[ac],XmNmarginWidth,0); ac++;
    XtSetArg(al[ac],XmNmarginHeight,0); ac++;
    XtSetArg(al[ac],XmNmarginTop,0); ac++;
    XtSetArg(al[ac],XmNmarginBottom,0); ac++;
    XtSetArg(al[ac],XmNmarginLeft,0); ac++;
    XtSetArg(al[ac],XmNmarginRight,0); ac++;
    sprintf(res,"button_%d",i);
    XtManageChild(b=XmCreatePushButton(parent,res,al,ac));
    switch (i) {
    case 0:
      XtAddCallback(b,XmNdisarmCallback,CmFileWindow,NULL);
      break;
    case 1:
      XtAddCallback(b,XmNdisarmCallback,CmAxisWindow,NULL);
      break;
    case 2:
      XtAddCallback(b,XmNdisarmCallback,CmLegendWindow,NULL);
      break;
    case 3:
      XtAddCallback(b,XmNdisarmCallback,CmMergeWindow,NULL);
      break;
    case 4:
      XtAddCallback(b,XmNdisarmCallback,CmCoordinateWindow,NULL);
      break;
    case 5:
      XtAddCallback(b,XmNdisarmCallback,CmInformationWindow,NULL);
      break;
    }
    XtAddEventHandler(b,EnterWindowMask | LeaveWindowMask,
                      False,TipCallback,NULL);
  }

  ac=0;
  XtSetArg(al[ac],XmNwidth,10); ac++;
  XtManageChild(XmCreateDrawingArea(parent,NULL,al,ac));

  for (i=6;i<14;i++) {
    ac=0;
    XtSetArg(al[ac],XmNlabelType,XmPIXMAP); ac++;
    XtSetArg(al[ac],XmNlabelPixmap,NgraphApp.com1pix[i]); ac++;
    XtSetArg(al[ac],XmNmarginWidth,0); ac++;
    XtSetArg(al[ac],XmNmarginHeight,0); ac++;
    XtSetArg(al[ac],XmNmarginTop,0); ac++;
    XtSetArg(al[ac],XmNmarginBottom,0); ac++;
    XtSetArg(al[ac],XmNmarginLeft,0); ac++;
    XtSetArg(al[ac],XmNmarginRight,0); ac++;
    sprintf(res,"button_%d",i);
    XtManageChild(b=XmCreatePushButton(parent,res,al,ac));
    switch (i) {
    case 6:
      XtAddCallback(b,XmNdisarmCallback,CmFileOpenB,NULL);
      break;
    case 7:
      XtAddCallback(b,XmNdisarmCallback,CmGraphLoadB,NULL);
      break;
    case 8:
      XtAddCallback(b,XmNdisarmCallback,CmGraphSaveB,NULL);
      break;
    case 9:
      XtAddCallback(b,XmNdisarmCallback,CmAxisClear,NULL);
      break;
    case 10:
      XtAddCallback(b,XmNdisarmCallback,CmViewerDrawB,NULL);
      break;
    case 11:
      XtAddCallback(b,XmNdisarmCallback,CmViewerClearB,NULL);
      break;
    case 12:
      XtAddCallback(b,XmNdisarmCallback,CmOutputDriverB,NULL);
      break;
    case 13:
      XtAddCallback(b,XmNdisarmCallback,CmOutputViewerB,NULL);
      break;
    }
    XtAddEventHandler(b,EnterWindowMask | LeaveWindowMask,
                      False,TipCallback,NULL);
  }
  ac=0;
  XtSetArg(al[ac],XmNwidth,10); ac++;
  XtManageChild(XmCreateDrawingArea(parent,NULL,al,ac));

  for (i=14;i<16;i++) {
    ac=0;
    XtSetArg(al[ac],XmNlabelType,XmPIXMAP); ac++;
    XtSetArg(al[ac],XmNlabelPixmap,NgraphApp.com1pix[i]); ac++;
    XtSetArg(al[ac],XmNmarginWidth,0); ac++;
    XtSetArg(al[ac],XmNmarginHeight,0); ac++;
    XtSetArg(al[ac],XmNmarginTop,0); ac++;
    XtSetArg(al[ac],XmNmarginBottom,0); ac++;
    XtSetArg(al[ac],XmNmarginLeft,0); ac++;
    XtSetArg(al[ac],XmNmarginRight,0); ac++;
    sprintf(res,"button_%d",i);
    XtManageChild(b=XmCreatePushButton(parent,res,al,ac));
    switch (i) {
    case 14:
      XtAddCallback(b,XmNdisarmCallback,CmFileWinMath,NULL);
      break;
    case 15:
      XtAddCallback(b,XmNdisarmCallback,CmAxisWinScaleUndo,NULL);
      break;
    }
    XtAddEventHandler(b,EnterWindowMask | LeaveWindowMask,
                      False,TipCallback,NULL);
  }
  ac=0;
  XtSetArg(al[ac],XmNwidth,10); ac++;
  XtManageChild(XmCreateDrawingArea(parent,NULL,al,ac));

  i=16;
  ac=0;
  XtSetArg(al[ac],XmNlabelType,XmPIXMAP); ac++;
  XtSetArg(al[ac],XmNlabelPixmap,NgraphApp.com1pix[16]); ac++;
  XtSetArg(al[ac],XmNmarginWidth,0); ac++;
  XtSetArg(al[ac],XmNmarginHeight,0); ac++;
  XtSetArg(al[ac],XmNmarginTop,0); ac++;
  XtSetArg(al[ac],XmNmarginBottom,0); ac++;
  XtSetArg(al[ac],XmNmarginLeft,0); ac++;
  XtSetArg(al[ac],XmNmarginRight,0); ac++;
  sprintf(res,"button_%d",i);
  XtManageChild(NgraphApp.interrupt=XmCreatePushButton(parent,res,al,ac)); 
  XtAddEventHandler(NgraphApp.interrupt,EnterWindowMask | LeaveWindowMask,
                    False,TipCallback,NULL);
}

void createcommand2(Widget parent)
{
  Arg al[20];
  Cardinal ac;
  int i;
  char res[128];

  for (i=0;i<19;i++) {
    ac=0;
    XtSetArg(al[ac],XmNindicatorOn,0); ac++; 
    XtSetArg(al[ac],XmNindicatorType,XmONE_OF_MANY); ac++;
    XtSetArg(al[ac],XmNlabelType,XmPIXMAP); ac++; 
    XtSetArg(al[ac],XmNselectPixmap,NgraphApp.com2pix[i][0]); ac++;
    XtSetArg(al[ac],XmNlabelPixmap,NgraphApp.com2pix[i][1]); ac++;
    XtSetArg(al[ac],XmNmarginWidth,0); ac++;
    XtSetArg(al[ac],XmNmarginHeight,0); ac++;
    XtSetArg(al[ac],XmNmarginTop,0); ac++;
    XtSetArg(al[ac],XmNmarginBottom,0); ac++;
    XtSetArg(al[ac],XmNmarginLeft,0); ac++;
    XtSetArg(al[ac],XmNmarginRight,0); ac++;
    XtSetArg(al[ac],XmNbackground,white); ac++;
    XtSetArg(al[ac],XmNforeground,black); ac++;
    if (i==0) XtSetArg(al[ac],XmNset,XmSET);
    else XtSetArg(al[ac],XmNset,XmUNSET);
    ac++; 
    sprintf(res,"button_%d",i);
    XtManageChild(NgraphApp.viewb[i]=XmCreateToggleButton(parent,res,al,ac));
    XtAddCallback(NgraphApp.viewb[i],XmNarmCallback,CmViewerButtonArm,NULL);
    XtAddEventHandler(NgraphApp.viewb[i],EnterWindowMask | LeaveWindowMask,
                      False,TipCallback,NULL);
  }
}

int createcolormap()
{
  int depth;
  Colormap cmap;

  depth=mxlocal->cdepth;
#ifdef PRIVATECOLOR
  cmap=XCreateColormap(Disp,RootWindow(Disp,0),
                       DefaultVisual(Disp,0),AllocNone);
#else
  cmap=DefaultColormap(Disp,0);
#endif
  mxlocal->cmap=cmap;
  return TRUE;
}

void setupwindow()
{
  Widget menubar,rowcolumn,command1,commandframe,command2;
  Widget msgrc,msgframe,msgform;
  Arg al[20];
  Cardinal ac;

  ac=0;
  XtSetArg(al[ac],XmNshowSeparator,True); ac++; 
  XtSetArg(al[ac],XmNscrollBarDisplayPolicy,XmSTATIC); ac++;
  XtSetArg(al[ac],XmNcommandWindowLocation,XmCOMMAND_ABOVE_WORKSPACE); ac++;
  XtManageChild(MainWin=XmCreateMainWindow(TopLevel,"mainwin",al,ac));
  ac=0;
  NgraphApp.Viewer.Win=XmCreateDrawingArea(MainWin,"viewer",al,ac);
  XtManageChild(NgraphApp.Viewer.Win); 

  menubar=XmVaCreateSimpleMenuBar(MainWin,"menubar",
         XmVaCASCADEBUTTON,NULL,NULL,
         XmVaCASCADEBUTTON,NULL,NULL,
         XmVaCASCADEBUTTON,NULL,NULL,
         XmVaCASCADEBUTTON,NULL,NULL,
         XmVaCASCADEBUTTON,NULL,NULL,
         XmVaCASCADEBUTTON,NULL,NULL,
         XmVaCASCADEBUTTON,NULL,NULL,
         XmVaCASCADEBUTTON,NULL,NULL,
         XmVaCASCADEBUTTON,NULL,NULL,
         NULL);
  XtManageChild(menubar);
  XtVaSetValues(menubar,XmNmenuHelpWidget,
                XtNameToWidget(menubar,"*button_8"),NULL);

  createmenu(menubar);
  if (menulocal.movechild)
    XmToggleButtonSetState(XtNameToWidget(TopLevel,"*windowmenu.button_7"),
                           True,False);
  else
    XmToggleButtonSetState(XtNameToWidget(TopLevel,"*windowmenu.button_7"),
                           False,False);

  if (menulocal.statusb)
    XmToggleButtonSetState(XtNameToWidget(TopLevel,"*windowmenu.button_8"),
                           True,False);
  else
    XmToggleButtonSetState(XtNameToWidget(TopLevel,"*windowmenu.button_8"),
                           False,False);

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

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

  createcommand1(command1);

  ac=0;
  XtManageChild(commandframe=XmCreateFrame(rowcolumn,"commandframe",al,ac));
  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  command2=XmCreateRadioBox(commandframe,"command2",al,ac);
  XtManageChild(command2);

  createcommand2(command2);

  ac=0;
  NgraphApp.Message=msgrc=XmCreateRowColumn(MainWin,NULL,al,ac);
  if (menulocal.statusb) XtManageChild(msgrc);
  ac=0;
  msgframe=XmCreateFrame(msgrc,NULL,al,ac);
  XtManageChild(msgframe);
  ac=0;
  msgform=XmCreateForm(msgframe,NULL,al,ac);
  XtManageChild(msgform);

  ac=0;
  XtSetArg(al[ac],XmNtopAttachment,XmATTACH_FORM); ac++;
  XtSetArg(al[ac],XmNbottomAttachment,XmATTACH_FORM); ac++;
  XtSetArg(al[ac],XmNleftAttachment,XmATTACH_POSITION); ac++;
  XtSetArg(al[ac],XmNleftPosition,0); ac++;
  XtSetArg(al[ac],XmNrightAttachment,XmATTACH_POSITION); ac++;
  XtSetArg(al[ac],XmNrightPosition,70); ac++;
  XtSetArg(al[ac],XmNrightOffset,2); ac++;
  XtSetArg(al[ac],XmNleftOffset,2); ac++;
  XtSetArg(al[ac],XmNalignment,XmALIGNMENT_BEGINNING); ac++;
  XtSetArg(al[ac],XmNresizable,FALSE); ac++;
  NgraphApp.Message1=XmCreateLabel(msgform," ",al,ac);
  XtManageChild(NgraphApp.Message1);
  ac=0;
  XtSetArg(al[ac],XmNtopAttachment,XmATTACH_FORM); ac++;
  XtSetArg(al[ac],XmNbottomAttachment,XmATTACH_FORM); ac++;
  XtSetArg(al[ac],XmNleftAttachment,XmATTACH_POSITION); ac++;
  XtSetArg(al[ac],XmNleftPosition,70); ac++;
  XtSetArg(al[ac],XmNrightOffset,2); ac++;
  XtSetArg(al[ac],XmNleftOffset,2); ac++;
  XtSetArg(al[ac],XmNrightAttachment,XmATTACH_POSITION); ac++;
  XtSetArg(al[ac],XmNrightPosition,80); ac++;
  XtSetArg(al[ac],XmNalignment,XmALIGNMENT_BEGINNING); ac++;
  XtSetArg(al[ac],XmNresizable,FALSE); ac++;
  NgraphApp.Message2=XmCreateLabel(msgform," ",al,ac);
  XtManageChild(NgraphApp.Message2);
  ac=0;
  XtSetArg(al[ac],XmNtopAttachment,XmATTACH_FORM); ac++;
  XtSetArg(al[ac],XmNbottomAttachment,XmATTACH_FORM); ac++;
  XtSetArg(al[ac],XmNleftAttachment,XmATTACH_POSITION); ac++;
  XtSetArg(al[ac],XmNleftPosition,80); ac++;
  XtSetArg(al[ac],XmNrightOffset,2); ac++;
  XtSetArg(al[ac],XmNleftOffset,2); ac++;
  XtSetArg(al[ac],XmNrightAttachment,XmATTACH_POSITION); ac++;
  XtSetArg(al[ac],XmNrightPosition,100); ac++;
  XtSetArg(al[ac],XmNalignment,XmALIGNMENT_BEGINNING); ac++;
  XtSetArg(al[ac],XmNresizable,FALSE); ac++;
  NgraphApp.Message3=XmCreateLabel(msgform," ",al,ac);
  XtManageChild(NgraphApp.Message3);

  ac=0;
  XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
  NgraphApp.Viewer.HScroll=XmCreateScrollBar(MainWin,NULL,al,ac);
  XtManageChild(NgraphApp.Viewer.HScroll);
  ac=0;
  XtSetArg(al[ac],XmNorientation,XmVERTICAL); ac++;
  NgraphApp.Viewer.VScroll=XmCreateScrollBar(MainWin,NULL,al,ac);
  XtManageChild(NgraphApp.Viewer.VScroll);

  XmMainWindowSetAreas(MainWin,menubar,rowcolumn,
                       NgraphApp.Viewer.HScroll,
                       NgraphApp.Viewer.VScroll,
                       NgraphApp.Viewer.Win); 
  XtVaSetValues(MainWin,XmNmessageWindow,msgrc,NULL); 

}

void defaultwindowconfig()
{
  int w,h;

  w=WidthOfScreen(DefaultScreenOfDisplay(Disp));
  h=w/2*1.2;
  if (menulocal.fileopen) {
    if (menulocal.filewidth==CW_USEDEFAULT) menulocal.filewidth=w/4;
    if (menulocal.fileheight==CW_USEDEFAULT) menulocal.fileheight=h/4;
    if (menulocal.filex==CW_USEDEFAULT) menulocal.filex=-menulocal.filewidth
                                                      -menulocal.framex*2-4;
    if (menulocal.filey==CW_USEDEFAULT) menulocal.filey=0;
  }
  if (menulocal.axisopen) {
    if (menulocal.axiswidth==CW_USEDEFAULT) menulocal.axiswidth=w/4;
    if (menulocal.axisheight==CW_USEDEFAULT) menulocal.axisheight=h/4;
    if (menulocal.axisx==CW_USEDEFAULT) menulocal.axisx=-menulocal.axiswidth
                                                     -menulocal.framex*2-4;
    if (menulocal.axisy==CW_USEDEFAULT) menulocal.axisy=menulocal.fileheight
                                                       +menulocal.framey+4;
  }
  if (menulocal.coordopen) {
    if (menulocal.coordwidth==CW_USEDEFAULT) menulocal.coordwidth=w/4;
    if (menulocal.coordheight==CW_USEDEFAULT) menulocal.coordheight=h/4;
    if (menulocal.coordx==CW_USEDEFAULT) 
      menulocal.coordx=-menulocal.coordwidth-menulocal.framex*2-4;
    if (menulocal.coordy==CW_USEDEFAULT) 
      menulocal.coordy=menulocal.fileheight+menulocal.axisheight
                                           +menulocal.framey*2+8;
  }
}

void application(char *file)
{
  int i;
  char *ext;
  struct objlist *aobj;
  Arg al[20];
  Cardinal ac;
  Atom xa_wm_delete;
  XColor col,exact;
  int x,y,width,height,w,h;
  char geometry[50];
  Atom importList[2];

  if (TopLevel==NULL) {

    w=WidthOfScreen(DefaultScreenOfDisplay(Disp));
    h=HeightOfScreen(DefaultScreenOfDisplay(Disp));
    if (menulocal.menux==CW_USEDEFAULT) menulocal.menux=w*3/8;
    if (menulocal.menuy==CW_USEDEFAULT) menulocal.menuy=h/8;
    if (menulocal.menuwidth==CW_USEDEFAULT) menulocal.menuwidth=w/2;
    if (menulocal.menuheight==CW_USEDEFAULT) menulocal.menuheight=w*1.2/2;

    x=menulocal.menux;
    y=menulocal.menuy;
    width=menulocal.menuwidth;
    height=menulocal.menuheight;
    ac=0;
    XtSetArg(al[ac],XmNborderWidth,1);ac++;
    XtSetArg(al[ac],XmNdefaultPosition,False); ac++;
    XtSetArg(al[ac],XmNx,x); ac++;
    XtSetArg(al[ac],XmNy,y); ac++;
    XtSetArg(al[ac],XmNheight,height); ac++;
    XtSetArg(al[ac],XmNwidth,width); ac++;
    sprintf(geometry,"%dx%d+%d+%d",width,height,x,y);
    XtSetArg(al[ac],XmNgeometry,geometry); ac++;
    TopLevel=XtAppCreateShell(AppName,AppClass,applicationShellWidgetClass,
                              Disp,al,ac);
    XtGetApplicationResources(TopLevel,&resources,Res,XtNumber(Res),NULL,0);

    XtVaSetValues(TopLevel,XmNdeleteResponse,XmDO_NOTHING,NULL);
    xa_wm_delete=XmInternAtom(Disp,"WM_DELETE_WINDOW",False);
    XmAddWMProtocolCallback(TopLevel,xa_wm_delete,CloseCallback,NULL);
    NgraphClose=XInternAtom(Disp,CloseMessage,FALSE);

    if (!setwindowfont()) {
      error(menulocal.obj,ERRFONT);
    }
    if (!createcolormap(Disp)) {
      error(menulocal.obj,ERRCMAP);
    }
    black=BlackPixel(Disp,0);
    white=WhitePixel(Disp,0);
    XAllocNamedColor(Disp,mxlocal->cmap,"gray",&col,&exact);
    gray=col.pixel;
    XAllocNamedColor(Disp,mxlocal->cmap,"red",&col,&exact);
    red=col.pixel;
    XAllocNamedColor(Disp,mxlocal->cmap,"blue",&col,&exact);
    blue=col.pixel;

    createicon(RootWindow(Disp,0));
    XtVaSetValues(TopLevel,XmNiconPixmap,NgraphApp.iconpix,NULL);

    createpixmap1(RootWindow(Disp,0));
    createpixmap2(RootWindow(Disp,0));
    createmarkpixmap(RootWindow(Disp,0));
    createcursor(Disp);

    NgraphApp.Viewer.Win=NULL;
    NgraphApp.FileWin.Win=NULL;
    NgraphApp.AxisWin.Win=NULL;
    NgraphApp.LegendWin.Win=NULL;
    NgraphApp.MergeWin.Win=NULL;
    NgraphApp.InfoWin.Win=NULL;
    NgraphApp.InfoWin.str=NULL;
    NgraphApp.CoordWin.Win=NULL;
    NgraphApp.CoordWin.str=NULL;

    initdialog();
    setupwindow();

    COMPOUND_TEXT=XmInternAtom(Disp,"COMPOUND_TEXT",False);
    importList[0]=COMPOUND_TEXT;
    ac=0;
    XtSetArg(al[ac],XmNimportTargets,importList);ac++;
    XtSetArg(al[ac],XmNnumImportTargets,1); ac++;
    XtSetArg(al[ac],XmNdropSiteOperations,XmDROP_COPY); ac++;
    XtSetArg(al[ac],XmNdropProc,DropHandle); ac++;
    XmDropSiteRegister(MainWin,al,ac);

  }

  XtRealizeWidget(TopLevel);
  XSetWindowColormap(XtDisplay(TopLevel),XtWindow(TopLevel),mxlocal->cmap);

  if ((menulocal.framex==0) && (menulocal.framey==0)) GetWMFrame(TopLevel);
  defaultwindowconfig();

  XtAddEventHandler(TopLevel,StructureNotifyMask,False,EvMove,NULL);

  putstderr=mx11putstderr;
  printfstderr=mx11printfstderr;
  ndisplaydialog=mx11displaydialog;
  ndisplaystatus=mx11displaystatus;
  ninterrupt=mx11interrupt;
  inputyn=mx11inputyn;

  ViewerWinSetup(); 
  SetCaption(NULL);
  SetCursor(XC_left_ptr);

  NgraphApp.Changed=FALSE;
  NgraphApp.FileName=NULL;

  ResetEvent();

  if (menulocal.dialogopen) CmInformationWindow(NULL,NULL,NULL);
  if (menulocal.coordopen) CmCoordinateWindow(NULL,NULL,NULL);
  if (menulocal.mergeopen) CmMergeWindow(NULL,NULL,NULL);
  if (menulocal.legendopen) CmLegendWindow(NULL,NULL,NULL);
  if (menulocal.axisopen) CmAxisWindow(NULL,NULL,NULL);
  if (menulocal.fileopen) CmFileWindow(NULL,NULL,NULL);

  if ((aobj=getobject("axis"))!=NULL) {
    for (i=0;i<=chkobjlastinst(aobj);i++) exeobj(aobj,"tight",i,0,NULL);
  }
  if ((aobj=getobject("axisgrid"))!=NULL) {
    for (i=0;i<=chkobjlastinst(aobj);i++) exeobj(aobj,"tight",i,0,NULL);
  }
  if (file!=NULL) {
    if ((ext=getextention(file))!=NULL) {
      if ((strcmp0(ext,"PRM")==0) || (strcmp0(ext,"prm")==0))
        LoadPrmFile(file); 
      else if ((strcmp0(ext,"NGP")==0) || (strcmp0(ext,"ngp")==0))
        LoadNgpFile(file,menulocal.ignorepath,menulocal.expand,
                         menulocal.expanddir,FALSE,NULL);
    }
  }

  CmViewerDrawB(NgraphApp.Viewer.Win,NULL,NULL);

  arrayinit(&childlist,sizeof(pid_t));
  signaltrap=TRUE;
  signal(SIGCHLD,childhandler); 

  RegisterWorkProc=FALSE;
  AppMainLoop(Application); 
  if (RegisterWorkProc) {
    XtRemoveWorkProc(WorkProcId);
    RegisterWorkProc=FALSE;
  }

  signaltrap=FALSE;
  arraydel(&childlist);

  ViewerWinClose();
  InfoWinUnmap(NULL,NULL,NULL);
  CoordWinUnmap(NULL,NULL,NULL);
  MergeWindowUnmap(NULL,NULL,NULL);
  LegendWindowUnmap(NULL,NULL,NULL);
  AxisWindowUnmap(NULL,NULL,NULL);
  FileWindowUnmap(NULL,NULL,NULL);

  memfree(NgraphApp.InfoWin.str);
  NgraphApp.InfoWin.str=NULL;
  memfree(NgraphApp.CoordWin.str);
  NgraphApp.CoordWin.str=NULL;
  memfree(NgraphApp.FileName);
  NgraphApp.FileName=NULL;

  XtUnrealizeWidget(TopLevel);
  ResetEvent();
}

void UpdateAll()
{
  ViewerWinUpdate(TRUE);
  FileWinUpdate(TRUE);
  AxisWinUpdate(TRUE);
  LegendWinUpdate(TRUE);
  MergeWinUpdate(TRUE);
  InfoWinUpdate(TRUE);
  CoordWinUpdate(TRUE);  
}

void UpdateAll2()
{
  FileWinUpdate(TRUE);
  AxisWinUpdate(TRUE);
  LegendWinUpdate(TRUE);
  MergeWinUpdate(TRUE);
  InfoWinUpdate(TRUE);
  CoordWinUpdate(TRUE);  
}

void ChangePage()
{
  CloseGC();
  CloseGRA();
  OpenGRA();
  OpenGC(); 
  SetScroller();
  ChangeDPI(TRUE);
}

void SetPoint(int x,int y)
{
  char buf[40];
  XmString s;

  sprintf(buf,"X:%d Y:%d",x,y);
  s=XmStringCreate(buf,XmFONTLIST_DEFAULT_TAG);
  XtVaSetValues(NgraphApp.Message3,XmNlabelString,s,NULL);
  XmStringFree(s);
  XClearArea(Disp,XtWindow(NgraphApp.Message3),0,0,0,0,TRUE);
  XmUpdateDisplay(NgraphApp.Message3);
}  

void SetZoom(double zm)
{
  char buf[20];
  XmString s;

  sprintf(buf,"%.2f%%",zm*100);
  s=XmStringCreate(buf,XmFONTLIST_DEFAULT_TAG);
  XtVaSetValues(NgraphApp.Message2,XmNlabelString,s,NULL);
  XmStringFree(s);
  XClearArea(Disp,XtWindow(NgraphApp.Message2),0,0,0,0,TRUE);
  XmUpdateDisplay(NgraphApp.Message2);
}  

void ResetZoom()
{
  XmString s;

  s=XmStringCreate(" ",XmFONTLIST_DEFAULT_TAG);
  XtVaSetValues(NgraphApp.Message2,XmNlabelString,s,NULL);
  XmStringFree(s);
  XClearArea(Disp,XtWindow(NgraphApp.Message2),0,0,0,0,TRUE);
  XmUpdateDisplay(NgraphApp.Message2);
}

void SetStatusBar(char *mes)
{
  XmString s;

  s=XmStringCreate(mes,XmFONTLIST_DEFAULT_TAG);
  XtVaSetValues(NgraphApp.Message1,XmNlabelString,s,NULL);
  XmStringFree(s);
  XClearArea(Disp,XtWindow(NgraphApp.Message1),0,0,0,0,TRUE);
  XmUpdateDisplay(NgraphApp.Message1);
}

void SetStatusBarXm(XmString s)
{
  XtVaSetValues(NgraphApp.Message1,XmNlabelString,s,NULL);
  XClearArea(Disp,XtWindow(NgraphApp.Message1),0,0,0,0,TRUE);
  XmUpdateDisplay(NgraphApp.Message1);
}

void ResetStatusBar()
{
  XmString s;

  s=XmStringCreate(" ",XmFONTLIST_DEFAULT_TAG);
  XtVaSetValues(NgraphApp.Message1,XmNlabelString,s,NULL);
  XmStringFree(s);
  XClearArea(Disp,XtWindow(NgraphApp.Message1),0,0,0,0,TRUE);
  XmUpdateDisplay(NgraphApp.Message1);
}

void SetCaption(char *file)
{
  char *fullpath;
  char *buf;
  int len;

  if (file==NULL) {
    fullpath=NULL;
    len=0;
  } else {
    fullpath=getfullpath(file);
    len=strlen(fullpath);
  }
  if ((buf=memalloc(len+10))!=NULL) {
    strcpy(buf,"Ngraph");
    if (fullpath!=NULL) {
      strcat(buf,": ");
      strcat(buf,fullpath);
    }
    XtVaSetValues(TopLevel,XmNtitle,buf,NULL);
  }
  memfree(fullpath);
}

void SetCursor(unsigned int type)
{
  struct Viewer *d;
  Window win;

  d=&(NgraphApp.Viewer);
  win=XtWindow(d->Win);
  XUndefineCursor(Disp,win);
  switch (type) {
  case XC_left_ptr:
    XDefineCursor(Disp,win,NgraphApp.cursor[0]);
    break;
  case XC_xterm:
    XDefineCursor(Disp,win,NgraphApp.cursor[1]);
    break;
  case XC_crosshair:
    XDefineCursor(Disp,win,NgraphApp.cursor[2]);
    break;
  case XC_top_left_corner:
    XDefineCursor(Disp,win,NgraphApp.cursor[3]);
    break;
  case XC_top_right_corner:
    XDefineCursor(Disp,win,NgraphApp.cursor[4]);
    break;
  case XC_bottom_right_corner:
    XDefineCursor(Disp,win,NgraphApp.cursor[5]);
    break;
  case XC_bottom_left_corner:
    XDefineCursor(Disp,win,NgraphApp.cursor[6]);
    break;
  case XC_centering:
    XDefineCursor(Disp,win,NgraphApp.cursor[7]);
    break;
  case XC_zoomin:
    XDefineCursor(Disp,win,NgraphApp.cursor[8]);
    break;
  case XC_zoomout:
    XDefineCursor(Disp,win,NgraphApp.cursor[9]);
    break;
  case XC_watch:
    XDefineCursor(Disp,win,NgraphApp.cursor[10]);
    break;
  }
}

void DisplayDialog(char *str)
{
  memfree(NgraphApp.InfoWin.str);
  NgraphApp.InfoWin.str=memalloc(strlen(str)+1);
  if (NgraphApp.InfoWin.str!=NULL)
    strcpy(NgraphApp.InfoWin.str,str);
  InfoWinDrawInfoText();
}

void DisplayStatus(char *str)
{
  SetStatusBar(str);
}

int PutStderr(char *s)
{
  int len;

  MessageBox(TopLevel,s,"Error:",MB_OK);
  UpdateAll2();
  len=strlen(s);
  return len+1;
}

int ChkInterrupt()
{
  XEvent event;
  XKeyEvent *e;
  KeySym sym;

  while (TRUE) {
    if (XCheckTypedEvent(Disp,KeyPress,&event)) {
      e=(XKeyEvent *)&event;
      sym=XKeycodeToKeysym(Disp,e->keycode,0);
      if (sym==XK_Escape) {
        NgraphApp.Interrupt=TRUE;
        break;
      }
    }
    if (XCheckTypedWindowEvent(Disp,XtWindow(NgraphApp.interrupt),ButtonPress,
                               &event)) {
      NgraphApp.Interrupt=TRUE;
      break;
    } else break;
  }
  if (NgraphApp.Interrupt) {
    NgraphApp.Interrupt=FALSE;
    return TRUE;
  }
  return FALSE;
}

int InputYN(char *mes)
{
  int ret;

  ret=MessageBox(TopLevel,mes,"Question",MB_YESNO);
  UpdateAll2();
  return (ret==IDYES)?TRUE:FALSE;
}

void CmReloadWindowConfig()
{
  Position x,y;
  Dimension w0,h0;

  if (NgraphApp.FileWin.Win!=NULL) CmFileWindow(NULL,NULL,NULL);
  if (NgraphApp.AxisWin.Win!=NULL) CmAxisWindow(NULL,NULL,NULL);
  if (NgraphApp.LegendWin.Win!=NULL) CmLegendWindow(NULL,NULL,NULL);
  if (NgraphApp.MergeWin.Win!=NULL) CmMergeWindow(NULL,NULL,NULL);
  if (NgraphApp.InfoWin.Win!=NULL) CmInformationWindow(NULL,NULL,NULL);
  if (NgraphApp.CoordWin.Win!=NULL) CmCoordinateWindow(NULL,NULL,NULL);
  ResetEvent();
  initwindowconfig();
  mx11windowconfig();
  XtVaGetValues(MainWin,
                XmNx,&x,XmNy,&y,
                XmNwidth,&w0,XmNheight,&h0,NULL);
  menulocal.menux=x;
  menulocal.menuy=y;
  menulocal.menuwidth=w0;
  menulocal.menuheight=h0;
  defaultwindowconfig();
  if (menulocal.dialogopen) CmInformationWindow(NULL,NULL,NULL);
  if (menulocal.coordopen) CmCoordinateWindow(NULL,NULL,NULL);
  if (menulocal.mergeopen) CmMergeWindow(NULL,NULL,NULL);
  if (menulocal.legendopen) CmLegendWindow(NULL,NULL,NULL);
  if (menulocal.axisopen) CmAxisWindow(NULL,NULL,NULL);
  if (menulocal.fileopen) CmFileWindow(NULL,NULL,NULL);
}

void CmMoveChildWindow()
{
  if (menulocal.movechild) menulocal.movechild=FALSE;
  else menulocal.movechild=TRUE;
}

void CmStatusBar()
{
  if (menulocal.statusb) {
    menulocal.statusb=FALSE;
    XtUnmanageChild(NgraphApp.Message);
  } else {
    menulocal.statusb=TRUE;
    XtManageChild(NgraphApp.Message);
  }
}


void CmWindowMenu(Widget w,XtPointer client_data,XtPointer call_data)
{
  switch ((int )client_data) {
  case 0:
    CmFileWindow(NULL,NULL,NULL);
    break;
  case 1:
    CmAxisWindow(NULL,NULL,NULL);
    break;
  case 2:
    CmLegendWindow(NULL,NULL,NULL);
    break;
  case 3:
    CmMergeWindow(NULL,NULL,NULL);
    break;
  case 4:
    CmCoordinateWindow(NULL,NULL,NULL);
    break;
  case 5:
    CmInformationWindow(NULL,NULL,NULL);
    break;
  case 6:
    CmReloadWindowConfig();
    break;
  case 7:
    CmMoveChildWindow();
    break;
  case 8:
    CmStatusBar();
    break;
  }
}
