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 #include <stdio.h>
32 #include <sys/types.h>
33 #include <sys/stat.h>
34 #ifndef NeXT
35 #include <unistd.h>
36 #endif
37 /*#include <sys/fcntl.h>*/
38 #include <signal.h>
39 #include <string.h>
40 #include <ctype.h>
41 #include <math.h>
42 #include <stdlib.h>
43 #include "ooglutil.h"
44 #include "drawer.h"
45 #include "lisp.h"
46 #include "lispext.h"
47 #include "lang.h"
48 #include "event.h"
49 #include "ui.h"
50 #include "comm.h"
51 #include "streampool.h"
52 #include "handleP.h"
53 #include "transform.h"
54 #include "mgrib.h"
55 #include "version.h"
56 
57 #include "clang.c"
58 
59 /* do-lang, do-lang, do-lang... */
60 
61 char geomview_version[] = GEOMVIEW_VERSION;
62 extern char *buildinfographics;	/* Possibly initialized elsewhere */
63 
lang_init()64 void lang_init()
65 {
66   LInit();
67   lispext_init();
68   clang_init();
69 
70   /*
71    * Functions that don't use LDECLARE need to be LDefun'ed
72    * here  because they are not part of the "clang" interface.
73    */
74   {
75     extern LObject *Lread(Lake *, LList *);
76     extern char Hread[];
77     extern LObject *Lmerge(Lake *, LList *);
78     extern char Hmerge[];
79     extern LObject *Lhdefine(Lake *, LList *);
80     extern char Hhdefine[];
81     extern LObject *LND_xform(Lake *, LList *);
82     extern char HND_xform[];
83 
84     LDefun("read", Lread, Hread);
85     LDefun("merge", Lmerge, Hmerge);
86     LDefun("hdefine", Lhdefine, Hhdefine);
87   }
88 
89   /*
90    * Define the language keywords
91    */
92   define_keyword("yes",	YES_KEYWORD);
93   define_keyword("no",	NO_KEYWORD);
94   define_keyword("on",	ON_KEYWORD);
95   define_keyword("off",	OFF_KEYWORD);
96   define_keyword("0",	ZERO_KEYWORD);
97   define_keyword("1",	ONE_KEYWORD);
98 
99   define_keyword("none", NONE_KEYWORD);
100   define_keyword("each", EACH_KEYWORD);
101   define_keyword("keep", KEEP_KEYWORD);
102   define_keyword("all",	ALL_KEYWORD);
103 
104   define_keyword("euclidean", EUCLIDEAN_KEYWORD);
105   define_keyword("hyperbolic", HYPERBOLIC_KEYWORD);
106   define_keyword("spherical", SPHERICAL_KEYWORD);
107 
108   define_keyword("virtual", VIRTUAL_KEYWORD);
109   define_keyword("projective", PROJECTIVE_KEYWORD);
110   define_keyword("conformal-ball", CONFORMALBALL_KEYWORD);
111   define_keyword("conformal", CONFORMALBALL_KEYWORD);
112 
113   define_keyword("tiff", TIFF_KEYWORD);
114   define_keyword("frame", FRAME_KEYWORD);
115 
116   define_keyword("camera", CAMERA_KEYWORD);
117   define_keyword("geometry", GEOM_KEYWORD);
118   define_keyword("transform", TRANSFORM_KEYWORD);
119   define_keyword("ntransform", NTRANSFORM_KEYWORD);
120   define_keyword("command", COMMAND_KEYWORD);
121   define_keyword("window", WINDOW_KEYWORD);
122   define_keyword("image", IMAGE_KEYWORD);
123   define_keyword("appearance", APPEARANCE_KEYWORD);
124 
125   define_keyword("translate", TRANSLATE_KEYWORD);
126   define_keyword("e-translate", E_TRANSLATE_KEYWORD);
127   define_keyword("h-translate", H_TRANSLATE_KEYWORD);
128   define_keyword("s-translate", S_TRANSLATE_KEYWORD);
129 
130   define_keyword("translate-scaled", TRANSLATE_SCALED_KEYWORD);
131   define_keyword("e-translate-scaled", E_TRANSLATE_SCALED_KEYWORD);
132   define_keyword("h-translate-scaled", H_TRANSLATE_SCALED_KEYWORD);
133   define_keyword("s-translate-scaled", S_TRANSLATE_SCALED_KEYWORD);
134 
135   define_keyword("rotate", ROTATE_KEYWORD);
136 
137   define_keyword("scale", SCALE_KEYWORD);
138   define_keyword("zoom", ZOOM_KEYWORD);
139 
140   define_keyword("horizontal", HORIZONTAL_KEYWORD);
141   define_keyword("vertical", VERTICAL_KEYWORD);
142   define_keyword("colored", COLORED_KEYWORD);
143 
144   define_keyword("toggle", TOGGLE_KEYWORD);
145 
146   define_keyword("smooth", SMOOTH_KEYWORD);
147 
148   define_keyword("bbox-center", BBOX_CENTER_KEYWORD);
149   define_keyword("origin", ORIGIN_KEYWORD);
150 
151   define_keyword("focus-change", FOCUS_CHANGE_KEYWORD);
152   define_keyword("mouse-cross", MOUSE_CROSS_KEYWORD);
153 
154   define_keyword("inertia", MOTION_INERTIA_KEYWORD);
155   define_keyword("constrain", MOTION_CONSTRAIN_KEYWORD);
156   define_keyword("own-coordinates", MOTION_OWN_COORDS_KEYWORD);
157 
158   /*
159    * Define various synonyms
160    */
161   LDefun("!", Lshell,
162 	 "(! COMMAND)\n`!' is a synonym for \"shell\"");
163   LDefun("|", Lemodule_run,
164 	 "(| EMODULE)\n`|' is a synonym for \"emodule-run\"");
165   LDefun("ui-emotion-program", Lui_emodule_define,
166 	 "(ui-emotion-program ...)\n"
167 	 "ui-emotion-program is an obsolete command."
168 	 "Use its new eqivalent \"emodule-define\" instead.");
169   LDefun("ui-emotion-run", Lui_emodule_start,
170 	 "(ui-emotion-run ...)\n"
171 	 "ui-emotion-run is an obsolete command."
172 	 "Use its new eqivalent \"emodule_start\" instead.");
173   LDefun("quit", Lexit,
174 	 "(quit)\n`quit' is a synonym for \"exit\"");
175   LDefun("merge-base-ap", Lmerge_baseap,
176 	 "(merge-base-ap)\n`merge-base-ap' is a synonym for merge-baseap.");
177 
178   /*
179    * And some extra help entries.
180    */
181   LHelpDef("ID",
182 	  "\nID is a string which names a geometry or camera. Besides\n\
183 	those you create, valid ones are:\n\
184 \n\
185 	World, world,\n\
186 	    worldgeom, g0:    the collection of all geom's\n\
187 	target:			selected target object (cam or geom)\n\
188 	center:			selected center-of-motion object\n\
189 	targetcam:		last selected target camera\n\
190 	targetgeom:		last selected target geom\n\
191 	focus:			camera where cursor is (or most\n\
192 				recently was)\n\
193 	allgeoms:		all geom objects\n\
194 	allcams:		all cameras\n\
195 	default, defaultcam:  prototype; future cameras inherit\n\
196 				default's settings\n\
197 \n\
198 	The following IDs are used to name coordinate systems,\n\
199 	e.g. in \"pick\" and \"write\" commands:\n\
200 \n\
201 	world, World, etc.:   the world, within which all other\n\
202 				geoms live.\n\
203 	universe, Universe:	the universe, in which the World, lights\n\
204 				and cameras live.  Cameras' world2cam\n\
205 				transforms might better be called\n\
206 				universe2cam, etc.\n\
207 	self:		      \"this geomview object\".	 Transform from\n\
208 				an object to \"self\" is the identity;\n\
209 				writing its geometry gives the object\n\
210 				itself with no enclosing transform;\n\
211 				picked points appear in the object's\n\
212 				coordinates.\n\
213 	primitive:	      (for \"pick\" only) Picked points appear in\n\
214 				the coordinate system of the\n\
215 				lowest-level OOGL primitive.\n\
216 \n\
217 	A name is also an acceptable id.  Given names are made unique\n\
218 	by appending numbers if necessary (i.e. \"foo<2>\"). Every geom\n\
219 	is also named g[n] and every camera is also named c[n] (\"g0\"\n\
220 	is always the worldgeom): this name is used as a prefix to\n\
221 	keyboard commands and can also be used as a command language\n\
222 	id.  Numbers are reused after an object is deleted. Both names\n\
223 	are shown in the Object browser.");
224 
225   LHelpDef("CAM-ID",
226 	   "\nCAM-ID is an ID that refers to a camera.");
227 
228   LHelpDef("GEOM-ID",
229 	   "\nGEOM-ID is an ID that refers to a geometry.");
230 
231   LHelpDef("GEOMETRY",
232 	   "\nGEOMETRY is an OOGL geometry specification.");
233 
234   LHelpDef("CAMERA",
235 	   "\nCAMERA is an OOGL camera specification.");
236 
237   LHelpDef("APPEARANCE",
238 	   "\nAPPEARANCE is an OOGL appearance specification.");
239 
240   LHelpDef("IMAGE",
241 	   "\nIMAGE is an OOGL image specification.");
242 
243   LHelpDef("TRANSFORM",
244 	   "\nTRANSFORM is an OOGL 4x4 transformation matrix.");
245 
246   LHelpDef("NTRANSFORM",
247 	   "\nNTRANSFORM is an OOGL NxM transformation matrix.");
248 }
249 
keyword2ops(Keyword keyword)250 HandleOps *keyword2ops(Keyword keyword)
251 {
252   switch (keyword) {
253   case CAMERA_KEYWORD:     return &CamOps;
254   case GEOM_KEYWORD:       return &GeomOps;
255   case TRANSFORM_KEYWORD:  return &TransOps;
256   case NTRANSFORM_KEYWORD: return &NTransOps;
257   case COMMAND_KEYWORD:    return &CommandOps;
258   case WINDOW_KEYWORD:     return &WindowOps;
259   case APPEARANCE_KEYWORD: return &AppearanceOps;
260   case IMAGE_KEYWORD:      return &ImageOps;
261   default: return NULL;
262   }
263 }
264 
265 /**********************************************************************/
266 
267 LDEFINE(shell, LVOID,
268 	"(shell SHELL-COMMAND)\n"
269 	"Execute the given UNIX SHELL-COMMAND using /bin/sh. Geomview"
270 	"waits for it to complete and will be unresponsive until it does.")
271 {
272   char *cmd;
273   int status;
274   void (*oldsigchld)();
275   LDECLARE(("shell", LBEGIN,
276 	    LSTRINGS, &cmd,
277 	    LEND));
278   oldsigchld = signal(SIGCHLD, SIG_DFL);
279   status = system(cmd);
280   signal(SIGCHLD, oldsigchld);
281   return LNew(LINT, &status);
282 }
283 
284 
285 LDEFINE(write_sexpr, LVOID,
286        "(write-sexpr     FILENAME LISPOBJECT)\n\
287 	Writes the given LISPOBJECT to FILENAME. This function is intended\n\
288 	for internal debugging use only.")
289 {
290   LObject *obj;
291   char *filename;
292   LDECLARE(("write-sexpr", LBEGIN,
293 	    LSTRING, &filename,
294 	    LHOLD, LLOBJECT, &obj,
295 	    LEND));
296   LWriteFile(filename, obj);
297   return Lt;
298 }
299 
300 LDEFINE(write_handle, LVOID,
301 	"(write-handle HANDLEOPS FILENAME HANDLE)\n"
302 	"Writes the object underlying the given handle to FILENAME."
303 	"This function is intended for internal debugging use only.")
304 {
305   char *prefix, *filename, *handle;
306   Handle *h;
307   HandleOps *ops;
308   Pool *p;
309 
310   LDECLARE(("write-handle", LBEGIN,
311 	    LSTRING, &prefix,
312 	    LSTRING, &filename,
313 	    LSTRING, &handle,
314 	    LEND));
315 
316   if ((ops = HandleOpsByName(prefix)) != NULL &&
317       (h = HandleByName(handle, ops)) != NULL) {
318     REFPUT(h);
319     if (h->ops->strmout) {
320       bool old_objsaved = h->obj_saved;
321       FILE *outf = NULL;
322       if (strcmp(filename, "-") == 0) {
323 	outf = stdout;
324       }
325       p = PoolStreamTemp(filename, NULL, outf, 1, &CommandOps);
326       h->obj_saved = false;
327       h->ops->strmout(p, h, HandleObject(h));
328       h->obj_saved = old_objsaved;
329       PoolClose(p);
330       PoolDelete(p);
331     }
332   } else {
333     OOGLWarn("Cannot find handle \"%s@%s\"", handle, prefix);
334   }
335 
336   return Lt;
337 }
338 
339 LDEFINE(dump_handles, LVOID,
340 	"(dump-handles)\n"
341 	"Dump the list of currently active handles to stdout."
342 	"This function is intended for internal debugging use only.")
343 {
344   extern void handle_dump(void);
345 
346   LDECLARE(("dump-handles", LBEGIN,
347 	    LEND));
348 
349   handle_dump();
350 
351   return Lt;
352 }
353 
354 LDEFINE(dump_pools, LVOID,
355 	"(dump-pools)\n"
356 	"Dump the list of currently active input-\"pools\" to stdout."
357 	"This function is intended for internal debugging use only.")
358 {
359   extern void pool_dump(void);
360 
361   LDECLARE(("dump-pools", LBEGIN,
362 	    LEND));
363 
364   pool_dump();
365 
366   return Lt;
367 }
368 
369 LDEFINE(geomview_version, LSTRING,
370 	"(geomview-version)\n\
371 	Returns a string representing the version of geomview that is\n\
372 	running.")
373 {
374   char buf[128];
375   char *s;
376   LDECLARE(("geomview-version", LBEGIN,
377 	    LEND));
378   sprintf(buf, buildinfographics ? "%s-%s" : "%s",
379 		geomview_version, buildinfographics);
380   s = strdup(buf);
381   return LNew( LSTRING, &s );
382 }
383 
boolval(char * s,Keyword keyword)384 bool boolval(char *s, Keyword keyword)
385 {
386   switch (keyword) {
387   case YES_KEYWORD:
388   case ON_KEYWORD:
389   case ONE_KEYWORD:
390     return true;
391   case NO_KEYWORD:
392   case OFF_KEYWORD:
393   case ZERO_KEYWORD:
394     return false;
395   default:
396     fprintf(stderr, "%s: %s is not a boolean keyword; assuming \"no\"\n",
397 	    s, keywordname(keyword));
398     return false;
399   }
400 }
401 
402 /*
403  * Local Variables: ***
404  * mode: c ***
405  * c-basic-offset: 2 ***
406  * End: ***
407  */
408