1 /* -*- tab-width: 4 -*-
2 *
3 * Electric(tm) VLSI Design System
4 *
5 * File: simfasthenry.cpp
6 * Simulation tool: FastHenry output
7 * Written by: Steven M. Rubin, Static Free Software
8 *
9 * Copyright (c) 2000 Static Free Software.
10 *
11 * Electric(tm) is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * Electric(tm) is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with Electric(tm); see the file COPYING. If not, write to
23 * the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
24 * Boston, Mass 02111-1307, USA.
25 *
26 * Static Free Software
27 * 4119 Alpine Road
28 * Portola Valley, California 94028
29 * info@staticfreesoft.com
30 */
31
32 #include "config.h"
33 #if SIMTOOL
34
35 #include "global.h"
36 #include "sim.h"
37 #include "usr.h"
38 #include "edialogs.h"
39
40
41 /* keys to cached variables */
42 INTBIG sim_fasthenrystatekey = 0; /* variable key for "SIM_fasthenry_state" */
43 INTBIG sim_fasthenryfreqstartkey = 0; /* variable key for "SIM_fasthenry_freqstart" */
44 INTBIG sim_fasthenryfreqendkey = 0; /* variable key for "SIM_fasthenry_freqend" */
45 INTBIG sim_fasthenryrunsperdecadekey = 0; /* variable key for "SIM_fasthenry_runsperdecade" */
46 INTBIG sim_fasthenrynumpoleskey = 0; /* variable key for "SIM_fasthenry_numpoles" */
47 INTBIG sim_fasthenryseglimitkey = 0; /* variable key for "SIM_fasthenry_seglimit" */
48 INTBIG sim_fasthenrythicknesskey = 0; /* variable key for "SIM_fasthenry_thickness" */
49 INTBIG sim_fasthenrywidthsubdivkey = 0; /* variable key for "SIM_fasthenry_width_subdivs" */
50 INTBIG sim_fasthenryheightsubdivkey = 0; /* variable key for "SIM_fasthenry_height_subdivs" */
51
52 INTBIG sim_fasthenryzheadkey = 0; /* variable key for "SIM_fasthenry_z_head" */
53 INTBIG sim_fasthenryztailkey = 0; /* variable key for "SIM_fasthenry_z_tail" */
54 INTBIG sim_fasthenrygroupnamekey = 0; /* variable key for "SIM_fasthenry_group_name" */
55
56 /* prototypes for local routines */
57 static BOOLEAN sim_writefhcell(NODEPROTO *np, FILE *io);
58 static void sim_fasthenryarcdlog(void);
59 static void sim_fasthenrydlog(void);
60 static void sim_fasthenrygetoptions(INTBIG *options, float *startfreq, float *endfreq,
61 INTBIG *runsperdecade, INTBIG *numpoles, INTBIG *seglenlimit, INTBIG *thickness,
62 INTBIG *widsubdiv, INTBIG *heisubdiv);
63 static CHAR *sim_fasthenrygetarcoptions(ARCINST *ai, INTBIG *thickness, INTBIG *widsubdiv,
64 INTBIG *heisubdiv, INTBIG *z_head, INTBIG *z_tail, BOOLEAN *zhover, BOOLEAN *ztover,
65 INTBIG *defz);
66 static PORTPROTO *sim_fasthenryfindotherport(ARCINST *ai, INTBIG end);
67
68 extern "C" { extern COMCOMP sim_fhp, sim_fhap; }
69
70 /*
71 * Routine called once to initialize this module
72 */
sim_fasthenryinit(void)73 void sim_fasthenryinit(void)
74 {
75 DiaDeclareHook(x_("fasthenry"), &sim_fhp, sim_fasthenrydlog);
76 DiaDeclareHook(x_("fasthenryarc"), &sim_fhap, sim_fasthenryarcdlog);
77 }
78
79 /*
80 * routine to write a ".sil" file from the cell "np"
81 */
sim_writefasthenrynetlist(NODEPROTO * np)82 void sim_writefasthenrynetlist(NODEPROTO *np)
83 {
84 CHAR name[100], *truename, txtpoles[20], *path;
85 FILE *io;
86 float startfreq, endfreq;
87 INTBIG options, runsperdecade, numpoles, seglenlimit, thickness, widsubdiv, heisubdiv,
88 lambda;
89
90 /* make sure network tool is on */
91 if ((net_tool->toolstate&TOOLON) == 0)
92 {
93 ttyputerr(_("Network tool must be running...turning it on"));
94 toolturnon(net_tool);
95 ttyputerr(_("...now reissue the simulation command"));
96 return;
97 }
98
99 /* get all parameters */
100 sim_fasthenrygetoptions(&options, &startfreq, &endfreq, &runsperdecade, &numpoles,
101 &seglenlimit, &thickness, &widsubdiv, &heisubdiv);
102
103 /* first write the "inp" file */
104 (void)estrcpy(name, np->protoname);
105 (void)estrcat(name, x_(".inp"));
106 io = xcreate(name, sim_filetypefasthenry, _("FastHenry File"), &truename);
107 if (io == NULL)
108 {
109 if (truename != 0) ttyputerr(_("Cannot write %s"), truename);
110 return;
111 }
112 xprintf(io, x_("* FastHenry for cell %s\n"), describenodeproto(np));
113 us_emitcopyright(io, x_("* "), x_(""));
114
115 if ((us_useroptions&NODATEORVERSION) == 0)
116 {
117 if (np->creationdate != 0)
118 xprintf(io, x_("* Cell created on %s\n"), timetostring((time_t)np->creationdate));
119 if (np->revisiondate != 0)
120 xprintf(io, x_("* Cell last modified on %s\n"), timetostring((time_t)np->revisiondate));
121 xprintf(io, x_("* Netlist written on %s\n"), timetostring(getcurrenttime()));
122 xprintf(io, x_("* Written by Electric VLSI Design System, version %s\n"), el_version);
123 } else
124 {
125 xprintf(io, x_("* Written by Electric VLSI Design System\n"));
126 }
127
128 xprintf(io, x_("\n* Units are microns\n"));
129 xprintf(io, x_(".units um\n"));
130
131 /* write default width and height subdivisions */
132 lambda = lambdaofcell(np);
133 xprintf(io, x_("\n* Default number of subdivisions\n"));
134 xprintf(io, x_(".Default nwinc=%ld nhinc=%ld h=%s\n"), widsubdiv, heisubdiv, latoa(thickness, lambda));
135
136 /* reset flags for cells that have been written */
137 if (sim_writefhcell(np, io))
138 ttyputmsg(x_("Back-annotation information has been added (library must be saved)"));
139
140 /* write frequency range */
141 if ((options&FHUSESINGLEFREQ) == 0)
142 {
143 xprintf(io, x_("\n.freq fmin=%g fmax=%g ndec=%ld\n"), startfreq, endfreq, runsperdecade);
144 } else
145 {
146 xprintf(io, x_("\n.freq fmin=%g fmax=%g ndec=1\n"), startfreq, startfreq);
147 }
148
149 /* clean up */
150 xprintf(io, x_("\n.end\n"));
151 xclose(io);
152 ttyputmsg(_("%s written"), truename);
153
154 /* generate invocation for fasthenry */
155 EProcess fh_process;
156 path = egetenv(x_("ELECTRIC_FASTHENRYLOC"));
157 if (path == NULL) path = FASTHENRYLOC;
158 fh_process.addArgument( path );
159 if ((options&FHMAKEMULTIPOLECKT) != 0)
160 {
161 fh_process.addArgument( x_("-r") );
162 esnprintf(txtpoles, 20, x_("%ld"), numpoles);
163 fh_process.addArgument( txtpoles );
164 fh_process.addArgument( x_("-M") );
165 }
166 fh_process.addArgument( truename );
167 fh_process.setCommunication( FALSE, FALSE, FALSE );
168 fh_process.start();
169 /* No wait */
170 }
171
172 /*
173 * recursively called routine to print the SILOS description of cell "np".
174 * The description is treated as the top-level cell if "top" is nonzero
175 * np is the current nodeproto
176 */
sim_writefhcell(NODEPROTO * np,FILE * io)177 BOOLEAN sim_writefhcell(NODEPROTO *np, FILE *io)
178 {
179 REGISTER BOOLEAN backannotate, found;
180 REGISTER NODEINST *ni;
181 REGISTER ARCINST *ai;
182 REGISTER PORTARCINST *pi;
183 REGISTER PORTPROTO *pp, *opp;
184 REGISTER INTBIG nodezval, zval, wid, thatend;
185 float xf, yf, zf, wf, hf;
186 CHAR *nname, *n1name, *n2name, *groupname;
187 static POLYGON *poly = NOPOLYGON;
188 REGISTER VARIABLE *var;
189 float startfreq, endfreq;
190 INTBIG options, runsperdecade, numpoles, seglenlimit, thickness, defthickness,
191 widsubdiv, defwidsubdiv, heisubdiv, defheisubdiv, z_head, z_tail, defz;
192 BOOLEAN zhover, ztover;
193
194 /* get polygon */
195 (void)needstaticpolygon(&poly, 4, sim_tool->cluster);
196
197 /* stop if requested */
198 if (el_pleasestop != 0)
199 {
200 stopping(STOPREASONDECK);
201 return(FALSE);
202 }
203
204 /* get overriding defaults */
205 sim_fasthenrygetoptions(&options, &startfreq, &endfreq, &runsperdecade, &numpoles,
206 &seglenlimit, &defthickness, &defwidsubdiv, &defheisubdiv);
207
208 /* make sure that all nodes have names on them */
209 backannotate = FALSE;
210 if (asktool(net_tool, x_("name-all-nodes"), (INTBIG)np) != 0) backannotate = TRUE;
211
212 /* look at every node in the cell */
213 xprintf(io, x_("\n* Traces\n"));
214 for(ni = np->firstnodeinst; ni != NONODEINST; ni = ni->nextnodeinst)
215 {
216 /* see if this node has a FastHenry arc on it */
217 found = FALSE;
218 nodezval = 0;
219 for(pi = ni->firstportarcinst; pi != NOPORTARCINST; pi = pi->nextportarcinst)
220 {
221 ai = pi->conarcinst;
222 groupname = sim_fasthenrygetarcoptions(ai, &thickness, &widsubdiv, &heisubdiv,
223 &z_head, &z_tail, &zhover, &ztover, &defz);
224 if (groupname == 0) continue;
225 zval = defz;
226 if (ai->end[0].portarcinst == pi && zhover) zval = z_head;
227 if (ai->end[1].portarcinst == pi && ztover) zval = z_tail;
228 if (found)
229 {
230 /* LINTED "nodezval" used in proper order */
231 if (zval != nodezval)
232 ttyputerr(_("Warning: inconsistent z value at node %s"),
233 describenodeinst(ni));
234 }
235 nodezval = zval;
236 found = TRUE;
237 }
238 if (!found) continue;
239
240 /* node is an end point: get its name */
241 if (ni->firstportexpinst != NOPORTEXPINST)
242 {
243 nname = ni->firstportexpinst->exportproto->protoname;
244 } else
245 {
246 var = getvalkey((INTBIG)ni, VNODEINST, VSTRING, el_node_name_key);
247 if (var == NOVARIABLE) nname = x_(""); else nname = (CHAR *)var->addr;
248 }
249
250 /* write the "N" line */
251 xf = scaletodispunit((ni->lowx+ni->highx)/2, DISPUNITMIC);
252 yf = scaletodispunit((ni->lowy+ni->highy)/2, DISPUNITMIC);
253 zf = scaletodispunit(nodezval, DISPUNITMIC);
254 xprintf(io, x_("N_%s x=%g y=%g z=%g\n"), nname, xf, yf, zf);
255 }
256
257 /* look at every arc in the cell */
258 for(ai = np->firstarcinst; ai != NOARCINST; ai = ai->nextarcinst)
259 {
260 /* get info about this arc, stop if not part of the FastHenry output */
261 groupname = sim_fasthenrygetarcoptions(ai, &thickness, &widsubdiv, &heisubdiv,
262 &z_head, &z_tail, &zhover, &ztover, &defz);
263 if (groupname == 0) continue;
264
265 /* get size */
266 wid = ai->width;
267
268 /* get the name of the nodes on each end */
269 if (ai->end[0].nodeinst->firstportexpinst != NOPORTEXPINST)
270 {
271 n1name = ai->end[0].nodeinst->firstportexpinst->exportproto->protoname;
272 } else
273 {
274 var = getvalkey((INTBIG)ai->end[0].nodeinst, VNODEINST, VSTRING, el_node_name_key);
275 if (var == NOVARIABLE) n1name = x_(""); else n1name = (CHAR *)var->addr;
276 }
277 if (ai->end[1].nodeinst->firstportexpinst != NOPORTEXPINST)
278 {
279 n2name = ai->end[1].nodeinst->firstportexpinst->exportproto->protoname;
280 } else
281 {
282 var = getvalkey((INTBIG)ai->end[1].nodeinst, VNODEINST, VSTRING, el_node_name_key);
283 if (var == NOVARIABLE) n2name = x_(""); else n2name = (CHAR *)var->addr;
284 }
285
286 /* write the "E" line */
287 wf = scaletodispunit(wid, DISPUNITMIC);
288 xprintf(io, x_("E_%s_%s N_%s N_%s w=%g"), n1name, n2name, n1name, n2name, wf);
289 if (thickness > 0)
290 {
291 hf = scaletodispunit(thickness, DISPUNITMIC);
292 xprintf(io, x_(" h=%g"), hf);
293 }
294 if (widsubdiv > 0) xprintf(io, x_(" nwinc=%ld"), widsubdiv);
295 if (heisubdiv > 0) xprintf(io, x_(" nhinc=%ld"), heisubdiv);
296 xprintf(io, x_("\n"));
297 }
298
299 /* find external connections */
300 xprintf(io, x_("\n* External connections\n"));
301 for(ai = np->firstarcinst; ai != NOARCINST; ai = ai->nextarcinst)
302 ai->temp1 = 0;
303 for(pp = np->firstportproto; pp != NOPORTPROTO; pp = pp->nextportproto)
304 pp->temp1 = 0;
305
306 /* look at every export in the cell */
307 for(pp = np->firstportproto; pp != NOPORTPROTO; pp = pp->nextportproto)
308 {
309 if (pp->temp1 != 0) continue;
310 pp->temp1 = 1;
311 ni = pp->subnodeinst;
312 for(pi = ni->firstportarcinst; pi != NOPORTARCINST; pi = pi->nextportarcinst)
313 {
314 ai = pi->conarcinst;
315 var = getvalkey((INTBIG)ai, VARCINST, VSTRING, sim_fasthenrygroupnamekey);
316 if (var != NOVARIABLE) break;
317 }
318 if (pi == NOPORTARCINST) continue;
319
320 /* port "pp" is one end, now find the other */
321 if (ai->end[0].portarcinst == pi) thatend = 1; else thatend = 0;
322 opp = sim_fasthenryfindotherport(ai, thatend);
323 if (opp == NOPORTPROTO)
324 {
325 ttyputerr(_("Warning: trace on port %s has no other end that is an export"),
326 pp->protoname);
327 continue;
328 }
329
330 /* found two ports: write the ".external" line */
331 opp->temp1 = 1;
332 xprintf(io, x_(".external N_%s N_%s\n"), pp->protoname, opp->protoname);
333 }
334
335 /* warn about arcs that aren't connected to ".external" lines */
336 for(ai = np->firstarcinst; ai != NOARCINST; ai = ai->nextarcinst)
337 {
338 if (ai->temp1 != 0) continue;
339 var = getvalkey((INTBIG)ai, VARCINST, VSTRING, sim_fasthenrygroupnamekey);
340 if (var == NOVARIABLE) continue;
341 ttyputerr(_("Warning: arc %s is not on a measured trace"), describearcinst(ai));
342 }
343 return(backannotate);
344 }
345
sim_fasthenryfindotherport(ARCINST * ai,INTBIG end)346 PORTPROTO *sim_fasthenryfindotherport(ARCINST *ai, INTBIG end)
347 {
348 REGISTER NODEINST *ni;
349 REGISTER PORTARCINST *pi;
350 REGISTER ARCINST *oai;
351 REGISTER INTBIG thatend;
352 REGISTER PORTPROTO *opp;
353 REGISTER VARIABLE *var;
354
355 ai->temp1 = 1;
356 ni = ai->end[end].nodeinst;
357 if (ni->firstportexpinst != NOPORTEXPINST) return(ni->firstportexpinst->exportproto);
358 for(pi = ni->firstportarcinst; pi != NOPORTARCINST; pi = pi->nextportarcinst)
359 {
360 oai = pi->conarcinst;
361 if (oai == ai) continue;
362 var = getvalkey((INTBIG)ai, VARCINST, VSTRING, sim_fasthenrygroupnamekey);
363 if (var == NOVARIABLE) continue;
364 if (oai->end[0].portarcinst == pi) thatend = 1; else thatend = 0;
365 opp = sim_fasthenryfindotherport(oai, thatend);
366 if (opp != NOPORTPROTO) return(opp);
367 }
368 return(NOPORTPROTO);
369 }
370
sim_fasthenrygetoptions(INTBIG * options,float * startfreq,float * endfreq,INTBIG * runsperdecade,INTBIG * numpoles,INTBIG * seglenlimit,INTBIG * thickness,INTBIG * widsubdiv,INTBIG * heisubdiv)371 void sim_fasthenrygetoptions(INTBIG *options, float *startfreq, float *endfreq,
372 INTBIG *runsperdecade, INTBIG *numpoles, INTBIG *seglenlimit, INTBIG *thickness,
373 INTBIG *widsubdiv, INTBIG *heisubdiv)
374 {
375 REGISTER VARIABLE *var;
376
377 var = getvalkey((INTBIG)sim_tool, VTOOL, VINTEGER, sim_fasthenrystatekey);
378 if (var != NOVARIABLE) *options = var->addr; else *options = 0;
379 var = getvalkey((INTBIG)sim_tool, VTOOL, VFLOAT, sim_fasthenryfreqstartkey);
380 if (var != NOVARIABLE) *startfreq = castfloat(var->addr); else *startfreq = 0.0;
381 var = getvalkey((INTBIG)sim_tool, VTOOL, VFLOAT, sim_fasthenryfreqendkey);
382 if (var != NOVARIABLE) *endfreq = castfloat(var->addr); else *endfreq = 0.0;
383 var = getvalkey((INTBIG)sim_tool, VTOOL, VINTEGER, sim_fasthenryrunsperdecadekey);
384 if (var != NOVARIABLE) *runsperdecade = var->addr; else *runsperdecade = 1;
385 var = getvalkey((INTBIG)sim_tool, VTOOL, VINTEGER, sim_fasthenrynumpoleskey);
386 if (var != NOVARIABLE) *numpoles = var->addr; else *numpoles = 20;
387 var = getvalkey((INTBIG)sim_tool, VTOOL, VINTEGER, sim_fasthenryseglimitkey);
388 if (var != NOVARIABLE) *seglenlimit = var->addr; else *seglenlimit = 0;
389 var = getvalkey((INTBIG)sim_tool, VTOOL, VINTEGER, sim_fasthenrythicknesskey);
390 if (var != NOVARIABLE) *thickness = var->addr; else *thickness = 2*el_curlib->lambda[el_curtech->techindex];
391 var = getvalkey((INTBIG)sim_tool, VTOOL, VINTEGER, sim_fasthenrywidthsubdivkey);
392 if (var != NOVARIABLE) *widsubdiv = var->addr; else *widsubdiv = 1;
393 var = getvalkey((INTBIG)sim_tool, VTOOL, VINTEGER, sim_fasthenryheightsubdivkey);
394 if (var != NOVARIABLE) *heisubdiv = var->addr; else *heisubdiv = 1;
395 }
396
sim_fasthenrygetarcoptions(ARCINST * ai,INTBIG * thickness,INTBIG * widsubdiv,INTBIG * heisubdiv,INTBIG * z_head,INTBIG * z_tail,BOOLEAN * zhover,BOOLEAN * ztover,INTBIG * defz)397 CHAR *sim_fasthenrygetarcoptions(ARCINST *ai, INTBIG *thickness, INTBIG *widsubdiv,
398 INTBIG *heisubdiv, INTBIG *z_head, INTBIG *z_tail, BOOLEAN *zhover, BOOLEAN *ztover,
399 INTBIG *defz)
400 {
401 REGISTER VARIABLE *var;
402 REGISTER INTBIG total, i;
403 float lheight, lthickness;
404 static POLYGON *poly = NOPOLYGON;
405
406 /* get polygon */
407 (void)needstaticpolygon(&poly, 4, sim_tool->cluster);
408
409 /* get miscellaneous parameters */
410 var = getvalkey((INTBIG)ai, VARCINST, VINTEGER, sim_fasthenrythicknesskey);
411 if (var != NOVARIABLE) *thickness = var->addr; else *thickness = -1;
412 var = getvalkey((INTBIG)ai, VARCINST, VINTEGER, sim_fasthenrywidthsubdivkey);
413 if (var != NOVARIABLE) *widsubdiv = var->addr; else *widsubdiv = -1;
414 var = getvalkey((INTBIG)ai, VARCINST, VINTEGER, sim_fasthenryheightsubdivkey);
415 if (var != NOVARIABLE) *heisubdiv = var->addr; else *heisubdiv = -1;
416
417 /* get z depth and any overrides */
418 total = arcpolys(ai, NOWINDOWPART);
419 for(i=0; i<total; i++)
420 {
421 shapearcpoly(ai, i, poly);
422 if (get3dfactors(ai->proto->tech, poly->layer, &lheight, <hickness))
423 continue;
424 *defz = (INTBIG)(lheight * lambdaofarc(ai));
425 break;
426 }
427 var = getvalkey((INTBIG)ai, VARCINST, VINTEGER, sim_fasthenryzheadkey);
428 if (var == NOVARIABLE) *zhover = FALSE; else
429 {
430 *z_head = var->addr;
431 *zhover = TRUE;
432 }
433 var = getvalkey((INTBIG)ai, VARCINST, VINTEGER, sim_fasthenryztailkey);
434 if (var == NOVARIABLE) *ztover = FALSE; else
435 {
436 *z_tail = var->addr;
437 *ztover = TRUE;
438 }
439
440 /* get the group name */
441 var = getvalkey((INTBIG)ai, VARCINST, VSTRING, sim_fasthenrygroupnamekey);
442 if (var == NOVARIABLE) return(0);
443 return((CHAR *)var->addr);
444 }
445
446 /***************************************** DIALOGS *****************************************/
447
448 /* Simulation: FastHenry Options */
449 static DIALOGITEM sim_fasthenrydialogitems[] =
450 {
451 /* 1 */ {0, {164,392,188,472}, BUTTON, N_("OK")},
452 /* 2 */ {0, {164,12,188,92}, BUTTON, N_("Cancel")},
453 /* 3 */ {0, {32,20,48,140}, MESSAGE, N_("Frequency start:")},
454 /* 4 */ {0, {32,144,48,200}, EDITTEXT, x_("")},
455 /* 5 */ {0, {56,20,72,140}, MESSAGE, N_("Frequency end:")},
456 /* 6 */ {0, {56,144,72,200}, EDITTEXT, x_("")},
457 /* 7 */ {0, {80,20,96,140}, MESSAGE, N_("Runs per decade:")},
458 /* 8 */ {0, {80,144,96,200}, EDITTEXT, x_("")},
459 /* 9 */ {0, {8,8,24,200}, CHECK, N_("Use single frequency")},
460 /* 10 */ {0, {128,20,144,140}, MESSAGE, N_("Number of poles:")},
461 /* 11 */ {0, {128,144,144,200}, EDITTEXT, x_("")},
462 /* 12 */ {0, {104,8,120,200}, CHECK, N_("Make multipole subcircuit")},
463 /* 13 */ {0, {104,224,120,420}, CHECK, N_("Make PostScript view")},
464 /* 14 */ {0, {80,224,96,420}, MESSAGE, N_("Maximum segment length:")},
465 /* 15 */ {0, {80,424,96,480}, EDITTEXT, x_("")},
466 /* 16 */ {0, {32,224,48,420}, MESSAGE, N_("Default width subdivisions:")},
467 /* 17 */ {0, {32,424,48,480}, EDITTEXT, x_("")},
468 /* 18 */ {0, {56,224,72,420}, MESSAGE, N_("Default height subdivisions:")},
469 /* 19 */ {0, {56,424,72,480}, EDITTEXT, x_("")},
470 /* 20 */ {0, {128,224,144,420}, CHECK, N_("Make SPICE subcircuit")},
471 /* 21 */ {0, {8,224,24,420}, MESSAGE, N_("Default thickness:")},
472 /* 22 */ {0, {8,424,24,480}, EDITTEXT, x_("")},
473 /* 23 */ {0, {176,140,192,344}, POPUP, x_("")},
474 /* 24 */ {0, {156,176,172,320}, MESSAGE, N_("After writing deck:")}
475 };
476 static DIALOG sim_fasthenrydialog = {{75,75,276,565}, N_("FastHenry Options"), 0, 24, sim_fasthenrydialogitems, 0, 0};
477
478 /* special items for the "FastHenry options" dialog: */
479 #define DFHO_FREQSTART 4 /* frequency start (edit text) */
480 #define DFHO_FREQEND_L 5 /* frequency end label (stat text) */
481 #define DFHO_FREQEND 6 /* frequency end (edit text) */
482 #define DFHO_RUNSPERDEC_L 7 /* runs per decade label (stat text) */
483 #define DFHO_RUNSPERDEC 8 /* runs per decade (edit text) */
484 #define DFHO_USESINGLEFREQ 9 /* use single frequency (check) */
485 #define DFHO_NUMPOLES_L 10 /* number of poles label (stat text) */
486 #define DFHO_NUMPOLES 11 /* number of poles (edit text) */
487 #define DFHO_MULTIPOLE 12 /* make multipole subckt (check) */
488 #define DFHO_POSTSCRIPT 13 /* make PostScript view (check) */
489 #define DFHO_MAXSEGLEN 15 /* max seg length (edit text) */
490 #define DFHO_DEFWIDSUB 17 /* default width subdiv (edit text) */
491 #define DFHO_DEFHEISUB 19 /* default height subdiv (edit text) */
492 #define DFHO_MAKESPICE 20 /* make SPICE subckt (check) */
493 #define DFHO_DEFTHICK 22 /* default thickness (edit text) */
494 #define DFHO_AFTERWRITE 23 /* after deck writing (popup) */
495
sim_fasthenrydlog(void)496 void sim_fasthenrydlog(void)
497 {
498 REGISTER INTBIG itemHit, value, i;
499 REGISTER BOOLEAN canexecute;
500 float fvalue;
501 CHAR line[30], *newlang[5];
502 static CHAR *exechoices[] = {N_("Nothing run"), N_("Run FastHenry"),
503 N_("Run FastHenry Multiprocessing")};
504 float startfreq, endfreq;
505 INTBIG options, runsperdecade, numpoles, seglenlimit, thickness,
506 widsubdiv, heisubdiv;
507 REGISTER void *dia;
508
509 /* get all parameters */
510 sim_fasthenrygetoptions(&options, &startfreq, &endfreq, &runsperdecade, &numpoles,
511 &seglenlimit, &thickness, &widsubdiv, &heisubdiv);
512
513 /* Display the FastHenry options dialog box */
514 dia = DiaInitDialog(&sim_fasthenrydialog);
515 if (dia == 0) return;
516
517 /* set popup */
518 for(i=0; i<3; i++) newlang[i] = TRANSLATE(exechoices[i]);
519 DiaSetPopup(dia, DFHO_AFTERWRITE, 3, newlang);
520 canexecute = graphicshas(CANRUNPROCESS);
521 if (canexecute)
522 {
523 DiaUnDimItem(dia, DFHO_AFTERWRITE);
524 if ((options&FHEXECUTETYPE) == FHEXECUTERUNFH)
525 {
526 DiaSetPopupEntry(dia, DFHO_AFTERWRITE, 1);
527 } else if ((options&FHEXECUTETYPE) == FHEXECUTERUNFHMUL)
528 {
529 DiaSetPopupEntry(dia, DFHO_AFTERWRITE, 2);
530 }
531 } else
532 {
533 DiaDimItem(dia, DFHO_AFTERWRITE);
534 }
535
536 /* set checkboxes */
537 if ((options&FHUSESINGLEFREQ) != 0) DiaSetControl(dia, DFHO_USESINGLEFREQ, 1);
538 if ((options&FHMAKEMULTIPOLECKT) != 0) DiaSetControl(dia, DFHO_MULTIPOLE, 1);
539 if ((options&FHMAKEPOSTSCRIPTVIEW) != 0) DiaSetControl(dia, DFHO_POSTSCRIPT, 1);
540 if ((options&FHMAKESPICESUBCKT) != 0) DiaSetControl(dia, DFHO_MAKESPICE, 1);
541
542 /* load default frequency range */
543 esnprintf(line, 30, x_("%g"), startfreq); DiaSetText(dia, DFHO_FREQSTART, line);
544 esnprintf(line, 30, x_("%g"), endfreq); DiaSetText(dia, DFHO_FREQEND, line);
545 esnprintf(line, 30, x_("%ld"), runsperdecade); DiaSetText(dia, DFHO_RUNSPERDEC, line);
546
547 /* load segment limits */
548 DiaSetText(dia, DFHO_MAXSEGLEN, latoa(seglenlimit, 0));
549 DiaSetText(dia, DFHO_DEFTHICK, latoa(thickness, 0));
550 esnprintf(line, 30, x_("%ld"), widsubdiv); DiaSetText(dia, DFHO_DEFWIDSUB, line);
551 esnprintf(line, 30, x_("%ld"), heisubdiv); DiaSetText(dia, DFHO_DEFHEISUB, line);
552
553 /* load other numeric options */
554 esnprintf(line, 30, x_("%ld"), numpoles); DiaSetText(dia, DFHO_NUMPOLES, line);
555
556 if ((options&FHMAKEMULTIPOLECKT) != 0)
557 {
558 DiaUnDimItem(dia, DFHO_NUMPOLES_L);
559 DiaEditControl(dia, DFHO_NUMPOLES);
560 } else
561 {
562 DiaDimItem(dia, DFHO_NUMPOLES_L);
563 DiaNoEditControl(dia, DFHO_NUMPOLES);
564 }
565 if ((options&FHUSESINGLEFREQ) != 0)
566 {
567 DiaDimItem(dia, DFHO_FREQEND_L);
568 DiaNoEditControl(dia, DFHO_FREQEND);
569 DiaDimItem(dia, DFHO_RUNSPERDEC_L);
570 DiaNoEditControl(dia, DFHO_RUNSPERDEC);
571 } else
572 {
573 DiaUnDimItem(dia, DFHO_FREQEND_L);
574 DiaEditControl(dia, DFHO_FREQEND);
575 DiaUnDimItem(dia, DFHO_RUNSPERDEC_L);
576 DiaEditControl(dia, DFHO_RUNSPERDEC);
577 }
578 DiaDimItem(dia, DFHO_POSTSCRIPT);
579 DiaNoEditControl(dia, DFHO_MAXSEGLEN);
580 DiaDimItem(dia, DFHO_MAKESPICE);
581
582 for(;;)
583 {
584 itemHit = DiaNextHit(dia);
585 if (itemHit == OK || itemHit == CANCEL) break;
586 if (itemHit == DFHO_USESINGLEFREQ || itemHit == DFHO_MULTIPOLE ||
587 itemHit == DFHO_POSTSCRIPT || itemHit == DFHO_MAKESPICE)
588 {
589 value = 1 - DiaGetControl(dia, itemHit);
590 DiaSetControl(dia, itemHit, value);
591 if (itemHit == DFHO_USESINGLEFREQ)
592 {
593 if (value != 0)
594 {
595 DiaDimItem(dia, DFHO_FREQEND_L);
596 DiaNoEditControl(dia, DFHO_FREQEND);
597 DiaDimItem(dia, DFHO_RUNSPERDEC_L);
598 DiaNoEditControl(dia, DFHO_RUNSPERDEC);
599 } else
600 {
601 DiaUnDimItem(dia, DFHO_FREQEND_L);
602 DiaEditControl(dia, DFHO_FREQEND);
603 DiaUnDimItem(dia, DFHO_RUNSPERDEC_L);
604 DiaEditControl(dia, DFHO_RUNSPERDEC);
605 }
606 }
607 if (itemHit == DFHO_MULTIPOLE)
608 {
609 if (value != 0)
610 {
611 DiaUnDimItem(dia, DFHO_NUMPOLES_L);
612 DiaEditControl(dia, DFHO_NUMPOLES);
613 } else
614 {
615 DiaDimItem(dia, DFHO_NUMPOLES_L);
616 DiaNoEditControl(dia, DFHO_NUMPOLES);
617 }
618 }
619 continue;
620 }
621 }
622
623 if (itemHit == OK)
624 {
625 /* save options */
626 value = 0;
627 if (DiaGetControl(dia, DFHO_USESINGLEFREQ) != 0) value |= FHUSESINGLEFREQ;
628 if (DiaGetControl(dia, DFHO_MULTIPOLE) != 0) value |= FHMAKEMULTIPOLECKT;
629 if (DiaGetControl(dia, DFHO_POSTSCRIPT) != 0) value |= FHMAKEPOSTSCRIPTVIEW;
630 if (DiaGetControl(dia, DFHO_MAKESPICE) != 0) value |= FHMAKESPICESUBCKT;
631 i = DiaGetPopupEntry(dia, DFHO_AFTERWRITE);
632 if (i == 1) value |= FHEXECUTERUNFH; else
633 if (i == 2) value |= FHEXECUTERUNFHMUL;
634 if (value != options)
635 (void)setvalkey((INTBIG)sim_tool, VTOOL, sim_fasthenrystatekey, value, VINTEGER);
636
637 /* save other limits */
638 fvalue = (float)eatof(DiaGetText(dia, DFHO_FREQSTART));
639 if (fvalue != startfreq)
640 (void)setvalkey((INTBIG)sim_tool, VTOOL, sim_fasthenryfreqstartkey, castint(fvalue), VFLOAT);
641 fvalue = (float)eatof(DiaGetText(dia, DFHO_FREQEND));
642 if (fvalue != endfreq)
643 (void)setvalkey((INTBIG)sim_tool, VTOOL, sim_fasthenryfreqendkey, castint(fvalue), VFLOAT);
644 value = eatoi(DiaGetText(dia, DFHO_RUNSPERDEC));
645 if (value != runsperdecade)
646 (void)setvalkey((INTBIG)sim_tool, VTOOL, sim_fasthenryrunsperdecadekey, value, VINTEGER);
647 value = atola(DiaGetText(dia, DFHO_MAXSEGLEN), 0);
648 if (value != seglenlimit)
649 (void)setvalkey((INTBIG)sim_tool, VTOOL, sim_fasthenryseglimitkey, value, VINTEGER);
650 value = atola(DiaGetText(dia, DFHO_DEFTHICK), 0);
651 if (value != thickness)
652 (void)setvalkey((INTBIG)sim_tool, VTOOL, sim_fasthenrythicknesskey, value, VINTEGER);
653 value = eatoi(DiaGetText(dia, DFHO_DEFWIDSUB));
654 if (value != widsubdiv)
655 (void)setvalkey((INTBIG)sim_tool, VTOOL, sim_fasthenrywidthsubdivkey, value, VINTEGER);
656 value = eatoi(DiaGetText(dia, DFHO_DEFHEISUB));
657 if (value != heisubdiv)
658 (void)setvalkey((INTBIG)sim_tool, VTOOL, sim_fasthenryheightsubdivkey, value, VINTEGER);
659 value = eatoi(DiaGetText(dia, DFHO_NUMPOLES));
660 if (value != numpoles)
661 (void)setvalkey((INTBIG)sim_tool, VTOOL, sim_fasthenrynumpoleskey, value, VINTEGER);
662 }
663 DiaDoneDialog(dia);
664 }
665
666 /* Simulation: FastHenry Arc */
667 static DIALOGITEM sim_fasthenryarcdialogitems[] =
668 {
669 /* 1 */ {0, {88,236,112,316}, BUTTON, N_("OK")},
670 /* 2 */ {0, {40,236,64,316}, BUTTON, N_("Cancel")},
671 /* 3 */ {0, {32,8,48,132}, MESSAGE, N_("Thickness:")},
672 /* 4 */ {0, {32,136,48,216}, EDITTEXT, x_("")},
673 /* 5 */ {0, {56,8,72,132}, MESSAGE, N_("Width:")},
674 /* 6 */ {0, {56,136,72,216}, MESSAGE, x_("")},
675 /* 7 */ {0, {80,8,96,180}, MESSAGE, N_("Width subdivisions:")},
676 /* 8 */ {0, {80,184,96,216}, EDITTEXT, x_("")},
677 /* 9 */ {0, {104,8,120,180}, MESSAGE, N_("Height subdivisions:")},
678 /* 10 */ {0, {104,184,120,216}, EDITTEXT, x_("")},
679 /* 11 */ {0, {232,8,248,36}, MESSAGE, N_("X:")},
680 /* 12 */ {0, {232,40,248,136}, MESSAGE, x_("")},
681 /* 13 */ {0, {204,8,220,144}, MESSAGE, N_("Head of arc is at:")},
682 /* 14 */ {0, {256,8,272,36}, MESSAGE, N_("Y:")},
683 /* 15 */ {0, {256,40,272,136}, MESSAGE, x_("")},
684 /* 16 */ {0, {280,8,296,36}, MESSAGE, N_("Z:")},
685 /* 17 */ {0, {280,40,296,132}, EDITTEXT, x_("")},
686 /* 18 */ {0, {232,180,248,208}, MESSAGE, N_("X:")},
687 /* 19 */ {0, {232,212,248,308}, MESSAGE, x_("")},
688 /* 20 */ {0, {204,180,220,316}, MESSAGE, N_("Tail of arc is at:")},
689 /* 21 */ {0, {256,180,272,208}, MESSAGE, N_("Y:")},
690 /* 22 */ {0, {256,212,272,308}, MESSAGE, x_("")},
691 /* 23 */ {0, {280,180,296,208}, MESSAGE, N_("Z:")},
692 /* 24 */ {0, {280,212,296,304}, EDITTEXT, x_("")},
693 /* 25 */ {0, {144,8,160,108}, MESSAGE, N_("Group name:")},
694 /* 26 */ {0, {144,112,160,316}, POPUP, x_("")},
695 /* 27 */ {0, {168,80,184,176}, BUTTON, N_("New Group")},
696 /* 28 */ {0, {132,8,133,316}, DIVIDELINE, x_("")},
697 /* 29 */ {0, {192,8,193,316}, DIVIDELINE, x_("")},
698 /* 30 */ {0, {8,8,24,316}, CHECK, N_("Include this arc in FastHenry analysis")},
699 /* 31 */ {0, {304,88,320,168}, MESSAGE, N_("Default Z:")},
700 /* 32 */ {0, {304,172,320,268}, MESSAGE, x_("")}
701 };
702 static DIALOG sim_fasthenryarcdialog = {{75,75,404,401}, N_("FastHenry Arc Properties"), 0, 32, sim_fasthenryarcdialogitems, 0, 0};
703
704 /* special items for the "FastHenry arc" dialog: */
705 #define DFHA_ARCTHICK_L 3 /* arc thickness label (stat text) */
706 #define DFHA_ARCTHICK 4 /* arc thickness (edit text) */
707 #define DFHA_ARCWIDTH 6 /* arc width (stat text) */
708 #define DFHA_WIDTHSUBDIV_L 7 /* width subdiv label (edit text) */
709 #define DFHA_WIDTHSUBDIV 8 /* width subdivisions (edit text) */
710 #define DFHA_HEIGHTSUBDIV_L 9 /* height subdiv label (edit text) */
711 #define DFHA_HEIGHTSUBDIV 10 /* height subdivisions (edit text) */
712 #define DFHA_ARCHEADX 12 /* arc head X (stat text) */
713 #define DFHA_ARCHEADY 15 /* arc head Y (stat text) */
714 #define DFHA_ARCHEADZ_L 16 /* arc head Z label (stat text) */
715 #define DFHA_ARCHEADZ 17 /* arc head Z (edit text) */
716 #define DFHA_ARCTAILX 19 /* arc tail X (stat text) */
717 #define DFHA_ARCTAILY 22 /* arc tail Y (stat text) */
718 #define DFHA_ARCTAILZ_L 23 /* arc tail Z label (stat text) */
719 #define DFHA_ARCTAILZ 24 /* arc tail Z (edit text) */
720 #define DFHA_GROUPNAME_L 25 /* group name label (stat text) */
721 #define DFHA_GROUPNAME 26 /* group name (popup) */
722 #define DFHA_NEWGROUP 27 /* make new group (button) */
723 #define DFHA_INCLUDE 30 /* include in FastHenry (check) */
724 #define DFHA_DEFZ 32 /* default z (stat text) */
725
sim_fasthenryarcdlog(void)726 void sim_fasthenryarcdlog(void)
727 {
728 REGISTER INTBIG itemHit, value, groupnamesize, i, val, lambda;
729 REGISTER ARCINST *ai, *oai;
730 REGISTER VARIABLE *var;
731 CHAR line[60], *groupname, *pt, **groupnames, **newgroupnames, *newname;
732 float startfreq, endfreq;
733 INTBIG options, runsperdecade, numpoles, seglenlimit, thickness, defthickness,
734 widsubdiv, defwidsubdiv, heisubdiv, defheisubdiv, z_head, z_tail, defz;
735 BOOLEAN zhover, ztover;
736 REGISTER void *dia;
737
738 /* get currently selected arc */
739 ai = (ARCINST *)asktool(us_tool, x_("get-arc"));
740 if (ai == NOARCINST)
741 {
742 ttyputerr(_("Select an arc first"));
743 return;
744 }
745 lambda = lambdaofarc(ai);
746
747 /* get all parameters */
748 sim_fasthenrygetoptions(&options, &startfreq, &endfreq, &runsperdecade, &numpoles,
749 &seglenlimit, &defthickness, &defwidsubdiv, &defheisubdiv);
750 groupname = sim_fasthenrygetarcoptions(ai, &thickness, &widsubdiv, &heisubdiv,
751 &z_head, &z_tail, &zhover, &ztover, &defz);
752
753 /* display the FastHenry arc dialog box */
754 dia = DiaInitDialog(&sim_fasthenryarcdialog);
755 if (dia == 0) return;
756
757 /* make a list of all group names */
758 groupnamesize = 0;
759 for(oai = ai->parent->firstarcinst; oai != NOARCINST; oai = oai->nextarcinst)
760 {
761 var = getvalkey((INTBIG)oai, VARCINST, VSTRING, sim_fasthenrygroupnamekey);
762 if (var != NOVARIABLE)
763 {
764 for(i=0; i<groupnamesize; i++)
765 {
766 /* LINTED "groupnames" used in proper order */
767 if (namesame(groupnames[i], (CHAR *)var->addr) == 0) break;
768 }
769 if (i < groupnamesize) continue;
770
771 /* add to the list */
772 newgroupnames = (CHAR **)emalloc((groupnamesize+1) * (sizeof (CHAR *)),
773 sim_tool->cluster);
774 for(i=0; i<groupnamesize; i++)
775 newgroupnames[i] = groupnames[i];
776 (void)allocstring(&newgroupnames[groupnamesize], (CHAR *)var->addr,
777 sim_tool->cluster);
778 if (groupnamesize > 0) efree((CHAR *)groupnames);
779 groupnames = newgroupnames;
780 groupnamesize++;
781 }
782 }
783 if (groupnamesize == 0)
784 {
785 groupnames = (CHAR **)emalloc((sizeof (CHAR *)), sim_tool->cluster);
786 (void)allocstring(&groupnames[0], _("Group 1"), sim_tool->cluster);
787 groupnamesize++;
788 }
789 DiaSetPopup(dia, DFHA_GROUPNAME, groupnamesize, groupnames);
790
791 /* select group name */
792 if (groupname != 0)
793 {
794 for(i=0; i<groupnamesize; i++)
795 if (namesame(groupname, groupnames[i]) == 0) break;
796 if (i < groupnamesize) DiaSetPopupEntry(dia, DFHA_GROUPNAME, i);
797 }
798
799 /* show arc parameters */
800 esnprintf(line, 60, _("Thickness (%s):"), latoa(defthickness, lambda));
801 DiaSetText(dia, DFHA_ARCTHICK_L, line);
802 if (thickness >= 0)
803 DiaSetText(dia, DFHA_ARCTHICK, latoa(thickness, lambda));
804 DiaSetText(dia, DFHA_ARCWIDTH, latoa(ai->width, lambda));
805
806 /* show subdivision overrides */
807 esnprintf(line, 60, _("Width subdivisions (%ld):"), defwidsubdiv);
808 DiaSetText(dia, DFHA_WIDTHSUBDIV_L, line);
809 if (widsubdiv > 0)
810 {
811 esnprintf(line, 60, x_("%ld"), widsubdiv);
812 DiaSetText(dia, DFHA_WIDTHSUBDIV, line);
813 }
814 esnprintf(line, 60, _("Height subdivisions (%ld):"), defheisubdiv);
815 DiaSetText(dia, DFHA_HEIGHTSUBDIV_L, line);
816 if (heisubdiv > 0)
817 {
818 esnprintf(line, 60, x_("%ld"), heisubdiv);
819 DiaSetText(dia, DFHA_HEIGHTSUBDIV, line);
820 }
821
822 /* show end coordinates */
823 DiaSetText(dia, DFHA_DEFZ, latoa(defz, lambda));
824 DiaSetText(dia, DFHA_ARCHEADX, latoa(ai->end[0].xpos, lambda));
825 DiaSetText(dia, DFHA_ARCHEADY, latoa(ai->end[0].ypos, lambda));
826 if (zhover) DiaSetText(dia, DFHA_ARCHEADZ, latoa(z_head, lambda));
827 DiaSetText(dia, DFHA_ARCTAILX, latoa(ai->end[1].xpos, lambda));
828 DiaSetText(dia, DFHA_ARCTAILY, latoa(ai->end[1].ypos, lambda));
829 if (ztover) DiaSetText(dia, DFHA_ARCTAILZ, latoa(z_tail, lambda));
830
831 if (groupname != 0)
832 {
833 DiaUnDimItem(dia, DFHA_ARCTHICK_L);
834 DiaEditControl(dia, DFHA_ARCTHICK);
835 DiaUnDimItem(dia, DFHA_WIDTHSUBDIV_L);
836 DiaEditControl(dia, DFHA_WIDTHSUBDIV);
837 DiaUnDimItem(dia, DFHA_HEIGHTSUBDIV_L);
838 DiaEditControl(dia, DFHA_HEIGHTSUBDIV);
839 DiaUnDimItem(dia, DFHA_ARCHEADZ_L);
840 DiaEditControl(dia, DFHA_ARCHEADZ);
841 DiaUnDimItem(dia, DFHA_ARCTAILZ_L);
842 DiaEditControl(dia, DFHA_ARCTAILZ);
843 DiaUnDimItem(dia, DFHA_GROUPNAME_L);
844 DiaUnDimItem(dia, DFHA_GROUPNAME);
845 DiaUnDimItem(dia, DFHA_NEWGROUP);
846 DiaSetControl(dia, DFHA_INCLUDE, 1);
847 } else
848 {
849 DiaDimItem(dia, DFHA_ARCTHICK_L);
850 DiaNoEditControl(dia, DFHA_ARCTHICK);
851 DiaDimItem(dia, DFHA_WIDTHSUBDIV_L);
852 DiaNoEditControl(dia, DFHA_WIDTHSUBDIV);
853 DiaDimItem(dia, DFHA_HEIGHTSUBDIV_L);
854 DiaNoEditControl(dia, DFHA_HEIGHTSUBDIV);
855 DiaDimItem(dia, DFHA_ARCHEADZ_L);
856 DiaNoEditControl(dia, DFHA_ARCHEADZ);
857 DiaDimItem(dia, DFHA_ARCTAILZ_L);
858 DiaNoEditControl(dia, DFHA_ARCTAILZ);
859 DiaDimItem(dia, DFHA_GROUPNAME_L);
860 DiaDimItem(dia, DFHA_GROUPNAME);
861 DiaDimItem(dia, DFHA_NEWGROUP);
862 }
863
864 for(;;)
865 {
866 itemHit = DiaNextHit(dia);
867 if (itemHit == OK || itemHit == CANCEL) break;
868 if (itemHit == DFHA_INCLUDE)
869 {
870 value = 1 - DiaGetControl(dia, itemHit);
871 DiaSetControl(dia, itemHit, value);
872 if (value != 0)
873 {
874 DiaUnDimItem(dia, DFHA_ARCTHICK_L);
875 DiaEditControl(dia, DFHA_ARCTHICK);
876 DiaUnDimItem(dia, DFHA_WIDTHSUBDIV_L);
877 DiaEditControl(dia, DFHA_WIDTHSUBDIV);
878 DiaUnDimItem(dia, DFHA_HEIGHTSUBDIV_L);
879 DiaEditControl(dia, DFHA_HEIGHTSUBDIV);
880 DiaUnDimItem(dia, DFHA_ARCHEADZ_L);
881 DiaEditControl(dia, DFHA_ARCHEADZ);
882 DiaUnDimItem(dia, DFHA_ARCTAILZ_L);
883 DiaEditControl(dia, DFHA_ARCTAILZ);
884 DiaUnDimItem(dia, DFHA_GROUPNAME_L);
885 DiaUnDimItem(dia, DFHA_GROUPNAME);
886 DiaUnDimItem(dia, DFHA_NEWGROUP);
887 DiaSetControl(dia, DFHA_INCLUDE, 1);
888 } else
889 {
890 DiaDimItem(dia, DFHA_ARCTHICK_L);
891 DiaNoEditControl(dia, DFHA_ARCTHICK);
892 DiaDimItem(dia, DFHA_WIDTHSUBDIV_L);
893 DiaNoEditControl(dia, DFHA_WIDTHSUBDIV);
894 DiaDimItem(dia, DFHA_HEIGHTSUBDIV_L);
895 DiaNoEditControl(dia, DFHA_HEIGHTSUBDIV);
896 DiaDimItem(dia, DFHA_ARCHEADZ_L);
897 DiaNoEditControl(dia, DFHA_ARCHEADZ);
898 DiaDimItem(dia, DFHA_ARCTAILZ_L);
899 DiaNoEditControl(dia, DFHA_ARCTAILZ);
900 DiaDimItem(dia, DFHA_GROUPNAME_L);
901 DiaDimItem(dia, DFHA_GROUPNAME);
902 DiaDimItem(dia, DFHA_NEWGROUP);
903 }
904 continue;
905 }
906 if (itemHit == DFHA_NEWGROUP) /* new group name */
907 {
908 newname = ttygetline(_("New group name:"));
909 if (newname == 0 || *newname == 0) continue;
910 for(i=0; i<groupnamesize; i++)
911 if (namesame(groupnames[i], newname) == 0) break;
912 if (i < groupnamesize) continue;
913
914 /* add to the list */
915 newgroupnames = (CHAR **)emalloc((groupnamesize+1) * (sizeof (CHAR *)), sim_tool->cluster);
916 for(i=0; i<groupnamesize; i++)
917 newgroupnames[i] = groupnames[i];
918 (void)allocstring(&newgroupnames[groupnamesize], newname, sim_tool->cluster);
919 if (groupnamesize > 0) efree((CHAR *)groupnames);
920 groupnames = newgroupnames;
921 groupnamesize++;
922 DiaSetPopup(dia, DFHA_GROUPNAME, groupnamesize, groupnames);
923 DiaSetPopupEntry(dia, DFHA_GROUPNAME, groupnamesize-1);
924 continue;
925 }
926 }
927
928 if (itemHit == OK)
929 {
930 startobjectchange((INTBIG)ai, VARCINST);
931 var = getvalkey((INTBIG)ai, VARCINST, VSTRING, sim_fasthenrygroupnamekey);
932 if (DiaGetControl(dia, DFHA_INCLUDE) != 0)
933 {
934 /* active in FastHenry */
935 i = DiaGetPopupEntry(dia, DFHA_GROUPNAME);
936 groupname = groupnames[i];
937 if (var == NOVARIABLE || estrcmp(groupname, (CHAR *)var->addr) != 0)
938 setvalkey((INTBIG)ai, VARCINST, sim_fasthenrygroupnamekey,
939 (INTBIG)groupname, VSTRING|VDISPLAY);
940 } else
941 {
942 if (var != NOVARIABLE)
943 (void)delvalkey((INTBIG)ai, VARCINST, sim_fasthenrygroupnamekey);
944 }
945
946 /* save thickness */
947 pt = DiaGetText(dia, DFHA_ARCTHICK);
948 var = getvalkey((INTBIG)ai, VARCINST, VINTEGER, sim_fasthenrythicknesskey);
949 if (*pt != 0)
950 {
951 val = atola(pt, 0);
952 if (var == NOVARIABLE || val != var->addr)
953 setvalkey((INTBIG)ai, VARCINST, sim_fasthenrythicknesskey, val, VINTEGER);
954 } else
955 {
956 if (var != NOVARIABLE)
957 (void)delvalkey((INTBIG)ai, VARCINST, sim_fasthenrythicknesskey);
958 }
959
960 /* save width and height subdivisions */
961 pt = DiaGetText(dia, DFHA_WIDTHSUBDIV);
962 var = getvalkey((INTBIG)ai, VARCINST, VINTEGER, sim_fasthenrywidthsubdivkey);
963 if (*pt != 0)
964 {
965 val = eatoi(pt);
966 if (var == NOVARIABLE || val != var->addr)
967 setvalkey((INTBIG)ai, VARCINST, sim_fasthenrywidthsubdivkey, val, VINTEGER);
968 } else
969 {
970 if (var != NOVARIABLE)
971 (void)delvalkey((INTBIG)ai, VARCINST, sim_fasthenrywidthsubdivkey);
972 }
973 pt = DiaGetText(dia, DFHA_HEIGHTSUBDIV);
974 var = getvalkey((INTBIG)ai, VARCINST, VINTEGER, sim_fasthenryheightsubdivkey);
975 if (*pt != 0)
976 {
977 val = eatoi(pt);
978 if (var == NOVARIABLE || val != var->addr)
979 setvalkey((INTBIG)ai, VARCINST, sim_fasthenryheightsubdivkey, val, VINTEGER);
980 } else
981 {
982 if (var != NOVARIABLE)
983 (void)delvalkey((INTBIG)ai, VARCINST, sim_fasthenryheightsubdivkey);
984 }
985
986 /* save z overrides */
987 pt = DiaGetText(dia, DFHA_ARCHEADZ);
988 var = getvalkey((INTBIG)ai, VARCINST, VINTEGER, sim_fasthenryzheadkey);
989 if (*pt != 0)
990 {
991 val = atola(pt, 0);
992 if (var == NOVARIABLE || val != var->addr)
993 setvalkey((INTBIG)ai, VARCINST, sim_fasthenryzheadkey, val, VINTEGER);
994 } else
995 {
996 if (var != NOVARIABLE)
997 (void)delvalkey((INTBIG)ai, VARCINST, sim_fasthenryzheadkey);
998 }
999 pt = DiaGetText(dia, DFHA_ARCTAILZ);
1000 var = getvalkey((INTBIG)ai, VARCINST, VINTEGER, sim_fasthenryztailkey);
1001 if (*pt != 0)
1002 {
1003 val = atola(pt, 0);
1004 if (var == NOVARIABLE || val != var->addr)
1005 setvalkey((INTBIG)ai, VARCINST, sim_fasthenryztailkey, val, VINTEGER);
1006 } else
1007 {
1008 if (var != NOVARIABLE)
1009 (void)delvalkey((INTBIG)ai, VARCINST, sim_fasthenryztailkey);
1010 }
1011 endobjectchange((INTBIG)ai, VARCINST);
1012 }
1013 DiaDoneDialog(dia);
1014
1015 /* free group list memory */
1016 for(i=0; i<groupnamesize; i++)
1017 efree(groupnames[i]);
1018 efree((CHAR *)groupnames);
1019 }
1020
1021 #endif /* SIMTOOL - at top */
1022