1 /* Copyright (C) 1992-1998 The Geometry Center
2  * Copyright (C) 1998-2000 Stuart Levy, Tamara Munzner, Mark Phillips
3  *
4  * This file is part of Geomview.
5  *
6  * Geomview is free software; you can redistribute it and/or modify it
7  * under the terms of the GNU Lesser General Public License as published
8  * by the Free Software Foundation; either version 2, or (at your option)
9  * any later version.
10  *
11  * Geomview is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with Geomview; see the file COPYING.  If not, write
18  * to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139,
19  * USA, or visit http://www.gnu.org.
20  */
21 
22 #if HAVE_CONFIG_H
23 # include "config.h"
24 #endif
25 
26 #if 0
27 static char copyright[] = "Copyright (C) 1992-1998 The Geometry Center\n\
28 Copyright (C) 1998-2000 Stuart Levy, Tamara Munzner, Mark Phillips";
29 #endif
30 
31 /* static char *copyright = "Copyright (C) 1992 The Geometry Center"; currently unused*/
32 
33 /* Authors: Stuart Levy, Tamara Munzner, Mark Phillips */
34 
35 #include "drawer.h"
36 #include "event.h"
37 #include "main.h"
38 #include "ui.h"
39 #include "comm.h"
40 #include "geom.h"
41 #include "camera.h"
42 #include "pick.h"
43 #include <stdlib.h>
44 #include <math.h>
45 #include <string.h>
46 #include <sys/types.h>
47 
48 #include <sys/stat.h>
49 #include <sys/file.h>
50 #ifdef NeXT
51 #include <libc.h>
52 #else
53 #include <unistd.h>
54 #endif
55 #if HAVE_LOCALE_H
56 # include <locale.h>
57 #endif
58 
59 #define STREQ(s1,s2) (strcmp(s1,s2)==0)
60 
61 static char *initfilename = ".geomview";
62 
63 char *geomview_system_initfile = NULL;
64 int do_init = 1;
65 
66 Color initial_defaultbackcolor = {1.0/3.0, 1.0/3.0, 1.0/3.0 };
67 static char *pipesubdir = "geomview";
68 
69 int gv_nwins = 1;
70 int gv_no_opengl = 0;
71 
72 vvec vv_load_path;
73 vvec vv_emodule_path;
74 
75 /* Default backstop appearance */
76 static char apdefault[] = "\
77 appearance { \
78 	+face \
79 	-edge \
80 	+vect \
81 	normscale 1.0 \
82 	linewidth 1 \
83 	patchdice 10 10 \
84 	-normal \
85 	+evert \
86 	shading flat \
87 	-transparent \
88 	material { \
89 		kd 1.0 diffuse 1 1 1 \
90 		ka 0.3 ambient 1 1 1 \
91 		ks 0.3 specular 1 1 1 \
92 		shininess 15 \
93 		edgecolor 0 0 0 \
94 		normalcolor 1 1 1 \
95 		alpha 1 \
96 	} \
97 	lighting { \
98 		ambient .2 .2 .2 \
99 		replacelights \
100 		light { color .75 .75 .75 position 0 0 10 0 } \
101 		light { color .6 .6 .6 position 0 1 -1 0 } \
102 		light { color .4 .4 .4 position 1 -2 -1 0 } \
103 	} \
104 }";
105 
106 /*
107  * Default geometry to use when drawing cameras.
108  */
109 static char defaultcam[] = "\
110 appearance {linewidth 4}\n\
111 VECT\n\
112 7 17 4\n\
113 2 2  2 2 2 2  5\n\
114 1 1  1 0 0 0  1\n\
115 -.5 -.5 -.5  0 -.5 -.5\n\
116 -.5 -.5 -.5  -.5 0 -.5\n\
117 0 0 0   .5 .5 -.5\n\
118 0 0 0   -.5 -.5 -.5\n\
119 0 0 0   -.5 .5 -.5\n\
120 0 0 0   .5 -.5 -.5\n\
121 -.5 0 -.5  -.5 .5 -.5  .5 .5 -.5  .5 -.5 -.5  0 -.5 -.5\n\
122 1 0 0 1\n\
123 0 1 0 1\n\
124 0 0 1 1\n\
125 0 0 0 1";
126 
127 static char windefault[] = "{ size 450 450  resize }";
128 
usage(char * me,char * morestuff)129 void usage(char *me, char *morestuff)
130 {
131   fprintf(stderr, "\
132 Usage: %s [-b r g b] [-c commandfile] [-wins #windows]\n\
133 	[-nopanels] [-noinit] [-noopengl]\n\
134         [-wpos width,height[@xmin,ymin]] [-wpos -] [-M[gc][sp] pipename]\n\
135         [-start external-module-string args ... --]\n\
136         [-run external-module-pathname args ... --]\n\
137 %s	[ file ... ]\n", me, morestuff);
138   exit(1);
139 }
140 
141 static void
parse_emodule(int room,int * acp,char *** avp,char * first,char * firstname,char * indir)142 parse_emodule(int room, int *acp, char ***avp, char *first, char *firstname, char *indir)
143 {
144   int i;
145   char *cmd;
146   char *next;
147   emodule new;
148   int baselen;
149 
150   for (i = 1; i <= *acp && !STREQ((next = (*avp)[i]), "--"); i++)
151     room += strlen(next)+1+1;
152   if (room) {
153     cmd = OOGLNewNE(char, room, "emod cmd");
154     if (first) {
155       strcpy(cmd, first);
156       strcat(cmd, " ");
157     } else
158       cmd[0] = '\0';
159     baselen = strlen(cmd);
160     while (*acp > 0 && !STREQ((next = *++(*avp)), "--")) {
161       strcat(cmd, next);
162       strcat(cmd, " ");
163       (*acp)--;
164     }
165     new.text = strdup(cmd);
166     if(firstname) {
167       new.name = OOGLNewNE(char, room + strlen(firstname) + 1, "emod name");
168       sprintf(new.name, "%s %s", firstname, cmd+baselen);
169     } else {
170       new.name = strdup(cmd);
171     }
172     new.data = NULL;
173     new.dir = indir;
174     emodule_run(&new);
175   }
176 }
177 
parse_common_arg(int * acp,char *** avp)178 int parse_common_arg(int *acp, char ***avp)
179 {
180   int ac = *acp;
181   char **av = *avp;
182   char *arg = *av;
183   int ok = 1;
184   int i;
185 
186   if (STREQ(arg,"-b") && (ac-=3) > 0) {
187     initial_defaultbackcolor.r = atof(*++av);
188     initial_defaultbackcolor.g = atof(*++av);
189     initial_defaultbackcolor.b = atof(*++av);
190     drawer_color(DEFAULTCAMID, DRAWER_BACKCOLOR, &initial_defaultbackcolor);
191   }
192   else if(STREQ(arg, "-wins") && --ac > 0) {
193     gv_nwins = atoi(*++av);
194   }
195   else if((STREQ(arg, "-wpos") || STREQ(arg, "-w")) && --ac > 0) {
196     WindowStruct ws;
197     WnPosition wp;
198     int a1,a2,a3,a4;
199     char ch;
200     static char rats[] = "geomview: -wpos: expected width,height[@xmin,ymin]";
201 
202     ws.wn = WnCreate(WN_ENLARGE, 1, WN_SHRINK, 1, WN_END);
203     ws.h = NULL;
204 
205     switch(sscanf(*++av, "%d%*c%d%c%d%*c%d", &a1,&a2,&ch,&a3,&a4)) {
206     case 2:
207       WnSet(ws.wn, WN_XSIZE, a1, WN_YSIZE, a2, WN_END);
208       break;
209     case 1:
210       wp.xmin = a1;
211       if((ac -= 3) < 0) {
212 	OOGLError(0, rats);
213 	exit(1);
214       }
215       wp.ymin = atoi(*++av);
216       wp.xmax = wp.xmin + atoi(*++av)-1;
217       wp.ymax = wp.ymin + atoi(*++av)-1;
218       break;
219     case 5:
220       if(ch == '@') {	/* xsize,ysize@xmin,ymin */
221 	wp.xmin = a3; wp.xmax = a3 + a1-1;
222 	wp.ymin = a4; wp.ymax = a4 + a2-1;
223       } else {		/* xmin,ymin,xsize,ysize */
224 	wp.xmin = a1; wp.ymin = a2; wp.xmax = a1+a3-1; wp.ymax = a2+a4-1;
225       }
226       WnSet(ws.wn, WN_PREFPOS, &wp, WN_END);
227       break;
228     default:
229       if(!STREQ(arg, "-")) {
230 	OOGLError(0, rats);
231 	exit(1);
232       }
233       /* "-" => interactive positioning -- fall through */
234     }
235     gv_window(DEFAULTCAMID, &ws);
236   } else if(STREQ(arg, "-debug")) {
237     /* -debug -- don't catch SIGINT, SIGSEGV, etc. signals */
238     /* -debug and -noopengl are handled in init_geomview()
239     gv_debug = 1;
240     */
241   } else if (STREQ(arg, "-noopengl")) {
242     /* -debug and -noopengl are handled in init_geomview()
243     gv_no_opengl = 1;
244     */
245   } else if(STREQ(arg, "-c") && --ac > 0) {
246     /* -c -- Process command file (or string) */
247     gv_load(*++av, "command");
248   } else if(!strncmp(arg, "-M", 2) && --ac > 0) {
249     /* -M[cg][ps[un|in|in6]] pipename|port  -- external connection */
250     char pipedir[PATH_MAX];
251     char *tmpdir = getenv("TMPDIR");
252 
253     if (tmpdir == NULL) {
254       tmpdir = "/tmp";
255     }
256     snprintf(pipedir, PATH_MAX, "%s/%s", tmpdir, pipesubdir);
257     usepipe(pipedir, *++av, &arg[2]);
258   } else if(strncmp(arg, "-nop", 4) == 0) {	/* "-nopanels" */
259     /* -nopanels -- Suppress all possible panels */
260     for(i=0; i<30; i++)
261       ui_showpanel(i, 0);
262   } else if(STREQ(arg, "-e") && --ac > 0) {
263     /* -e -- start an e-module with no arguments */
264     gv_ui_emodule_start(*++av);
265   } else if(STREQ(arg, "-start") && --ac > 0) {
266     /* -start emodule-name args ... */
267     emodule *old;
268     int room;
269     char *name;
270     ui_emodule_index((name = *++av), &old);
271     if (old) {
272       room = strlen(old->text) +1 +1;
273       ac--;
274       parse_emodule(room, &ac, &av, old->text, old->name, old->dir);
275     } else {
276       OOGLError(0, "No external module named %s.", name);
277     }
278   } else if(STREQ(arg, "-run") && --ac > 0) {
279     /* -run program-name args ... -- run program as e-module */
280     parse_emodule(0, &ac, &av, NULL, NULL, NULL);
281   } else if(STREQ(arg, "-time")) {
282     /* Enable timing as with ctrl-T */
283     timing(999999);
284   } else if(STREQ(arg, "-noinit")) {
285     /* Don't read any initialization files */
286     do_init = 0;
287   } else if(arg[0] == '-' && arg[1] != '\0') {
288     ok = 0;		/* Unrecognized */
289   } else {
290     gv_load(arg, NULL);
291   }
292   *acp = ac;
293   *avp = av;
294   return ok;
295 }
296 
297 void
init_geomview(int argc,char ** argv)298 init_geomview(int argc, char **argv)
299 {
300   char *userhome, homefile[512], dotfile[512];
301   struct stat homebuf, dotbuf;
302   int i, homestat, dotstat;
303 
304 #if HAVE_SETLOCALE && HAVE_DECL_LC_ALL
305   setlocale(LC_ALL, "POSIX");
306 #endif
307 
308   if (getenv("GEOMVIEW_DEBUG"))
309     gv_debug = 1;
310 
311   if (getenv("GEOMVIEW_NO_OPENGL"))
312     gv_no_opengl = 1;
313 
314   for(i = 1; i < argc; i++)
315     if(STREQ(argv[i], "-noinit"))
316       do_init = 0;
317     else if(STREQ(argv[i], "-debug"))
318       gv_debug = 1;
319     else if(STREQ(argv[i], "-noopengl"))
320       gv_no_opengl = 1;
321 
322   drawer_init(apdefault, defaultcam, windefault);
323 
324   comm_init();
325 
326   event_init();
327   ui_init();
328 
329   VVINIT(vv_load_path, char *, 3);
330   VVINIT(vv_emodule_path, char *, 3);
331 
332   /*
333     env_init() should arrange for vv_load_path, vv_emodule_path, and
334     geomview_system_initfile to be set to whatever default values
335     are appropriate for the environment.  On the IRIS this is done
336     through environment variables set in a driving shell script
337     (the IRIS version of env_init() is in gl/glmain.c).
338     The NeXT uses a CONFIG.gv script in the Geomview.app wrapper.
339   */
340 
341   env_init();
342 
343   if(do_init) {
344     /* load system init file, if present */
345     if (geomview_system_initfile) {
346       if (access(geomview_system_initfile, R_OK) == 0) {
347 	gv_load(geomview_system_initfile, "command");
348       }
349     }
350 
351 
352     /* now load ~/.geomview and ./.geomview, in that order, if present,
353        unless they are the same, in which case just load once */
354 
355     userhome = getenv("HOME");
356     sprintf(homefile,"%s/%s", userhome, initfilename);
357     sprintf(dotfile,"./%s", initfilename);
358 
359     homestat =  stat(homefile, &homebuf);
360     dotstat =  stat(dotfile, &dotbuf);
361 
362 
363     if (homestat == 0) {
364       if (access(homefile, R_OK) == 0)
365 	gv_load(homefile, "command");
366       else
367 	OOGLError(0, "Warning: file %s present but unreadable; ignoring it.",
368 		  homefile);
369     }
370 
371     if ( (dotstat == 0) && (   (dotbuf.st_dev != homebuf.st_dev)
372 			       || (dotbuf.st_ino != homebuf.st_ino))) {
373       if (access(dotfile, R_OK) == 0)
374 	gv_load(dotfile, "command");
375       else
376 	OOGLError(0, "Warning: file %s present but unreadable; ignoring it.",
377 		  dotfile);
378     }
379   }
380 }
381 
382 /*
383  * Local Variables: ***
384  * mode: c ***
385  * c-basic-offset: 2 ***
386  * End: ***
387  */
388