1 /*
2  * $Id: x11print.c,v 1.5 2003/02/16 12:43: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: x11print.c,v $
27  * Revision 1.5  2003/02/16 12:43:37  isizaka
28  * for release 6.13.18
29  *
30  * Revision 1.4  2002/07/06 08:57:25  isizaka
31  * change to GPL.
32  *
33  * Revision 1.3  2001/03/23 12:17:43  isizaka
34  * for 6.3.13
35  *
36  * Revision 1.2  1999/04/11 06:09:20  isizaka
37  * *** empty log message ***
38  *
39  * Revision 1.1  1999/03/17 13:29:01  isizaka
40  * Initial revision
41  *
42  *
43  **/
44 
45 #include <Xm/XmAll.h>
46 #include <stdlib.h>
47 #include <stdio.h>
48 #include <unistd.h>
49 
50 #include "motif12.h"
51 
52 #include "ngraph.h"
53 #include "object.h"
54 #include "ioutil.h"
55 #include "mathcode.h"
56 
57 #include "x11gui.h"
58 #include "x11dialg.h"
59 #include "ox11menu.h"
60 #include "x11menu.h"
61 #include "x11print.h"
62 #include "x11file.h"
63 #include "x11commn.h"
64 #include "x11view.h"
65 
DriverDialogSelectCB(Widget w,XtPointer client_data,XtPointer call_data)66 void DriverDialogSelectCB(Widget w,XtPointer client_data,XtPointer call_data)
67 {
68   int a,i,j;
69   char *s;
70   struct extprinter *pcur;
71   struct DriverDialog *d;
72   XmComboBoxCallbackStruct *dd;
73   char buf[1024];
74 
75   dd=(XmComboBoxCallbackStruct *)call_data;
76   d=(struct DriverDialog *)client_data;
77 #ifdef ZEROBASECOMBOBOX
78   a=dd->item_position;
79 #else
80   a=dd->item_position-1;
81 #endif
82   if (a<0) return;
83   pcur=menulocal.extprinterroot;
84   i=0;
85   while (pcur!=NULL) {
86     if (i==a) {
87       XtVaSetValues(XtNameToWidget(d->widget,"*file"),XmNvalue,"",NULL);
88       if ((pcur->ext!=NULL) && (pcur->ext[0]!='\0')
89       && (NgraphApp.FileName!=NULL)) {
90         strcpy(buf,NgraphApp.FileName);
91         if (strchr(buf,'.')!=NULL) {
92           for (j=strlen(buf)-1;buf[j]!='.';j--);
93           buf[j]='\0';
94         }
95         strcat(buf,pcur->ext);
96         XtVaSetValues(XtNameToWidget(d->widget,"*file"),XmNvalue,buf,NULL);
97       }
98       if (pcur->option==NULL) s="";
99       else s=pcur->option;
100       XtVaSetValues(XtNameToWidget(d->widget,"*option"),XmNvalue,s,NULL);
101       break;
102     }
103     pcur=pcur->next;
104     i++;
105   }
106 }
107 
DriverDialogBrowseCB(Widget w,XtPointer client_data,XtPointer call_data)108 void DriverDialogBrowseCB(Widget w,XtPointer client_data,XtPointer call_data)
109 {
110   char *file;
111   struct DriverDialog *d;
112 
113   d=(struct DriverDialog *)client_data;
114   if (nGetSaveFileName(TopLevel,"External Driver Output",NULL,NULL,
115       NULL,&file,"*",menulocal.changedirectory)==IDOK) {
116     XtVaSetValues(XtNameToWidget(d->widget,"*file"),XmNvalue,file,NULL);
117   }
118   free(file);
119 }
120 
DriverDialogSetup(Widget w,void * data,int makewidget)121 void DriverDialogSetup(Widget w,void *data,int makewidget)
122 {
123   Arg al[20];
124   Cardinal ac;
125   Widget rc,rc1;
126   XmString s;
127   struct DriverDialog *d;
128   struct extprinter *pcur;
129   int j;
130 
131   d=(struct DriverDialog *)data;
132   if (makewidget) {
133     ac=0;
134     XtSetArg(al[ac],XmNorientation,XmVERTICAL); ac++;
135     XtManageChild(rc=XmCreateRowColumn(w,"rc",al,ac));
136     ac=0;
137     XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
138     XtManageChild(rc1=XmCreateRowColumn(rc,"driverrc",al,ac));
139     ac=0;
140     XtManageChild(XmCreateLabel(rc1,"Driver",al,ac));
141     ac=0;
142     XtSetArg(al[ac],XmNcomboBoxType,XmDROP_DOWN_LIST); ac++;
143     XtManageChild(XmCreateComboBox(rc1,"driver",al,ac));
144     XtAddCallback(XtNameToWidget(w,"*driver"),XmNselectionCallback,
145                   DriverDialogSelectCB,d);
146     ac=0;
147     XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
148     XtManageChild(rc1=XmCreateRowColumn(rc,"optionrc",al,ac));
149     ac=0;
150     XtManageChild(XmCreateLabel(rc1,"Option",al,ac));
151     ac=0;
152     XtManageChild(XmCreateTextField(rc1,"option",al,ac));
153     ac=0;
154     XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
155     XtManageChild(rc1=XmCreateRowColumn(rc,"filerc",al,ac));
156     ac=0;
157     XtManageChild(XmCreateLabel(rc1,"File",al,ac));
158     ac=0;
159     XtManageChild(XmCreateTextField(rc1,"file",al,ac));
160     ac=0;
161     XtManageChild(XmCreatePushButton(rc1,"Browse",al,ac));
162     XtAddCallback(XtNameToWidget(w,"*Browse"),XmNdisarmCallback,
163                   DriverDialogBrowseCB,d);
164   }
165   XmListDeleteAllItems(GetComboBoxList(w,"*driver"));
166   pcur=menulocal.extprinterroot;
167   j=0;
168   while (pcur!=NULL) {
169     s=XmStringCreateLocalized(pcur->name);
170     XmListAddItem(GetComboBoxList(w,"*driver"),s,0);
171     XmStringFree(s);
172     pcur=pcur->next;
173     j++;
174   }
175   SetComboBoxVisibleItemCount(w,"*driver",j);
176   XmListSelectPos(GetComboBoxList(w,"*driver"),1,TRUE);
177 }
178 
DriverDialogClose(Widget w,void * data)179 void DriverDialogClose(Widget w,void *data)
180 {
181   int a,*selected,count,i,j,len1,len2;
182   struct extprinter *pcur;
183   struct DriverDialog *d;
184   char *s,*driver,*option,*file;
185   char *buf;
186 
187   d=(struct DriverDialog *)data;
188   if (d->ret==IDCANCEL) return;
189   XmListGetSelectedPos(GetComboBoxList(w,"*driver"),&selected,&count);
190   if (count!=0) {
191     a=selected[0]-1;
192     XtFree((char *)selected);
193     pcur=menulocal.extprinterroot;
194     i=0;
195     while (pcur!=NULL) {
196       if (i==a) {
197         if (pcur->driver!=NULL) {
198           if ((driver=(char *)memalloc(strlen(pcur->driver)+1))!=NULL) {
199             strcpy(driver,pcur->driver);
200             putobj(d->Obj,"driver",d->Id,driver);
201           }
202         }
203         break;
204       }
205       pcur=pcur->next;
206       i++;
207     }
208   }
209   XtVaGetValues(XtNameToWidget(w,"*option"),XmNvalue,&s,NULL);
210   XtVaGetValues(XtNameToWidget(w,"*file"),XmNvalue,&file,NULL);
211   if (s==NULL) len1=0;
212   else len1=strlen(s);
213   if (file==NULL) len2=0;
214   else len2=strlen(file);
215   if ((option=memalloc(len1+len2+7))!=NULL) {
216     j=0;
217     option[j]='\0';
218     if (len2!=0) {
219       if (access(file,04)==0) {
220         buf=(char *)memalloc(len2+60);
221         if (buf!=NULL) {
222           sprintf(buf,"`%s'\n\nOverwrite existing file?",file);
223           if (MessageBox(TopLevel,buf,"Driver",MB_YESNO)!=IDYES) {
224             memfree(buf);
225             memfree(option);
226             XtFree(s);
227             XtFree(file);
228             d->ret=IDCANCEL;
229             return;
230           }
231           memfree(buf);
232         } else {
233           if (MessageBox(TopLevel,"Overwrite existing file?",
234                          "Driver",MB_YESNO)!=IDNO) {
235             memfree(option);
236             XtFree(s);
237             XtFree(file);
238             d->ret=IDCANCEL;
239             return;
240           }
241         }
242       }
243       option[j++]='-';
244       option[j++]='o';
245       option[j++]=' ';
246       option[j++]='\'';
247       strcpy(option+j,file);
248       j=strlen(option);
249       option[j++]='\'';
250       option[j++]=' ';
251       option[j]='\0';
252       changefilename(option);
253     }
254     if (len1!=0) strcat(option,s);
255     putobj(d->Obj,"option",d->Id,option);
256   } else {
257     XtFree(s);
258     XtFree(file);
259     d->ret=IDCANCEL;
260     return;
261   }
262   XtFree(s);
263   XtFree(file);
264 }
265 
DriverDialog(struct DriverDialog * data,struct objlist * obj,int id)266 void DriverDialog(struct DriverDialog *data,
267                  struct objlist *obj,int id)
268 {
269   data->SetupWindow=DriverDialogSetup;
270   data->CloseWindow=DriverDialogClose;
271   data->Obj=obj;
272   data->Id=id;
273 }
274 
PrintDialogSelectCB(Widget w,XtPointer client_data,XtPointer call_data)275 void PrintDialogSelectCB(Widget w,XtPointer client_data,XtPointer call_data)
276 {
277   int a,i;
278   char *s;
279   struct prnprinter *pcur;
280   struct PrintDialog *d;
281   XmComboBoxCallbackStruct *dd;
282 
283   dd=(XmComboBoxCallbackStruct *)call_data;
284   d=(struct PrintDialog *)client_data;
285 #ifdef ZEROBASECOMBOBOX
286   a=dd->item_position;
287 #else
288   a=dd->item_position-1;
289 #endif
290   if (a<0) return;
291   pcur=menulocal.prnprinterroot;
292   i=0;
293   while (pcur!=NULL) {
294     if (i==a) {
295       if (pcur->option==NULL) s="";
296       else s=pcur->option;
297       XtVaSetValues(XtNameToWidget(d->widget,"*option"),XmNvalue,s,NULL);
298       if (pcur->prn==NULL) s="";
299       else s=pcur->prn;
300       XtVaSetValues(XtNameToWidget(d->widget,"*print"),XmNvalue,s,NULL);
301       break;
302     }
303     pcur=pcur->next;
304     i++;
305   }
306 }
307 
PrintDialogSetup(Widget w,void * data,int makewidget)308 void PrintDialogSetup(Widget w,void *data,int makewidget)
309 {
310   Arg al[20];
311   Cardinal ac;
312   Widget rc,rc1;
313   XmString s;
314   struct PrintDialog *d;
315   struct prnprinter *pcur;
316   int j;
317 
318   d=(struct PrintDialog *)data;
319   if (makewidget) {
320     ac=0;
321     XtSetArg(al[ac],XmNorientation,XmVERTICAL); ac++;
322     XtManageChild(rc=XmCreateRowColumn(w,"rc",al,ac));
323     ac=0;
324     XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
325     XtManageChild(rc1=XmCreateRowColumn(rc,"driverrc",al,ac));
326     ac=0;
327     XtManageChild(XmCreateLabel(rc1,"Driver",al,ac));
328     ac=0;
329     XtSetArg(al[ac],XmNcomboBoxType,XmDROP_DOWN_LIST); ac++;
330     XtManageChild(XmCreateComboBox(rc1,"driver",al,ac));
331     XtAddCallback(XtNameToWidget(w,"*driver"),XmNselectionCallback,
332                   PrintDialogSelectCB,d);
333     ac=0;
334     XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
335     XtManageChild(rc1=XmCreateRowColumn(rc,"optionrc",al,ac));
336     ac=0;
337     XtManageChild(XmCreateLabel(rc1,"Option",al,ac));
338     ac=0;
339     XtManageChild(XmCreateTextField(rc1,"option",al,ac));
340     ac=0;
341     XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
342     XtManageChild(rc1=XmCreateRowColumn(rc,"printrc",al,ac));
343     ac=0;
344     XtManageChild(XmCreateLabel(rc1,"Print",al,ac));
345     ac=0;
346     XtManageChild(XmCreateTextField(rc1,"print",al,ac));
347   }
348 
349   XmListDeleteAllItems(GetComboBoxList(w,"*driver"));
350   pcur=menulocal.prnprinterroot;
351   j=0;
352   while (pcur!=NULL) {
353     s=XmStringCreateLocalized(pcur->name);
354     XmListAddItem(GetComboBoxList(w,"*driver"),s,0);
355     XmStringFree(s);
356     pcur=pcur->next;
357     j++;
358   }
359   SetComboBoxVisibleItemCount(w,"*driver",j);
360   XmListSelectPos(GetComboBoxList(w,"*driver"),1,TRUE);
361 }
362 
PrintDialogClose(Widget w,void * data)363 void PrintDialogClose(Widget w,void *data)
364 {
365   int a,*selected,count,i;
366   struct prnprinter *pcur;
367   struct PrintDialog *d;
368   char *s,*driver,*option,*prn;
369 
370   d=(struct PrintDialog *)data;
371   if (d->ret==IDCANCEL) return;
372   XmListGetSelectedPos(GetComboBoxList(w,"*driver"),&selected,&count);
373   if (count!=0) {
374     a=selected[0]-1;
375     XtFree((char *)selected);
376     pcur=menulocal.prnprinterroot;
377     i=0;
378     while (pcur!=NULL) {
379       if (i==a) {
380         if (pcur->driver!=NULL) {
381           if ((driver=(char *)memalloc(strlen(pcur->driver)+1))!=NULL) {
382             strcpy(driver,pcur->driver);
383             putobj(d->Obj,"driver",d->Id,driver);
384           }
385         }
386         break;
387       }
388       pcur=pcur->next;
389       i++;
390     }
391   }
392   XtVaGetValues(XtNameToWidget(w,"*option"),XmNvalue,&s,NULL);
393   if ((s!=NULL) && (strlen(s)!=0)) {
394     if ((option=(char *)memalloc(strlen(s)+1))!=NULL) {
395       strcpy(option,s);
396       putobj(d->Obj,"option",d->Id,option);
397     }
398   }
399   XtFree(s);
400   XtVaGetValues(XtNameToWidget(w,"*print"),XmNvalue,&s,NULL);
401   if ((s!=NULL) && (strlen(s)!=0)) {
402     if ((prn=(char *)memalloc(strlen(s)+1))!=NULL) {
403       strcpy(prn,s);
404       putobj(d->Obj,"prn",d->Id,prn);
405     }
406   }
407   XtFree(s);
408 }
409 
PrintDialog(struct PrintDialog * data,struct objlist * obj,int id)410 void PrintDialog(struct PrintDialog *data,
411                  struct objlist *obj,int id)
412 {
413   data->SetupWindow=PrintDialogSetup;
414   data->CloseWindow=PrintDialogClose;
415   data->Obj=obj;
416   data->Id=id;
417 }
418 
OutputDataDialogSetupItem(Widget w,struct OutputDataDialog * d)419 void OutputDataDialogSetupItem(Widget w,struct OutputDataDialog *d)
420 {
421   char buf[256];
422 
423   sprintf(buf,"%d",d->div);
424   XtVaSetValues(XtNameToWidget(w,"*div"),XmNvalue,buf,NULL);
425 }
426 
OutputDataDialogSetup(Widget w,void * data,int makewidget)427 void OutputDataDialogSetup(Widget w,void *data,int makewidget)
428 {
429   Arg al[20];
430   Cardinal ac;
431   Widget rc;
432   struct OutputDataDialog *d;
433 
434   d=(struct OutputDataDialog *)data;
435   if (makewidget) {
436     ac=0;
437     XtSetArg(al[ac],XmNorientation,XmHORIZONTAL); ac++;
438     XtManageChild(rc=XmCreateRowColumn(w,"rc",al,ac));
439     ac=0;
440     XtManageChild(XmCreateLabel(rc,"Div",al,ac));
441     ac=0;
442     XtManageChild(XmCreateTextField(rc,"div",al,ac));
443   }
444   OutputDataDialogSetupItem(w,d);
445 }
446 
OutputDataDialogClose(Widget w,void * data)447 void OutputDataDialogClose(Widget w,void *data)
448 {
449   struct OutputDataDialog *d;
450   int a;
451   char *buf,*endptr;
452 
453   d=(struct OutputDataDialog *)data;
454   if (d->ret!=IDOK) return;
455   XtVaGetValues(XtNameToWidget(d->widget,"*div"),XmNvalue,&buf,NULL);
456   a=strtol(buf,&endptr,10);
457   if (endptr[0]=='\0') d->div=a;
458   XtFree(buf);
459 }
460 
OutputDataDialog(struct OutputDataDialog * data,int div)461 void OutputDataDialog(struct OutputDataDialog *data,int div)
462 {
463   data->SetupWindow=OutputDataDialogSetup;
464   data->CloseWindow=OutputDataDialogClose;
465   data->div=div;
466 }
467 
CmOutputDriver(int print)468 void CmOutputDriver(int print)
469 {
470   struct objlist *graobj,*g2wobj;
471   int id,g2wid,g2woid;
472   char *device,*g2winst;
473   int GC;
474   struct narray *drawrable;
475   int i,ret;
476   struct savedstdio stdio;
477 
478   if (menulock || globallock ) return;
479   if (SetFileHidden()) {
480     FileAutoScale();
481     AdjustAxis();
482     if ((graobj=chkobject("gra"))==NULL) return;
483     if ((g2wobj=chkobject("gra2prn"))==NULL) return;
484     g2wid=newobj(g2wobj);
485     if (g2wid>=0) {
486       if (print) {
487         PrintDialog(&DlgPrinter,g2wobj,g2wid);
488         ret=DialogExecute(TopLevel,&DlgPrinter);
489       } else {
490         DriverDialog(&DlgDriver,g2wobj,g2wid);
491         ret=DialogExecute(TopLevel,&DlgDriver);
492       }
493       if (ret==IDOK) {
494         SetStatusBar("Spawning external driver.");
495         g2winst=chkobjinst(g2wobj,g2wid);
496         _getobj(g2wobj,"oid",g2winst,&g2woid);
497         id=newobj(graobj);
498         putobj(graobj,"paper_width",id,&(menulocal.PaperWidth));
499         putobj(graobj,"paper_height",id,&(menulocal.PaperHeight));
500         putobj(graobj,"left_margin",id,&(menulocal.LeftMargin));
501         putobj(graobj,"top_margin",id,&(menulocal.TopMargin));
502         putobj(graobj,"zoom",id,&(menulocal.PaperZoom));
503         if (arraynum(&(menulocal.drawrable))>0) {
504           drawrable=arraynew(sizeof(char *));
505           for (i=0;i<arraynum(&(menulocal.drawrable));i++) {
506             arrayadd2(drawrable,(char **)arraynget(&(menulocal.drawrable),i));
507           }
508         } else drawrable=NULL;
509         putobj(graobj,"draw_obj",id,drawrable);
510         device=(char *)memalloc(20);
511         sprintf(device,"gra2prn:^%d",g2woid);
512         putobj(graobj,"device",id,device);
513         SetStatusBar("Printing.");
514         ignorestdio(&stdio);
515         getobj(graobj,"open",id,0,NULL,&GC);
516         exeobj(graobj,"draw",id,0,NULL);
517         exeobj(graobj,"flush",id,0,NULL);
518         exeobj(graobj,"close",id,0,NULL);
519         restorestdio(&stdio);
520         delobj(graobj,id);
521         ResetStatusBar();
522       }
523       delobj(g2wobj,g2wid);
524     }
525   }
526 }
527 
CmOutputViewer()528 void CmOutputViewer()
529 {
530   struct objlist *graobj,*g2wobj;
531   int id,g2wid,g2woid;
532   char *device,*g2winst;
533   int GC,delgra;
534   struct narray *drawrable;
535   int i;
536 
537   if (menulock || globallock ) return;
538   if (SetFileHidden()) {
539     FileAutoScale();
540     AdjustAxis();
541     if ((graobj=chkobject("gra"))==NULL) return;
542     if ((g2wobj=chkobject("gra2x11"))==NULL) return;
543     SetStatusBar("Spawning external viewer.");
544     g2wid=newobj(g2wobj);
545     if (g2wid!=-1) {
546       g2winst=chkobjinst(g2wobj,g2wid);
547       _getobj(g2wobj,"oid",g2winst,&g2woid);
548       putobj(g2wobj,"dpi",g2wid,&(menulocal.exwindpi));
549       putobj(g2wobj,"store_in_memory",g2wid,&(menulocal.exwinbackingstore));
550       id=newobj(graobj);
551       putobj(graobj,"paper_width",id,&(menulocal.PaperWidth));
552       putobj(graobj,"paper_height",id,&(menulocal.PaperHeight));
553       putobj(graobj,"left_margin",id,&(menulocal.LeftMargin));
554       putobj(graobj,"top_margin",id,&(menulocal.TopMargin));
555       putobj(graobj,"zoom",id,&(menulocal.PaperZoom));
556       if (arraynum(&(menulocal.drawrable))>0) {
557         drawrable=arraynew(sizeof(char *));
558         for (i=0;i<arraynum(&(menulocal.drawrable));i++) {
559           arrayadd2(drawrable,(char **)arraynget(&(menulocal.drawrable),i));
560         }
561       } else drawrable=NULL;
562       putobj(graobj,"draw_obj",id,drawrable);
563       device=(char *)memalloc(20);
564       sprintf(device,"gra2x11:^%d",g2woid);
565       putobj(graobj,"device",id,device);
566       getobj(graobj,"open",id,0,NULL,&GC);
567       exeobj(graobj,"draw",id,0,NULL);
568       exeobj(graobj,"flush",id,0,NULL);
569       delgra=TRUE;
570       _putobj(g2wobj,"delete_gra",g2winst,&delgra);
571     }
572     ResetStatusBar();
573   }
574 }
575 
CmPrintGRAFile()576 void CmPrintGRAFile()
577 {
578   struct objlist *graobj,*g2wobj;
579   int id,g2wid,g2woid;
580   char *device,*g2winst;
581   int GC;
582   char *file,*buf;
583   struct narray *drawrable;
584   int i;
585   char *filebuf;
586 
587   if (menulock || globallock ) return;
588   if (nGetSaveFileName(TopLevel,"GRA file","gra",NULL,NULL,
589       &filebuf,"*.gra",menulocal.changedirectory)==IDOK) {
590     if (access(filebuf,04)==0) {
591       buf=(char *)memalloc(strlen(filebuf)+60);
592       if (buf!=NULL) {
593         sprintf(buf,"`%s'\n\nOverwrite existing file?",filebuf);
594         if (MessageBox(TopLevel,buf,"GRA file",MB_YESNO)!=IDYES) {
595           memfree(buf);
596           free(filebuf);
597           return;
598         }
599         memfree(buf);
600       } else {
601         if (MessageBox(TopLevel,"Overwrite existing file?",
602                        "GRA file",MB_YESNO)!=IDYES) {
603           free(filebuf);
604           return;
605         }
606       }
607     }
608     if ((file=(char *)memalloc(strlen(filebuf)+1))==NULL) {
609       free(filebuf);
610       return;
611     }
612     strcpy(file,filebuf);
613     free(filebuf);
614     if (SetFileHidden()) {
615       FileAutoScale();
616       AdjustAxis();
617       if ((graobj=chkobject("gra"))==NULL) {
618         memfree(file);
619         return;
620       }
621       if ((g2wobj=chkobject("gra2file"))==NULL) {
622         memfree(file);
623         return;
624       }
625       g2wid=newobj(g2wobj);
626       if (g2wid>=0) {
627         SetStatusBar("Making GRA file.");
628         g2winst=chkobjinst(g2wobj,g2wid);
629         _getobj(g2wobj,"oid",g2winst,&g2woid);
630         putobj(g2wobj,"file",g2wid,file);
631         id=newobj(graobj);
632         putobj(graobj,"paper_width",id,&(menulocal.PaperWidth));
633         putobj(graobj,"paper_height",id,&(menulocal.PaperHeight));
634         putobj(graobj,"left_margin",id,&(menulocal.LeftMargin));
635         putobj(graobj,"top_margin",id,&(menulocal.TopMargin));
636         putobj(graobj,"zoom",id,&(menulocal.PaperZoom));
637         if (arraynum(&(menulocal.drawrable))>0) {
638           drawrable=arraynew(sizeof(char *));
639           for (i=0;i<arraynum(&(menulocal.drawrable));i++) {
640             arrayadd2(drawrable,(char **)arraynget(&(menulocal.drawrable),i));
641           }
642         } else drawrable=NULL;
643         putobj(graobj,"draw_obj",id,drawrable);
644         device=(char *)memalloc(20);
645         sprintf(device,"gra2file:^%d",g2woid);
646         putobj(graobj,"device",id,device);
647         getobj(graobj,"open",id,0,NULL,&GC);
648         exeobj(graobj,"draw",id,0,NULL);
649         exeobj(graobj,"flush",id,0,NULL);
650         exeobj(graobj,"close",id,0,NULL);
651         delobj(graobj,id);
652         delobj(g2wobj,g2wid);
653         ResetStatusBar();
654       }
655     }
656   }
657 }
658 
CmPrintDataFile()659 void CmPrintDataFile()
660 {
661   struct objlist *obj;
662   int id;
663   double dx,dy,d2,d3;
664   int type,div;
665   char *buf,*file;
666   char *argv[3];
667 
668   if (menulock || globallock ) return;
669   if ((obj=chkobject("file"))==NULL) return;
670   if (chkobjlastinst(obj)==-1) return;
671   CopyDialog(&DlgCopy,obj,-1,FileCB);
672   if (DialogExecute(TopLevel,&DlgCopy)==IDOK) {
673     id=DlgCopy.sel;
674     if ((id>=0) && (id<=chkobjlastinst(obj))) {
675       div=10;
676       getobj(obj,"type",id,0,NULL,&type);
677       if (type==3) {
678         OutputDataDialog(&DlgOutputData,div);
679         if (DialogExecute(TopLevel,&DlgOutputData)!=IDOK) return;
680         div=DlgOutputData.div;
681       }
682       if (nGetSaveFileName(TopLevel,"Data file",NULL,NULL,NULL,
683           &file,"*",menulocal.changedirectory)==IDOK) {
684         if (access(file,04)==0) {
685           buf=(char *)memalloc(strlen(file)+60);
686           if (buf!=NULL) {
687             sprintf(buf,"`%s'\n\nOverwrite existing file?",file);
688             if (MessageBox(TopLevel,buf,"Data file",MB_YESNO)!=IDYES) {
689               free(file);
690               memfree(buf);
691               return;
692             }
693             memfree(buf);
694           } else {
695             if (MessageBox(TopLevel,"Overwrite existing file?",
696                            "Data file",MB_YESNO)!=IDYES) {
697               free(file);
698               return;
699             }
700           }
701         }
702         SetStatusBar("Making data file.");
703         argv[0]=(char *)file;
704         argv[1]=(char *)&div;
705         argv[2]=NULL;
706         exeobj(obj,"output_file",id,2,argv);
707         ResetStatusBar();
708       }
709       free(file);
710     }
711   }
712 }
713 
CmOutputDriverB(Widget w,XtPointer client_data,XtPointer call_data)714 void CmOutputDriverB(Widget w,XtPointer client_data,XtPointer call_data)
715 {
716   CmOutputDriver(TRUE);
717 }
718 
CmOutputViewerB(Widget w,XtPointer client_data,XtPointer call_data)719 void CmOutputViewerB(Widget w,XtPointer client_data,XtPointer call_data)
720 {
721   CmOutputViewer(TRUE);
722 }
723 
CmOutputMenu(Widget w,XtPointer client_data,XtPointer call_data)724 void CmOutputMenu(Widget w,XtPointer client_data,XtPointer call_data)
725 {
726   switch ((int )client_data) {
727   case 0:
728     CmViewerDraw();
729     break;
730   case 1:
731     CmViewerClear();
732     break;
733   case 2:
734     CmOutputViewer();
735     break;
736   case 3:
737     CmOutputDriver(FALSE);
738     break;
739   case 4:
740     CmPrintGRAFile();
741     break;
742   case 5:
743     CmPrintDataFile();
744     break;
745   }
746 }
747