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