1 /*
2  * $Id: x11view.c,v 1.10 2005/11/06 14:39:37 isizaka Exp isizaka $
3  *
4  * This file is part of "Ngraph for X11".
5  *
6  * Copyright (C) 2002, Satoshi ISHIZAKA. isizaka@msa.biglobe.ne.jp
7  *
8  * "Ngraph for X11" is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * as published by the Free Software Foundation; either version 2
11  * of the License, or (at your option) any later version.
12  *
13  * "Ngraph for X11" is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
21  *
22  */
23 
24 /**
25  *
26  * $Log: x11view.c,v $
27  * Revision 1.10  2005/11/06 14:39:37  isizaka
28  * round error about zooming is fixed (thanks to Mr. tanaka)
29  *
30  * Revision 1.9  2003/02/16 12:43:37  isizaka
31  * for release 6.13.18
32  *
33  * Revision 1.8  2002/07/06 08:57:25  isizaka
34  * change to GPL.
35  *
36  * Revision 1.7  2001/07/14 17:44:50  isizaka
37  * for 6.03.14
38  *
39  * Revision 1.6  2001/03/23 12:17:43  isizaka
40  * for 6.3.13
41  *
42  * Revision 1.5  2000/11/11 07:01:28  isizaka
43  * Zooming rate: 2 --> sqrt(2)
44  *
45  * Revision 1.4  1999/04/15 12:14:26  isizaka
46  * for release 6.03.01
47  *
48  * Revision 1.3  1999/04/11 06:09:20  isizaka
49  * *** empty log message ***
50  *
51  * Revision 1.2  1999/03/21 12:51:18  isizaka
52  * change axis initialization
53  *
54  * Revision 1.1  1999/03/17 13:29:01  isizaka
55  * Initial revision
56  *
57  *
58  **/
59 
60 #include <Xm/XmAll.h>
61 #include <X11/keysym.h>
62 #include <X11/cursorfont.h>
63 #include <math.h>
64 
65 #include "motif12.h"
66 
67 #include "ngraph.h"
68 #include "object.h"
69 #include "gra.h"
70 #include "mathfn.h"
71 
72 #include "x11gui.h"
73 #include "x11dialg.h"
74 #include "ox11menu.h"
75 #include "x11menu.h"
76 #include "x11graph.h"
77 #include "x11file.h"
78 #include "x11axis.h"
79 #include "x11cood.h"
80 #include "x11lgnd.h"
81 #include "x11view.h"
82 #include "x11commn.h"
83 
84 struct focuslist {
85   struct objlist *obj;
86   int oid;
87   int ofsx,ofsy;
88 };
89 
90 struct pointslist {
91   int x,y;
92 };
93 
94 #define MOUSENONE 0
95 #define MOUSEPOINT 1
96 #define MOUSEDRAG  2
97 #define MOUSEZOOM1 3
98 #define MOUSEZOOM2 4
99 #define MOUSEZOOM3 5
100 #define MOUSEZOOM4 6
101 #define MOUSECHANGE 7
102 
103 #define PointB 0
104 #define LegendB 1
105 #define LineB 2
106 #define CurveB 3
107 #define PolyB 4
108 #define RectB 5
109 #define ArcB 6
110 #define MarkB 7
111 #define TextB 8
112 #define GaussB 9
113 #define AxisB 10
114 #define TrimB 11
115 #define FrameB 12
116 #define SectionB 13
117 #define CrossB 14
118 #define SingleB 15
119 #define DataB 16
120 #define EvalB 17
121 #define ZoomB 18
122 
123 Region region=NULL;
124 int PaintLock=FALSE;
125 
126 struct evaltype evallist[100];
127 struct narray sellist;
128 char evbuf[256];
129 
130 #define IDEVMASK        101
131 #define IDEVMOVE        102
132 
EvalDialogSetupItem(Widget w,struct EvalDialog * d)133 void EvalDialogSetupItem(Widget w,struct EvalDialog *d)
134 {
135   int i,j;
136   XmString xs;
137 
138   XmListDeleteAllItems(XtNameToWidget(w,"*list"));
139   for (i=0;i<d->Num;i++) {
140     j=0;
141     j+=sprintf(evbuf+j,"%6d ",evallist[i].id);
142     j+=sprintf(evbuf+j,"%8d ",evallist[i].line);
143     j+=sprintf(evbuf+j,"%+.15e %+.15e",evallist[i].x,evallist[i].y);
144     xs=XmStringCreateLocalized(evbuf);
145     XmListAddItem(XtNameToWidget(w,"*list"),xs,0);
146     XmStringFree(xs);
147   }
148 }
149 
EvalDialogMask(Widget w,XtPointer client_data,XtPointer call_data)150 void EvalDialogMask(Widget w,XtPointer client_data,XtPointer call_data)
151 {
152   struct EvalDialog *d;
153 
154   d=(struct EvalDialog *)client_data;
155   d->ret=IDEVMASK;
156   d->CloseWindow(d->widget,client_data);
157 }
158 
EvalDialogMove(Widget w,XtPointer client_data,XtPointer call_data)159 void EvalDialogMove(Widget w,XtPointer client_data,XtPointer call_data)
160 {
161   struct EvalDialog *d;
162 
163   d=(struct EvalDialog *)client_data;
164   d->ret=IDEVMOVE;
165   d->CloseWindow(d->widget,client_data);
166 }
167 
EvalDialogSetup(Widget w,void * data,int makewidget)168 void EvalDialogSetup(Widget w,void *data,int makewidget)
169 {
170   Arg al[20];
171   Cardinal ac;
172   Widget rc,button;
173   struct EvalDialog *d;
174 
175   d=(struct EvalDialog *)data;
176   if (makewidget) {
177     XtUnmanageChild(XmMessageBoxGetChild(w,XmDIALOG_CANCEL_BUTTON));
178     ac=0;
179     XtManageChild(button=XmCreatePushButton(w,"Mask",al,ac));
180     XtAddCallback(button,XmNdisarmCallback,EvalDialogMask,d);
181     ac=0;
182     XtManageChild(button=XmCreatePushButton(w,"Move",al,ac));
183     XtAddCallback(button,XmNdisarmCallback,EvalDialogMove,d);
184 
185     ac=0;
186     XtSetArg(al[ac],XmNorientation,XmVERTICAL); ac++;
187     XtManageChild(rc=XmCreateRowColumn(w,"rc",al,ac));
188     ac=0;
189     XtManageChild(XmCreateLabel(rc,
190                   "--#--Line----------X----------------Y----------",al,ac));
191     ac=0;
192     XtSetArg(al[ac],XmNlistSizePolicy,XmCONSTANT); ac++;
193     XtSetArg(al[ac],XmNscrollBarDisplayPolicy,XmSTATIC); ac++;
194     XtSetArg(al[ac],XmNselectionPolicy,XmEXTENDED_SELECT); ac++;
195     XtManageChild(XmCreateScrolledList(rc,"list",al,ac));
196   }
197   EvalDialogSetupItem(w,d);
198 }
199 
EvalDialogClose(Widget w,void * data)200 void EvalDialogClose(Widget w,void *data)
201 {
202   struct EvalDialog *d;
203   int i,a,num;
204   int *selected;
205 
206   d=(struct EvalDialog *)data;
207   if ((d->ret==IDEVMASK) || (d->ret==IDEVMOVE)) {
208     XmListGetSelectedPos(XtNameToWidget(w,"*list"),&selected,&num);
209     if (num!=0) {
210       for (i=0;i<num;i++) {
211         a=selected[i]-1;
212         arrayadd(d->sel,&a);
213       }
214       XtFree((char *)selected);
215     }
216   }
217 }
218 
EvalDialog(struct EvalDialog * data,struct objlist * obj,int num,struct narray * iarray)219 void EvalDialog(struct EvalDialog *data,
220                 struct objlist *obj,int num,struct narray *iarray)
221 {
222   data->SetupWindow=EvalDialogSetup;
223   data->CloseWindow=EvalDialogClose;
224   data->Obj=obj;
225   data->Num=num;
226   arrayinit(iarray,sizeof(int));
227   data->sel=iarray;
228 }
229 
ViewerWinSetup()230 void ViewerWinSetup()
231 {
232   struct Viewer *d;
233   int x,y;
234   unsigned int width,height,border,depth;
235   Window root;
236   XSetWindowAttributes attr;
237 
238   d=&(NgraphApp.Viewer);
239   d->win=XtWindow(NgraphApp.Viewer.Win);
240   menulocal.GRAoid=-1;
241   menulocal.GRAinst=NULL;
242   d->Mode=PointB;
243   d->Capture=FALSE;
244   d->MoveData=FALSE;
245   d->MouseMode=MOUSENONE;
246   d->focusobj=arraynew(sizeof(struct focuslist *));
247   d->points=arraynew(sizeof(struct pointslist *));
248   d->FrameOfsX=0;
249   d->FrameOfsY=0;
250   d->LineX=0;
251   d->LineY=0;
252   d->CrossX=0;
253   d->CrossY=0;
254   d->ShowFrame=FALSE;
255   d->ShowLine=FALSE;
256   d->ShowRect=FALSE;
257   d->ShowCross=FALSE;
258   d->allclear=TRUE;
259   d->ignoreredraw=FALSE;
260   d->Mode=PointB;
261   region=NULL;
262   OpenGRA();
263   OpenGC();
264   SetScroller();
265   ChangeDPI(TRUE);
266   XGetGeometry(XtDisplay(d->Win),XtWindow(d->Win),
267                &root,&x,&y,&width,&height,&border,&depth);
268   d->width=width;
269   d->height=height;
270   d->cx=width/2;
271   d->cy=height/2;
272   XtVaSetValues(d->HScroll,XmNincrement,10,XmNminimum,0,NULL);
273   XtVaSetValues(d->VScroll,XmNincrement,10,XmNminimum,0,NULL);
274   XtVaGetValues(d->HScroll,XmNvalue,&(d->hscroll),NULL);
275   XtVaGetValues(d->VScroll,XmNvalue,&(d->vscroll),NULL);
276   XtAddCallback(d->Win,XmNexposeCallback,ViewerEvPaint,NULL);
277   XtAddCallback(d->Win,XmNresizeCallback,ViewerEvSize,NULL);
278   XtAddCallback(d->HScroll,XmNvalueChangedCallback,ViewerEvHScroll,NULL);
279   XtAddCallback(d->VScroll,XmNvalueChangedCallback,ViewerEvVScroll,NULL);
280   XtAddEventHandler(d->Win,ButtonPressMask,False,ViewerEvButtonDown,d);
281   XtAddEventHandler(d->Win,ButtonReleaseMask,False,ViewerEvButtonUp,d);
282   XtAddEventHandler(d->Win,PointerMotionMask,False,ViewerEvMouseMotion,d);
283   XtAddEventHandler(d->Win,KeyPressMask,False,ViewerEvKeyDown,d);
284   XtAddEventHandler(d->Win,KeyReleaseMask,False,ViewerEvKeyUp,d);
285   if (mxlocal->backingstore) attr.backing_store=Always;
286   else attr.backing_store=NotUseful;
287   XChangeWindowAttributes(XtDisplay(d->Win),XtWindow(d->Win),
288                           CWBackingStore,&attr);
289   d->popup=XmVaCreateSimplePopupMenu(d->Win,"viewerpopup",ViewerPopupMenu,
290     XmVaPUSHBUTTON,NULL,NULL,NULL,NULL,
291     XmVaPUSHBUTTON,NULL,NULL,NULL,NULL,
292     XmVaPUSHBUTTON,NULL,NULL,NULL,NULL,
293     XmVaPUSHBUTTON,NULL,NULL,NULL,NULL,
294     XmVaPUSHBUTTON,NULL,NULL,NULL,NULL,
295     XmVaPUSHBUTTON,NULL,NULL,NULL,NULL,
296     NULL);
297 }
298 
ViewerWinClose()299 void ViewerWinClose()
300 {
301   struct Viewer *d;
302 
303   d=&(NgraphApp.Viewer);
304   CloseGC();
305   CloseGRA();
306   arrayfree2(d->focusobj);
307   arrayfree2(d->points);
308   XUndefineCursor(XtDisplay(d->Win),XtWindow(d->Win));
309   if (region!=NULL) XDestroyRegion(region);
310 }
311 
ViewerWinFileUpdate(int x1,int y1,int x2,int y2,int err)312 int ViewerWinFileUpdate(int x1,int y1,int x2,int y2,int err)
313 {
314   struct objlist *fileobj;
315   char *argv[7];
316   struct narray *sarray;
317   char **sdata;
318   int snum;
319   struct objlist *dobj;
320   int did,id,limit;
321   char *dfield,*dinst;
322   int i,j;
323   struct narray *eval;
324   int evalnum;
325   int minx,miny,maxx,maxy;
326   struct savedstdio save;
327   char mes[256];
328   struct narray dfile;
329   int *ddata,dnum;
330   int ret,ret2;
331 
332   ret=FALSE;
333   ignorestdio(&save);
334   minx=(x1<x2)?x1:x2;
335   miny=(y1<y2)?y1:y2;
336   maxx=(x1>x2)?x1:x2;
337   maxy=(y1>y2)?y1:y2;
338   limit=1;
339   argv[0]=(char *)&minx;
340   argv[1]=(char *)&miny;
341   argv[2]=(char *)&maxx;
342   argv[3]=(char *)&maxy;
343   argv[4]=(char *)&err;
344   argv[5]=(char *)&limit;
345   argv[6]=NULL;
346   if ((fileobj=chkobject("file"))!=NULL) {
347     arrayinit(&dfile,sizeof(int));
348     sprintf(mes,"Searching for data.");
349     SetStatusBar(mes);
350     if (_getobj(menulocal.obj,"_list",menulocal.inst,&sarray)) return ret;
351     if ((snum=arraynum(sarray))==0) return ret;
352     sdata=(char **)arraydata(sarray);
353     for (i=1;i<snum;i++) {
354       if (((dobj=getobjlist(sdata[i],&did,&dfield,NULL))!=NULL)
355       && chkobjchild(fileobj,dobj)) {
356         if ((dinst=chkobjinstoid(dobj,did))!=NULL) {
357           _getobj(dobj,"id",dinst,&id);
358           _exeobj(dobj,"evaluate",dinst,6,argv);
359           _getobj(dobj,"evaluate",dinst,&eval);
360           evalnum=arraynum(eval)/3;
361           if (evalnum!=0) arrayadd(&dfile,&id);
362         }
363       }
364     }
365     ResetStatusBar();
366     dnum=arraynum(&dfile);
367     ddata=(int *)arraydata(&dfile);
368     for (i=0;i<dnum;i++) {
369       id=ddata[i];
370       FileDialog(&DlgFile,fileobj,id);
371       if ((ret2=DialogExecute(TopLevel,&DlgFile))==IDDELETE) {
372         FitDel(fileobj,id);
373         delobj(fileobj,id);
374         for (j=i+1;j<dnum;j++) if (ddata[j]>id) ddata[j]=ddata[j]-1;
375       }
376       if (ret2!=IDCANCEL) NgraphApp.Changed=TRUE;
377       ret=TRUE;
378     }
379     arraydel(&dfile);
380   }
381   restorestdio(&save);
382   return ret;
383 }
384 
Evaluate(int x1,int y1,int x2,int y2,int err)385 void Evaluate(int x1,int y1,int x2,int y2,int err)
386 {
387   struct objlist *fileobj;
388   char *argv[7];
389   struct narray *sarray;
390   char **sdata;
391   int snum;
392   struct objlist *dobj;
393   int did,id,limit;
394   char *dfield,*dinst;
395   int i,j;
396   struct narray *eval;
397   int evalnum,tot;
398   int minx,miny,maxx,maxy;
399   struct savedstdio save;
400   double line,dx,dy;
401   char mes[256];
402   int ret;
403   int selnum,sel;
404   int masknum,iline;
405   struct narray *mask;
406   struct Viewer *d;
407 
408   d=&(NgraphApp.Viewer);
409   ignorestdio(&save);
410   minx=(x1<x2)?x1:x2;
411   miny=(y1<y2)?y1:y2;
412   maxx=(x1>x2)?x1:x2;
413   maxy=(y1>y2)?y1:y2;
414   limit=100;
415   argv[0]=(char *)&minx;
416   argv[1]=(char *)&miny;
417   argv[2]=(char *)&maxx;
418   argv[3]=(char *)&maxy;
419   argv[4]=(char *)&err;
420   argv[5]=(char *)&limit;
421   argv[6]=NULL;
422   if ((fileobj=chkobject("file"))!=NULL) {
423     sprintf(mes,"Evaluating.");
424     SetStatusBar(mes);
425     if (_getobj(menulocal.obj,"_list",menulocal.inst,&sarray)) return;
426     if ((snum=arraynum(sarray))==0) return;
427     sdata=(char **)arraydata(sarray);
428     tot=0;
429     for (i=1;i<snum;i++) {
430       if (((dobj=getobjlist(sdata[i],&did,&dfield,NULL))!=NULL)
431       && (fileobj==dobj)) {
432         if ((dinst=chkobjinstoid(dobj,did))!=NULL) {
433           _getobj(dobj,"id",dinst,&id);
434           _exeobj(dobj,"evaluate",dinst,6,argv);
435           _getobj(dobj,"evaluate",dinst,&eval);
436           evalnum=arraynum(eval)/3;
437           for (j=0;j<evalnum;j++) {
438             if (tot>=limit) break;
439             tot++;
440             line=*(double *)arraynget(eval,j*3+0);
441             dx=*(double *)arraynget(eval,j*3+1);
442             dy=*(double *)arraynget(eval,j*3+2);
443             evallist[tot-1].id=id;
444             evallist[tot-1].line=nround(line);
445             evallist[tot-1].x=dx;
446             evallist[tot-1].y=dy;
447           }
448           if (tot>=limit) break;
449         }
450       }
451     }
452     ResetStatusBar();
453     if (tot>0) {
454       EvalDialog(&DlgEval,fileobj,tot,&sellist);
455       ret=DialogExecute(TopLevel,&DlgEval);
456       selnum=arraynum(&sellist);
457       if (ret==IDEVMASK) {
458         for (i=0;i<selnum;i++) {
459           sel=*(int *)arraynget(&sellist,i);
460           getobj(fileobj,"mask",evallist[sel].id,0,NULL,&mask);
461           if (mask==NULL) {
462             mask=arraynew(sizeof(int));
463             putobj(fileobj,"mask",evallist[sel].id,mask);
464           }
465           masknum=arraynum(mask);
466           for (j=0;j<masknum;j++) {
467             iline=*(int *)arraynget(mask,j);
468             if (iline==evallist[sel].line) break;
469           }
470           if (j==masknum) {
471             arrayadd(mask,&(evallist[sel].line));
472             NgraphApp.Changed=TRUE;
473           }
474         }
475         arraydel(&sellist);
476       } else if ((ret==IDEVMOVE) && (selnum>0)) {
477         SetCursor(XC_left_ptr);
478         d->Capture=TRUE;
479         d->MoveData=TRUE;
480       }
481     }
482   }
483   restorestdio(&save);
484 }
485 
Trimming(int x1,int y1,int x2,int y2)486 void Trimming(int x1,int y1,int x2,int y2)
487 {
488   struct narray farray;
489   struct objlist *obj;
490   int i,id;
491   int *array,num;
492   int vx1,vy1,vx2,vy2;
493   int maxx,maxy,minx,miny;
494   int dir,rcode1,rcode2,room;
495   double ax,ay,ip1,ip2,min,max;
496   char *argv[4];
497   struct Viewer *d;
498 
499   d=&(NgraphApp.Viewer);
500   if ((x1==x2) && (y1==y2)) return;
501   if ((obj=chkobject("axis"))==NULL) return;
502   if (chkobjlastinst(obj)==-1) return;
503   SelectDialog(&DlgSelect,obj,AxisCB,(struct narray *)&farray,NULL);
504   if (DialogExecute(TopLevel,&DlgSelect)==IDOK) {
505     vx1=x1-x2;
506     vy1=y1-y2;
507     vx2=x2-x1;
508     vy2=y1-y2;
509     num=arraynum(&farray);
510     array=(int *)arraydata(&farray);
511     for (i=0;i<num;i++) {
512       id=array[i];
513       getobj(obj,"direction",id,0,NULL,&dir);
514       ax=cos(dir/18000.0*MPI);
515       ay=-sin(dir/18000.0*MPI);
516       ip1=ax*vx1+ay*vy1;
517       ip2=ax*vx2+ay*vy2;
518       if (fabs(ip1)>fabs(ip2)) {
519         if (ip1>0) {
520           maxx=x1;
521           maxy=y1;
522           minx=x2;
523           miny=y2;
524         } else if (ip1<0) {
525           maxx=x2;
526           maxy=y2;
527           minx=x1;
528           miny=y1;
529         } else {
530           maxx=minx=0;
531           maxy=miny=0;
532         }
533       } else {
534         if (ip2>0) {
535           maxx=x2;
536           maxy=y1;
537           minx=x1;
538           miny=y2;
539         } else if (ip2<0) {
540           maxx=x1;
541           maxy=y2;
542           minx=x2;
543           miny=y1;
544         } else {
545           maxx=minx=0;
546           maxy=miny=0;
547         }
548       }
549       if ((minx!=maxx) && (miny!=maxy)) {
550         argv[0]=(char *)&minx;
551         argv[1]=(char *)&miny;
552         argv[2]=NULL;
553         rcode1=getobj(obj,"coordinate",id,2,argv,&min);
554         argv[0]=(char *)&maxx;
555         argv[1]=(char *)&maxy;
556         argv[2]=NULL;
557         rcode2=getobj(obj,"coordinate",id,2,argv,&max);
558         if ((rcode1!=-1) && (rcode2!=-1)) {
559           exeobj(obj,"scale_push",id,0,NULL);
560           room=1;
561           argv[0]=(char *)&min;
562           argv[1]=(char *)&max;
563           argv[2]=(char *)&room;
564           argv[3]=NULL;
565           exeobj(obj,"scale",id,3,argv);
566           NgraphApp.Changed=TRUE;
567         }
568       }
569     }
570     AdjustAxis();
571     d->allclear=TRUE;
572     UpdateAll();
573   }
574   arraydel(&farray);
575 }
576 
577 
Match(char * objname,int x1,int y1,int x2,int y2,int err)578 void Match(char *objname,int x1,int y1,int x2,int y2,int err)
579 {
580   struct objlist *fobj;
581   char *argv[6];
582   struct narray *sarray;
583   char **sdata;
584   int snum;
585   struct objlist *dobj;
586   int did;
587   char *dfield,*dinst;
588   int i,match;
589   struct focuslist *focus;
590   int minx,miny,maxx,maxy;
591   struct savedstdio save;
592   struct Viewer *d;
593 
594   d=&(NgraphApp.Viewer);
595   ignorestdio(&save);
596   minx=(x1<x2)?x1:x2;
597   miny=(y1<y2)?y1:y2;
598   maxx=(x1>x2)?x1:x2;
599   maxy=(y1>y2)?y1:y2;
600   argv[0]=(char *)&minx;
601   argv[1]=(char *)&miny;
602   argv[2]=(char *)&maxx;
603   argv[3]=(char *)&maxy;
604   argv[4]=(char *)&err;
605   argv[5]=NULL;
606   if ((fobj=chkobject(objname))!=NULL) {
607     if (_getobj(menulocal.obj,"_list",menulocal.inst,&sarray)) return;
608     if ((snum=arraynum(sarray))==0) return;
609     sdata=(char **)arraydata(sarray);
610     for (i=1;i<snum;i++) {
611       if (((dobj=getobjlist(sdata[i],&did,&dfield,NULL))!=NULL)
612        && chkobjchild(fobj,dobj)) {
613         if ((dinst=chkobjinstoid(dobj,did))!=NULL) {
614           _exeobj(dobj,"match",dinst,5,argv);
615           _getobj(dobj,"match",dinst,&match);
616           if (match) {
617             if ((focus=(struct focuslist *)memalloc(sizeof(struct focuslist)))
618             !=NULL) {
619               focus->obj=dobj;
620               focus->oid=did;
621               arrayadd(d->focusobj,&focus);
622             }
623           }
624         }
625       }
626     }
627   }
628   restorestdio(&save);
629 }
630 
AddList(struct objlist * obj,char * inst)631 void AddList(struct objlist *obj,char *inst)
632 {
633   int addi;
634   struct objlist *aobj;
635   char *ainst;
636   char *afield;
637   int i,j,po,num,oid,id,id2;
638   struct objlist **objlist;
639   struct objlist *obj2;
640   char *inst2;
641   char *field,**objname;
642   struct narray *draw,drawrable;
643   struct Viewer *d;
644 
645   d=&(NgraphApp.Viewer);
646   aobj=obj;
647   ainst=inst;
648   afield="draw";
649   addi=-1;
650   _getobj(obj,"id",inst,&id);
651   draw=&(menulocal.drawrable);
652   num=arraynum(draw);
653   if (num==0) {
654     arrayinit(&drawrable,sizeof(char *));
655     menuadddrawrable(chkobject("draw"),&drawrable);
656     draw=&drawrable;
657     num=arraynum(draw);
658   }
659   if ((objlist=(struct objlist **)memalloc(sizeof(struct objlist *)*num))
660   ==NULL) return;
661   po=0;
662   for (i=0;i<num;i++) {
663     objname=(char **)arraynget(draw,i);
664     objlist[i]=chkobject(*objname);
665     if (objlist[i]==obj) po=i;
666   }
667   i=1;
668   j=0;
669   while ((obj2=GRAgetlist(menulocal.GC,&oid,&field,i))!=NULL) {
670    for (;j<num;j++) if (objlist[j]==obj2) break;
671    if (j==po) {
672      inst2=chkobjinstoid(obj2,oid);
673      _getobj(obj2,"id",inst2,&id2);
674      if (id2>id) {
675        addi=i;
676        memfree(objlist);
677        mx_inslist(menulocal.obj,menulocal.inst,aobj,ainst,afield,addi);
678        if (draw!=&(menulocal.drawrable)) arraydel2(draw);
679        return;
680      }
681    } else if (j>po) {
682      addi=i;
683      memfree(objlist);
684      mx_inslist(menulocal.obj,menulocal.inst,aobj,ainst,afield,addi);
685      if (draw!=&(menulocal.drawrable)) arraydel2(draw);
686      return;
687    }
688    i++;
689   }
690   addi=i;
691   memfree(objlist);
692   mx_inslist(menulocal.obj,menulocal.inst,aobj,ainst,afield,addi);
693   if (draw!=&(menulocal.drawrable)) arraydel2(draw);
694 }
695 
DelList(struct objlist * obj,char * inst)696 void DelList(struct objlist *obj,char *inst)
697 {
698   int i,oid,oid2;
699   struct objlist *obj2;
700   char *field;
701   struct Viewer *d;
702 
703   d=&(NgraphApp.Viewer);
704   _getobj(obj,"oid",inst,&oid);
705   i=0;
706   while ((obj2=GRAgetlist(menulocal.GC,&oid2,&field,i))!=NULL) {
707     if ((obj2==obj) && (oid==oid2))
708       mx_dellist(menulocal.obj,menulocal.inst,i);
709     i++;
710   }
711 }
712 
AddInvalidateRect(struct objlist * obj,char * inst)713 void AddInvalidateRect(struct objlist *obj,char *inst)
714 {
715   struct narray *abbox;
716   int bboxnum,*bbox;
717   double zoom;
718   struct Viewer *d;
719   XRectangle rect;
720 
721   d=&(NgraphApp.Viewer);
722   _exeobj(obj,"bbox",inst,0,NULL);
723   _getobj(obj,"bbox",inst,&abbox);
724   bboxnum=arraynum(abbox);
725   bbox=(int *)arraydata(abbox);
726   if (bboxnum>=4) {
727     zoom=menulocal.PaperZoom/10000.0;
728     rect.x=mxd2p(bbox[0]*zoom+menulocal.LeftMargin)
729           -d->hscroll+d->cx-7;
730     rect.y=mxd2p(bbox[1]*zoom+menulocal.TopMargin)
731           -d->vscroll+d->cy-7;
732     rect.width=mxd2p(bbox[2]*zoom+menulocal.LeftMargin)
733               -d->hscroll+d->cx+7-rect.x;
734     rect.height=mxd2p(bbox[3]*zoom+menulocal.TopMargin)
735                -d->vscroll+d->cy+7-rect.y;
736     if (region==NULL) region=XCreateRegion();
737     XUnionRectWithRegion(&rect,region,region);
738   }
739 }
740 
741 
GetLargeFrame(int * minx,int * miny,int * maxx,int * maxy)742 void GetLargeFrame(int *minx,int *miny,int *maxx,int *maxy)
743 {
744   int i,num;
745   struct focuslist **focus;
746   struct narray *abbox;
747   int bboxnum,*bbox;
748   char *inst;
749   struct savedstdio save;
750   struct Viewer *d;
751 
752   d=&(NgraphApp.Viewer);
753   ignorestdio(&save);
754   *minx=*miny=*maxx=*maxy=0;
755   num=arraynum(d->focusobj);
756   focus=(struct focuslist **)arraydata(d->focusobj);
757   if ((inst=chkobjinstoid(focus[0]->obj,focus[0]->oid))!=NULL) {
758     _exeobj(focus[0]->obj,"bbox",inst,0,NULL);
759     _getobj(focus[0]->obj,"bbox",inst,&abbox);
760     bboxnum=arraynum(abbox);
761     bbox=(int *)arraydata(abbox);
762     if (bboxnum>=4) {
763       *minx=bbox[0];
764       *miny=bbox[1];
765       *maxx=bbox[2];
766       *maxy=bbox[3];
767     }
768   }
769   for (i=1;i<num;i++)
770   if ((inst=chkobjinstoid(focus[i]->obj,focus[i]->oid))!=NULL) {
771     _exeobj(focus[i]->obj,"bbox",inst,0,NULL);
772     _getobj(focus[i]->obj,"bbox",inst,&abbox);
773     bboxnum=arraynum(abbox);
774     bbox=(int *)arraydata(abbox);
775     if (bboxnum>=4) {
776       if (bbox[0]<*minx) *minx=bbox[0];
777       if (bbox[1]<*miny) *miny=bbox[1];
778       if (bbox[2]>*maxx) *maxx=bbox[2];
779       if (bbox[3]>*maxy) *maxy=bbox[3];
780     }
781   }
782   restorestdio(&save);
783 }
784 
GetFocusFrame(int * minx,int * miny,int * maxx,int * maxy,int ofsx,int ofsy)785 void GetFocusFrame(int *minx,int *miny,int *maxx,int *maxy,int ofsx,int ofsy)
786 {
787   int x1,y1,x2,y2;
788   double zoom;
789   struct Viewer *d;
790 
791   d=&(NgraphApp.Viewer);
792   GetLargeFrame(&x1,&y1,&x2,&y2);
793   zoom=menulocal.PaperZoom/10000.0;
794   *minx=mxd2p((x1+ofsx)*zoom+menulocal.LeftMargin)-d->hscroll+d->cx;
795   *miny=mxd2p((y1+ofsy)*zoom+menulocal.TopMargin)-d->vscroll+d->cy;
796   *maxx=mxd2p((x2+ofsx)*zoom+menulocal.LeftMargin)-d->hscroll+d->cx;
797   *maxy=mxd2p((y2+ofsy)*zoom+menulocal.TopMargin)-d->vscroll+d->cy;
798 }
799 
ShowFocusFrame(GC gc)800 void ShowFocusFrame(GC gc)
801 {
802   int i,j,num;
803   struct focuslist **focus;
804   struct narray *abbox;
805   int bboxnum;
806   int *bbox;
807   int x1,y1,x2,y2;
808   char *inst;
809   struct savedstdio save;
810   double zoom;
811   struct Viewer *d;
812   int minx,miny,height,width;
813 
814   d=&(NgraphApp.Viewer);
815   ignorestdio(&save);
816   XSetForeground(Disp,gc,white ^ black);
817   XSetFunction(Disp,gc,GXxor);
818   XSetLineAttributes(Disp,gc,0,LineOnOffDash,CapButt,JoinMiter);
819   XSetDashes(Disp,gc,0,dashes,2);
820   num=arraynum(d->focusobj);
821   focus=(struct focuslist **)arraydata(d->focusobj);
822   if (num>0) {
823     GetFocusFrame(&x1,&y1,&x2,&y2,d->FrameOfsX,d->FrameOfsY);
824     x1-=5;
825     y1-=5;
826     x2+=4;
827     y2+=4;
828     minx=(x1<x2)?x1:x2;
829     miny=(y1<y2)?y1:y2;
830     width=abs(x2-x1);
831     height=abs(y2-y1);
832     XDrawRectangle(Disp,d->win,gc,minx,miny,width,height);
833     XFillRectangle(Disp,d->win,gc,x1-6,y1-6,6,6);
834     XFillRectangle(Disp,d->win,gc,x1-6,y2,6,6);
835     XFillRectangle(Disp,d->win,gc,x2,y1-6,6,6);
836     XFillRectangle(Disp,d->win,gc,x2,y2,6,6);
837   }
838   zoom=menulocal.PaperZoom/10000.0;
839   if (num>1) {
840     for (i=0;i<num;i++) {
841       if ((inst=chkobjinstoid(focus[i]->obj,focus[i]->oid))!=NULL) {
842         _exeobj(focus[i]->obj,"bbox",inst,0,NULL);
843         _getobj(focus[i]->obj,"bbox",inst,&abbox);
844         bboxnum=arraynum(abbox);
845         bbox=(int *)arraydata(abbox);
846         if (bboxnum>=4) {
847           x1=mxd2p((bbox[0]+d->FrameOfsX)*zoom+menulocal.LeftMargin)
848             -d->hscroll+d->cx;
849           y1=mxd2p((bbox[1]+d->FrameOfsY)*zoom+menulocal.TopMargin)
850             -d->vscroll+d->cy;
851           x2=mxd2p((bbox[2]+d->FrameOfsX)*zoom+menulocal.LeftMargin)
852             -d->hscroll+d->cx;
853           y2=mxd2p((bbox[3]+d->FrameOfsY)*zoom+menulocal.TopMargin)
854             -d->vscroll+d->cy;
855           minx=(x1<x2)?x1:x2;
856           miny=(y1<y2)?y1:y2;
857           width=abs(x2-x1);
858           height=abs(y2-y1);
859           XDrawRectangle(Disp,d->win,gc,minx,miny,width,height);
860         }
861       }
862     }
863   } else if (num==1) {
864     i=0;
865     if ((inst=chkobjinstoid(focus[i]->obj,focus[i]->oid))!=NULL) {
866       _exeobj(focus[i]->obj,"bbox",inst,0,NULL);
867       _getobj(focus[i]->obj,"bbox",inst,&abbox);
868       bboxnum=arraynum(abbox);
869       bbox=(int *)arraydata(abbox);
870       for (j=4;j<bboxnum;j+=2) {
871         x1=mxd2p((bbox[j  ]+d->FrameOfsX)*zoom+menulocal.LeftMargin)
872           -d->hscroll+d->cx;
873         y1=mxd2p((bbox[j+1]+d->FrameOfsY)*zoom+menulocal.TopMargin)
874           -d->vscroll+d->cy;
875         XFillRectangle(Disp,d->win,gc,x1-3,y1-3,6,6);
876       }
877     }
878   }
879   XSetFunction(Disp,gc,GXcopy);
880   restorestdio(&save);
881 }
882 
ShowFocusLine(GC gc,int change)883 void ShowFocusLine(GC gc,int change)
884 {
885   int j,num;
886   struct focuslist **focus;
887   struct narray *abbox;
888   int bboxnum;
889   int *bbox;
890   int x0=0,y0=0,x1=0,y1=0,x2=0,y2=0,ofsx,ofsy;
891   char *inst;
892   struct savedstdio save;
893   double zoom;
894   int frame;
895   char *group;
896   int minx,miny,height,width;
897   struct Viewer *d;
898 
899   d=&(NgraphApp.Viewer);
900   ignorestdio(&save);
901   XSetForeground(Disp,gc,white ^ black);
902   XSetFunction(Disp,gc,GXxor);
903   XSetLineAttributes(Disp,gc,0,LineOnOffDash,CapButt,JoinMiter);
904   XSetDashes(Disp,gc,0,dashes,2);
905   num=arraynum(d->focusobj);
906   focus=(struct focuslist **)arraydata(d->focusobj);
907   zoom=menulocal.PaperZoom/10000.0;
908   if (num==1) {
909     if ((inst=chkobjinstoid(focus[0]->obj,focus[0]->oid))!=NULL) {
910       _exeobj(focus[0]->obj,"bbox",inst,0,NULL);
911       _getobj(focus[0]->obj,"bbox",inst,&abbox);
912       bboxnum=arraynum(abbox);
913       bbox=(int *)arraydata(abbox);
914       frame=FALSE;
915       if (focus[0]->obj==chkobject("rectangle")) frame=TRUE;
916       if (focus[0]->obj==chkobject("axis")) {
917         _getobj(focus[0]->obj,"group",inst,&group);
918         if ((group!=NULL) && (group[0]!='a')) frame=TRUE;
919       }
920       if (!frame) {
921         for (j=4;j<bboxnum;j+=2) {
922           if (change==(j-4)/2) {
923             ofsx=d->LineX;
924             ofsy=d->LineY;
925           } else {
926             ofsx=0;
927             ofsy=0;
928           }
929           x1=mxd2p((bbox[j  ]+ofsx)*zoom+menulocal.LeftMargin)
930             -d->hscroll+d->cx;
931           y1=mxd2p((bbox[j+1]+ofsy)*zoom+menulocal.TopMargin)
932             -d->vscroll+d->cy;
933           if (j!=4) XDrawLine(Disp,d->win,gc,x0,y0,x1,y1);
934           x0=x1;
935           y0=y1;
936         }
937       } else {
938         if (change==0) {
939           x1=mxd2p((bbox[4]+d->LineX)*zoom+menulocal.LeftMargin)
940             -d->hscroll+d->cx;
941           y1=mxd2p((bbox[5]+d->LineY)*zoom+menulocal.TopMargin)
942             -d->vscroll+d->cy;
943           x2=mxd2p((bbox[8])*zoom+menulocal.LeftMargin)
944             -d->hscroll+d->cx;
945           y2=mxd2p((bbox[9])*zoom+menulocal.TopMargin)
946             -d->vscroll+d->cy;
947         } else if (change==1) {
948           x1=mxd2p((bbox[4])*zoom+menulocal.LeftMargin)
949             -d->hscroll+d->cx;
950           y1=mxd2p((bbox[5]+d->LineY)*zoom+menulocal.TopMargin)
951             -d->vscroll+d->cy;
952           x2=mxd2p((bbox[8]+d->LineX)*zoom+menulocal.LeftMargin)
953             -d->hscroll+d->cx;
954           y2=mxd2p((bbox[9])*zoom+menulocal.TopMargin)
955             -d->vscroll+d->cy;
956         } else if (change==2) {
957           x1=mxd2p((bbox[4])*zoom+menulocal.LeftMargin)
958             -d->hscroll+d->cx;
959           y1=mxd2p((bbox[5])*zoom+menulocal.TopMargin)
960             -d->vscroll+d->cy;
961           x2=mxd2p((bbox[8]+d->LineX)*zoom+menulocal.LeftMargin)
962             -d->hscroll+d->cx;
963           y2=mxd2p((bbox[9]+d->LineY)*zoom+menulocal.TopMargin)
964             -d->vscroll+d->cy;
965         } else if (change==3) {
966           x1=mxd2p((bbox[4]+d->LineX)*zoom+menulocal.LeftMargin)
967             -d->hscroll+d->cx;
968           y1=mxd2p((bbox[5])*zoom+menulocal.TopMargin)
969             -d->vscroll+d->cy;
970           x2=mxd2p((bbox[8])*zoom+menulocal.LeftMargin)
971             -d->hscroll+d->cx;
972           y2=mxd2p((bbox[9]+d->LineY)*zoom+menulocal.TopMargin)
973             -d->vscroll+d->cy;
974         }
975         minx=(x1<x2)?x1:x2;
976         miny=(y1<y2)?y1:y2;
977         width=abs(x2-x1);
978         height=abs(y2-y1);
979         XDrawRectangle(Disp,d->win,gc,minx,miny,width,height);
980       }
981     }
982   }
983   XSetFunction(Disp,gc,GXcopy);
984   restorestdio(&save);
985 }
986 
ShowPoints(GC gc)987 void ShowPoints(GC gc)
988 {
989   int i,num,x0=0,y0=0,x1,y1,x2,y2;
990   struct pointslist **po;
991   double zoom;
992   struct Viewer *d;
993   int minx,miny,height,width;
994 
995   d=&(NgraphApp.Viewer);
996   XSetForeground(Disp,gc,white ^ black);
997   XSetFunction(Disp,gc,GXxor);
998   num=arraynum(d->points);
999   po=(struct pointslist **)arraydata(d->points);
1000   zoom=menulocal.PaperZoom/10000.0;
1001   if ((d->Mode==RectB) || (d->Mode==ArcB) || (d->Mode==GaussB)
1002   || (d->Mode==FrameB) || (d->Mode==SectionB) || (d->Mode==CrossB)) {
1003     if (num==2) {
1004       XSetLineAttributes(Disp,gc,0,LineOnOffDash,CapButt,JoinMiter);
1005       XSetDashes(Disp,gc,0,dashes,2);
1006       x1=mxd2p(po[0]->x*zoom+menulocal.LeftMargin)-d->hscroll+d->cx;
1007       y1=mxd2p(po[0]->y*zoom+menulocal.TopMargin)-d->vscroll+d->cy;
1008       x2=mxd2p(po[1]->x*zoom+menulocal.LeftMargin)-d->hscroll+d->cx;
1009       y2=mxd2p(po[1]->y*zoom+menulocal.TopMargin)-d->vscroll+d->cy;
1010       minx=(x1<x2)?x1:x2;
1011       miny=(y1<y2)?y1:y2;
1012       width=abs(x2-x1);
1013       height=abs(y2-y1);
1014       XDrawRectangle(Disp,d->win,gc,minx,miny,width,height);
1015     }
1016   } else {
1017     XSetLineAttributes(Disp,gc,0,LineSolid,CapButt,JoinMiter);
1018     for (i=0;i<num;i++) {
1019       x1=mxd2p(po[i]->x*zoom+menulocal.LeftMargin)-d->hscroll+d->cx;
1020       y1=mxd2p(po[i]->y*zoom+menulocal.TopMargin)-d->vscroll+d->cy;
1021       XDrawLine(Disp,d->win,gc,x1-4,y1,x1+5,y1);
1022       XDrawLine(Disp,d->win,gc,x1,y1-4,x1,y1+5);
1023     }
1024     if (num>=1) {
1025       x1=mxd2p(po[0]->x*zoom+menulocal.LeftMargin)-d->hscroll+d->cx;
1026       y1=mxd2p(po[0]->y*zoom+menulocal.TopMargin)-d->vscroll+d->cy;
1027       x0=x1;
1028       y0=y1;
1029     }
1030     for (i=1;i<num;i++) {
1031       x1=mxd2p(po[i]->x*zoom+menulocal.LeftMargin)-d->hscroll+d->cx;
1032       y1=mxd2p(po[i]->y*zoom+menulocal.TopMargin)-d->vscroll+d->cy;
1033       XDrawLine(Disp,d->win,gc,x0,y0,x1,y1);
1034       x0=x1;
1035       y0=y1;
1036     }
1037   }
1038   XSetFunction(Disp,gc,GXcopy);
1039 }
1040 
ShowFrameRect(GC gc)1041 void ShowFrameRect(GC gc)
1042 {
1043   int x1,y1,x2,y2;
1044   double zoom;
1045   struct Viewer *d;
1046   int minx,miny,width,height;
1047 
1048   d=&(NgraphApp.Viewer);
1049   zoom=menulocal.PaperZoom/10000.0;
1050   XSetForeground(Disp,gc,white ^ black);
1051   XSetFunction(Disp,gc,GXxor);
1052   XSetLineAttributes(Disp,gc,0,LineOnOffDash,CapButt,JoinMiter);
1053   XSetDashes(Disp,gc,0,dashes,2);
1054   if ((d->MouseX1!=d->MouseX2) || (d->MouseY1!=d->MouseY2)) {
1055     x1=mxd2p(d->MouseX1*zoom+menulocal.LeftMargin)-d->hscroll+d->cx;
1056     y1=mxd2p(d->MouseY1*zoom+menulocal.TopMargin)-d->vscroll+d->cy;
1057     x2=mxd2p(d->MouseX2*zoom+menulocal.LeftMargin)-d->hscroll+d->cx;
1058     y2=mxd2p(d->MouseY2*zoom+menulocal.TopMargin)-d->vscroll+d->cy;
1059     minx=(x1<x2)?x1:x2;
1060     miny=(y1<y2)?y1:y2;
1061     width=abs(x2-x1);
1062     height=abs(y2-y1);
1063     XDrawRectangle(Disp,d->win,gc,minx,miny,width,height);
1064   }
1065   XSetFunction(Disp,gc,GXcopy);
1066 }
1067 
ShowCrossGauge(GC gc)1068 void ShowCrossGauge(GC gc)
1069 {
1070   int x,y;
1071   double zoom;
1072   unsigned int width,height,border,depth;
1073   Window root;
1074   struct Viewer *d;
1075 
1076   d=&(NgraphApp.Viewer);
1077   XSetForeground(Disp,gc,white ^ gray);
1078   XSetFunction(Disp,gc,GXxor);
1079   XSetLineAttributes(Disp,gc,0,LineSolid,CapButt,JoinMiter);
1080   XGetGeometry(Disp,d->win,&root,&x,&y,&width,&height,&border,&depth);
1081   zoom=menulocal.PaperZoom/10000.0;
1082   x=mxd2p(d->CrossX*zoom+menulocal.LeftMargin)-d->hscroll+d->cx;
1083   y=mxd2p(d->CrossY*zoom+menulocal.TopMargin)-d->vscroll+d->cy;
1084   XDrawLine(Disp,d->win,gc,x,0,x,height);
1085   XDrawLine(Disp,d->win,gc,0,y,width,y);
1086   XSetFunction(Disp,gc,GXcopy);
1087 }
1088 
CheckGrid(int ofs,unsigned int state,int * x,int * y,double * zoom)1089 void CheckGrid(int ofs,unsigned int state,int *x,int *y,double *zoom)
1090 {
1091   int offset;
1092   int grid;
1093 
1094   if ((state & ControlMask) && (!ofs)) {
1095     if ((x!=NULL) && (y!=NULL)) {
1096       if (abs(*x)>abs(*y)) *y=0;
1097       else *x=0;
1098     }
1099   }
1100   grid=mxlocal->grid;
1101   if (!(state & ShiftMask)) {
1102     if (ofs) offset=grid/2;
1103     else offset=0;
1104     if (x!=NULL) *x=((*x+offset)/grid)*grid;
1105     if (y!=NULL) *y=((*y+offset)/grid)*grid;
1106     if (zoom!=NULL) *zoom=nround(*zoom*grid)/((double )grid);
1107   }
1108 }
1109 
ViewerEvLButtonDown(unsigned int state,TPoint point,struct Viewer * d)1110 void ViewerEvLButtonDown(unsigned int state,TPoint point,struct Viewer *d)
1111 {
1112   GC dc;
1113   int minx,miny,maxx,maxy;
1114   int x1,y1,vx1,vx2,vy1,vy2;
1115   double cc,nn;
1116   struct pointslist *po;
1117   double zoom,zoom2;
1118   int i,j;
1119   struct narray *abbox;
1120   int bboxnum;
1121   int *bbox;
1122   char *inst;
1123   struct focuslist *focus;
1124   int vdpi;
1125   int selnum,sel,movenum,iline;
1126   struct narray *move,*movex,*movey;
1127   struct objlist *fileobj,*aobjx,*aobjy;
1128   char *argv[3];
1129   double dx,dy;
1130   int ax,ay,anum;
1131   struct narray iarray;
1132   char *axis;
1133 
1134   if (menulock || globallock) return;
1135   if (region!=NULL) return;
1136   zoom=menulocal.PaperZoom/10000.0;
1137   d->MouseX1=d->MouseX2=(mxp2d(point.x-d->cx+d->hscroll)
1138                        -menulocal.LeftMargin)/zoom;
1139   d->MouseY1=d->MouseY2=(mxp2d(point.y-d->cy+d->vscroll)
1140                        -menulocal.TopMargin)/zoom;
1141   d->MouseMode=MOUSENONE;
1142   dc=XCreateGC(Disp,d->win,0,0);
1143   if (d->MoveData) {
1144     if ((fileobj=chkobject("file"))!=NULL) {
1145       selnum=arraynum(&sellist);
1146       for (i=0;i<selnum;i++) {
1147         sel=*(int *)arraynget(&sellist,i);
1148         getobj(fileobj,"axis_x",evallist[sel].id,0,NULL,&axis);
1149         arrayinit(&iarray,sizeof(int));
1150         if (getobjilist(axis,&aobjx,&iarray,FALSE,NULL)) ax=-1;
1151         else {
1152           anum=arraynum(&iarray);
1153           if (anum<1) ax=-1;
1154           else ax=*(int *)arraylast(&iarray);
1155           arraydel(&iarray);
1156         }
1157         getobj(fileobj,"axis_y",evallist[sel].id,0,NULL,&axis);
1158         arrayinit(&iarray,sizeof(int));
1159         if (getobjilist(axis,&aobjy,&iarray,FALSE,NULL)) ay=-1;
1160         else {
1161           anum=arraynum(&iarray);
1162           if (anum<1) ay=-1;
1163           else ay=*(int *)arraylast(&iarray);
1164           arraydel(&iarray);
1165         }
1166         if ((ax!=-1) && (ax!=-1)) {
1167           argv[0]=(char *)&(d->MouseX1);
1168           argv[1]=(char *)&(d->MouseY1);
1169           argv[2]=NULL;
1170           if ((getobj(aobjx,"coordinate",ax,2,argv,&dx)!=-1)
1171            && (getobj(aobjy,"coordinate",ay,2,argv,&dy)!=-1)) {
1172             getobj(fileobj,"move_data",evallist[sel].id,0,NULL,&move);
1173             getobj(fileobj,"move_data_x",evallist[sel].id,0,NULL,&movex);
1174             getobj(fileobj,"move_data_y",evallist[sel].id,0,NULL,&movey);
1175             if (move==NULL) {
1176               move=arraynew(sizeof(int));
1177               putobj(fileobj,"move_data",evallist[sel].id,move);
1178             }
1179             if (movex==NULL) {
1180               movex=arraynew(sizeof(double));
1181               putobj(fileobj,"move_data_x",evallist[sel].id,movex);
1182             }
1183             if (movey==NULL) {
1184               movey=arraynew(sizeof(double));
1185               putobj(fileobj,"move_data_y",evallist[sel].id,movey);
1186             }
1187             movenum=arraynum(move);
1188             if (arraynum(movex)<movenum) {
1189               for (j=movenum-1;j>=arraynum(movex);j--) {
1190                 arrayndel(move,j);
1191               }
1192               movenum=arraynum(movex);
1193             }
1194             if (arraynum(movey)<movenum) {
1195               for (j=movenum-1;j>=arraynum(movey);j--) {
1196                 arrayndel(move,j);
1197                 arrayndel(movex,j);
1198               }
1199               movenum=arraynum(movey);
1200             }
1201             for (j=0;j<movenum;j++) {
1202               iline=*(int *)arraynget(move,j);
1203               if (iline==evallist[sel].line) break;
1204             }
1205             if (j==movenum) {
1206               arrayadd(move,&(evallist[sel].line));
1207               arrayadd(movex,&dx);
1208               arrayadd(movey,&dy);
1209               NgraphApp.Changed=TRUE;
1210             } else {
1211               arrayput(move,&(evallist[sel].line),j);
1212               arrayput(movex,&dx,j);
1213               arrayput(movey,&dy,j);
1214               NgraphApp.Changed=TRUE;
1215             }
1216           }
1217         }
1218       }
1219       MessageBox(TopLevel,"Data points are moved.","Confirm",MB_OK);
1220     }
1221     arraydel(&sellist);
1222     d->MoveData=FALSE;
1223     d->Capture=FALSE;
1224     SetCursor(XC_left_ptr);
1225   } else if ((d->Mode==PointB) || (d->Mode==LegendB) || (d->Mode==AxisB)) {
1226     d->Capture=TRUE;
1227     if (arraynum(d->focusobj)!=0) {
1228       GetFocusFrame(&minx,&miny,&maxx,&maxy,0,0);
1229       if ((minx-10<=point.x) && (point.x<=minx-4)
1230        && (miny-10<=point.y) && (point.y<=miny-4)) {
1231         GetLargeFrame(&(d->RefX2),&(d->RefY2),&(d->RefX1),&(d->RefY1));
1232         d->MouseMode=MOUSEZOOM1;
1233         SetCursor(XC_top_left_corner);
1234       } else if ((maxx+4<=point.x) && (point.x<=maxx+10)
1235        && (miny-10<=point.y) && (point.y<=miny-4)) {
1236         GetLargeFrame(&(d->RefX1),&(d->RefY2),&(d->RefX2),&(d->RefY1));
1237         d->MouseMode=MOUSEZOOM2;
1238         SetCursor(XC_top_right_corner);
1239       } else if ((maxx+4<=point.x) && (point.x<=maxx+10)
1240        && (maxy+4<=point.y) && (point.y<=maxy+10)) {
1241         GetLargeFrame(&(d->RefX1),&(d->RefY1),&(d->RefX2),&(d->RefY2));
1242         d->MouseMode=MOUSEZOOM3;
1243         SetCursor(XC_bottom_right_corner);
1244       } else if ((minx-10<=point.x) && (point.x<=minx-4)
1245        && (maxy+4<=point.y) && (point.y<=maxy+10)) {
1246         GetLargeFrame(&(d->RefX2),&(d->RefY1),&(d->RefX1),&(d->RefY2));
1247         d->MouseMode=MOUSEZOOM4;
1248         SetCursor(XC_bottom_left_corner);
1249       } else {
1250         focus=*(struct focuslist **)arraynget(d->focusobj,0);
1251         if ((arraynum(d->focusobj)==1)
1252         && ((inst=chkobjinstoid(focus->obj,focus->oid))!=NULL)) {
1253           _exeobj(focus->obj,"bbox",inst,0,NULL);
1254           _getobj(focus->obj,"bbox",inst,&abbox);
1255           bboxnum=arraynum(abbox);
1256           bbox=(int *)arraydata(abbox);
1257           for (j=4;j<bboxnum;j+=2) {
1258             x1=mxd2p(bbox[j]*zoom+menulocal.LeftMargin)
1259               -d->hscroll+d->cx;
1260             y1=mxd2p(bbox[j+1]*zoom+menulocal.TopMargin)
1261               -d->vscroll+d->cy;
1262             if ((x1-3<=point.x) && (point.x<=x1+3)
1263              && (y1-3<=point.y) && (point.y<=y1+3)) break;
1264           }
1265           if (j<bboxnum) {
1266             d->MouseMode=MOUSECHANGE;
1267             d->ChangePoint=(j-4)/2;
1268             ShowFocusFrame(dc);
1269             d->ShowFrame=FALSE;
1270             SetCursor(XC_crosshair);
1271             d->ShowLine=TRUE;
1272             d->LineX=d->LineY=0;
1273             ShowFocusLine(dc,d->ChangePoint);
1274           }
1275         }
1276       }
1277       if (d->MouseMode==MOUSENONE) {
1278         if ((minx<=point.x) && (point.x<=maxx)
1279          && (miny<=point.y) && (point.y<=maxy)) d->MouseMode=MOUSEDRAG;
1280         else {
1281           ShowFocusFrame(dc);
1282           d->ShowFrame=FALSE;
1283           arraydel2(d->focusobj);
1284         }
1285       } else if ((MOUSEZOOM1<=d->MouseMode) && (d->MouseMode<=MOUSEZOOM4)) {
1286         ShowFocusFrame(dc);
1287         d->ShowFrame=FALSE;
1288         d->MouseDX=d->RefX2-d->MouseX1;
1289         d->MouseDY=d->RefY2-d->MouseY1;
1290         vx1=d->MouseX1;
1291         vy1=d->MouseY1;
1292         vx1-=d->RefX1-d->MouseDX;
1293         vy1-=d->RefY1-d->MouseDY;
1294         vx2=(d->RefX2-d->RefX1);
1295         vy2=(d->RefY2-d->RefY1);
1296         cc=vx1*vx2+vy1*vy2;
1297         nn=vx2*vx2+vy2*vy2;
1298         if ((nn==0) || (cc<0)) {
1299           zoom2=0;
1300         } else {
1301           zoom2=cc/nn;
1302         }
1303         CheckGrid(FALSE,state,NULL,NULL,&zoom2);
1304         SetZoom(zoom2);
1305         vx1=d->RefX1+vx2*zoom2;
1306         vy1=d->RefY1+vy2*zoom2;
1307         d->MouseX1=d->RefX1;
1308         d->MouseY1=d->RefY1;
1309         d->MouseX2=vx1;
1310         d->MouseY2=vy1;
1311         ShowFrameRect(dc);
1312         d->ShowRect=TRUE;
1313       }
1314     }
1315     if (arraynum(d->focusobj)==0) {
1316       d->MouseMode=MOUSEPOINT;
1317       d->ShowRect=TRUE;
1318     }
1319   } else if ((d->Mode==TrimB) || (d->Mode==DataB) || (d->Mode==EvalB)) {
1320     d->Capture=TRUE;
1321     d->MouseMode=MOUSEPOINT;
1322     d->ShowRect=TRUE;
1323   } else if ((d->Mode==MarkB) || (d->Mode==TextB)) {
1324     if (!d->Capture) {
1325       x1=d->MouseX1;
1326       y1=d->MouseY1;
1327       CheckGrid(TRUE,state,&x1,&y1,NULL);
1328       if ((po=(struct pointslist *)memalloc(sizeof(struct pointslist)))
1329           !=NULL) {
1330          po->x=x1;
1331          po->y=y1;
1332          arrayadd(d->points,&po);
1333       }
1334       ShowPoints(dc);
1335       d->Capture=TRUE;
1336     }
1337   } else if (d->Mode==ZoomB) {
1338     if (state & ShiftMask) {
1339       d->hscroll-=(d->cx-point.x);
1340       d->vscroll-=(d->cy-point.y);
1341       ChangeDPI(TRUE);
1342     } else if (getobj(menulocal.obj,"dpi",0,0,NULL,&vdpi)!=-1) {
1343       if (state & ControlMask) {
1344         if (nround(vdpi/sqrt(2))>=20) {
1345           vdpi=nround(vdpi/sqrt(2));
1346           if (putobj(menulocal.obj,"dpi",0,&vdpi)!=-1) {
1347             d->hscroll-=(d->cx-point.x);
1348             d->vscroll-=(d->cy-point.y);
1349             ChangeDPI(FALSE);
1350           }
1351         } else MessageBeep(TopLevel);
1352       } else {
1353         if (nround(vdpi*sqrt(2))<=620) {
1354           vdpi=nround(vdpi*sqrt(2));
1355           if (putobj(menulocal.obj,"dpi",0,&vdpi)!=-1) {
1356             d->hscroll-=(d->cx-point.x);
1357             d->vscroll-=(d->cy-point.y);
1358             ChangeDPI(FALSE);
1359           }
1360         } else MessageBeep(TopLevel);
1361       }
1362     }
1363   } else {
1364     if (!(d->Capture)) {
1365       x1=d->MouseX1;
1366       y1=d->MouseY1;
1367       CheckGrid(TRUE,state,&x1,&y1,NULL);
1368       if ((po=(struct pointslist *)memalloc(sizeof(struct pointslist)))
1369           !=NULL) {
1370          po->x=x1;
1371          po->y=y1;
1372          arrayadd(d->points,&po);
1373       }
1374       if ((po=(struct pointslist *)memalloc(sizeof(struct pointslist)))
1375           !=NULL) {
1376          po->x=x1;
1377          po->y=y1;
1378          arrayadd(d->points,&po);
1379       }
1380       ShowPoints(dc);
1381       d->Capture=TRUE;
1382     }
1383   }
1384   XFreeGC(Disp,dc);
1385 }
1386 
ViewerEvLButtonUp(unsigned int state,TPoint point,struct Viewer * d)1387 void ViewerEvLButtonUp(unsigned int state,TPoint point,struct Viewer *d)
1388 {
1389   int x1,y1,x2,y2,err;
1390   GC dc;
1391   int i,num,dx,dy;
1392   struct focuslist *focus;
1393   struct objlist *obj;
1394   char *inst;
1395   char *argv[4];
1396   struct pointslist *po;
1397   int vx1,vx2,vy1,vy2;
1398   double cc,nn,zoom,zoom2;
1399   int zm;
1400   int axis;
1401 
1402   if (menulock || globallock) return;
1403   dc=XCreateGC(Disp,d->win,0,0);
1404   zoom=menulocal.PaperZoom/10000.0;
1405   axis=FALSE;
1406   if (d->Capture) {
1407     if ((d->Mode==PointB) || (d->Mode==LegendB) || (d->Mode==AxisB)
1408      || (d->Mode==TrimB) || (d->Mode==DataB) || (d->Mode==EvalB)) {
1409       if (d->MouseMode==MOUSEDRAG) {
1410         d->Capture=FALSE;
1411         if ((d->MouseX1!=d->MouseX2) || (d->MouseY1!=d->MouseY2)) {
1412           ShowFocusFrame(dc);
1413           d->ShowFrame=FALSE;
1414           d->MouseX2=(mxp2d(point.x+d->hscroll-d->cx)
1415                     -menulocal.LeftMargin)/zoom;
1416           d->MouseY2=(mxp2d(point.y+d->vscroll-d->cy)
1417                     -menulocal.TopMargin)/zoom;
1418           dx=d->MouseX2-d->MouseX1;
1419           dy=d->MouseY2-d->MouseY1;
1420           CheckGrid(FALSE,state,&dx,&dy,NULL);
1421           argv[0]=(char *)&dx;
1422           argv[1]=(char *)&dy;
1423           argv[2]=NULL;
1424           num=arraynum(d->focusobj);
1425           PaintLock=TRUE;
1426           for (i=num-1;i>=0;i--) {
1427             focus=*(struct focuslist **)arraynget(d->focusobj,i);
1428             obj=focus->obj;
1429             if (obj==chkobject("axis")) axis=TRUE;
1430             if ((inst=chkobjinstoid(focus->obj,focus->oid))!=NULL) {
1431               AddInvalidateRect(obj,inst);
1432               _exeobj(obj,"move",inst,2,argv);
1433               NgraphApp.Changed=TRUE;
1434               AddInvalidateRect(obj,inst);
1435             }
1436           }
1437           PaintLock=FALSE;
1438           d->FrameOfsX=d->FrameOfsY=0;
1439           ShowFocusFrame(dc);
1440           d->ShowFrame=TRUE;
1441           if ((d->Mode==LegendB) || ((d->Mode==PointB) && (!axis)))
1442             d->allclear=FALSE;
1443           UpdateAll();
1444         }
1445         d->MouseMode=MOUSENONE;
1446       } else if ((MOUSEZOOM1<=d->MouseMode) && (d->MouseMode<=MOUSEZOOM4)) {
1447         d->Capture=FALSE;
1448         ShowFrameRect(dc);
1449         d->ShowRect=FALSE;
1450         vx1=(mxp2d(point.x-d->cx+d->hscroll)
1451            -menulocal.LeftMargin)/zoom;
1452         vy1=(mxp2d(point.y-d->cy+d->vscroll)
1453            -menulocal.TopMargin)/zoom;
1454         vx1-=d->RefX1-d->MouseDX;
1455         vy1-=d->RefY1-d->MouseDY;
1456         vx2=(d->RefX2-d->RefX1);
1457         vy2=(d->RefY2-d->RefY1);
1458         cc=vx1*vx2+vy1*vy2;
1459         nn=vx2*vx2+vy2*vy2;
1460         if ((nn==0) || (cc<0)) {
1461           zoom2=0;
1462         } else {
1463           zoom2=cc/nn;
1464         }
1465         if ((d->Mode!=DataB) && (d->Mode!=EvalB))
1466           CheckGrid(FALSE,state,NULL,NULL,&zoom2);
1467         zm=nround(zoom2*10000);
1468         ResetZoom();
1469         argv[0]=(char *)&zm;
1470         argv[1]=(char *)&(d->RefX1);
1471         argv[2]=(char *)&(d->RefY1);
1472         argv[3]=NULL;
1473         num=arraynum(d->focusobj);
1474         PaintLock=TRUE;
1475         for (i=num-1;i>=0;i--) {
1476           focus=*(struct focuslist **)arraynget(d->focusobj,i);
1477           obj=focus->obj;
1478           if (obj==chkobject("axis")) axis=TRUE;
1479           if ((inst=chkobjinstoid(focus->obj,focus->oid))!=NULL) {
1480             AddInvalidateRect(obj,inst);
1481             _exeobj(obj,"zooming",inst,3,argv);
1482             NgraphApp.Changed=TRUE;
1483             AddInvalidateRect(obj,inst);
1484           }
1485         }
1486         PaintLock=FALSE;
1487         d->FrameOfsX=d->FrameOfsY=0;
1488         d->ShowFrame=TRUE;
1489         ShowFocusFrame(dc);
1490         if ((d->Mode==LegendB) || ((d->Mode==PointB) && (!axis)))
1491           d->allclear=FALSE;
1492         UpdateAll();
1493         SetCursor(XC_left_ptr);
1494         d->MouseMode=MOUSENONE;
1495       } else if (d->MouseMode==MOUSECHANGE) {
1496         d->Capture=FALSE;
1497         ShowFocusLine(dc,d->ChangePoint);
1498         d->ShowLine=FALSE;
1499         if ((d->MouseX1!=d->MouseX2) || (d->MouseY1!=d->MouseY2)) {
1500           d->MouseX2=(mxp2d(point.x+d->hscroll-d->cx)
1501                     -menulocal.LeftMargin)/zoom;
1502           d->MouseY2=(mxp2d(point.y+d->vscroll-d->cy)
1503                     -menulocal.TopMargin)/zoom;
1504           dx=d->MouseX2-d->MouseX1;
1505           dy=d->MouseY2-d->MouseY1;
1506           if ((d->Mode!=DataB) && (d->Mode!=EvalB))
1507             CheckGrid(FALSE,state,&dx,&dy,NULL);
1508           argv[0]=(char *)&(d->ChangePoint);
1509           argv[1]=(char *)&dx;
1510           argv[2]=(char *)&dy;
1511           argv[3]=NULL;
1512           focus=*(struct focuslist **)arraynget(d->focusobj,0);
1513           obj=focus->obj;
1514           if (obj==chkobject("axis")) axis=TRUE;
1515           PaintLock=TRUE;
1516           if ((inst=chkobjinstoid(focus->obj,focus->oid))!=NULL) {
1517             AddInvalidateRect(obj,inst);
1518             _exeobj(obj,"change",inst,3,argv);
1519             NgraphApp.Changed=TRUE;
1520             AddInvalidateRect(obj,inst);
1521           }
1522           PaintLock=FALSE;
1523           d->FrameOfsX=d->FrameOfsY=0;
1524           d->ShowFrame=TRUE;
1525           ShowFocusFrame(dc);
1526           if ((d->Mode==LegendB) || ((d->Mode==PointB) && (!axis)))
1527             d->allclear=FALSE;
1528           UpdateAll();
1529         } else {
1530           d->FrameOfsX=d->FrameOfsY=0;
1531           d->ShowFrame=TRUE;
1532           ShowFocusFrame(dc);
1533         }
1534         SetCursor(XC_left_ptr);
1535         d->MouseMode=MOUSENONE;
1536       } else if (d->MouseMode==MOUSEPOINT) {
1537         d->Capture=FALSE;
1538         ShowFrameRect(dc);
1539         d->ShowRect=FALSE;
1540         d->MouseX2=(mxp2d(point.x+d->hscroll-d->cx)
1541                   -menulocal.LeftMargin)/zoom;
1542         d->MouseY2=(mxp2d(point.y+d->vscroll-d->cy)
1543                   -menulocal.TopMargin)/zoom;
1544         x1=d->MouseX1;
1545         y1=d->MouseY1;
1546         x2=d->MouseX2;
1547         y2=d->MouseY2;
1548         err=mxp2d(2)/zoom;
1549         if (d->Mode==PointB) {
1550           Match("legend",x1,y1,x2,y2,err);
1551           Match("axis",x1,y1,x2,y2,err);
1552           Match("merge",x1,y1,x2,y2,err);
1553           d->FrameOfsX=d->FrameOfsY=0;
1554           d->ShowFrame=TRUE;
1555           ShowFocusFrame(dc);
1556         } else if (d->Mode==LegendB) {
1557           Match("legend",x1,y1,x2,y2,err);
1558           Match("merge",x1,y1,x2,y2,err);
1559           d->FrameOfsX=d->FrameOfsY=0;
1560           d->ShowFrame=TRUE;
1561           ShowFocusFrame(dc);
1562         } else if (d->Mode==AxisB) {
1563           Match("axis",x1,y1,x2,y2,err);
1564           d->FrameOfsX=d->FrameOfsY=0;
1565           d->ShowFrame=TRUE;
1566           ShowFocusFrame(dc);
1567         } else if (d->Mode==TrimB) {
1568           Trimming(x1,y1,x2,y2);
1569         } else if (d->Mode==DataB) {
1570           if (ViewerWinFileUpdate(x1,y1,x2,y2,err)) UpdateAll();
1571         } else {
1572           Evaluate(x1,y1,x2,y2,err);
1573         }
1574       }
1575       d->MouseMode=MOUSENONE;
1576     } else if ((d->Mode==MarkB) || (d->Mode==TextB)) {
1577       d->Capture=FALSE;
1578       ShowPoints(dc);
1579       d->MouseX1=(mxp2d(point.x+d->hscroll-d->cx)
1580                 -menulocal.LeftMargin)/zoom;
1581       d->MouseY1=(mxp2d(point.y+d->vscroll-d->cy)
1582                 -menulocal.TopMargin)/zoom;
1583       x1=d->MouseX1;
1584       y1=d->MouseY1;
1585       CheckGrid(TRUE,state,&x1,&y1,NULL);
1586       num=arraynum(d->points);
1587       if (num>=1) {
1588         po=*(struct pointslist **)arraynget(d->points,0);
1589         po->x=x1;
1590         po->y=y1;
1591       }
1592       ShowPoints(dc);
1593       if (arraynum(d->points)==1) {
1594         ViewerEvLButtonDblClk(state,point,d);
1595       }
1596     } else if ((d->Mode!=MarkB) && (d->Mode!=TextB)) {
1597       ShowPoints(dc);
1598       d->MouseX1=(mxp2d(point.x+d->hscroll-d->cx)
1599                 -menulocal.LeftMargin)/zoom;
1600       d->MouseY1=(mxp2d(point.y+d->vscroll-d->cy)
1601                 -menulocal.TopMargin)/zoom;
1602       x1=d->MouseX1;
1603       y1=d->MouseY1;
1604       CheckGrid(TRUE,state,&x1,&y1,NULL);
1605       num=arraynum(d->points);
1606       if (num>=2) po=*(struct pointslist **)arraynget(d->points,num-2);
1607       if ((num<2) || (po->x!=x1) || (po->y!=y1)) {
1608         if ((po=(struct pointslist *)memalloc(sizeof(struct pointslist)))
1609            !=NULL) {
1610           po->x=x1;
1611           po->y=y1;
1612           arrayadd(d->points,&po);
1613         }
1614       }
1615       ShowPoints(dc);
1616       if ((d->Mode==RectB) || (d->Mode==ArcB) || (d->Mode==GaussB)
1617       || (d->Mode==FrameB) || (d->Mode==SectionB) || (d->Mode==CrossB)
1618       || (d->Mode==SingleB)) {
1619         if (arraynum(d->points)==3) {
1620           d->Capture=FALSE;
1621           ViewerEvLButtonDblClk(state,point,d);
1622         }
1623       }
1624     }
1625   }
1626   XFreeGC(Disp,dc);
1627 }
1628 
ViewerEvLButtonDblClk(unsigned int state,TPoint point,struct Viewer * d)1629 void ViewerEvLButtonDblClk(unsigned int state,TPoint point,struct Viewer *d)
1630 {
1631   int i,id,num;
1632   struct objlist *obj=NULL,*obj2;
1633   char *inst;
1634   int ret=IDCANCEL;
1635   GC dc;
1636   int x1,y1,x2,y2,x,y,rx,ry;
1637   struct pointslist *po,**pdata;
1638   struct narray *parray;
1639   int idx,idy,idu,idr,idg,lenx,leny,oidx,oidy;
1640   double fx1,fy1;
1641   int dir;
1642   struct narray group;
1643   int type;
1644   char *argv[2];
1645   char *ref;
1646 
1647   if (menulock || globallock) return;
1648   if ((d->Mode==PointB) || (d->Mode==LegendB) || (d->Mode==AxisB)) {
1649     d->Capture=FALSE;
1650     ViewUpdate();
1651   } else if ((d->Mode!=TrimB) && (d->Mode!=DataB) && (d->Mode!=EvalB)) {
1652     dc=XCreateGC(Disp,d->win,0,0);
1653     if ((d->Mode==MarkB) || (d->Mode==TextB)) {
1654       d->Capture=FALSE;
1655       num=arraynum(d->points);
1656       if (d->Mode==MarkB) obj=chkobject("mark");
1657       else obj=chkobject("text");
1658       if (obj!=NULL) {
1659         if ((id=newobj(obj))>=0) {
1660           if (num>=1) {
1661             po=*(struct pointslist **)arraynget(d->points,0);
1662             x1=po->x;
1663             y1=po->y;
1664           }
1665           inst=chkobjinst(obj,id);
1666           _putobj(obj,"x",inst,&x1);
1667           _putobj(obj,"y",inst,&y1);
1668           PaintLock=TRUE;
1669           if (d->Mode==MarkB) {
1670             LegendMarkDialog(&DlgLegendMark,obj,id);
1671             ret=DialogExecute(TopLevel,&DlgLegendMark);
1672           } else {
1673             LegendTextDialog(&DlgLegendText,obj,id);
1674             ret=DialogExecute(TopLevel,&DlgLegendText);
1675           }
1676           if ((ret==IDDELETE) || (ret==IDCANCEL)) delobj(obj,id);
1677           else {
1678             AddList(obj,inst);
1679             AddInvalidateRect(obj,inst);
1680             NgraphApp.Changed=TRUE;
1681           }
1682           PaintLock=FALSE;
1683         }
1684       }
1685       ShowPoints(dc);
1686       arraydel2(d->points);
1687       d->allclear=FALSE;
1688     } else if ((d->Mode==LineB) || (d->Mode==CurveB) || (d->Mode==PolyB)) {
1689       d->Capture=FALSE;
1690       num=arraynum(d->points);
1691       if (num>=3) {
1692         if (d->Mode==LineB) obj=chkobject("line");
1693         else if (d->Mode==CurveB) obj=chkobject("curve");
1694         else if (d->Mode==PolyB) obj=chkobject("polygon");
1695         if (obj!=NULL) {
1696           if ((id=newobj(obj))>=0) {
1697             inst=chkobjinst(obj,id);
1698             parray=arraynew(sizeof(int));
1699             for (i=0;i<num-1;i++) {
1700               po=*(struct pointslist **)arraynget(d->points,i);
1701               arrayadd(parray,&(po->x));
1702               arrayadd(parray,&(po->y));
1703             }
1704             _putobj(obj,"points",inst,parray);
1705             PaintLock=TRUE;
1706             if (d->Mode==LineB) {
1707               LegendArrowDialog(&DlgLegendArrow,obj,id);
1708               ret=DialogExecute(TopLevel,&DlgLegendArrow);
1709             } else if (d->Mode==CurveB) {
1710               LegendCurveDialog(&DlgLegendCurve,obj,id);
1711               ret=DialogExecute(TopLevel,&DlgLegendCurve);
1712             } else if (d->Mode==PolyB) {
1713               LegendPolyDialog(&DlgLegendPoly,obj,id);
1714               ret=DialogExecute(TopLevel,&DlgLegendPoly);
1715             }
1716             if ((ret==IDDELETE) || (ret==IDCANCEL)) delobj(obj,id);
1717             else {
1718               AddList(obj,inst);
1719               AddInvalidateRect(obj,inst);
1720               NgraphApp.Changed=TRUE;
1721             }
1722             PaintLock=FALSE;
1723           }
1724         }
1725       }
1726       ShowPoints(dc);
1727       arraydel2(d->points);
1728       d->allclear=FALSE;
1729     } else if ((d->Mode==RectB) || (d->Mode==ArcB)) {
1730       d->Capture=FALSE;
1731       num=arraynum(d->points);
1732       pdata=(struct pointslist **)arraydata(d->points);
1733       if (num>=3) {
1734         if (d->Mode==RectB) obj=chkobject("rectangle");
1735         else if (d->Mode==ArcB) obj=chkobject("arc");
1736         if (obj!=NULL) {
1737           if ((id=newobj(obj))>=0) {
1738             inst=chkobjinst(obj,id);
1739             x1=pdata[0]->x;
1740             y1=pdata[0]->y;
1741             x2=pdata[1]->x;
1742             y2=pdata[1]->y;
1743             PaintLock=TRUE;
1744             if (d->Mode==RectB) {
1745               _putobj(obj,"x1",inst,&x1);
1746               _putobj(obj,"y1",inst,&y1);
1747               _putobj(obj,"x2",inst,&x2);
1748               _putobj(obj,"y2",inst,&y2);
1749               LegendRectDialog(&DlgLegendRect,obj,id);
1750               ret=DialogExecute(TopLevel,&DlgLegendRect);
1751             } else if (d->Mode==ArcB) {
1752               x=(x1+x2)/2;
1753               y=(y1+y2)/2;
1754               rx=abs(x1-x);
1755               ry=abs(y1-y);
1756               _putobj(obj,"x",inst,&x);
1757               _putobj(obj,"y",inst,&y);
1758               _putobj(obj,"rx",inst,&rx);
1759               _putobj(obj,"ry",inst,&ry);
1760               LegendArcDialog(&DlgLegendArc,obj,id);
1761               ret=DialogExecute(TopLevel,&DlgLegendArc);
1762             }
1763             if ((ret==IDDELETE) || (ret==IDCANCEL)) delobj(obj,id);
1764             else {
1765               AddList(obj,inst);
1766               AddInvalidateRect(obj,inst);
1767               NgraphApp.Changed=TRUE;
1768             }
1769             PaintLock=FALSE;
1770           }
1771         }
1772       }
1773       ShowPoints(dc);
1774       arraydel2(d->points);
1775       d->allclear=FALSE;
1776     } else if (d->Mode==GaussB) {
1777       d->Capture=FALSE;
1778       num=arraynum(d->points);
1779       pdata=(struct pointslist **)arraydata(d->points);
1780       if (num>=3) {
1781         obj=chkobject("curve");
1782         if (obj!=NULL) {
1783           if ((id=newobj(obj))>=0) {
1784             inst=chkobjinst(obj,id);
1785             x1=pdata[0]->x;
1786             y1=pdata[0]->y;
1787             x2=pdata[1]->x;
1788             y2=pdata[1]->y;
1789             if (x1>x2) {
1790               x=x1; x1=x2; x2=x;
1791             }
1792             if (y1>y2) {
1793               y=y1; y1=y2; y2=y;
1794             }
1795             PaintLock=TRUE;
1796             if ((x1!=x2) && (y1!=y2)) {
1797               LegendGaussDialog(&DlgLegendGauss,obj,id,x1,y1,x2-x1,y2-y1);
1798               ret=DialogExecute(TopLevel,&DlgLegendGauss);
1799               if (ret!=IDOK) delobj(obj,id);
1800               else {
1801                 AddList(obj,inst);
1802                 AddInvalidateRect(obj,inst);
1803                 NgraphApp.Changed=TRUE;
1804               }
1805             }
1806             PaintLock=FALSE;
1807           }
1808         }
1809       }
1810       ShowPoints(dc);
1811       arraydel2(d->points);
1812       d->allclear=FALSE;
1813     } else if (d->Mode==SingleB) {
1814       d->Capture=FALSE;
1815       num=arraynum(d->points);
1816       pdata=(struct pointslist **)arraydata(d->points);
1817       if (num>=3) {
1818         obj=chkobject("axis");
1819         if (obj!=NULL) {
1820           if ((id=newobj(obj))>=0) {
1821             inst=chkobjinst(obj,id);
1822             x1=pdata[0]->x;
1823             y1=pdata[0]->y;
1824             x2=pdata[1]->x;
1825             y2=pdata[1]->y;
1826             fx1=x2-x1;
1827             fy1=y2-y1;
1828             lenx=nround(sqrt(fx1*fx1+fy1*fy1));
1829             if (fx1==0) {
1830               if (fy1>=0) dir=27000;
1831               else dir=9000;
1832             } else {
1833               dir=nround(atan(-fy1/fx1)/MPI*18000);
1834               if (fx1<0) dir+=18000;
1835               if (dir<0) dir+=36000;
1836               if (dir>=36000) dir-=36000;
1837             }
1838             inst=chkobjinst(obj,id);
1839             _putobj(obj,"x",inst,&x1);
1840             _putobj(obj,"y",inst,&y1);
1841             _putobj(obj,"length",inst,&lenx);
1842             _putobj(obj,"direction",inst,&dir);
1843             AxisDialog(&DlgAxis,obj,id,TRUE);
1844             ret=DialogExecute(TopLevel,&DlgAxis);
1845             if ((ret==IDDELETE) || (ret==IDCANCEL)) {
1846               delobj(obj,id);
1847             } else NgraphApp.Changed=TRUE;
1848             AddList(obj,inst);
1849           }
1850         }
1851       }
1852       ShowPoints(dc);
1853       arraydel2(d->points);
1854       d->allclear=TRUE;
1855     } else if ((d->Mode==FrameB) || (d->Mode==SectionB) || (d->Mode==CrossB)) {
1856       d->Capture=FALSE;
1857       num=arraynum(d->points);
1858       pdata=(struct pointslist **)arraydata(d->points);
1859       if (num>=3) {
1860         obj=chkobject("axis");
1861         obj2=chkobject("axisgrid");
1862         if (obj!=NULL) {
1863           x1=pdata[0]->x;
1864           y1=pdata[0]->y;
1865           x2=pdata[1]->x;
1866           y2=pdata[1]->y;
1867           lenx=abs(x1-x2);
1868           leny=abs(y1-y2);
1869           x1=(x1<x2)?x1:x2;
1870           y1=(y1>y2)?y1:y2;
1871           idx=newobj(obj);
1872           idy=newobj(obj);
1873           if (d->Mode!=CrossB) {
1874             idu=newobj(obj);
1875             idr=newobj(obj);
1876             arrayinit(&group,sizeof(int));
1877             if (d->Mode==FrameB) type=1;
1878             else type=2;
1879             arrayadd(&group,&type);
1880             arrayadd(&group,&idx);
1881             arrayadd(&group,&idy);
1882             arrayadd(&group,&idu);
1883             arrayadd(&group,&idr);
1884             arrayadd(&group,&x1);
1885             arrayadd(&group,&y1);
1886             arrayadd(&group,&lenx);
1887             arrayadd(&group,&leny);
1888             argv[0]=(char *)&group;
1889             argv[1]=NULL;
1890             exeobj(obj,"default_grouping",idr,1,argv);
1891             arraydel(&group);
1892           } else {
1893             arrayinit(&group,sizeof(int));
1894             type=3;
1895             arrayadd(&group,&type);
1896             arrayadd(&group,&idx);
1897             arrayadd(&group,&idy);
1898             arrayadd(&group,&x1);
1899             arrayadd(&group,&y1);
1900             arrayadd(&group,&lenx);
1901             arrayadd(&group,&leny);
1902             argv[0]=(char *)&group;
1903             argv[1]=NULL;
1904             exeobj(obj,"default_grouping",idx,1,argv);
1905             arraydel(&group);
1906           }
1907           if ((d->Mode==SectionB) && (obj2!=NULL)) {
1908             idg=newobj(obj2);
1909             if (idg>=0) {
1910               getobj(obj,"oid",idx,0,NULL,&oidx);
1911               if ((ref=(char *)memalloc(15))!=NULL) {
1912                 sprintf(ref,"axis:^%d",oidx);
1913                 putobj(obj2,"axis_x",idg,ref);
1914               }
1915               getobj(obj,"oid",idy,0,NULL,&oidy);
1916               if ((ref=(char *)memalloc(15))!=NULL) {
1917                 sprintf(ref,"axis:^%d",oidy);
1918                 putobj(obj2,"axis_y",idg,ref);
1919               }
1920             }
1921           } else idg=-1;
1922           if (d->Mode==FrameB) {
1923             SectionDialog(&DlgSection,x1,y1,lenx,leny,obj,idx,
1924                           idy,idu,idr,obj2,&idg,FALSE);
1925             ret=DialogExecute(TopLevel,&DlgSection);
1926           } else if (d->Mode==SectionB) {
1927             SectionDialog(&DlgSection,x1,y1,lenx,leny,obj,idx,
1928                           idy,idu,idr,obj2,&idg,TRUE);
1929             ret=DialogExecute(TopLevel,&DlgSection);
1930           } else if (d->Mode==CrossB) {
1931             CrossDialog(&DlgCross,x1,y1,lenx,leny,obj,idx,idy);
1932             ret=DialogExecute(TopLevel,&DlgCross);
1933           }
1934           if ((ret==IDDELETE) || (ret==IDCANCEL)) {
1935             if (d->Mode!=CrossB) {
1936               delobj(obj,idr);
1937               delobj(obj,idu);
1938             }
1939             delobj(obj,idy);
1940             delobj(obj,idx);
1941             if ((idg!=-1) && (obj2!=NULL)) delobj(obj2,idg);
1942           } else {
1943             if ((inst=chkobjinst(obj,idx))!=NULL) AddList(obj,inst);
1944             if ((inst=chkobjinst(obj,idy))!=NULL) AddList(obj,inst);
1945             if (d->Mode!=CrossB) {
1946               if ((inst=chkobjinst(obj,idu))!=NULL) AddList(obj,inst);
1947               if ((inst=chkobjinst(obj,idr))!=NULL) AddList(obj,inst);
1948             }
1949             if ((idg!=-1) && (obj2!=NULL)) {
1950               if ((inst=chkobjinst(obj2,idg))!=NULL) AddList(obj2,inst);
1951             }
1952             NgraphApp.Changed=TRUE;
1953           }
1954         }
1955       }
1956       ShowPoints(dc);
1957       arraydel2(d->points);
1958       d->allclear=TRUE;
1959     }
1960     XFreeGC(Disp,dc);
1961     UpdateAll();
1962   }
1963 }
1964 
ViewerEvRButtonDown(unsigned int state,TPoint point,struct Viewer * d,XButtonPressedEvent * event)1965 void ViewerEvRButtonDown(unsigned int state,TPoint point,struct Viewer *d,
1966                          XButtonPressedEvent *event)
1967 {
1968   GC dc;
1969   int num;
1970   struct pointslist *po;
1971   double zoom;
1972   int vdpi;
1973   struct focuslist *focus;
1974   struct objlist *obj;
1975 
1976   if (menulock || globallock) return;
1977   if (d->MoveData) {
1978     arraydel(&sellist);
1979     d->MoveData=FALSE;
1980     d->Capture=FALSE;
1981     SetCursor(XC_left_ptr);
1982     MessageBox(TopLevel,"Moving data points is canceled.","Confirm",MB_OK);
1983   } else if (d->Capture
1984   && ((d->Mode==LineB) || (d->Mode==CurveB) || (d->Mode==PolyB))) {
1985     zoom=menulocal.PaperZoom/10000.0;
1986     dc=XCreateGC(Disp,d->win,0,0);
1987     num=arraynum(d->points);
1988     if (num>0) {
1989       ShowPoints(dc);
1990       arrayndel2(d->points,num-1);
1991       if (num<=2) {
1992         arraydel2(d->points);
1993         d->Capture=FALSE;
1994       } else {
1995         po=*(struct pointslist **)arraylast(d->points);
1996         if (po!=NULL) {
1997           d->MouseX1=(mxp2d(d->hscroll+point.x-d->cx)
1998                     -menulocal.LeftMargin)/zoom;
1999           d->MouseY1=(mxp2d(d->vscroll+point.y-d->cy)
2000                     -menulocal.TopMargin)/zoom;
2001           po->x=d->MouseX1;
2002           po->y=d->MouseY1;
2003           CheckGrid(TRUE,state,&(po->x),&(po->y),NULL);
2004         }
2005         ShowPoints(dc);
2006       }
2007     }
2008     XFreeGC(Disp,dc);
2009   } else if (d->Mode==ZoomB) {
2010     if (state & ShiftMask) {
2011       d->hscroll-=(d->cx-point.x);
2012       d->vscroll-=(d->cy-point.y);
2013       ChangeDPI(TRUE);
2014     } else if (getobj(menulocal.obj,"dpi",0,0,NULL,&vdpi)!=-1) {
2015       if (state & ControlMask) {
2016         if (nround(vdpi*sqrt(2))<=620) {
2017           vdpi=nround(vdpi*sqrt(2));
2018           if (putobj(menulocal.obj,"dpi",0,&vdpi)!=-1) {
2019             d->hscroll-=(d->cx-point.x);
2020             d->vscroll-=(d->cy-point.y);
2021             ChangeDPI(FALSE);
2022           }
2023         } else MessageBeep(TopLevel);
2024       } else {
2025         if (nround(vdpi/sqrt(2))>=20) {
2026           vdpi=nround(vdpi/sqrt(2));
2027           if (putobj(menulocal.obj,"dpi",0,&vdpi)!=-1) {
2028             d->hscroll-=(d->cx-point.x);
2029             d->vscroll-=(d->cy-point.y);
2030             ChangeDPI(FALSE);
2031           }
2032         } else MessageBeep(TopLevel);
2033       }
2034     }
2035   } else if (!(d->MoveData) && !(d->Capture) && (d->MouseMode==MOUSENONE)) {
2036     XtSetSensitive(XtNameToWidget(d->popup,"button_0"),False);
2037     XtSetSensitive(XtNameToWidget(d->popup,"button_1"),False);
2038     XtSetSensitive(XtNameToWidget(d->popup,"button_2"),False);
2039     XtSetSensitive(XtNameToWidget(d->popup,"button_3"),False);
2040     XtSetSensitive(XtNameToWidget(d->popup,"button_4"),False);
2041     if ((d->Mode==PointB) || (d->Mode==LegendB) || (d->Mode==AxisB)) {
2042       num=arraynum(d->focusobj);
2043       if (num>0) {
2044         XtSetSensitive(XtNameToWidget(d->popup,"button_0"),True);
2045         XtSetSensitive(XtNameToWidget(d->popup,"button_1"),True);
2046         XtSetSensitive(XtNameToWidget(d->popup,"button_2"),True);
2047       }
2048       if (num==1) {
2049         focus=*(struct focuslist **)arraynget(d->focusobj,0);
2050         obj=focus->obj;
2051         if (chkobjchild(chkobject("legend"),obj)) {
2052           XtSetSensitive(XtNameToWidget(d->popup,"button_3"),True);
2053           XtSetSensitive(XtNameToWidget(d->popup,"button_4"),True);
2054         }
2055       }
2056     }
2057     XmMenuPosition(d->popup,event);
2058     XtManageChild(d->popup);
2059   }
2060 }
2061 
ViewerEvMButtonDown(unsigned int state,TPoint point,struct Viewer * d)2062 void ViewerEvMButtonDown(unsigned int state,TPoint point,struct Viewer *d)
2063 {
2064   if (menulock || globallock) return;
2065   if (d->Mode==ZoomB) {
2066     d->hscroll-=(d->cx-point.x);
2067     d->vscroll-=(d->cy-point.y);
2068     ChangeDPI(TRUE);
2069   } else {
2070     ViewerEvLButtonDown(state,point,d);
2071     ViewerEvLButtonUp(state,point,d);
2072     ViewerEvLButtonDblClk(state,point,d);
2073   }
2074 }
2075 
ViewerEvMouseMove(unsigned int state,TPoint point,struct Viewer * d)2076 void ViewerEvMouseMove(unsigned int state,TPoint point,struct Viewer *d)
2077 {
2078   GC dc;
2079   struct pointslist *po;
2080   int x,y,dx,dy,vx1,vx2,vy1,vy2;
2081   double cc,nn;
2082   double zoom,zoom2;
2083 
2084   if (menulock || globallock) return;
2085   zoom=menulocal.PaperZoom/10000.0;
2086   dx=(mxp2d(point.x+d->hscroll-d->cx)-menulocal.LeftMargin)/zoom;
2087   dy=(mxp2d(point.y+d->vscroll-d->cy)-menulocal.TopMargin)/zoom;
2088   if ((d->Mode!=DataB) && (d->Mode!=EvalB) && (d->Mode!=ZoomB) &&
2089       (d->MouseMode!=MOUSEPOINT)
2090   && (((d->Mode!=PointB) && (d->Mode!=LegendB) && (d->Mode!=AxisB))
2091   || (d->MouseMode!=MOUSENONE)))
2092     CheckGrid(TRUE,state,&dx,&dy,NULL);
2093   CoordWinSetCoord(dx,dy);
2094   SetPoint(dx,dy);
2095   dc=XCreateGC(Disp,d->win,0,0);
2096   if (region==NULL) {
2097     if (d->ShowCross) ShowCrossGauge(dc);
2098     d->CrossX=dx;
2099     d->CrossY=dy;
2100     if (d->ShowCross) ShowCrossGauge(dc);
2101   }
2102   if (d->Capture) {
2103     if ((d->Mode==PointB) || (d->Mode==LegendB) || (d->Mode==AxisB)
2104      || (d->Mode==TrimB) || (d->Mode==DataB) || (d->Mode==EvalB)) {
2105       if (d->MouseMode==MOUSEDRAG) {
2106         ShowFocusFrame(dc);
2107         d->MouseX2=(mxp2d(point.x+d->hscroll-d->cx)
2108                   -menulocal.LeftMargin)/zoom;
2109         d->MouseY2=(mxp2d(point.y+d->vscroll-d->cy)
2110                   -menulocal.TopMargin)/zoom;
2111         x=d->MouseX2-d->MouseX1;
2112         y=d->MouseY2-d->MouseY1;
2113         CheckGrid(FALSE,state,&x,&y,NULL);
2114         d->FrameOfsX=x;
2115         d->FrameOfsY=y;
2116         ShowFocusFrame(dc);
2117       } else if ((MOUSEZOOM1<=d->MouseMode) && (d->MouseMode<=MOUSEZOOM4)) {
2118         ShowFrameRect(dc);
2119         vx1=(mxp2d(point.x-d->cx+d->hscroll)
2120             -menulocal.LeftMargin)/zoom;
2121         vy1=(mxp2d(point.y-d->cy+d->vscroll)
2122             -menulocal.TopMargin)/zoom;
2123         vx1-=d->RefX1-d->MouseDX;
2124         vy1-=d->RefY1-d->MouseDY;
2125         vx2=(d->RefX2-d->RefX1);
2126         vy2=(d->RefY2-d->RefY1);
2127         cc=vx1*vx2+vy1*vy2;
2128         nn=vx2*vx2+vy2*vy2;
2129         if ((nn==0) || (cc<0)) {
2130           zoom2=0;
2131         } else {
2132           zoom2=cc/nn;
2133         }
2134         if ((d->Mode!=DataB) && (d->Mode!=EvalB))
2135           CheckGrid(FALSE,state,NULL,NULL,&zoom2);
2136         SetZoom(zoom2);
2137         vx1=d->RefX1+vx2*zoom2;
2138         vy1=d->RefY1+vy2*zoom2;
2139         d->MouseX1=d->RefX1;
2140         d->MouseY1=d->RefY1;
2141         d->MouseX2=vx1;
2142         d->MouseY2=vy1;
2143         ShowFrameRect(dc);
2144       } else if (d->MouseMode==MOUSECHANGE) {
2145         ShowFocusLine(dc,d->ChangePoint);
2146         d->MouseX2=(mxp2d(point.x+d->hscroll-d->cx)
2147                   -menulocal.LeftMargin)/zoom;
2148         d->MouseY2=(mxp2d(point.y+d->vscroll-d->cy)
2149                   -menulocal.TopMargin)/zoom;
2150         x=d->MouseX2-d->MouseX1;
2151         y=d->MouseY2-d->MouseY1;
2152         if ((d->Mode!=DataB) && (d->Mode!=EvalB))
2153           CheckGrid(FALSE,state,&x,&y,NULL);
2154         d->LineX=x;
2155         d->LineY=y;
2156         ShowFocusLine(dc,d->ChangePoint);
2157       } else if (d->MouseMode==MOUSEPOINT) {
2158         ShowFrameRect(dc);
2159         d->MouseX2=(mxp2d(point.x+d->hscroll-d->cx)
2160                   -menulocal.LeftMargin)/zoom;
2161         d->MouseY2=(mxp2d(point.y+d->vscroll-d->cy)
2162                   -menulocal.TopMargin)/zoom;
2163         ShowFrameRect(dc);
2164       }
2165     } else {
2166       ShowPoints(dc);
2167       if (arraynum(d->points)!=0) {
2168         po=*(struct pointslist **)arraylast(d->points);
2169         if (po!=NULL) {
2170           po->x=dx;
2171           po->y=dy;
2172         }
2173       }
2174       ShowPoints(dc);
2175     }
2176   }
2177   XFreeGC(Disp,dc);
2178 }
2179 
ViewerEvMouseMotion(Widget w,XtPointer client_data,XEvent * event,Boolean * dispatch)2180 void ViewerEvMouseMotion(Widget w,XtPointer client_data,XEvent *event,
2181                          Boolean *dispatch)
2182 {
2183   struct Viewer *d;
2184   XMotionEvent *e;
2185   TPoint point;
2186 
2187   d=(struct Viewer *)client_data;
2188   e=(XMotionEvent *)event;
2189   point.x=e->x;
2190   point.y=e->y;
2191   ViewerEvMouseMove(e->state,point,d);
2192 }
2193 
2194 Time ViewerTime=0;
2195 TPoint ViewerPoint;
2196 
ViewerEvButtonDown(Widget w,XtPointer client_data,XEvent * event,Boolean * dispatch)2197 void ViewerEvButtonDown(Widget w,XtPointer client_data,XEvent *event,
2198                         Boolean *dispatch)
2199 {
2200   struct Viewer *d;
2201   XButtonEvent *e;
2202   TPoint point;
2203   int dbl;
2204 
2205   d=(struct Viewer *)client_data;
2206   e=(XButtonEvent *)event;
2207   point.x=e->x;
2208   point.y=e->y;
2209   if (((e->time-ViewerTime)<menulocal.mouseclick)
2210   && (ViewerPoint.x==point.x) && (ViewerPoint.y==point.y)) dbl=TRUE;
2211   else dbl=FALSE;
2212   ViewerTime=e->time;
2213   ViewerPoint.x=point.x;
2214   ViewerPoint.y=point.y;
2215   if (e->button==Button1) {
2216     if (dbl) ViewerEvLButtonDblClk(e->state,point,d);
2217     else ViewerEvLButtonDown(e->state,point,d);
2218   } else if (e->button==Button2) {
2219     ViewerEvMButtonDown(e->state,point,d);
2220   } else if (e->button==Button3) ViewerEvRButtonDown(e->state,point,d,e);
2221 }
2222 
ViewerEvButtonUp(Widget w,XtPointer client_data,XEvent * event,Boolean * dispatch)2223 void ViewerEvButtonUp(Widget w,XtPointer client_data,XEvent *event,
2224                       Boolean *dispatch)
2225 {
2226   struct Viewer *d;
2227   XButtonEvent *e;
2228   TPoint point;
2229 
2230   d=(struct Viewer *)client_data;
2231   e=(XButtonEvent *)event;
2232   point.x=e->x;
2233   point.y=e->y;
2234   if (e->button==Button1) ViewerEvLButtonUp(e->state,point,d);
2235 }
2236 
ViewerEvKeyDown(Widget w,XtPointer client_data,XEvent * event,Boolean * dispatch)2237 void ViewerEvKeyDown(Widget w,XtPointer client_data,XEvent *event,
2238                      Boolean *dispatch)
2239 {
2240   struct Viewer *d;
2241   XKeyEvent *e;
2242   KeySym sym;
2243   GC dc;
2244   int dx=0,dy=0,mv;
2245   double zoom;
2246   struct objlist *obj;
2247   int num;
2248   struct focuslist *focus;
2249 
2250   if (menulock || globallock) return;
2251   d=(struct Viewer *)client_data;
2252   e=(XKeyEvent *)event;
2253   sym=XKeycodeToKeysym(Disp,e->keycode,0);
2254   switch (sym) {
2255   case XK_space:
2256     CmViewerDrawB(NULL,NULL,NULL);
2257     break;
2258   case XK_Delete:
2259     ViewDelete();
2260     break;
2261   case XK_Return:
2262     ViewUpdate();
2263     break;
2264   case XK_Insert:
2265     ViewCopy();
2266     break;
2267   case XK_Home:
2268     if (e->state & ShiftMask) ViewTop();
2269     break;
2270   case XK_End:
2271     if (e->state & ShiftMask) ViewLast();
2272     break;
2273   case XK_Down: case XK_Up: case XK_Left: case XK_Right:
2274     if (((d->MouseMode==MOUSENONE) || (d->MouseMode==MOUSEDRAG))
2275      && ((d->Mode==PointB) || (d->Mode==LegendB) || (d->Mode==AxisB))) {
2276       dc=XCreateGC(Disp,d->win,0,0);
2277       zoom=menulocal.PaperZoom/10000.0;
2278       ShowFocusFrame(dc);
2279       if (e->state & ShiftMask) mv=mxlocal->grid/10;
2280       else mv=mxlocal->grid;
2281       if (sym==XK_Down) {
2282         dx=0;
2283         dy=mv;
2284       } else if (sym==XK_Up) {
2285         dx=0;
2286         dy=-mv;
2287       } else if (sym==XK_Right) {
2288         dx=mv;
2289         dy=0;
2290       } else if (sym==XK_Left) {
2291         dx=-mv;
2292         dy=0;
2293       }
2294       d->FrameOfsX+=dx/zoom;
2295       d->FrameOfsY+=dy/zoom;
2296       ShowFocusFrame(dc);
2297       XFreeGC(Disp,dc);
2298       d->MouseMode=MOUSEDRAG;
2299     }
2300     break;
2301   case XK_Shift_L: case XK_Shift_R:
2302     if (d->Mode==ZoomB) SetCursor(XC_centering);
2303     break;
2304   case XK_Control_L: case XK_Control_R:
2305     if (d->Mode==ZoomB) SetCursor(XC_zoomout);
2306     break;
2307   case XK_BackSpace:
2308     ViewCross();
2309     break;
2310   case XK_P: case XK_p:
2311     if (e->state & ControlMask) {
2312       if (!(d->MoveData) && !(d->Capture) && (d->MouseMode==MOUSENONE)) {
2313         XmMenuPosition(d->popup,(XButtonPressedEvent *)event);
2314         XtManageChild(d->popup);
2315         XtSetSensitive(XtNameToWidget(d->popup,"button_0"),False);
2316         XtSetSensitive(XtNameToWidget(d->popup,"button_1"),False);
2317         XtSetSensitive(XtNameToWidget(d->popup,"button_2"),False);
2318         XtSetSensitive(XtNameToWidget(d->popup,"button_3"),False);
2319         XtSetSensitive(XtNameToWidget(d->popup,"button_4"),False);
2320         if ((d->Mode==PointB) || (d->Mode==LegendB) || (d->Mode==AxisB)) {
2321           num=arraynum(d->focusobj);
2322           if (num>0) {
2323             XtSetSensitive(XtNameToWidget(d->popup,"button_0"),True);
2324             XtSetSensitive(XtNameToWidget(d->popup,"button_1"),True);
2325             XtSetSensitive(XtNameToWidget(d->popup,"button_2"),True);
2326           }
2327           if (num==1) {
2328             focus=*(struct focuslist **)arraynget(d->focusobj,0);
2329             obj=focus->obj;
2330             if (chkobjchild(chkobject("legend"),obj)) {
2331               XtSetSensitive(XtNameToWidget(d->popup,"button_3"),True);
2332               XtSetSensitive(XtNameToWidget(d->popup,"button_4"),True);
2333             }
2334           }
2335         }
2336       }
2337     }
2338     break;
2339   default:
2340     break;
2341   }
2342 }
2343 
ViewerEvKeyUp(Widget w,XtPointer client_data,XEvent * event,Boolean * dispatch)2344 void ViewerEvKeyUp(Widget w,XtPointer client_data,XEvent *event,
2345                      Boolean *dispatch)
2346 {
2347   struct Viewer *d;
2348   XKeyEvent *e;
2349   KeySym sym;
2350   GC dc;
2351   int num,i,dx,dy;
2352   struct focuslist *focus;
2353   char *inst;
2354   struct objlist *obj;
2355   char *argv[4];
2356   int axis;
2357 
2358   if (menulock || globallock) return;
2359   d=(struct Viewer *)client_data;
2360   e=(XKeyEvent *)event;
2361   sym=XKeycodeToKeysym(Disp,e->keycode,0);
2362   switch (sym) {
2363   case XK_Shift_L: case XK_Shift_R:
2364   case XK_Control_L: case XK_Control_R:
2365     if (d->Mode==ZoomB) SetCursor(XC_zoomin);
2366     break;
2367   case XK_Down: case XK_Up: case XK_Left: case XK_Right:
2368     if (d->MouseMode==MOUSEDRAG) {
2369       dc=XCreateGC(Disp,d->win,0,0);
2370       ShowFocusFrame(dc);
2371       dx=d->FrameOfsX;
2372       dy=d->FrameOfsY;
2373       argv[0]=(char *)&dx;
2374       argv[1]=(char *)&dy;
2375       argv[2]=NULL;
2376       num=arraynum(d->focusobj);
2377       axis=FALSE;
2378       PaintLock=TRUE;
2379       for (i=num-1;i>=0;i--) {
2380         focus=*(struct focuslist **)arraynget(d->focusobj,i);
2381         obj=focus->obj;
2382         if (obj==chkobject("axis")) axis=TRUE;
2383         if ((inst=chkobjinstoid(focus->obj,focus->oid))!=NULL) {
2384           AddInvalidateRect(obj,inst);
2385           _exeobj(obj,"move",inst,2,argv);
2386           NgraphApp.Changed=TRUE;
2387           AddInvalidateRect(obj,inst);
2388         }
2389       }
2390       PaintLock=FALSE;
2391       d->FrameOfsX=d->FrameOfsY=0;
2392       d->ShowFrame=TRUE;
2393       ShowFocusFrame(dc);
2394       XFreeGC(Disp,dc);
2395       if ((d->Mode==LegendB) || ((d->Mode==PointB) && (!axis)))
2396         d->allclear=FALSE;
2397       UpdateAll();
2398       d->MouseMode=MOUSENONE;
2399     }
2400     break;
2401   default:
2402     break;
2403   }
2404 }
2405 
ViewerEvSize(Widget w,XtPointer client_data,XtPointer call_data)2406 void ViewerEvSize(Widget w,XtPointer client_data,XtPointer call_data)
2407 {
2408   struct Viewer *d;
2409   int x,y;
2410   unsigned int width,height,border,depth;
2411   Window root;
2412 
2413   d=&(NgraphApp.Viewer);
2414   XGetGeometry(XtDisplay(w),XtWindow(w),
2415                &root,&x,&y,&width,&height,&border,&depth);
2416   d->cx=width/2;
2417   d->cy=height/2;
2418   ChangeDPI(TRUE);
2419   d->width=width;
2420   d->height=height;
2421 }
2422 
ViewerEvPaint(Widget w,XtPointer client_data,XtPointer call_data)2423 void ViewerEvPaint(Widget w,XtPointer client_data,XtPointer call_data)
2424 {
2425   GC gc;
2426   struct mxlocal mxsave;
2427   struct savedstdio save;
2428   XmAnyCallbackStruct *dd;
2429   XExposeEvent *e;
2430   struct Viewer *d;
2431   XRectangle rect;
2432   Arg al[20];
2433   Cardinal ac;
2434   unsigned pixel;
2435 
2436   d=&(NgraphApp.Viewer);
2437   dd=(XmAnyCallbackStruct *)call_data;
2438   e=(XExposeEvent *)(dd->event);
2439   if (region==NULL) region=XCreateRegion();
2440   XtAddExposureToRegion(dd->event,region);
2441   if ((e->count!=0) || globallock) return;
2442   gc=XCreateGC(e->display,e->window,0,0);
2443   XSetRegion(e->display,gc,region);
2444   XClipBox(region,&rect);
2445   if (!PaintLock) {
2446     ac=0;
2447     XtSetArg(al[ac],XmNbackground,&pixel); ac++;
2448     XtGetValues(d->Win,al,ac);
2449     XSetForeground(e->display,gc,pixel);
2450     XFillRectangle(e->display,e->window,gc,
2451                    rect.x,rect.y,rect.width,rect.height);
2452   }
2453   if (chkobjinstoid(menulocal.GRAobj,menulocal.GRAoid)!=NULL) {
2454     mxsaveGC(gc,e->window,-d->cx+d->hscroll,-d->cy+d->vscroll,
2455              &mxsave,-1,region);
2456     MakeRuler(gc);
2457     if (mxlocal->autoredraw && !d->ignoreredraw) {
2458       ignorestdio(&save);
2459       mx_redraw(menulocal.obj,menulocal.inst);
2460       restorestdio(&save);
2461     }
2462     mxrestoreGC(&mxsave);
2463     XSetRegion(e->display,gc,region);
2464     if (d->ShowFrame) ShowFocusFrame(gc);
2465     ShowPoints(gc);
2466     if (d->ShowLine) ShowFocusLine(gc,d->ChangePoint);
2467     if (d->ShowRect) ShowFrameRect(gc);
2468     if (d->ShowCross) ShowCrossGauge(gc);
2469     XFreeGC(e->display,gc);
2470     mxlocal->scrollx=-d->cx+d->hscroll;
2471     mxlocal->scrolly=-d->cy+d->vscroll;
2472   }
2473   if (!PaintLock) {
2474     XDestroyRegion(region);
2475     region=NULL;
2476   }
2477 }
2478 
ViewerEvVScroll(Widget w,XtPointer client_data,XtPointer call_data)2479 void ViewerEvVScroll(Widget w,XtPointer client_data,XtPointer call_data)
2480 {
2481   XmScrollBarCallbackStruct *dd;
2482   struct Viewer *d;
2483   int dy;
2484   int x,y;
2485   unsigned int width,height,border,depth;
2486   Window root;
2487   GC gc;
2488 
2489   d=&(NgraphApp.Viewer);
2490   dd=(XmScrollBarCallbackStruct *)call_data;
2491   dy=dd->value-d->vscroll;
2492   if (dy!=0) {
2493     gc=XCreateGC(Disp,d->win,0,0);
2494     XGetGeometry(Disp,d->win,&root,&x,&y,&width,&height,&border,&depth);
2495     XCopyArea(Disp,d->win,d->win,gc,0,dy,width,height,0,0);
2496     XFreeGC(Disp,gc);
2497     if (dy>0) XClearArea(Disp,d->win,0,height-dy,width,dy,TRUE);
2498     else XClearArea(Disp,d->win,0,0,width,-dy,TRUE);
2499   }
2500   d->vscroll=dd->value;
2501 }
2502 
ViewerEvHScroll(Widget w,XtPointer client_data,XtPointer call_data)2503 void ViewerEvHScroll(Widget w,XtPointer client_data,XtPointer call_data)
2504 {
2505   XmScrollBarCallbackStruct *dd;
2506   struct Viewer *d;
2507   int dx;
2508   int x,y;
2509   unsigned int width,height,border,depth;
2510   Window root;
2511   GC gc;
2512 
2513   d=&(NgraphApp.Viewer);
2514   dd=(XmScrollBarCallbackStruct *)call_data;
2515   dx=dd->value-d->hscroll;
2516   if (dx!=0) {
2517     gc=XCreateGC(Disp,d->win,0,0);
2518     XGetGeometry(Disp,d->win,&root,&x,&y,&width,&height,&border,&depth);
2519     XCopyArea(Disp,d->win,d->win,gc,dx,0,width,height,0,0);
2520     XFreeGC(Disp,gc);
2521     if (dx>0) XClearArea(Disp,d->win,width-dx,0,dx,height,TRUE);
2522     else XClearArea(Disp,d->win,0,0,-dx,height,TRUE);
2523   }
2524   d->hscroll=dd->value;
2525 }
2526 
ViewerWinUpdate(int clear)2527 void ViewerWinUpdate(int clear)
2528 {
2529   int i,num;
2530   struct focuslist **focus;
2531   struct Viewer *d;
2532 
2533   d=&(NgraphApp.Viewer);
2534   if (chkobjinstoid(menulocal.GRAobj,menulocal.GRAoid)==NULL) {
2535     CloseGC();
2536     CloseGRA();
2537     OpenGRA();
2538     OpenGC();
2539     SetScroller();
2540     ChangeDPI(TRUE);
2541   }
2542   CheckPage();
2543   num=arraynum(d->focusobj);
2544   focus=(struct focuslist **)arraydata(d->focusobj);
2545   for (i=num-1;i>=0;i--) {
2546     if (chkobjoid(focus[i]->obj,focus[i]->oid)==-1) arrayndel2(d->focusobj,i);
2547   }
2548   if (d->allclear) XClearArea(XtDisplay(d->Win),XtWindow(d->Win),0,0,0,0,TRUE);
2549   else if (region!=NULL)
2550     XClearArea(XtDisplay(d->Win),XtWindow(d->Win),1,1,1,1,TRUE);
2551   d->allclear=TRUE;
2552 }
2553 
MakeRuler(GC gc)2554 void MakeRuler(GC gc)
2555 {
2556   int Width,Height;
2557   int x,y,len;
2558   struct Viewer *d;
2559   int x1,y1,x2,y2;
2560   int minx,miny,width,height;
2561 
2562   d=&(NgraphApp.Viewer);
2563   Width=menulocal.PaperWidth;
2564   Height=menulocal.PaperHeight;
2565   XSetFunction(Disp,gc,GXcopy);
2566   XSetLineAttributes(Disp,gc,0,LineSolid,CapButt,JoinMiter);
2567   XSetForeground(Disp,gc,gray);
2568   x1=mxd2px(0);
2569   y1=mxd2py(0);
2570   x2=mxd2px(Width)-1;
2571   y2=mxd2py(Height)-1;
2572   minx=(x1<x2)?x1:x2;
2573   miny=(y1<y2)?y1:y2;
2574   width=abs(x2-x1);
2575   height=abs(y2-y1);
2576   XDrawRectangle(Disp,d->win,gc,minx,miny,width,height);
2577   if (mxlocal->ruler) {
2578     XSetForeground(Disp,gc,gray);
2579     for (x=500;x<Width;x+=500) {
2580       if (!(x%10000)) {
2581         XSetForeground(Disp,gc,red);
2582       }
2583       if (!(x%10000)) len=225;
2584       else if (!(x%1000)) len=150;
2585       else len=75;
2586       XDrawLine(Disp,d->win,gc,
2587                 mxd2px(x),mxd2py(0),
2588                 mxd2px(x),mxd2py(len));
2589       XDrawLine(Disp,d->win,gc,
2590                 mxd2px(x),mxd2py(Height)-1,
2591                 mxd2px(x),mxd2py(Height-len)-1);
2592       if (!(x%10000)) {
2593         XSetForeground(Disp,gc,gray);
2594       }
2595     }
2596     for (y=500;y<Height;y+=500) {
2597       if (!(y%10000)) {
2598         XSetForeground(Disp,gc,red);
2599       }
2600       if (!(y%10000)) len=225;
2601       else if (!(y%1000)) len=150;
2602       else len=75;
2603       XDrawLine(Disp,d->win,gc,
2604                 mxd2px(0),mxd2py(y),
2605                 mxd2px(len),mxd2py(y));
2606       XDrawLine(Disp,d->win,gc,
2607                 mxd2px(Width)-1,mxd2py(y),
2608                 mxd2px(Width-len)-1,mxd2py(y));
2609       if (!(y%10000)) {
2610         XSetForeground(Disp,gc,gray);
2611       }
2612     }
2613   }
2614 }
2615 
Focus(struct objlist * fobj,int id)2616 void Focus(struct objlist *fobj,int id)
2617 {
2618   int oid;
2619   char *inst;
2620   struct narray *sarray;
2621   char **sdata;
2622   int snum;
2623   struct objlist *dobj;
2624   int did;
2625   char *dfield;
2626   int i;
2627   struct focuslist *focus;
2628   struct savedstdio save;
2629   GC dc;
2630   int man;
2631   struct Viewer *d;
2632 
2633   d=&(NgraphApp.Viewer);
2634   if (chkobjchild(chkobject("legend"),fobj)) {
2635     CmViewerButtonArm(NgraphApp.viewb[1],NULL,NULL);
2636   } else if (chkobjchild(chkobject("axis"),fobj)) {
2637     CmViewerButtonArm(NgraphApp.viewb[10],NULL,NULL);
2638   } else if (chkobjchild(chkobject("merge"),fobj)) {
2639     CmViewerButtonArm(NgraphApp.viewb[0],NULL,NULL);
2640   } else return;
2641   UnFocus();
2642   dc=XCreateGC(Disp,d->win,0,0);
2643   inst=chkobjinst(fobj,id);
2644   _getobj(fobj,"oid",inst,&oid);
2645   ignorestdio(&save);
2646   if (fobj!=NULL) {
2647     if (_getobj(menulocal.obj,"_list",menulocal.inst,&sarray)) return;
2648     if ((snum=arraynum(sarray))==0) return;
2649     sdata=(char **)arraydata(sarray);
2650     for (i=1;i<snum;i++) {
2651       if (((dobj=getobjlist(sdata[i],&did,&dfield,NULL))!=NULL)
2652       && (fobj==dobj) && (did==oid)) {
2653         if ((focus=(struct focuslist *)memalloc(sizeof(struct focuslist)))
2654         !=NULL) {
2655           if (chkobjchild(chkobject("axis"),dobj)) {
2656             getobj(fobj,"group_manager",id,0,NULL,&man);
2657             getobj(fobj,"oid",man,0,NULL,&did);
2658           }
2659           focus->obj=dobj;
2660           focus->oid=did;
2661           arrayadd(d->focusobj,&focus);
2662           d->ShowFrame=TRUE;
2663           ShowFocusFrame(dc);
2664         }
2665         d->MouseMode=MOUSENONE;
2666         break;
2667       }
2668     }
2669   }
2670   XFreeGC(Disp,dc);
2671   restorestdio(&save);
2672 }
2673 
2674 
UnFocus()2675 void UnFocus()
2676 {
2677   GC gc;
2678   struct Viewer *d;
2679 
2680   d=&(NgraphApp.Viewer);
2681   if (arraynum(d->focusobj)!=0) {
2682     gc=XCreateGC(Disp,d->win,0,0);
2683     ShowFocusFrame(gc);
2684     XFreeGC(Disp,gc);
2685     arraydel2(d->focusobj);
2686   }
2687   d->ShowFrame=FALSE;
2688   if (arraynum(d->points)!=0) {
2689     gc=XCreateGC(Disp,d->win,0,0);
2690     ShowPoints(gc);
2691     XFreeGC(Disp,gc);
2692     arraydel2(d->points);
2693   }
2694 }
2695 
OpenGC()2696 void OpenGC()
2697 {
2698   int i;
2699 
2700   if (mxlocal->gc!=0) return;
2701   Disp=XtDisplay(NgraphApp.Viewer.Win);
2702   mxlocal->win=XtWindow(NgraphApp.Viewer.Win);
2703   mxlocal->gc=XCreateGC(Disp,mxlocal->win,0,0);
2704   mxlocal->offsetx=0;
2705   mxlocal->offsety=0;
2706   mxlocal->cpx=0;
2707   mxlocal->cpy=0;
2708   mxlocal->pixel_dot=mxlocal->windpi/25.4/100;
2709   mxlocal->fontalias=NULL;
2710   for (i=0;i<X11FONTCASH;i++) (mxlocal->font[i]).fontalias=NULL;
2711   mxlocal->loadfont=0;
2712   mxlocal->loadfontf=-1;
2713   mxlocal->linetonum=0;
2714   mxlocal->scrollx=0;
2715   mxlocal->scrolly=0;
2716   mxlocal->region=NULL;
2717 }
2718 
SetScroller()2719 void SetScroller()
2720 {
2721   int width,height,x,y;
2722   struct Viewer *d;
2723 
2724   d=&(NgraphApp.Viewer);
2725   width=mxd2p(menulocal.PaperWidth);
2726   height=mxd2p(menulocal.PaperHeight);
2727   x=width/2;
2728   y=height/2;
2729   XtVaSetValues(d->HScroll,XmNmaximum,width,XmNvalue,x,NULL);
2730   XtVaSetValues(d->VScroll,XmNmaximum,height,XmNvalue,y,NULL);
2731   d->hscroll=x;
2732   d->vscroll=y;
2733 }
2734 
ChangeDPI(int redraw)2735 void ChangeDPI(int redraw)
2736 {
2737   int width,height,i;
2738   double ratex,ratey;
2739   struct objlist *obj;
2740   int num;
2741   struct narray *array;
2742   char *inst;
2743   struct Viewer *d;
2744   int XPos,YPos,XRange,YRange;
2745 
2746   d=&(NgraphApp.Viewer);
2747   XtVaGetValues(d->HScroll,XmNmaximum,&XRange,NULL);
2748   XtVaGetValues(d->VScroll,XmNmaximum,&YRange,NULL);
2749   XPos=d->hscroll;
2750   YPos=d->vscroll;
2751   if (XPos<0) XPos=0;
2752   if (YPos<0) YPos=0;
2753   if (XPos>XRange) XPos=XRange;
2754   if (YPos>YRange) YPos=YRange;
2755   if (XRange==0) ratex=0;
2756   else ratex=XPos/(double )XRange;
2757   if (YRange==0) ratey=0;
2758   else ratey=YPos/(double )YRange;
2759   width=mxd2p(menulocal.PaperWidth);
2760   height=mxd2p(menulocal.PaperHeight);
2761   XPos=width*ratex;
2762   YPos=height*ratey;
2763   XtVaSetValues(d->HScroll,XmNmaximum,width,XmNvalue,XPos,NULL);
2764   XtVaSetValues(d->VScroll,XmNmaximum,height,XmNvalue,YPos,NULL);
2765   d->hscroll=XPos;
2766   d->vscroll=YPos;
2767   mxlocal->scrollx=-d->cx+XPos;
2768   mxlocal->scrolly=-d->cy+YPos;
2769   if ((obj=chkobject("text"))!=NULL) {
2770     num=chkobjlastinst(obj);
2771     for (i=0;i<=num;i++) {
2772       inst=chkobjinst(obj,i);
2773       _getobj(obj,"bbox",inst,&array);
2774       arrayfree(array);
2775       _putobj(obj,"bbox",inst,NULL);
2776     }
2777   }
2778   XClearArea(Disp,d->win,0,0,0,0,redraw);
2779 }
2780 
CloseGC()2781 void CloseGC()
2782 {
2783   int i;
2784 
2785   if (mxlocal->gc==0) return;
2786   if (mxlocal->linetonum!=0) {
2787     XDrawLines(Disp,mxlocal->win,mxlocal->gc,
2788                mxlocal->points,mxlocal->linetonum,CoordModeOrigin);
2789     mxlocal->linetonum=0;
2790   }
2791   XFlush(Disp);
2792   XFreeGC(Disp,mxlocal->gc);
2793   mxlocal->gc=0;
2794   memfree(mxlocal->fontalias);
2795   for (i=0;i<X11FONTCASH;i++) memfree((mxlocal->font[i]).fontalias);
2796   if (mxlocal->region!=NULL) XDestroyRegion(mxlocal->region);
2797   mxlocal->region=NULL;
2798   UnFocus();
2799 }
2800 
ReopenGC()2801 void ReopenGC()
2802 {
2803   if (mxlocal->gc!=0) {
2804     if (mxlocal->linetonum!=0) {
2805       XDrawLines(Disp,mxlocal->win,mxlocal->gc,
2806                  mxlocal->points,mxlocal->linetonum,CoordModeOrigin);
2807       mxlocal->linetonum=0;
2808     }
2809     XFlush(Disp);
2810     XFreeGC(Disp,mxlocal->gc);
2811   }
2812   mxlocal->gc=XCreateGC(Disp,mxlocal->win,0,0);
2813   mxlocal->offsetx=0;
2814   mxlocal->offsety=0;
2815   mxlocal->cpx=0;
2816   mxlocal->cpy=0;
2817   mxlocal->pixel_dot=mxlocal->windpi/25.4/100;
2818   mxlocal->loadfontf=-1;
2819   mxlocal->linetonum=0;
2820   if (mxlocal->region!=NULL) XDestroyRegion(mxlocal->region);
2821   mxlocal->region=NULL;
2822 }
2823 
Draw(int SelectFile)2824 void Draw(int SelectFile)
2825 {
2826   int SShowFrame,SShowLine,SShowRect,SShowCross;
2827   GC gc;
2828   struct Viewer *d;
2829 
2830   d=&(NgraphApp.Viewer);
2831   if (SelectFile && !SetFileHidden()) return;
2832   FitClear();
2833   FileAutoScale();
2834   AdjustAxis();
2835   SetStatusBar("Drawing.");
2836   gc=XCreateGC(Disp,d->win,0,0);
2837   if (d->ShowFrame) ShowFocusFrame(gc);
2838   if (d->ShowLine) ShowFocusLine(gc,d->ChangePoint);
2839   if (d->ShowRect) ShowFrameRect(gc);
2840   if (d->ShowCross) ShowCrossGauge(gc);
2841   XFreeGC(Disp,gc);
2842   SShowFrame=d->ShowFrame;
2843   SShowLine=d->ShowLine;
2844   SShowRect=d->ShowRect;
2845   SShowCross=d->ShowCross;
2846   d->ShowFrame=d->ShowLine=d->ShowRect=d->ShowCross=FALSE;
2847   ReopenGC();
2848   if (chkobjinstoid(menulocal.GRAobj,menulocal.GRAoid)!=NULL) {
2849     _exeobj(menulocal.GRAobj,"clear",menulocal.GRAinst,0,NULL);
2850     d->ignoreredraw=TRUE;
2851     XmUpdateDisplay(d->Win);
2852     d->ignoreredraw=FALSE;
2853     _exeobj(menulocal.GRAobj,"draw",menulocal.GRAinst,0,NULL);
2854     _exeobj(menulocal.GRAobj,"flush",menulocal.GRAinst,0,NULL);
2855   }
2856   d->ShowFrame=SShowFrame;
2857   d->ShowLine=SShowLine;
2858   d->ShowRect=SShowRect;
2859   d->ShowCross=SShowCross;
2860   gc=XCreateGC(Disp,d->win,0,0);
2861   if (d->ShowFrame) ShowFocusFrame(gc);
2862   if (d->ShowLine) ShowFocusLine(gc,d->ChangePoint);
2863   if (d->ShowRect) ShowFrameRect(gc);
2864   if (d->ShowCross) ShowCrossGauge(gc);
2865   XFreeGC(Disp,gc);
2866   ResetStatusBar();
2867 }
2868 
Clear()2869 void Clear()
2870 {
2871   if (chkobjinstoid(menulocal.GRAobj,menulocal.GRAoid)!=NULL) {
2872     UnFocus();
2873     _exeobj(menulocal.GRAobj,"clear",menulocal.GRAinst,0,NULL);
2874     ReopenGC();
2875   }
2876 }
2877 
CmViewerDraw()2878 void CmViewerDraw()
2879 {
2880   if (menulock || globallock) return;
2881   Draw(TRUE);
2882   FileWinUpdate(TRUE);
2883   AxisWinUpdate(TRUE);
2884 }
2885 
CmViewerDrawB(Widget w,XtPointer client_data,XtPointer call_data)2886 void CmViewerDrawB(Widget w,XtPointer client_data,XtPointer call_data)
2887 {
2888 
2889   if (menulock || globallock) return;
2890   Draw(FALSE);
2891   FileWinUpdate(TRUE);
2892   AxisWinUpdate(TRUE);
2893 }
2894 
CmViewerClear()2895 void CmViewerClear()
2896 {
2897   if (menulock || globallock) return;
2898   Clear();
2899   FileWinUpdate(TRUE);
2900 }
2901 
CmViewerClearB(Widget w,XtPointer client_data,XtPointer call_data)2902 void CmViewerClearB(Widget w,XtPointer client_data,XtPointer call_data)
2903 {
2904   CmViewerClear();
2905 }
2906 
ViewUpdate()2907 void ViewUpdate()
2908 {
2909   int i,id,id2,did,num;
2910   struct focuslist *focus;
2911   struct objlist *obj,*dobj=NULL,*aobj;
2912   char *inst,*inst2,*dinst,*dfield;
2913   int ret,section;
2914   int x1,y1;
2915   int aid=0,idx=0,idy=0,idu=0,idr=0,idg,j,lenx,leny;
2916   int findX,findY,findU,findR,findG;
2917   char *axisx,*axisy;
2918   int matchx,matchy;
2919   struct narray iarray,*sarray;
2920   int snum;
2921   char **sdata;
2922   GC dc;
2923   char type;
2924   char *group,*group2;
2925   int  axis;
2926   struct Viewer *d;
2927 
2928   if (menulock || globallock) return;
2929   d=&(NgraphApp.Viewer);
2930   dc=XCreateGC(Disp,d->win,0,0);
2931   ShowFocusFrame(dc);
2932   d->ShowFrame=FALSE;
2933   num=arraynum(d->focusobj);
2934   axis=FALSE;
2935   PaintLock=TRUE;
2936   for (i=num-1;i>=0;i--) {
2937     focus=*(struct focuslist **)arraynget(d->focusobj,i);
2938     if ((focus!=NULL) && ((inst=chkobjinstoid(focus->obj,focus->oid))!=NULL)) {
2939       obj=focus->obj;
2940       _getobj(obj,"id",inst,&id);
2941       ret=IDCANCEL;
2942       if (obj==chkobject("axis")) {
2943         axis=TRUE;
2944         _getobj(obj,"group",inst,&group);
2945         if ((group!=NULL) && (group[0]!='a')) {
2946           findX=findY=findU=findR=findG=FALSE;
2947           type=group[0];
2948           for (j=0;j<=id;j++) {
2949             inst2=chkobjinst(obj,j);
2950             _getobj(obj,"group",inst2,&group2);
2951             _getobj(obj,"id",inst2,&id2);
2952             if ((group2!=NULL) && (group2[0]==type)) {
2953               if (strcmp(group+2,group2+2)==0) {
2954                 if (group2[1]=='X') {
2955                   findX=TRUE;
2956                   idx=id2;
2957                 } else if (group2[1]=='Y') {
2958                   findY=TRUE;
2959                   idy=id2;
2960                 } else if (group2[1]=='U') {
2961                   findU=TRUE;
2962                   idu=id2;
2963                 } else if (group2[1]=='R') {
2964                   findR=TRUE;
2965                   idr=id2;
2966                 }
2967               }
2968             }
2969           }
2970           if (((type=='s') || (type=='f')) && findX && findY
2971           && !_getobj(menulocal.obj,"_list",menulocal.inst,&sarray)
2972           && ((snum=arraynum(sarray))>=0)) {
2973             sdata=(char **)arraydata(sarray);
2974             for (j=1;j<snum;j++) {
2975               if (((dobj=getobjlist(sdata[j],&did,&dfield,NULL))!=NULL)
2976               && (dobj==chkobject("axisgrid"))) {
2977                 if ((dinst=chkobjinstoid(dobj,did))!=NULL) {
2978                   _getobj(dobj,"axis_x",dinst,&axisx);
2979                   _getobj(dobj,"axis_y",dinst,&axisy);
2980                   matchx=matchy=FALSE;
2981                   if (axisx!=NULL) {
2982                     arrayinit(&iarray,sizeof(int));
2983                     if (!getobjilist(axisx,&aobj,&iarray,FALSE,NULL)) {
2984                       if ((arraynum(&iarray)>=1) && (obj==aobj)
2985                       && (*(int *)arraylast(&iarray)==idx)) matchx=TRUE;
2986                     }
2987                     arraydel(&iarray);
2988                   }
2989                   if (axisy!=NULL) {
2990                     arrayinit(&iarray,sizeof(int));
2991                     if (!getobjilist(axisy,&aobj,&iarray,FALSE,NULL)) {
2992                       if ((arraynum(&iarray)>=1) && (obj==aobj)
2993                       && (*(int *)arraylast(&iarray)==idy)) matchy=TRUE;
2994                     }
2995                     arraydel(&iarray);
2996                   }
2997                   if (matchx && matchy) {
2998                     findG=TRUE;
2999                     _getobj(dobj,"id",dinst,&idg);
3000                     break;
3001                   }
3002                 }
3003               }
3004             }
3005           }
3006           if (((type=='s') || (type=='f'))
3007           && findX && findY && findU && findR) {
3008             if (!findG) {
3009               dobj=chkobject("axisgrid");
3010               idg=-1;
3011             }
3012             if (type=='s') section=TRUE;
3013             else section=FALSE;
3014             getobj(obj,"y",idx,0,NULL,&y1);
3015             getobj(obj,"x",idy,0,NULL,&x1);
3016             getobj(obj,"y",idu,0,NULL,&leny);
3017             getobj(obj,"x",idr,0,NULL,&lenx);
3018             leny=y1-leny;
3019             lenx=lenx-x1;
3020             SectionDialog(&DlgSection,x1,y1,lenx,leny,obj,idx,
3021                           idy,idu,idr,dobj,&idg,section);
3022             ret=DialogExecute(TopLevel,&DlgSection);
3023             if (ret==IDDELETE) {
3024               AxisDel(id);
3025               arrayndel2(d->focusobj,i);
3026             }
3027             if (!findG) {
3028               if (idg!=-1) {
3029                 if ((dinst=chkobjinst(dobj,idg))!=NULL) AddList(dobj,dinst);
3030               }
3031             }
3032             if (ret!=IDCANCEL) NgraphApp.Changed=TRUE;
3033           } else if ((type=='c') && findX && findY) {
3034             getobj(obj,"x",idx,0,NULL,&x1);
3035             getobj(obj,"y",idy,0,NULL,&y1);
3036             getobj(obj,"length",idx,0,NULL,&lenx);
3037             getobj(obj,"length",idy,0,NULL,&leny);
3038             CrossDialog(&DlgCross,x1,y1,lenx,leny,obj,idx,idy);
3039             ret=DialogExecute(TopLevel,&DlgCross);
3040             if (ret==IDDELETE) {
3041               AxisDel(aid);
3042               arrayndel2(d->focusobj,i);
3043             }
3044             if (ret!=IDCANCEL) NgraphApp.Changed=TRUE;
3045           }
3046         } else {
3047           AxisDialog(&DlgAxis,obj,id,TRUE);
3048           ret=DialogExecute(TopLevel,&DlgAxis);
3049           if (ret==IDDELETE) {
3050             AxisDel(id);
3051             arrayndel2(d->focusobj,i);
3052           }
3053           if (ret!=IDCANCEL) NgraphApp.Changed=TRUE;
3054         }
3055       } else {
3056         AddInvalidateRect(obj,inst);
3057         if (obj==chkobject("line")) {
3058           LegendArrowDialog(&DlgLegendArrow,obj,id);
3059           ret=DialogExecute(TopLevel,&DlgLegendArrow);
3060         } else if (obj==chkobject("curve")) {
3061           LegendCurveDialog(&DlgLegendCurve,obj,id);
3062           ret=DialogExecute(TopLevel,&DlgLegendCurve);
3063         } else if (obj==chkobject("polygon")) {
3064           LegendPolyDialog(&DlgLegendPoly,obj,id);
3065           ret=DialogExecute(TopLevel,&DlgLegendPoly);
3066         } else if (obj==chkobject("rectangle")) {
3067           LegendRectDialog(&DlgLegendRect,obj,id);
3068           ret=DialogExecute(TopLevel,&DlgLegendRect);
3069         } else if (obj==chkobject("arc")) {
3070           LegendArcDialog(&DlgLegendArc,obj,id);
3071           ret=DialogExecute(TopLevel,&DlgLegendArc);
3072         } else if (obj==chkobject("mark")) {
3073           LegendMarkDialog(&DlgLegendMark,obj,id);
3074           ret=DialogExecute(TopLevel,&DlgLegendMark);
3075         } else if (obj==chkobject("text")) {
3076           LegendTextDialog(&DlgLegendText,obj,id);
3077           ret=DialogExecute(TopLevel,&DlgLegendText);
3078         } else if (obj==chkobject("merge")) {
3079           MergeDialog(&DlgMerge,obj,id);
3080           ret=DialogExecute(TopLevel,&DlgMerge);
3081         }
3082         if (ret==IDDELETE) {
3083           delobj(obj,id);
3084         }
3085         if (ret==IDOK) AddInvalidateRect(obj,inst);
3086         if (ret!=IDCANCEL) NgraphApp.Changed=TRUE;
3087       }
3088     }
3089   }
3090   PaintLock=FALSE;
3091   if ((d->Mode==LegendB) || ((d->Mode==PointB) && (!axis))) d->allclear=FALSE;
3092   UpdateAll();
3093   ShowFocusFrame(dc);
3094   d->ShowFrame=TRUE;
3095   XFreeGC(Disp,dc);
3096 }
3097 
ViewDelete()3098 void ViewDelete()
3099 {
3100   int i,id,num;
3101   struct focuslist *focus;
3102   struct objlist *obj;
3103   char *inst;
3104   GC dc;
3105   int axis;
3106   struct Viewer *d;
3107 
3108   d=&(NgraphApp.Viewer);
3109   if ((d->MouseMode==MOUSENONE)
3110   && ((d->Mode==PointB) || (d->Mode==LegendB) || (d->Mode==AxisB))) {
3111     dc=XCreateGC(Disp,d->win,0,0);
3112     ShowFocusFrame(dc);
3113     d->ShowFrame=FALSE;
3114     axis=FALSE;
3115     PaintLock=TRUE;
3116     num=arraynum(d->focusobj);
3117     for (i=num-1;i>=0;i--) {
3118       focus=*(struct focuslist **)arraynget(d->focusobj,i);
3119       obj=focus->obj;
3120       if ((inst=chkobjinstoid(obj,focus->oid))!=NULL) {
3121         AddInvalidateRect(obj,inst);
3122         DelList(obj,inst);
3123         _getobj(obj,"id",inst,&id);
3124         if (obj==chkobject("axis")) {
3125           AxisDel(id);
3126           axis=TRUE;
3127         } else delobj(obj,id);
3128         NgraphApp.Changed=TRUE;
3129       }
3130     }
3131     PaintLock=FALSE;
3132     if ((d->Mode==LegendB) || ((d->Mode==PointB) && (!axis)))
3133       d->allclear=FALSE;
3134     if (num!=0) UpdateAll();
3135   }
3136 }
3137 
ViewTop()3138 void ViewTop()
3139 {
3140   int id,num;
3141   struct focuslist *focus;
3142   struct objlist *obj;
3143   char *inst;
3144   struct Viewer *d;
3145 
3146   d=&(NgraphApp.Viewer);
3147   if ((d->MouseMode==MOUSENONE)
3148   && ((d->Mode==PointB) || (d->Mode==LegendB) || (d->Mode==AxisB))) {
3149     num=arraynum(d->focusobj);
3150     if (num==1) {
3151       focus=*(struct focuslist **)arraynget(d->focusobj,0);
3152       obj=focus->obj;
3153       if (chkobjchild(chkobject("legend"),obj)) {
3154         if ((inst=chkobjinstoid(obj,focus->oid))!=NULL) {
3155           DelList(obj,inst);
3156           _getobj(obj,"id",inst,&id);
3157           movetopobj(obj,id);
3158           AddList(obj,inst);
3159           NgraphApp.Changed=TRUE;
3160           d->allclear=TRUE;
3161           UpdateAll();
3162         }
3163       }
3164     }
3165   }
3166 }
3167 
ViewLast()3168 void ViewLast()
3169 {
3170   int id,num;
3171   struct focuslist *focus;
3172   struct objlist *obj;
3173   char *inst;
3174   struct Viewer *d;
3175 
3176   d=&(NgraphApp.Viewer);
3177   if ((d->MouseMode==MOUSENONE)
3178   && ((d->Mode==PointB) || (d->Mode==LegendB) || (d->Mode==AxisB))) {
3179     num=arraynum(d->focusobj);
3180     if (num==1) {
3181       focus=*(struct focuslist **)arraynget(d->focusobj,0);
3182       obj=focus->obj;
3183       if (chkobjchild(chkobject("legend"),obj)) {
3184         if ((inst=chkobjinstoid(obj,focus->oid))!=NULL) {
3185           DelList(obj,inst);
3186           _getobj(obj,"id",inst,&id);
3187           movelastobj(obj,id);
3188           AddList(obj,inst);
3189           NgraphApp.Changed=TRUE;
3190           d->allclear=TRUE;
3191           UpdateAll();
3192          }
3193       }
3194     }
3195   }
3196 }
3197 
ncopyobj(struct objlist * obj,int id1,int id2)3198 void ncopyobj(struct objlist *obj,int id1,int id2)
3199 {
3200   int j;
3201   char *field;
3202   int perm,type;
3203 
3204   for (j=0;j<chkobjfieldnum(obj);j++) {
3205     field=chkobjfieldname(obj,j);
3206     perm=chkobjperm(obj,field);
3207     type=chkobjfieldtype(obj,field);
3208     if (((perm&NREAD)!=0) && ((perm&NWRITE)!=0) && (type<NVFUNC))
3209       copyobj(obj,field,id1,id2);
3210   }
3211 }
3212 
ViewCopy()3213 void ViewCopy()
3214 {
3215   int i,j,id,id2,did,num;
3216   struct focuslist *focus;
3217   struct objlist *obj,*dobj,*aobj;
3218   char *inst,*inst2,*dinst,*dfield;
3219   GC dc;
3220   int findX,findY,findU,findR,findG;
3221   char *axisx,*axisy;
3222   int matchx,matchy;
3223   struct narray iarray,*sarray;
3224   int snum;
3225   char **sdata;
3226   int oidx,oidy;
3227   int idx=0,idy=0,idu=0,idr=0,idg;
3228   int idx2,idy2,idu2,idr2,idg2;
3229   char type;
3230   char *group,*group2;
3231   int tp;
3232   struct narray agroup;
3233   char *argv[2];
3234   int axis;
3235   struct Viewer *d;
3236 
3237   d=&(NgraphApp.Viewer);
3238   if ((d->MouseMode==MOUSENONE)
3239   && ((d->Mode==PointB) || (d->Mode==LegendB) || (d->Mode==AxisB))) {
3240     dc=XCreateGC(Disp,d->win,0,0);
3241     ShowFocusFrame(dc);
3242     d->ShowFrame=FALSE;
3243     axis=FALSE;
3244     PaintLock=TRUE;
3245     num=arraynum(d->focusobj);
3246     for (i=0;i<num;i++) {
3247       focus=*(struct focuslist **)arraynget(d->focusobj,i);
3248       if ((focus!=NULL)
3249       && ((inst=chkobjinstoid(focus->obj,focus->oid))!=NULL)) {
3250         obj=focus->obj;
3251         _getobj(obj,"id",inst,&id);
3252         if (obj==chkobject("axis")) {
3253           axis=TRUE;
3254           _getobj(obj,"group",inst,&group);
3255           if ((group!=NULL) && (group[0]!='a')) {
3256             findX=findY=findU=findR=findG=FALSE;
3257             type=group[0];
3258             for (j=0;j<=id;j++) {
3259               inst2=chkobjinst(obj,j);
3260               _getobj(obj,"group",inst2,&group2);
3261               _getobj(obj,"id",inst2,&id2);
3262               if ((group2!=NULL) && (group2[0]==type)) {
3263                 if (strcmp(group+2,group2+2)==0) {
3264                   if (group2[1]=='X') {
3265                     findX=TRUE;
3266                     idx=id2;
3267                   } else if (group2[1]=='Y') {
3268                     findY=TRUE;
3269                     idy=id2;
3270                   } else if (group2[1]=='U') {
3271                     findU=TRUE;
3272                     idu=id2;
3273                   } else if (group2[1]=='R') {
3274                     findR=TRUE;
3275                     idr=id2;
3276                   }
3277                 }
3278               }
3279             }
3280             if (((type=='s') || (type=='f')) && findX && findY
3281             && !_getobj(menulocal.obj,"_list",menulocal.inst,&sarray)
3282             && ((snum=arraynum(sarray))>=0)) {
3283               sdata=(char **)arraydata(sarray);
3284               for (j=1;j<snum;j++) {
3285                 if (((dobj=getobjlist(sdata[j],&did,&dfield,NULL))!=NULL)
3286                 && (dobj==chkobject("axisgrid"))) {
3287                   if ((dinst=chkobjinstoid(dobj,did))!=NULL) {
3288                     _getobj(dobj,"axis_x",dinst,&axisx);
3289                     _getobj(dobj,"axis_y",dinst,&axisy);
3290                     matchx=matchy=FALSE;
3291                     if (axisx!=NULL) {
3292                       arrayinit(&iarray,sizeof(int));
3293                       if (!getobjilist(axisx,&aobj,&iarray,FALSE,NULL)) {
3294                         if ((arraynum(&iarray)>=1) && (obj==aobj)
3295                         && (*(int *)arraylast(&iarray)==idx)) matchx=TRUE;
3296                       }
3297                       arraydel(&iarray);
3298                     }
3299                     if (axisy!=NULL) {
3300                       arrayinit(&iarray,sizeof(int));
3301                       if (!getobjilist(axisy,&aobj,&iarray,FALSE,NULL)) {
3302                         if ((arraynum(&iarray)>=1) && (obj==aobj)
3303                         && (*(int *)arraylast(&iarray)==idy)) matchy=TRUE;
3304                       }
3305                       arraydel(&iarray);
3306                     }
3307                     if (matchx && matchy) {
3308                       findG=TRUE;
3309                       _getobj(dobj,"id",dinst,&idg);
3310                       break;
3311                     }
3312                   }
3313                 }
3314               }
3315             }
3316             if (((type=='s') || (type=='f'))
3317             && findX && findY && findU && findR) {
3318               if ((idx2=newobj(obj))>=0) {
3319                 ncopyobj(obj,idx2,idx);
3320                 inst2=chkobjinst(obj,idx2);
3321                 _getobj(obj,"oid",inst2,&oidx);
3322                 AddList(obj,inst2);
3323                 AddInvalidateRect(obj,inst2);
3324                 NgraphApp.Changed=TRUE;
3325               } else {
3326                 AddInvalidateRect(obj,inst);
3327               }
3328               if ((idy2=newobj(obj))>=0) {
3329                 ncopyobj(obj,idy2,idy);
3330                 inst2=chkobjinst(obj,idy2);
3331                 _getobj(obj,"oid",inst2,&oidy);
3332                 AddList(obj,inst2);
3333                 AddInvalidateRect(obj,inst2);
3334                 NgraphApp.Changed=TRUE;
3335               } else {
3336                 AddInvalidateRect(obj,inst);
3337               }
3338               if ((idu2=newobj(obj))>=0) {
3339                 ncopyobj(obj,idu2,idu);
3340                 inst2=chkobjinst(obj,idu2);
3341                 if ((idx2>=0) && ((axisx=(char *)memalloc(13))!=NULL)) {
3342                   sprintf(axisx,"axis:^%d",oidx);
3343                   putobj(obj,"reference",idu2,axisx);
3344                 }
3345                 AddList(obj,inst2);
3346                 AddInvalidateRect(obj,inst2);
3347                 NgraphApp.Changed=TRUE;
3348               } else {
3349                 AddInvalidateRect(obj,inst);
3350               }
3351               if ((idr2=newobj(obj))>=0) {
3352                 ncopyobj(obj,idr2,idr);
3353                 inst2=chkobjinst(obj,idr2);
3354                 if ((idy2>=0) && ((axisy=(char *)memalloc(13))!=NULL)) {
3355                   sprintf(axisy,"axis:^%d",oidy);
3356                   putobj(obj,"reference",idr2,axisy);
3357                 }
3358                 arrayinit(&agroup,sizeof(int));
3359                 if (type=='f') tp=1;
3360                 else tp=2;
3361                 arrayadd(&agroup,&tp);
3362                 arrayadd(&agroup,&idx2);
3363                 arrayadd(&agroup,&idy2);
3364                 arrayadd(&agroup,&idu2);
3365                 arrayadd(&agroup,&idr2);
3366                 argv[0]=(char *)&agroup;
3367                 argv[1]=NULL;
3368                 exeobj(obj,"grouping",idr2,1,argv);
3369                 arraydel(&agroup);
3370                 _getobj(obj,"oid",inst2,&(focus->oid));
3371                 AddList(obj,inst2);
3372                 AddInvalidateRect(obj,inst2);
3373                 NgraphApp.Changed=TRUE;
3374               } else {
3375                 AddInvalidateRect(obj,inst);
3376               }
3377               if (findG) {
3378                 dobj=chkobject("axisgrid");
3379                 if ((idg2=newobj(dobj))>=0) {
3380                   ncopyobj(dobj,idg2,idg);
3381                   inst2=chkobjinst(dobj,idg2);
3382                   if ((idx2>=0) && (idu2>=0)
3383                   && ((axisx=(char *)memalloc(13))!=NULL)) {
3384                     sprintf(axisx,"axis:^%d",oidx);
3385                     putobj(dobj,"axis_x",idg2,axisx);
3386                   }
3387                   if ((idy2>=0) && (idr2>=0)
3388                   && ((axisy=(char *)memalloc(13))!=NULL)) {
3389                     sprintf(axisy,"axis:^%d",oidy);
3390                     putobj(dobj,"axis_y",idg2,axisy);
3391                   }
3392                   AddList(dobj,inst2);
3393                   NgraphApp.Changed=TRUE;
3394                 }
3395               }
3396             } else if ((type=='c') && findX && findY) {
3397               if ((idx2=newobj(obj))>=0) {
3398                 ncopyobj(obj,idx2,idx);
3399                 inst2=chkobjinst(obj,idx2);
3400                 _getobj(obj,"oid",inst2,&oidx);
3401                 AddList(obj,inst2);
3402                 AddInvalidateRect(obj,inst2);
3403                 NgraphApp.Changed=TRUE;
3404               } else {
3405                 AddInvalidateRect(obj,inst);
3406               }
3407               if ((idy2=newobj(obj))>=0) {
3408                 ncopyobj(obj,idy2,idy);
3409                 inst2=chkobjinst(obj,idy2);
3410                 _getobj(obj,"oid",inst2,&oidy);
3411                 arrayinit(&agroup,sizeof(int));
3412                 tp=3;
3413                 arrayadd(&agroup,&tp);
3414                 arrayadd(&agroup,&idx2);
3415                 arrayadd(&agroup,&idy2);
3416                 argv[0]=(char *)&agroup;
3417                 argv[1]=NULL;
3418                 exeobj(obj,"grouping",idy2,1,argv);
3419                 arraydel(&agroup);
3420                 focus->oid=oidy;
3421                 AddList(obj,inst2);
3422                 AddInvalidateRect(obj,inst2);
3423                 NgraphApp.Changed=TRUE;
3424               } else {
3425                 AddInvalidateRect(obj,inst);
3426               }
3427               if ((idx2>=0) && (idy2>=0)) {
3428                 if ((axisy=(char *)memalloc(13))!=NULL) {
3429                   sprintf(axisy,"axis:^%d",oidy);
3430                   putobj(obj,"adjust_axis",idx2,axisy);
3431                 }
3432                 if ((axisx=(char *)memalloc(13))!=NULL) {
3433                   sprintf(axisx,"axis:^%d",oidx);
3434                   putobj(obj,"adjust_axis",idy2,axisx);
3435                 }
3436               }
3437             }
3438           } else {
3439             if ((id2=newobj(obj))>=0) {
3440               ncopyobj(obj,id2,id);
3441               inst2=chkobjinst(obj,id2);
3442               _getobj(obj,"oid",inst2,&(focus->oid));
3443               AddList(obj,inst2);
3444               AddInvalidateRect(obj,inst2);
3445               NgraphApp.Changed=TRUE;
3446             } else {
3447               AddInvalidateRect(obj,inst);
3448             }
3449           }
3450         } else {
3451           if ((id2=newobj(obj))>=0) {
3452             ncopyobj(obj,id2,id);
3453             inst2=chkobjinst(obj,id2);
3454             _getobj(obj,"oid",inst2,&(focus->oid));
3455             AddList(obj,inst2);
3456             AddInvalidateRect(obj,inst2);
3457             NgraphApp.Changed=TRUE;
3458           } else {
3459             AddInvalidateRect(obj,inst);
3460           }
3461         }
3462       }
3463     }
3464     PaintLock=FALSE;
3465     if ((d->Mode==LegendB) || ((d->Mode==PointB) && (!axis)))
3466       d->allclear=FALSE;
3467     UpdateAll();
3468     ShowFocusFrame(dc);
3469     d->ShowFrame=TRUE;
3470     XFreeGC(Disp,dc);
3471   }
3472 }
3473 
ViewCross()3474 void ViewCross()
3475 {
3476   GC dc;
3477   struct Viewer *d;
3478 
3479   d=&(NgraphApp.Viewer);
3480   dc=XCreateGC(Disp,d->win,0,0);
3481   if (d->ShowCross) {
3482     ShowCrossGauge(dc);
3483     d->ShowCross=FALSE;
3484   } else {
3485     ShowCrossGauge(dc);
3486     d->ShowCross=TRUE;
3487   }
3488   XFreeGC(Disp,dc);
3489 }
3490 
ViewerPopupMenu(Widget w,XtPointer client_data,XtPointer call_data)3491 void ViewerPopupMenu(Widget w,XtPointer client_data,XtPointer call_data)
3492 {
3493   switch ((int )client_data) {
3494   case 0:
3495     ViewUpdate();
3496     break;
3497   case 1:
3498     ViewDelete();
3499     break;
3500   case 2:
3501     ViewCopy();
3502     break;
3503   case 3:
3504     ViewTop();
3505     break;
3506   case 4:
3507     ViewLast();
3508     break;
3509   case 5:
3510     ViewCross();
3511     break;
3512   }
3513 }
3514 
CmViewerButtonArm(Widget w,XtPointer client_data,XtPointer call_data)3515 void CmViewerButtonArm(Widget w,XtPointer client_data,XtPointer call_data)
3516 {
3517   int i,Mode=PointB;
3518   struct Viewer *d;
3519 
3520   d=&(NgraphApp.Viewer);
3521   UnFocus();
3522   for(i=0;i<19;i++) {
3523     if (w==NgraphApp.viewb[i]) {
3524       Mode=NgraphApp.Viewer.Mode=i;
3525       XtVaSetValues(NgraphApp.viewb[i],XmNset,XmSET,NULL);
3526     } else XtVaSetValues(NgraphApp.viewb[i],XmNset,XmUNSET,NULL);
3527   }
3528   if ((Mode==PointB) || (Mode==LegendB) || (Mode==AxisB) || (Mode==TrimB)
3529    || (Mode==DataB) || (Mode==EvalB)) {
3530     SetCursor(XC_left_ptr);
3531   } else if (Mode==TextB) {
3532     SetCursor(XC_xterm);
3533   } else if (Mode==ZoomB) {
3534     SetCursor(XC_zoomin);
3535   } else {
3536     SetCursor(XC_crosshair);
3537   }
3538   NgraphApp.Viewer.Capture=FALSE;
3539   NgraphApp.Viewer.MouseMode=MOUSENONE;
3540 }
3541