1 /*
2 * $Id: main.c,v 1.10 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: main.c,v $
27 * Revision 1.10 2003/02/16 12:43:37 isizaka
28 * for release 6.13.18
29 *
30 * Revision 1.9 2002/07/06 08:57:25 isizaka
31 * change to GPL.
32 *
33 * Revision 1.8 2001/03/23 12:17:43 isizaka
34 * for 6.3.13
35 *
36 * Revision 1.7 1999/07/31 11:12:30 isizaka
37 * about stderr
38 *
39 * Revision 1.6 1999/05/31 10:33:13 isizaka
40 * for release 6.03.03
41 *
42 * Revision 1.5 1999/05/08 13:31:30 isizaka
43 * for release 6.03.02
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:08:57 isizaka
49 * *** empty log message ***
50 *
51 * Revision 1.2 1999/03/20 12:32:54 isizaka
52 * minor change
53 *
54 * Revision 1.1 1999/03/17 13:27:48 isizaka
55 * Initial revision
56 *
57 *
58 **/
59
60 #include <Xm/XmAll.h>
61 #include <sys/stat.h>
62 #include <sys/types.h>
63 #include <stdio.h>
64 #include <stdlib.h>
65 #include <string.h>
66 #include <fcntl.h>
67 #include <unistd.h>
68 #include <stdarg.h>
69
70 #include "ngraph.h"
71 #include "object.h"
72 #include "ioutil.h"
73 #include "nstring.h"
74 #include "config.h"
75
76 #define TRUE 1
77 #define FALSE 0
78
79 #define SYSCONF "[Ngraph]"
80 #ifndef LIBDIR
81 #define LIBDIR "/usr/local/lib/Ngraph"
82 #endif
83
84 int consolecol=80;
85 int consolerow=25;
86
87
88 char **mainenviron;
89 char *systemname;
90 int consolefdout;
91 int consolefdin;
92 int consoleac=FALSE;
93
94 void *addobjectroot(void);
95 void *addint(void);
96 void *adddouble(void);
97 void *addstring(void);
98 void *addiarray(void);
99 void *adddarray(void);
100 void *addsarray(void);
101 void *addsystem(void);
102 void *addshell(void);
103 void *adddraw(void);
104 void *addfile(void);
105 void *addmath(void);
106 void *addfit(void);
107 void *addgra(void);
108 void *addgra2(void);
109 void *addgra2null(void);
110 void *addgra2file(void);
111 void *addgra2prn(void);
112 void *addmerge(void);
113 void *addlegend(void);
114 void *addline(void);
115 void *addcurve(void);
116 void *addrectangle(void);
117 void *addarc(void);
118 void *addpolygon(void);
119 void *addmark(void);
120 void *addtext(void);
121 void *addaxis(void);
122 void *addagrid(void);
123 void *addprm(void);
124
125 void *addgra2x11(void);
126 void *addmenu(void);
127 void *adddialog(void);
128
129 void resizeconsole(int col,int row);
130
131 XtAppContext Application=NULL;
132 Display *Disp=NULL;
133 char *AppName="Ngraph";
134 char *AppClass="Ngraph";
135 extern Widget TopLevel;
136 static String fallbacks[] = {
137 "Ngraph*title: Ngraph",
138 NULL
139 };
140
Xerrorhandler(Display * d,XErrorEvent * e)141 int Xerrorhandler(Display *d,XErrorEvent *e)
142 {
143 char buf[256];
144
145 XGetErrorText(d,e->error_code,buf,sizeof(buf));
146 fprintf(stderr,"%s\n",buf);
147 return 0;
148 }
149
OpenApplication()150 int OpenApplication()
151 {
152 int argc;
153 char *argv[2];
154
155 if (Application==NULL) {
156 XtToolkitInitialize();
157 Application=XtCreateApplicationContext();
158 XtSetLanguageProc(NULL,NULL,NULL);
159 XtAppSetFallbackResources(Application,fallbacks);
160 }
161 if (Disp==NULL) {
162 argc=1;
163 argv[0]="Ngraph";
164 argv[1]="NULL";
165 Disp=XtOpenDisplay(Application,NULL,AppName,AppClass,NULL,0,&argc,argv);
166 if (Disp==NULL) {
167 fprintf(stderr,"Cannot open display.\n");
168 return FALSE;
169 }
170 XSetErrorHandler(Xerrorhandler);
171 }
172 return TRUE;
173 }
174
putconsole(char * s)175 int putconsole(char *s)
176 {
177 int len;
178
179 len=strlen(s);
180 write(consolefdout,s,len);
181 write(consolefdout,"\n",1);
182 return len+1;
183 }
184
printfconsole(char * fmt,...)185 int printfconsole(char *fmt,...)
186 {
187 int len;
188 char buf[1024];
189 va_list ap;
190
191 va_start(ap,fmt);
192 len=vsprintf(buf,fmt,ap);
193 va_end(ap);
194 write(consolefdout,buf,len);
195 return len;
196 }
197
interruptconsole(void)198 int interruptconsole(void)
199 {
200 return FALSE;
201 }
202
inputynconsole(char * mes)203 int inputynconsole(char *mes)
204 {
205 int len;
206 char buf[10];
207
208 len=strlen(mes);
209 write(consolefdout,mes,len);
210 do {
211 read(consolefdin,buf,1);
212 } while ((buf[0]!='y') && (buf[0]!='Y') && (buf[0]!='n') && (buf[0]!='N'));
213 if ((buf[0]=='y') || (buf[0]=='Y')) return TRUE;
214 return FALSE;
215 }
216
displaydialogconsole(char * str)217 void displaydialogconsole(char *str)
218 {
219 putconsole(str);
220 }
221
displaystatusconsole(char * str)222 void displaystatusconsole(char *str)
223 {
224 }
225
226 char *terminal=NULL;
227 struct savedstdio consolesave;
228 int consolefd[3];
229 int pipefd=-1;
230 pid_t consolepid=-1;
231
resizeconsole(int col,int row)232 void resizeconsole(int col,int row)
233 {
234 }
235
nallocconsole()236 int nallocconsole()
237 {
238 int fd[3],fdi[2],fdo[2],len,i;
239 pid_t pid;
240 char buf[256],ttyname[256];
241 char *s,*s2;
242 char **argv;
243 struct objlist *sys;
244 char *sysname;
245 char *version;
246
247 if (consoleac) return FALSE;
248 if (terminal==NULL) return FALSE;
249 if (pipe(fdi)==-1) return FALSE;
250 if (pipe(fdo)==-1) {
251 close(fdi[0]);
252 close(fdi[1]);
253 return FALSE;
254 }
255 if ((pid=fork())==-1) {
256 close(fdi[0]);
257 close(fdi[1]);
258 close(fdo[0]);
259 close(fdo[1]);
260 return FALSE;
261 } else if (pid==0) {
262 sprintf(buf,"%s %d %d %d %d",terminal,fdi[0],fdi[1],fdo[0],fdo[1]);
263 argv=NULL;
264 s=buf;
265 while ((s2=getitok2(&s,&len," \t"))!=NULL) {
266 arg_add(&argv,s2);
267 }
268 execvp(argv[0],argv);
269 exit(1);
270 }
271 close(fdi[1]);
272 close(fdo[0]);
273 sys=chkobject("system");
274 getobj(sys,"name",0,0,NULL,&sysname);
275 getobj(sys,"version",0,0,NULL,&version);
276 sprintf(buf,"%c]2;Ngraph shell%c%s version %s. Script interpreter.\n",
277 0x1b,0x07,sysname,version);
278 write(fdo[1],buf,strlen(buf)+1);
279 pipefd=fdo[1];
280 consolepid=pid;
281 i=0;
282 while ((read(fdi[0],buf,1)==1) && (buf[0]!='\0')) {
283 ttyname[i]=buf[0];
284 i++;
285 }
286 ttyname[i]='\0';
287 close(fdi[0]);
288 if (i==0) return FALSE;
289 fd[0]=open(ttyname,O_RDONLY);
290 fd[1]=open(ttyname,O_WRONLY);
291 fd[2]=open(ttyname,O_WRONLY);
292 consolefd[0]=dup(0);
293 close(0);
294 dup2(fd[0],0);
295 consolefd[1]=dup(1);
296 close(1);
297 dup2(fd[1],1);
298 consolefd[2]=dup(2);
299 close(2);
300 dup2(fd[2],2);
301 close(fd[0]);
302 close(fd[1]);
303 close(fd[2]);
304 consolefdin=dup(0);
305 consolefdout=dup(2);
306 consoleac=TRUE;
307 savestdio(&consolesave);
308 putstderr=putconsole;
309 printfstderr=printfconsole;
310 ninterrupt=interruptconsole;
311 inputyn=inputynconsole;
312 ndisplaydialog=displaydialogconsole;
313 ndisplaystatus=displaystatusconsole;
314 return TRUE;
315 }
316
nfreeconsole()317 void nfreeconsole()
318 {
319 char buf[1];
320
321 if (consoleac) {
322 close(0);
323 if (consolefd[0]!=-1) {
324 dup2(consolefd[0],0);
325 close(consolefd[0]);
326 }
327 close(1);
328 if (consolefd[1]!=-1) {
329 dup2(consolefd[1],1);
330 close(consolefd[1]);
331 }
332 close(2);
333 if (consolefd[2]!=-1) {
334 dup2(consolefd[2],2);
335 close(consolefd[2]);
336 }
337 buf[0]='\0';
338 write(pipefd,buf,1);
339 close(pipefd);
340 pipefd=-1;
341 consolepid=-1;
342 close(consolefdin);
343 close(consolefdout);
344 consolefdin=0;
345 consolefdout=2;
346 consoleac=FALSE;
347 loadstdio(&consolesave);
348 }
349 }
350
nforegroundconsole()351 void nforegroundconsole()
352 {
353 }
354
main(int argc,char ** argv,char ** environ)355 int main(int argc,char **argv,char **environ)
356 {
357 char *homedir,*libdir,*home,*lib,*inifile,*loginshell;
358 char *inst;
359 struct objlist *sys,*obj,*lobj;
360 int i,id;
361 char *sarg[2];
362 struct narray sarray;
363 FILE *fp;
364 char *tok,*str,*s2;
365 char *f1,*endptr;
366 int len,val;
367 int allocnow,allocconsole;
368 struct narray iarray;
369 char *arg;
370
371 mainenviron=environ;
372
373 ignorestdio(NULL);
374 inputyn=vinputyn;
375 ninterrupt=vinterrupt;
376 printfstderr=seprintf;
377 putstderr=seputs;
378 consolefdin=0;
379 consolefdout=2;
380
381 if ((lib=getenv("NGRAPHLIB"))!=NULL) {
382 if ((libdir=(char *)memalloc(strlen(lib)+1))==NULL) exit(1);
383 strcpy(libdir,lib);
384 } else {
385 if ((libdir=(char *)memalloc(strlen(LIBDIR)+1))==NULL) exit(1);
386 strcpy(libdir,LIBDIR);
387 }
388 if ((home=getenv("NGRAPHHOME"))!=NULL) {
389 if ((homedir=(char *)memalloc(strlen(home)+1))==NULL) exit(1);
390 strcpy(homedir,home);
391 } else if ((home=getenv("HOME"))!=NULL) {
392 if ((homedir=(char *)memalloc(strlen(home)+1))==NULL) exit(1);
393 strcpy(homedir,home);
394 } else {
395 if ((homedir=(char *)memalloc(strlen(libdir)+1))==NULL) exit(1);
396 strcpy(homedir,libdir);
397 }
398
399 if (addobjectroot()==NULL) exit(1);
400 if (addsystem()==NULL) exit(1);
401
402 newobj(getobject("system"));
403 if ((sys=getobject("system"))==NULL) exit(1);
404 inst=chkobjinst(sys,0);
405 if (_putobj(sys,"lib_dir",inst,libdir)) exit(1);
406 if (_putobj(sys,"home_dir",inst,homedir)) exit(1);
407 if (_getobj(sys,"lib_dir",inst,&libdir)==-1) exit(1);
408 if (_getobj(sys,"home_dir",inst,&homedir)==-1) exit(1);
409 if (_getobj(sys,"name",inst,&systemname)==-1) exit(1);
410
411 if (addshell()==NULL) exit(1);
412
413 if (addgra()==NULL) exit(1);
414 if (addgra2()==NULL) exit(1);
415 if (addgra2null()==NULL) exit(1);
416 if (addgra2file()==NULL) exit(1);
417 if (addgra2prn()==NULL) exit(1);
418
419 if (addgra2x11()==NULL) exit(1);
420
421 if (addint()==NULL) exit(1);
422 if (adddouble()==NULL) exit(1);
423 if (addstring()==NULL) exit(1);
424 if (addiarray()==NULL) exit(1);
425 if (adddarray()==NULL) exit(1);
426 if (addsarray()==NULL) exit(1);
427 if (addmath()==NULL) exit(1);
428 if (addfit()==NULL) exit(1);
429 if (addprm()==NULL) exit(1);
430
431 if (adddraw()==NULL) exit(1);
432 if (addagrid()==NULL) exit(1);
433 if (addaxis()==NULL) exit(1);
434 if (addfile()==NULL) exit(1);
435 if (addmerge()==NULL) exit(1);
436 if (addlegend()==NULL) exit(1);
437 if (addrectangle()==NULL) exit(1);
438 if (addline()==NULL) exit(1);
439 if (addcurve()==NULL) exit(1);
440 if (addarc()==NULL) exit(1);
441 if (addpolygon()==NULL) exit(1);
442 if (addmark()==NULL) exit(1);
443 if (addtext()==NULL) exit(1);
444
445 if (addmenu()==NULL) exit(1);
446 if (adddialog()==NULL) exit(1);
447
448 loginshell=NULL;
449 if ((fp=openconfig(SYSCONF))!=NULL) {
450 while ((tok=getconfig(fp,&str))!=NULL) {
451 s2=str;
452 if (strcmp(tok,"login_shell")==0) {
453 f1=getitok2(&s2,&len," \t,");
454 if (_putobj(sys,"login_shell",inst,f1)) exit(1);
455 } else if (strcmp(tok,"create_object")==0) {
456 while ((f1=getitok2(&s2,&len," \t,"))!=NULL) {
457 newobj(getobject(f1));
458 memfree(f1);
459 }
460 } else if (strcmp(tok,"alloc_console")==0) {
461 f1=getitok2(&s2,&len," \t,");
462 val=strtol(f1,&endptr,10);
463 if (endptr[0]=='\0') {
464 if (val==0) allocconsole=FALSE;
465 else allocconsole=TRUE;
466 }
467 memfree(f1);
468 } else if (strcmp(tok,"console_size")==0) {
469 f1=getitok2(&s2,&len," \x09,");
470 val=strtol(f1,&endptr,10);
471 if (endptr[0]=='\0') consolecol=val;
472 memfree(f1);
473 f1=getitok2(&s2,&len," \x09,");
474 val=strtol(f1,&endptr,10);
475 if (endptr[0]=='\0') consolerow=val;
476 memfree(f1);
477 } else if (strcmp(tok,"terminal")==0) {
478 terminal=getitok2(&s2,&len,"");
479 }
480 memfree(tok);
481 memfree(str);
482 }
483 closeconfig(fp);
484 }
485
486 putstderr=putconsole;
487 printfstderr=printfconsole;
488 inputyn=inputynconsole;
489 ndisplaydialog=displaydialogconsole;
490 ndisplaystatus=displaystatusconsole;
491 if (allocconsole) nallocconsole();
492 if (isatty(0) && isatty(1) && isatty(2)) {
493 consoleac=TRUE;
494 if (!allocconsole) {
495 consolefdin=dup(0);
496 consolefdout=dup(2);
497 }
498 } else consoleac=FALSE;
499
500 inifile=NULL;
501 id=newobj((obj=getobject("shell")));
502 for (i=1;i<argc;i++) {
503 if (argv[i][0]=='-') {
504 if (argv[i][1]=='i') {
505 i++;
506 if (i<argc) {
507 if ((inifile=(char *)memalloc(strlen(argv[i])+1))==NULL) exit(1);
508 strcpy(inifile,argv[i]);
509 changefilename(inifile);
510 } else break;
511 } else break;
512 } else break;
513 }
514 if (inifile==NULL) {
515 if (findfilename(homedir,CONFTOP,systemname))
516 inifile=getfilename(homedir,CONFTOP,systemname);
517 else if (findfilename(libdir,CONFTOP,systemname))
518 inifile=getfilename(libdir,CONFTOP,systemname);
519 }
520 if (inifile!=NULL) {
521 arrayinit(&sarray,sizeof(char *));
522 if (arrayadd(&sarray,&inifile)==NULL) exit(1);
523 for (;i<argc;i++)
524 if (arrayadd(&sarray,&(argv[i]))==NULL) exit(1);
525 sarg[0]=(char *)&sarray;
526 sarg[1]=NULL;
527 exeobj(obj,"shell",id,1,sarg);
528 arraydel(&sarray);
529 memfree(inifile);
530 }
531 if (getobj(sys,"login_shell",0,0,NULL,&loginshell)) exit(1);
532 do {
533 if (_putobj(sys,"login_shell",inst,NULL)) exit(1);
534 if (loginshell==NULL) {
535 allocnow=nallocconsole();
536 exeobj(obj,"shell",id,0,NULL);
537 if (allocnow) nfreeconsole();
538 } else {
539 arrayinit(&iarray,sizeof(int));
540 arg=loginshell;
541 if (getobjilist2(&arg,&lobj,&iarray,TRUE)) return -1;
542 arraydel(&iarray);
543 if (lobj==obj) allocnow=nallocconsole();
544 else allocnow=FALSE;
545 sexeobj(loginshell);
546 if (allocnow) nfreeconsole();
547 }
548 memfree(loginshell);
549 if (getobj(sys,"login_shell",0,0,NULL,&loginshell)) exit(1);
550 } while (loginshell!=NULL);
551 if (consoleac && (consolepid!=-1)) nfreeconsole();
552 memfree(terminal);
553 delobj(getobject("system"),0);
554 return 0;
555 }
556